#clojure logs

2010-06-03

00:07KirinDaveAnyone wanna tell me I'm wrong?
00:07KirinDavehttp://kirindave.tumblr.com/post/658770511/monkey-patching-gorilla-engineering-protocols-in
00:08tomojyour fonts are ultra sexy
00:12KirinDavetomoj: Thanks. Museo and Museo Slab.
00:12KirinDaveMuseo is free. Slab is not.
00:14KirinDavetomoj: My opinion: typekit is worth every penny ;)
00:25mabesKirinDave: great post. The only thing that you might want to add is an explanation on why defprotocols, etc, are not simply wrapper objects like you would see in Ruby and other OO languages
00:25KirinDavemabes: Care to be more specific?
00:26mabesKirinDave: sure, the the problem with wrapper objects is (as explained to me at the recent clojure training) is that they usually destroy the concept of identity
00:27KirinDaveSure.
00:27KirinDaveI actually don't know how protocols work
00:28KirinDaveI noticed that if you have two protocols on the same type with the same name, it complains.
00:28KirinDaveWhich leads me to believe it's actually injecting things into the class?
00:29mabesso a MyIntHolder in Ruby would not == an int of the same value unless the the programmer explicitly added a #== method, where as in clojure the concept of equality is much simpler and is constant
00:29KirinDaveRight, but does it actually inject the method into the class?
00:30mabesinto the what class?
00:30mabeser.. into what class
00:31KirinDaveSay, I extend MyIntHolder with 2 protocols that both name a method with identical name and arity, it complains.
00:31tomojyeah, the generated class gets actual methods
00:33KirinDaveBut for say java.lang.String?
00:33tomojoh, I was thinking of deftype/defrecord
00:36tomojextend-protocol just modifies the protocol, not any classes
00:36mabesI know there was a misunderstanding on stackoverflow about that very issue.. people were saying that clojure somehow allowed for monkey patching of java.lang.String, but that is really not the case... I'm trying to find it to see if a more knowledgeable person explained the difference well
00:38mabesI think stuart holloway's video may touch on this subject as well: http://vimeo.com/11236603
00:41mabeshrm... I can't seem to find it..
00:43tomojhttps://gist.github.com/3fbd7c6f776820639aa1
00:43tomojalso, (.foo "") gives an error
00:45mabestomoj: very nice. thats the best example I've seen showing how the extensions respect name spaces and how they are different from monkey patches :)
00:48tomojit seems like deftype/defrecord examples usually use extend-protocol
00:48tomojI wonder why
00:50KirinDavetomoj: I tried to mention both. Probalby because most people have one protocol and many types. Because it's more typing.
00:50KirinDaveErr, less typing to have one protocol and more types.
00:50qebabAssuming I know scheme, python, c and have some passing experience with common lisp and haskell, should I just get a language reference and jump right into coding something or am I better off following a tutorial?
00:51KirinDaveIf you know python you are TAINTED
00:51seoushiqebab, thats what I've done so far. I've watched and read a few things but for the most part just jumped into coding.
00:51KirinDaveTAIIINNNTTEEEDDDDD
00:52qebabKirinDave: even worse, I even like it! :(
00:52qebabseoushi: okay, that sounds good
00:52mabesqebab: with a lisp background you could probably jump right in... this is a pretty good tutorial that you could skim through: http://java.ociweb.com/mark/clojure/article.html
00:52qebabthanks mabes
00:53tomojKirinDave: ah, yeah
00:54mabesqebab: reading this, if you haven't already, might also save you some frustration as well: http://clojure.org/lisps
00:55qebabmabes: thanks again
01:41lancepantzisn't there a reader macro that sets the :tag key in a functions meta data?
01:41lancepantzor is that deprecated in 1.2?
01:42tomoj,(meta #^String (fn [x] x))
01:42clojurebot{:tag java.lang.String}
01:42tomojhmm
01:43tomoj,(meta ^String (fn [x] x))
01:43clojurebot{:tag java.lang.String}
01:43tomoj,*clojure-version*
01:43clojurebot{:interim true, :major 1, :minor 2, :incremental 0, :qualifier "master"}
01:44lancepantzso it has to be a java class?
01:44tomoj,(meta ^:foo {})
01:44clojurebot{:tag :foo}
01:45lancepantznice
01:45lancepantzthanks tomoj
01:45tomojthis is kinda weird
01:45tomoj,(let [a 3] (meta ^a {}))
01:45clojurebot{:tag 3}
01:45tomoj(meta ^3 {})
01:45tomoj,(meta ^3 {})
01:45clojurebotMetadata must be Symbol,Keyword,String or Map
01:50lancepantzwish i could use a list or vector as metadata
01:50lancepantz*tag metadata
01:52tomojhow would that make sense
01:52tomoj^[Foo] for a function that returns a seq of Foos?
01:52lancepantzi'm using it to "tag" tests
01:53tomojthat sounds evil
01:53lancepantzso you can tag a test as unit, functional etc, i like the reader macro, but i'd like to be able to tag one test with multiple tags
01:53lancepantzwhy's that?
01:54tomoj:tag has special meaning
01:54lancepantzi was afraid that's what you were going to say, do you know what its used for?
01:55tomojit's for the return type of a fn or type of a value in a var
01:55tomoj,(meta ^{:test-tags [:foo :bar :baz]} {})
01:55clojurebot{:test-tags [:foo :bar :baz]}
01:55qebabwhat's the best way of running a clojure shell in emacs? just setting *inferior-lisp*?
01:56lancepantzyeah, i guess i'll do it that way
01:56tomojI don't think anything will blow up if you misuse :tag.. but it sounds like a bad idea to me
01:56tomojyou can of course define a macro which makes it prettier :)
01:56tomojqebab: SLIME?
01:57qebabtomoj: ohh, neat
01:57qebabtomoj: didn't know clojure was supported, I'll look into that, thanks :)
01:57lancepantztest functions don't actually have a return value, so i don't think it would affect anything, for now.
01:57tomojqebab: http://github.com/technomancy/swank-clojure/blob/master/README.md
01:57qebabthanks a million tomoj
01:59tomojqebab: basically: install ELPA, install clojure-mode and slime-repl from ELPA, use leiningen or maven
02:00lancepantztomoj: how could i use a macro to make it prettier?
02:00lancepantzi would have to redefine deftest, correct?
02:01tomojwrap over it, yeah
02:01tomojyours could be called deftest or something else
02:02lancepantzcool, thanks for the pointers
02:47tomojcan anyone confirm that rec-map at http://blog.ethanjfast.com/2010/03/analyzing-word-frequencies-with-clojure-enlive-and-incanter/ is absolutely bonkers?
02:51replacatomoj: bonkers in what way?
02:53tomojwell, very overcomplicated and misusing trampoline, for example?
02:55replacatomoj: maybe. I doubt the tree would be so deep as to really need trampoline
02:55tomojright
02:55tomojbut isn't that use of trampoline equivalent to just recurring naively (e.g. (rec-map newc))?
02:56replacatomoj: but I don't have a problem with using it and otherwise it doesn't look too complicated to me
02:56tomojI mean, if the tree were deep enough, those trampolines wouldn't help
02:56replacatomoj: hmm, maybe. I'd have to reread the docs
02:57tomojalso.. (defn match [thing lst] (reduce #(or %1 %2) (map #(= thing %1) lst)))
02:57tomojthat, at least, is overcomplication, I hope
02:58replacayeah, you could just do (#{:div ...} mytag)
02:59replacaand not string the tag
02:59tomojI didn't even think about the stringification
03:00replacatomoj: now that you mention it, just replace the whole (let...) with
03:01tomojI think the whole function could be replaced by some simple enlive stuff, but I'm not sure because I still don't really understand what the heck it's doing
03:02replaca(rec-map (if (#{:div ...} (:tag %1)) (:content %1) ""))
03:03replacafor starters
03:03tomojso.. at least a little bonkers, eh?
03:03tomoj:)
03:04replacaoh, we all need some cod review
03:04replacabut using enlive just means letting Christophe handle your complexity for you
03:04tomojyeah, the question for me was whether the code could be improved or whether I needed to be improved
03:05replacabut, yeah I would say the (str (%1 :tag)) is bad style
03:05tomojI think code by people who are much smarter than me usually doesn't make any sense at first, so hard to tell whether it's the code or me that sucks
03:05replacait's more idiomatic to live in keyword-space
03:08replacabut it's important to read lots of code
03:08replacaI recommend the enlive source, in particular
03:08tomojthanks
03:09replacait'll warp your brain, but you'll come out the end a better functional programmer
03:10timcharperany concurrency/lazy-seq wiz's in here?
03:10replacahmm, maybe
03:10replacashoot your q
03:10timcharperI'm trying to build a pipeline function
03:11timcharperwhere a collection is passed through a various set of map transformations
03:11timcharperI'd like each step of the pipeline to happen in parallel, similar to how | works in bash (each process runs at full speed, sensitive to the buffers of the surrounding processes)
03:11timcharperthis implementation, unfortunately, does not work:
03:11timcharperhttp://pastie.org/990136
03:13timcharperIt eager loads, but what happens is map #1 will eager load 33 records, then once that's done, map #2 will proceed, do some work, wait for map #1
03:13timcharperin the end, they effectively wait on one-another instead of processing each seq in parallel
03:14timcharper(i've tried it with pmap too.... pmap of a pmap ends up not being much of a pmap at all :( )
03:14timcharperwell... pmap + chunking... because overhead of thread scheduling is great
03:14replacatimcharper: yeah, that looks completely serial to me
03:15timcharperbut since I'm wrapping the lazy-seq in a future... wouldn't it cause it to eager load in a separate thread ?
03:15timcharperor is it because the deref of the future is what causes the eager-load, so therefore it blocks?
03:15replacayeah, the deref will load it
03:15timcharperoh... ok
03:16timcharperso the future is effectively worthless (as the results show)
03:16replacalazyness and futures have nothing to do with each other, really
03:19timcharperyeah, I understand that
03:19timcharperhttp://clojure-log.n01se.net/date/2010-06-02.html
03:19timcharpertechnomancy mentioned I can wrap my calculations in a future, and it will work
03:19replacayou might be able to get something to work if you did a future with a doall on the collection to force the evaluation in the other thread
03:19timcharperwanting to exploit streams here (not load the whole thing in memory)
03:19replacabut you're still going to be lock stepping on the deref
03:19timcharperor rather, streaming-properties of lazy sequences
03:19timcharperperhaps I ask for too much ?
03:19timcharper(I don't see any reason why this shouldn't be possible)
03:19replacayou might look at fill-queue, though that adds a little complexity
03:19replaca(c.c.seq/fill-queue)
03:20timcharperextra complexity is acceptable so long as it gets the job done and it's tucked away in an abstraction
03:21replacayour lazy seqs could be built around reading from a queue of values
03:21replacaI'd have to play around with that, but I bet you could get a nice abstraction there
03:21timcharperhow would it look?
03:22replacahmmm
03:27replacaat it's core would be something like (fill-queue (fn [fill] (map f-sub-0 (fill-queue (fn [fill] (map f-sub-1 (fill-queue (fn [fill] ...)))))
03:27replacabut you wouldn't really build it that way - you'd automatically create a vector of fill functions or something
03:28timcharperyeah :) which I have already in the pipeline function
03:28timcharperI'll give it a shot
03:28replacaalso, you probably want to specify a significant queue size with the :queue-size parameter
03:29timcharperin other news.... I caused a eager-load to occur in the future
03:29replacait would be nice to abstract the fill-queue stuff away from the caller, of course
03:29timcharperit loaded the first 33 itmes
03:29replacasound like 1 chunk
03:29timcharperstill... even though it was occurring in a separate thread and the first item was calculated, it wouldn't give it to me until it was done eager loading
03:30replacayeah, cause you're really sucking the whole thing over to the other thread
03:30replacaconcurrency in clojure is tricky!
03:30tomojreplaca: StackOverflowError
03:30tomoj:D
03:31replacacool when you get it right, but head scratching when you don't
03:31timcharperthe fill-queue will overcome it ?
03:31replacaused properly, my son, it is a weapon of great power :-)
03:31timcharperheheh, ok
03:32replacain any case, time for me to get some sleep
03:32replacalet me know how it goes
03:32timcharperan excellent plan
03:32timcharpergood luck with it
03:32replacathx :)
03:47tomojoh, wow, the stack overflow wasn't from rec-map calling itself
03:48tomojit was inside .replaceAll
03:48tomojapparently you can get stack overflows from bad regexes
04:02LauJensentotally OT, but if there are any network experts that can help I'd really appreciate it: http://bbs.archlinux.org/viewtopic.php?pid=768835
04:03tomoj:( good luck
04:04TheBusbyer, is it only with wireless you have the problem?
04:05LauJensenTheBusby: I would imagine so, but I actually haven't tested eth0
04:05TheBusbyI'd do that first since it'll reduce the numbers of potential issues considerably
04:05LauJensenk, sec
04:24LauJensenOk - I think I know what the problem is now, thanks TheBusby for getting me out of my chair :)
04:43TheBusbyhehe, good to hear
04:45LauJensenYes - Except for the fact that its probably unfixable
04:46tomojwhat was the problem? just curious
04:46tomojoh, nevermind, saw your last post
04:47LauJensenYea I just updated it with my last whine :)
04:47TheBusbywell I thought you said it worked fine in Ubuntu 9.04 . That means there is definitely a work around though it may require some trade off rightT?
04:48LauJensenMy wifes laptop is running Ubuntu 9.04, I've never tried 9.04 of this machine as I installed 10.04 directly when I got it, then when I discovered this issue, I upgraded to Arch 2010.05
04:48LauJensenBut I guess booting from a 9.04 live-cd is a cheap way to find out
04:48TheBusbyyep
04:49TheBusbyer, what was the issue? driver I'm guessing?
04:49LauJensenI think it has to be the iwl-5000-ucode firmware
04:50LauJensencore/iwlwifi-5000-ucode 8.24.2.12-2
04:50LauJensen Intel wireless firmware for Intel's 5100BG, 5100ABG, 5100AGN, 5300AGN and 5350AGN wireless devices
04:50LauJensen
04:51TheBusbyisn't the firmware the same between Windows and Linux though? Wouldn't that still be a driver issue? (or is the firmware require a signed driver or something strange?)
04:52LauJensen I don't know. I imagine that Windows has a firmware/driver combo developed by Intel,and Linux has something 2 hobby devs slapped together in a basement
04:54LauJensenThis might be the way to go: http://www.instructables.com/id/WIFI-Antenna-Hack!/
04:56TheBusbyI'm assuming from this topic that when you used an ethernet cable the speeds were fine right?
04:56TheBusbywhat leads you to believe it's the wireless driver?
04:58LauJensenTheBusby: The tip was, eth0 was fullspeed, bringing it down and going to wlan was also full speed. Going back into my office was slow speed. I think its the driver because it works fine in Windows, eliminiting any hardware issues
04:58TheBusbyso after you connected via ethernet, and experienced no problems
04:58TheBusbythe wireless continued to work with no problems?
04:59TheBusbyyou've essentially removed the possibility of hardware issues with the Windows/Linux test
05:00TheBusbybut a number of possibilities remain. Is it driver, kernel, tcp/ip, etc...
05:00LauJensenYes the wireless had no problems when I was sitting right next to the router, going back to the office (about 20m away caused the issue)
05:01TheBusbyso you only experience the problem in linux at a distance from the router correct?
05:01LauJensenYes
05:02TheBusbyand do the signal strength, and noise ratio appear the same in both windows and linux at that distance?
05:03LauJensenNo, like I state in the post on the forum, the signal strength is 350% better when Im in Windows - Measuring from the office. I didn't test both OS' while next to the router, but I noticed that Linux had only 54% strength at 1.5 meters distance, which is much too little, I imagine Windows would have 100%.
05:09TheBusbycan you increase the signal strength? $ sudo iwconfig wlan0 txpower 15
05:09LauJensenHmm, my router can adjust its transmission power from 0 - 255, it was set to 10 which is the default
05:09LauJensenincreasing to 100 makes the signal 20% instead 8%
05:09TheBusbyyou were having problems uploading though correct?
05:09TheBusbyI'm wondering what you broadcast strength is set at...
05:10LauJensenNo problem uploading
05:10LauJensenBut to be honest I think this was the queue I needed to install cabled internet throughout the house
05:10TheBusbystill it's nice to use wireless with a laptop
05:10eevar2or switch to windows/mac? :p
05:11LauJenseneevar2: I'd rather loose 350% wifi signal, than 750% productivity, but thanks
05:11TheBusbyso you only have the bandwidth problem with downloading?
05:11TheBusbyyour archlinux post says the bandwidth problem is when "upholding"
05:12TheBusbyalso wondering if you're using the same channel, etc when using linux/win
05:12eevar2TheBusby: that's a router setting afaik?
05:13eevar2channel, that is
05:14TheBusbydon't remember the proper terms, but is it using the same frequency and everything?
05:16LauJensenping?
05:16clojurebotPONG!
05:16LauJensen,ping
05:16clojurebotjava.lang.Exception: Unable to resolve symbol: ping in this context
05:16LauJensenI had some kind of drop, but order is restored, 200x amplified signal solved the problem
05:16LauJensencables will be the permanent solution
05:17TheBusbyJust for background, https://bugs.launchpad.net/ubuntu/+source/linux-backports-modules-2.6.27/+bug/282453
05:17TheBusbyer, nmind
05:50esjLauJensen: More Power !
05:50LauJensenesj: hehe - I'm cable shopping now
05:50LauJensenBut I guess with Linux its true, you really get what you pay for :)
06:02LauJensenslurp does about 30mb/s here, how are you guys doing?
06:03LauJensenInteresting:
06:03LauJensenbestinclass.admin> (time (do (last (read-lines "access.log")) nil))
06:03LauJensen"Elapsed time: 372.741705 msecs"
06:03LauJensenbestinclass.admin> (time (do (slurp "access.log") nil))
06:03LauJensen"Elapsed time: 2030.449639 msecs"
06:03LauJensen
06:04LauJensenProbably the missing hints in slurps definition
06:51LauJensenrhickey: Any particular reason conj takes xs and conj! only takes x ?
06:51rhickeyLauJensen: nope
07:06Licenser_swing makes me sad :(
07:08hoeckLicenser_: why?
07:08Licenser_because my swing tree does not update
07:08Licenser_it works great in my demo example but not in my code :/
07:08eevar2Licenser_: read the tutorial. learn the event model
07:09Licenser_eevar2: it works for the example, sadly not in my real app and I'm not sure why
07:09hoeckand stick your gui-code to the event-dispatch-thread
07:09Licenser_well it gets called and all that isn't the problem I think
07:10Licenser_it is very odd
07:10eevar2Licenser_: i'd make the same assumption as hoeck. guess i should have written event/threading/painting
07:11Licenser_everything that gets called from without swing will be in the swing thread right?
07:11Licenser_or do I have to wrap every form into it?
07:14hoeckLicenser_: http://java.sun.com/docs/books/tutorial/uiswing/concurrency/dispatch.html
07:16hoeckLicenser_: if you call something from an action-listener, it is executed within the swing thread, from the repl you should use SwingUtilities/invokeLater
07:18Licenser_hoeck: I am only calling stuff from listeners
07:20Licenser_odd thing is, in the thread if I call it once it works if I call it twice it doesn't
07:20Licenser_erm the other way round
07:27hoeckmhh, maybe some listeners are fireing in the wrong order
07:29hoeckLicenser_: do you have a small example which reproduces the error?
07:31Licenser_hoeck: that is the problem, I have a smnall example which does not even so I do mostly the same
07:39Licenser_but I try to make it so it breaks there too :P
07:45Licenser_hoeck: I got on the trace of it, problerm seems to be maps as keys
07:53Licenser_hoeck: problem is the exxam ple can't be small since it uses clj-swing :/
07:56sparievcandera: thanks for the suggestion, I didn't know about <= taking more that 2 args
08:00hoeckLicenser_: mhh, if you do everything via listeners, maybe some of your actions must be invoked with SwingUtilities/invokeLater?
08:00Licenser_hoeck: I think the problem is something else it wokrs unless I use hashmaps as keys
08:00hoeckLicenser_: so that, before taking other actions, the "initial" event chain can be executed
08:00Licenser_I think it is an algoriuthm error not one of swing
08:00canderaspariev: NP. That problem has been in my head since you mentioned it yesterday. :)
08:01hoeckLicenser_: ah, ok
08:01sparievheh )
08:01canderaI was also trying to figure out if a zipper would make it easier to express.
08:01Licenser_which is hard since it's uglyish complex
08:01Licenser_and I have to wrap stuff in treepath and events and all other kind of ugly objects
08:02Licenser_oh this makes headache
08:09sparievcandera: I found it quite hard for me to think about such kind of problems in functional style, where you basically have to mutate data structures
08:10sparievtoo accustomed to imperative style thinking
08:10canderaThat's my big challenge too.
08:10canderaThe other areas of Clojure that are new to me haven't been nearly as hard to adjust to.
08:11canderaWhich is why I was thinking of zippers, since it's a functional way to "remember" your location in a sequence, which might make an approach that looks ahead a bit more tractable.
08:11canderaBut maybe I'm just trying to be pseudo-imperative.
08:25Licenser_I really don't get it :(
08:27bartjer, can't lazy seq be returned from a function?
08:27cemerickof course they can
08:27bartjfor eg: using the code in the winning answer here - http://stackoverflow.com/questions/613929/how-do-i-connect-to-a-mysql-database-from-clojure
08:28bartjI am unable to return only the resultset of the sql query
08:28bartjie. instead of (dorun (map #(println %) rs)) -> can't I just return rs?
08:30cemerickbartj: if the population of the rs (or any lazy seq) is dependent upon a thread-local binding (which may be the case given with-connection?), then you just need to return (doall rs) to ensure the seq is fully realized before escaping that scope.
08:30hoeckbartj: you can, but then you have to keep the connection open
08:30Licenser_\huzza I found it!
08:32cgrandbartj: try (doall rs) to force realization of the seq inside of the with-connection (dynamic) scope
08:32hoeckLicenser_: what was it?
08:32bartjanother approach I tried was to store the resultset into a variable using let and return that, which still doesn't help
08:32Licenser_I casted something to a string at one point
08:33bartjcgrand: no luck
08:33Licenser_which made it work with string indexes (of cause) but not anything else
08:33bartjcgrand: did try that
08:35bartjcemercik: no (doall rs) strangely doesn't seem to work
08:35cgrandbartj: what did you get? an error? nil?
08:35bartjnil
08:37candera(into [] rs), to realize the seq, perhaps?
08:37cemerickbartj: if it's returning nil, you've got bigger issues than returning a lazy seq
08:38canderaAh, right. I was thinking doall didn't return the seq. Wrong again! :)
08:39bartjlike I said: (dorun (map #(println %) lazy-seq)) does show some output
08:40bartjso wondering WTH I can't return the lazy-seq as well
08:43bartjcemerick: actually it doesn't return anything
08:44cemerickbartj: if you can print the results, you can return the results
08:48bartjcemerick: (defn get-result-set [] (sql/with-connection *db* (sql/with-query-results rs ["select-query"] rs)))
08:57LauJensen,(import '(javax.mail Session))
08:57clojurebotjava.lang.ClassNotFoundException: javax.mail.Session
08:59zmila-- download jar: http://www.java2s.com/Code/JarDownload/mail.jar.zip
08:59LauJensenyea I got it, just missed a dep in project.clj
09:00LauJensenIs there anything in contrib like (max 5 "hi there buddy") =>> "hi..y" ?
09:02cemerickbartj: I don't know what the semantics are of with-connection or with-query-results, but assuming rs is a lazy seq, then returning (doall rs) would seem sensible.
09:05r0man,(defrecord Dataset [url])
09:05clojurebotDENIED
09:06r0man,(new (type (Dataset. nil)) nil)
09:06clojurebotjava.lang.IllegalArgumentException: Unable to resolve classname: (type (Dataset. nil))
09:09r0manhow can i make a new record from instance of a record?
09:19a_strange_guyr0man why would you do that?
09:20a_strange_guythey are immutable, so there is no copiing necissary
09:23r0mana_strange_guy: i want to create a new modified instance
09:24a_strange_guy(assoc instance :key value)
09:24r0mana_strange_guy: and because (dissoc my-data-datatype :key-to-remove) yields a map and not a instance of my datatype
09:25a_strange_guyyou cannot dissoc a 'field' in a record
09:25a_strange_guywell, you can
09:26r0man(defrecord Dataset [url])
09:26r0man(class (dissoc (Dataset. "some-url") :url))
09:26a_strange_guybut it will return a map
09:26r0manyes and i want a datatype
09:26a_strange_guythat is not possible
09:26a_strange_guya defrecord MUST have the specified keys
09:27r0mana_strange_guy: so i thought building a new one with one of the keys set to nil
09:27r0mana_strange_guy: (Dataset. nil)
09:28a_strange_guy(assoc (Dataset. "Url") : url nil)
09:29r0mana_strange_guy: but i want to decide at runtime which record i instantiate
09:29r0mana_strange_guy: ok
09:30a_strange_guyif you want to remove the key completely
09:30a_strange_guythen you shouldnt sprecify it as a key
09:30r0mana_strange_guy: thx, it's solved. i was thinking around the corner :)
09:30a_strange_guyxD
09:50_extermhey everybody, after switching from clojure 1.0.0 to 1.1.0 I get the following stacktrace when building: http://pastebin.com/kvHvqHwe
09:50_extermany ideas?
09:58_extermi don't use with-bindings anywhere in my own code...
10:00chousermaybe your swank version is out of date?
10:00_extermah, now that's an idea :-)
10:01_extermdo you think it's somehow defining its own version of with-bindings?
10:01_extermI'll look for it
10:01_extermthanks for the idea!
10:12_extermno, it's definitely not the swank version. Nonetheless I'll check the other libraries I use.
10:14korrehawing problem with printing on other threads?
10:18_extermturns out it was (:use clojure.main) .
11:31chouserI have data handed to me that I would like to extend with a protocol. But the data is a vector, and I don't mean to extend *all* vectors.
11:32canderaWhy a protocol? To group a set of functions?
11:32chouserI could put metadata on the vector and use multimethods, or I could add a defrecord wrapper.
11:32chousercandera: yes, and because I need polymorphism. Other things will hand me similar data in a different format, and I want the same set of functions to work on both.
11:33AWizzArdchouser: I am in the same situation. I would have to wrap maps into a defrecord on which I then can define a protocoll. Kind of artificial though.
11:33chouserright. wrappers are bad.
11:33canderaIf you don't care about the perf involved with protocols, seems like a multimethod would be a good fit.
11:34canderaprotocol = dispatch on type, which you don't want. mm = dispatch on whatever.
11:34KirinDavechouser: Hey, I'm about to toss an article towards the digg/reddit/hnews sphere
11:34KirinDavechouser: Did I get anything majorly wrong with http://kirindave.tumblr.com/post/658770511/monkey-patching-gorilla-engineering-protocols-in
11:34KirinDave?
11:34canderaAnd as you said, wrappers are bad, especially here, where I'd assume you don't want to lose all the other operations that are valid against the vector.
11:34chouserI wonder if multimethod calls could ever get call-site caching like protocols, and how close the performance would be then.
11:35KirinDavechouser: I was reading a paper on that, actually
11:35chouserKirinDave: I was just reading that.
11:35chouseryour blog, I mean.
11:35KirinDaveAh
11:35KirinDavechouser: Egregiously wrong?
11:35chouservery smoothly written
11:36KirinDaveThanks. cemerick and I are putting together a book proposal so I figured it was time to dust off my writing and see if it was still readable.
11:36LauJensenchouser: Got a link to some descent explanation of call-site caching and all that goes with it?
11:36chouserLauJensen: no, I've got nuthin'
11:36LauJensenchouser: then you'll have to hack out something in here, go:
11:36chouserI've done the research, so I should write something up.
11:37KirinDaveLauJensen: http://anyall.org/self%20-%20polymorphic%20inline%20caching%20-%20ecoop91.pdf
11:37KirinDaveThe self paper is popular for that.
11:37KirinDaveLauJensen: If you're running a mac, get Papers.app. helps you organize+find these things.
11:37eintrwhat's the idiomatic way for a noop-function? I have a list of functions to be applied to a set, but some should be blank... something like apply-if-not-nil
11:37cemerickKirinDave: Probably shouldn't spread that around until, we, y'know, know what's going to happen. ;-)
11:37canderachouser: obviously didn't mean to imply that you don't know any of that. :)
11:37chouserKirinDave: "protocols laid out in advance" might give the impression the protocol has to exist before the classes in question. I don't think that's what you meant, is it?
11:38KirinDavechouser: No.
11:38KirinDavecemerick: I don't think it matters that much. I did recruit publicly in here, if you recall ;)
11:39bsteuberare there still active discount codes for Clojure in Action?
11:39chousercandera: I was hoping rhickey would show up and so, "oh right, I'll just check in a change so that protocols can dispatch on metadata"
11:39chousereintr: (constantly nil)
11:39canderaHeh. Wave his magic brain, as it were.
11:40KirinDaveSpeaking of protocols, chouser
11:40KirinDaveI was wondering if you knew how the implementation worked underneath.
11:40LauJensenAre there any (java?) libs out there estimating IQ based on some text that people have written, like a comment? Is it even possible?
11:40chouserKirinDave: not deeply, but I have some clues.
11:40KirinDaveSpecifically, how come if you have an object with 2 protocols that both implement a similar signature same name method, they can't coexist.
11:41KirinDaveI was surprised to learn that.
11:41KirinDaveSo I deftype and project two protocols that both implement (fn mymethod [x] ...)
11:41KirinDaveI thought that it WASN'T opening the type to include methods, since you could also do it to things like String.
11:41clojurebotmultimethods is what separates the boys from the men.
11:41chouserKirinDave: it's not opening the type, but the protocol functions are real functions and live in a namespace
11:42KirinDavechouser: Sure, but if I have a.Proto1 and b.Proto1 and I try to project them onto user.Type1 and they have identical signatures, it collides.
11:42KirinDaveI'd have thought in that scenario it'd be okay.
11:42chouserwhere a and b are different namespaces? That should be fine.
11:43KirinDaveI tried it the other day and it complained. Standby
11:45KirinDavechouser: https://gist.github.com/f680abfeb365a3f881e6
11:45KirinDavechouser: See?
11:46chouserah, fascinating!
11:46chouserI wonder if that's documented anywhere...
11:47KirinDaveReload it
11:47chouserbut the reason is that defining a method inline in a defrecord or deftype is not the same ...
11:47chouserright
11:47KirinDaveIt works fine with java.lang.String
11:47chouseris not the same as extending it after it exists.
11:47KirinDaveLet me try
11:48KirinDaveHuh , you're right.
11:48chouserdefining it inline makes it an actual java method of the actual java class. This is good for interop, performance, etc. but you can't do it after the class is defined and the methods can collide.
11:48chousermay collide
11:48KirinDaveBut it's still wired into the protocol system
11:48chouseryes
11:48KirinDaveThat's a little confusing
11:50KirinDaveI don't think that asymmetry is documented. It may be implied, but it's not really specified.
11:50chouserwhen you define a protocol, it creates an interface of the same name.
11:51KirinDaveI get that part
11:51chouserany java class that implements that interface is then wired into the protocol system
11:51chouser(defprotocol testp (x [this])) (x (proxy [user.testp] [] (x [] :hello)))
11:51KirinDaveIt's just, I thought that (deftype internals ifacea ... ifaceb ...) was isomorphic to (extend-type)
11:52KirinDaveBut it seems like extend-type must be doing something quite different
11:52cemerickeverything in the deftype/defrecord body is about defining a class
11:52chousermethod defs inlined in deftype actually implement the interface methods, not really the protocol method.
11:52cemerickextend-type is bridging a protocol to a (fixed) class
11:52KirinDaveThat's really interestin.
11:53KirinDaveI guess that's sort of implied by the visibility of internal members in deftype but not in extend-type
11:53chouserbut since the protocol function knows how to work with all things that implement the interface, it works properly
11:53KirinDaveSo where do the mappings made by extend-type and extend-protocol live?
11:54KirinDaveIn something related to the protocol functions themselves?
11:54chouserKirinDave: defprotocol creates an interface and a var
11:54chouseruser.testp and user/testp
11:55chouserthe var has all the dynamic info
11:56chouser(-> testp :impls keys) should return all the dynamically extended classes
11:58KirinDaveAhhh, that's clever
11:59KirinDaveI read something about the performance of protocols being much better though
11:59chouserbetter than what?
11:59KirinDaveGenerics
11:59chouserJava Generics?
11:59KirinDaveclojure generic multi-methods.
11:59chouseroh. yes, better than multi-methods
12:00KirinDaveThe multiple dispatch stuff
12:00KirinDaveBut it seems like it has a similar map lookup to do.
12:00chouserwhen you call a multimethod it calls your dispatch function every time. Then looks up the result in a cache to get the implemention method, which is then called.
12:00chousercache miss is of course worse
12:02chouserwhen you call a protocol, there is a one-item cache right at that call site. If the type of the object, it calls the implementation method directly.
12:03chouserbecause instance? is fast on JVM, and because processors do branch prediction and speculative execution, this type lookup stuff is very close to free.
12:32bartjer, is there a clojure function which converts strings to integers
12:33bartjI am asking this because Integer.parseInt(String) in Java returns int -> which I do not want to use since the strings are really long
12:33defn,(map int "abcdef")
12:33clojurebot(97 98 99 100 101 102)
12:33pedroteixeirabartj: could use (read-string "1")
12:34bartjdefn: I mean the string is already an integer
12:34bartjpedroteixeira: clojure decides the type of the object?
12:35pedroteixeirabartj: yep, just reads the object.
12:35ChousukeThe BigInteger class probably has a suitable method
12:35defn,(class (read-string "1"))
12:35clojurebotjava.lang.Integer
12:36Chousukeif you use the reader you might get non-integer objects though :P
12:36defnYeah, might be...shall we say...messy...
12:39LajlaChousuke, onko clojure:ssa conintuation:ia?
12:40pedroteixeiraChousuke: using the reader, seemed the easiest to achieve this.. but one can use the (.parse (java.text.NumberFormat/getInstance) "1")
12:40pedroteixeira,(.parse (java.text.NumberFormat/getInstance) "1")
12:40clojurebot1
12:50cemerickbartj: (BigInteger. "somestring") is what you're looking for.
12:50cemerickjeez, never thought of using NumberFormat for parsing simple integers :-/
12:53bartjcontinuing the experiment - well, this seems puzzling
12:53bartj(def numbers '(37107287533902102798797998220837590246510135740250 46376937677490009712648124896970078050417018260538))
12:53bartj,(def numbers '(37107287533902102798797998220837590246510135740250 46376937677490009712648124896970078050417018260538))
12:53clojurebotDENIED
12:53bartj(+ (first numbers) (ffirst numbers))
12:54bartjthrows up a Don't know how to create ISeq from java.math.BigInteger
12:54bartjbut this seems to work:
12:54bartj, (+ 37107287533902102798797998220837590246510135740250 46376937677490009712648124896970078050417018260538)
12:54clojurebotjava.lang.ExceptionInInitializerError
12:54bartj,(+ 37107287533902102798797998220837590246510135740250 46376937677490009712648124896970078050417018260538)
12:54clojurebotjava.lang.ExceptionInInitializerError
12:54Chousukeffirst is short ofr (first (first ..))
12:54bartjer, atleast on my sistem
12:54bartj*system
12:55Chousukeyou mean "second"
12:55bartjoh
12:55defnim not quite sure what you're trying to accomplish bartj
12:56bartjdefn: I have large numbers in a file and am trying to sum them up
12:56defnis this project euler?
12:56bartjdefn: yes
12:57defnis it the 1000 digit number?
12:58cemerickwhat's the problem, exactly?
12:58cemerick,(BigInteger. "37107287533902102798797998220837590246510135740250")
12:58clojurebot37107287533902102798797998220837590246510135740250
13:01bartj13
13:03bartjdefn: I mean problem 13
13:12bartjcemerick: thanks!
13:13KirinDaveHmm
13:14KirinDaveIs it tacky to submit my own article to hackernews?
13:15_fogus_KirinDave: Yes. But not if you ask someone else to do it.
13:16KirinDavehaha
13:16KirinDaveDoes anyone want to submit my clojure article to them?
13:16KirinDavehttp://kirindave.tumblr.com/post/658770511/monkey-patching-gorilla-engineering-protocols-in
13:16_fogus_Which article?
13:16KirinDavelinked
13:16_fogus_on it
13:17technomancyKirinDave: only if your HN username matches your domain name =)
13:17_fogus_submitted
13:17_fogus_Is it tacky for me to tell everyone to go and upvote it? ;-)
13:17KirinDavetechnomancy: Which it does.
13:17KirinDave_fogus_: Never
13:18_fogus_Everyone wins!
13:18KirinDavetechnomancy: Damn my well-managed web identity!
13:19KirinDaveSo funny how easy it is to get onto the frontpage of hackernews
13:19_fogus_Yes. Whihc reminds me, I should work on my latest blog post
13:19_fogus_"Erlang, Clojure, Paul Graham, Starups"
13:19KirinDave_fogus_: I imagine you're doing a lot of writing lately. Is it making it hard to keep the blog going?
13:20_fogus_KirinDave: Actually, we're done. :-) Mostly
13:20KirinDaveOh congrats
13:20_fogus_Thank you
13:20KirinDaveThe Meap doesn't seem to have everything yet then?
13:20chouserthere's a pipeline...
13:21KirinDaveAh
13:21_fogus_No. They have a somewhat different release frequency than we'd like
13:21chouserwe've got robots trying to cut the pipeline and cap it, but we're not sure it'll work
13:21chouserwait, that's not right
13:22canderaAnyone have any ideas on how I can stop typing "(using ..." and "(foreach ..." in C# instead of "using (..." and "foreach (..."? :)
13:22KirinDavetext macros
13:22_fogus_candera: I have similar issues with Python
13:23canderaWell, supposedly C# 5 is all about metaprogramming...
13:23KirinDaveburgh
13:23KirinDaveC# is all about vestigal features
13:23canderaYeah, I sort of hope not to be around to learn about it.
13:23KirinDaveThat "no feature left behind" policy microsoft has hurts a language even more than an OS
13:23canderaOne thing Clojure has taught me, though, is that I like it better than Java.
13:24KirinDaveClojure over java or C# over java?
13:24canderaClojure >> C# > Java
13:24clojurebotamespaces are (more or less, Chouser) java packages. they look like foo.bar; and corresponde to a directory foo/ containg a file bar.clj in your classpath. the namespace declaration in bar.clj would like like (ns foo.bar). Do not try to use single segment namespaces. a single segment namespace is a namespace without a period in it
13:24KirinDavecandera: Really?
13:24KirinDavecandera: Java may not have some features I want, but C#'s design is just a mess.
13:24KirinDaveAnd the class libraries, the core ones, are WAY worse than Java's.
13:24KirinDaveI mean, you want to see a mess?
13:25KirinDaveThe reflection is a complete cluster.
13:25canderaSo, I agree that C# is a big ball of "features". But I've been using them incrementally for ten years, and I'd miss a lot of them (Linq, Closures, properties) if I didn't have them.
13:25KirinDaveLinq is a great example of a terrible idea.
13:25canderaNot going to argue the library design, either. But again, I've gotten used to it.
13:26KirinDaveA consistent collection API would have made way more sense than Linq, but linq predates lambdas
13:26canderaLinq is not perfect. But it's damn handy a lot of times. I'm talking about the extension methods over IEnumerable<T>, not the language keywords.
13:26KirinDaveSo now we're stuck with linq.
13:26KirinDaveSure, but those are also polluted by linq.
13:26KirinDaveFor example, what everyone calls map, they call select
13:26KirinDaveBut it's also sorta different
13:26canderaYep. That's suboptimal.
13:26canderaStill take it over nothing. ;)
13:27KirinDaveThat's a charitable way to put it.
13:27canderaWell, I'm hanging out on the Clojure channel while I'm supposed to be hacking C#, so you know where my heart is...
13:27KirinDave;0
13:27KirinDavesame
13:28canderaJava just feels like C# 1.0 to me. Strictly from a "how annoyed would I be using it" standpoint.
13:29canderaBut that turns out to be awesome from a "use it from Clojure" standpoint. Generics, properties, events, delegates, etc. - all that would be annoying to interop with. Not sure how D. Miller is going to pull all that off in a reasonable way.
13:33bendlashey guys
13:33bendlasfound a glitch in c.c.zip-filter.xml
13:34bendlaswhen parsing with zf/xml-> , zf/text eats newlines and the like
13:34bendlaswhen they are properly quoted in the original xml
13:35bendlaslike &#xd;
13:36bendlasusing v1.1
13:38bendlasam i doing something wrong?
13:42_fogus_"My conclusion is that Clojure without TDD is just as much a nightmare as Java or Ruby without TDD."
13:43LauJensen_fogus_: ?
13:43LauJensenI think you mean "TDD is a nightmare in any language"
13:44_fogus_not mine. blame uncle bob.
13:44KirinDaveHuh
13:44KirinDaveI am just not a TDD guy
13:44KirinDaveMaybe I am just AMAZING
13:44KirinDaveBut I sort of test interactively with the repl.
13:45_fogus_What's the acronym for someone who tests after the code is written?
13:45KirinDaveI test during the coding cycle
13:45KirinDaveI just don't write formalized unit tests
13:45KirinDaveI do that later
13:45_fogus_I guess I do something similar
13:45KirinDaveI test interactively as I go, that's what repls are good at.
13:46KirinDaveUsually I understand a function I have just written fairly intimiately because I've called it a few times.
13:46canderaI have found TDD to be great working in C#.
13:47canderaGood enough that I would hesitate to give it up until enough experience in Clojure shows me that it's not necessary. Stu Halloway has said that he's largely moved away from test-first towards test-post-facto.
13:47_fogus_I like DDD
13:47_fogus_(Developer Driven Development)
13:48bendlasHey, I don't want to bother you, but could at least somebody tell me off for not getting xml/zipfilters/...
13:48bendlassee above
13:48canderaAnd here I was trying to think of a good "triple D" joke.
13:50LauJensenbendlas: you should bug chouser about it, I think he broke it
13:51KirinDaveShoot! I forgot to mention that you could extend pre-existing types.
13:51_fogus_That can be part 2
13:51KirinDaveGuess so.
13:51KirinDaveI should show how you can do a real thing with it
13:52bendlasLauJensen: thanks
13:52KirinDaveMaybe I should rewrite my exchat server using those things.
13:52TimMcI'm trying to use Clojure to make a medium-sized web app -- does anyone have recommendations on HTML templating libraries?
13:52LauJensenTimMc: Did you catch my last blogpost?
13:52TimMcLauJensen: Link?
13:52LauJensenhttp://bestinclass.dk/index.clj/2010/05/refresh-your-cache--best-in-class-has-been-baked.html
13:53LauJensenIm working on OpenSourcing the entire project as we speak
13:53TimMcthansk
13:55TimMcHmmm... this web app is very much database-driven.
13:56LauJensenTimMc: Not a problem, that just means that you make an update cycle which updates the db and not the html files - i use those as a db
13:56LauJensenThe way you would use Enlive-templates is exactly the same
13:57TimMcEnlive... another good pointer.
13:57LauJensenAlmost the only pointer, Enlive generated everything you see on bestinclass.dk incl. the atom-feed
13:58TimMcA little background -- I'm researching languages, libraries, and frameworks for use in replacing a doddering old internal web app that ships our company's software to customers.
13:59TimMcIt is mostly CRUD operations on MySQL, with some emailing.
14:00TimMcWe're a Java shop, but some of the higher-ups have background in LISP, so Clojure is possibly viable.
14:00LauJensenok, there's a javalib for emailing which I have wrapped in Clojure, then you have contrib.sql and http://gitorious.org/clojureql for sql interfaces, and then enlive can help you build/scrape whatever html/xml you might want
14:00TimMcI'm very new to it, though.
14:01TimMcCool. I think Enlive was the missing piece. Once I understand exactly what that does, I'll check out your stuff. :-)
14:01LauJensenJavalib is javax.mail - available from maven central
14:01LauJensenTimMc: If you hang around or follow me on twitter/laujensen you'll get a ping once I upload the opensource code for the entire site, hopefully tonight or early tomorrow
14:02TimMcWill do.
14:05LauJensenTimMc: http://bestinclass.dk/index.clj/2009/12/dynamic-interactive-webdevelopment.html
14:05LauJensenThat might also be interesting - It shows a little web and a little sql action, though I don't use Compojure anymore myself, bestinclass.dk is driven entirely by Moustache, but the transistion is easy
14:16TimMc(I really need to get comfortable with Emacs, but it has a long learning curve.)
14:16TimMc(Watching your screencast.)
14:17LauJensenTimMc: There are altenatives to Emacs (I've also blogged about them), but if you want to be at the top of the class, then yes you need to check out Emacs :)
14:19bartjLauJensen: your solution in the above blogpost and Compojure (which I have looked yesterday) seem to "mix" html and Clojure
14:20bartjI thought web-designers would not want to touch any Clojure
14:20LauJensenbartj: Yea, you mean the screencast?
14:20bartjno this - http://bestinclass.dk/index.clj/2010/05/refresh-your-cache--best-in-class-has-been-baked.html
14:21LauJensenOh, not the HTML and the code are seperated completely. I have html files which serve as templates, and then template.clj which generates the final pages by mixing some params/transformations with the html
14:26bartjLauJensen: from my very limited knowledge of compojure, it seems that the html and clojure is quite interleaved
14:27LauJensenbartj: Ok - But good luck trying to find any compojure in the blogpost you just linked :)
14:28bartjLauJensen: which I apparently will not because you used Enlive?
14:28LauJensenYes
14:29LauJensenI mean, right, you wont
14:30LauJensenThe backend is still spewing out some html, but still using templates, no html/code mixed
14:30LauJensenAnd thats the Moustache part
14:38bartjLauJensen: Can you please post your Repl commands in the screencast somewhere?
14:39LauJensenbartj: Its a pretty old blogpost and the code is supremely outdated, so if there's anything specific you need to do lets talk about it instead :)
14:39LauJensen(not that I dont want to help, but I doubt its relevant now)
14:44bartjI seem to be currently using clojure.contrib.sql and the screen-cast uses clojureeql
14:44LauJensenclojureql, yes
14:45TimMcUrgh, it's going to take a bit for me to get used to tilde instead of comma for unquote.
14:46LauJensenTimMc: The good news is, that the macro-handler is going away in version 1.0 of ClojureQl, it will have an entirely new frontend, so at present I wouldn't start any new projects with it: http://gitorious.org/clojureql/pages/FrontendReworked
14:48LauJensenAnd before you ask about a release date, Im waiting for kotarak to finish his work on aliases, and we're working on getting an overview of how much we need to retrofit the backend - and then we're 1.0 :)
14:49bartjis there some comparision of clojureeql and clojure.contrib.sql
14:50bartjI am not sure if clojure.contrib.sql allows one to open a "global" handle ie. only one sql connection
14:51LauJensenNot that I know of. ClojureQL lets you run the same code on MySql, Oracle, Sqlite and PostgreSql - Mongo and Fleet are almost implemented as well
14:51LauJensenClojureQL is also all-lisp, and in Frontend2.0 all statements are Higher Order functions
14:51bartjand re-use it as necessary, where as looking at Lau's screencast shows that I can open a single global sql connection and use that for multiple sql statements - is this right Lau?
14:52TimMcLauJensen: The screencast is good, but the reuse of names for bindings and MySQL tables and columns is confusing.
14:52LauJensenbartj: We're putting in a connection pool, but I dont know how complex it will be. The 'run' function will take either a description of a connection, which it will open and close, or it will take the name of a global persistently open connection
14:52LauJensenTimMc: And like I said - thats going away in 1.0 :)
14:53TimMcNo, I mean in your screencast -- calling your vector of vectors "roster" and then iterating through it to insert the data into `roster`.
14:53TimMcOh! But in the new frontend, it wouldn't be as confusing. Got it.
14:54TimMcLooking at using keywords?
14:54LauJensenYea, it would be (insert-into :name name :age age) etc
14:54TimMcsweet
15:00bartjLauJensen: your screen-cast doesn't create a globally persistent connection. Am I right?
15:00LauJensenNo it does - I call (open-global :mysql (...)) right at the beginning, that opens a connection which is managed by ClojureQL
15:01TimMcLauJensen: WHen you saved your webdev.clj file and hit refresh in the browser, the changes were there. I assume that means the server is dynamically running the .clj files? Or is something intelligently updating variables?
15:03LauJensenTimMc: In that example, the page is generated on every load, so refreshing updates the clock
15:04TimMcSorry, not that bit -- where you added (ANY "*" 404)
15:04LauJensenAh - I most likely evaluated that expression (all routes) by hitting M-C-x and just forgot to mentioned it :±
15:04TimMcOr was that a little white lie, because the browser wasn't going to try getting the favicon again so soon?
15:04LauJensenNo lies
15:04TimMcHeh, OK.
15:06TimMcSo, you rebound my-routes to the new value, and the next time the servlet consulted its routing table, it had the new routes?
15:06bartjyes - you mean (open-global :mysql connection-info) where connection-info is a map right?
15:07bartjI also find it surprising that the connection-info map does not contain the driver class-name (com.mysql.jdbc.Driver) as a key
15:07LauJensenTimMc: Correct
15:07LauJensenbartj: Correct
15:08LauJensenbartj: You dont necessarily want to load a driver everytime to define a connection
15:08bartjLau Jensen: how else would it get the class name?
15:09LauJensenNot following
15:12bartjLauJensen: let me re-phrase - why doesn't the connection-map not have a key which has the name of the driver to load?
15:14LauJensenbartj: Because the task of defining a connection isn't directly linked with loading a driver
15:15TimMcLauJensen: Is that because there are multiple possible drivers per connection type?
15:15TimMc(So saying "I want to talk to a MySQL instance" wouldn't be sufficient.)
15:16LauJensenTimMc: No its more to do with the fact that if I dont have a clear reason to do so I wont force it upon the user. But I suppose you could use different drivers for the same connection, for some odd type of troubleshooting, but I admit Ive never seen it
15:16bartjer, how? if the protocol which is in the connection map is "mysql" then, don't I *have-to* know that the driver class-name is "com.mysql.jdbc.Driver"
15:16LauJensenAnd it might be better to bundle the two in (defconnection) or similar, so Im definitely open to it
15:16TimMcPerhaps dependency injection for test suites.
15:16TimMc(If you need to snoop the connection, for instance.)
15:16LauJensenbartj: Oh like that you mean - I cant guess which driver you're going to use
15:17LauJensenI use com.mysql, but you might use net.openjvm.mysql
15:18TimMcYeah, that's what I was referring to.
15:18bartjOK, I get what you say....the driver class is not related to the connection because different drivers can be used. Right?
15:19LauJensenYes
15:24maxhodakprint-dup monkeypatches java classes/
15:24maxhodak?
15:24maxhodakit seems to override the toString method
15:25maxhodak(. myclass toString) --> whatever serialization i've defined in (defmethod print-dup com.foo.myclassdef [o w] ...)
15:28kotarakmaxhodak: you have some code with some output showing the problem in a paste?
15:30tomoj(print-dup (Foo.) *out*) -> "foo\"
15:30tomoj(.toString (Foo.)) -> ".......Foo@1f95fc4"
15:31maxhodakkotarak: http://gist.github.com/424341
15:31chouserprn doesn't use print-dup by default
15:31chouserit uses print-method unless *print-dup* is true
15:31maxhodakhmm
15:32tomojthat shouldn't matter, should it?
15:32tomojthe thing being prn'd is a string
15:34maxhodak(prn *print-dup*) --> false
15:34pedroteixeiraany way to bind a private var in another namespace? was thinking something like (let [#'foo/bar 1]) )
15:35maxhodak(prn (. (ObjectId.) toString))) --> "(com.mongodb.ObjectId. \"4c08030520559bdc153828d5\")"
15:35maxhodak???
15:35maxhodakmakes no sense
15:35bartjLauJensen: what were the pain points that you were trying to solve with ClojureQL?
15:35tomojmaxhodak: yeah, no sense at all
15:36maxhodakit's not a prn using print-dup or print-method issue
15:36maxhodakit's a toString method issue
15:36maxhodakbecause prn is just getting a string anyway
15:37LauJensenbartj: Actually it started with me not wanting to write SQL, but rather stay completely in the lisp syntax. On larger projects its a pain to troubleshoot and quality maintain SQL. Then kotarak brought in the multimethod approach to the backend, which made it very easy to target multiple backends, so that was the groundwork
15:38chousertomoj: is there a print-method of ObjectId or one of its ancestors?
15:38tomojI don't know, but why would it matter?
15:39tomojmaxhodak is telling us that after defining print-dup for ObjectId, the toString method of ObjectId changes
15:39chousersorry, wrong person. also, I'm not thinking clearly.
15:39tomojthat can't be true, can it?
15:39maxhodakchouser: ObjectId is defined completely in java and doesn't inherit from anything
15:40chousermaxhodak: you see the same result without (prn ...), right?
15:41chouserif ObjectId is a java class, that 'use' isn't right.
15:42maxhodakchouser: oh
15:42maxhodakcrap wait
15:42bartjLauJensen: ok thanks
15:42maxhodakwhen i'm (read)'ing the serialized forms back
15:42maxhodakit's returning '(com.mongodb.ObjectId. "4c0804fa87f39bdcb900f8a9")
15:42maxhodakrather than (com.mongodb.ObjectId. "4c0804fa87f39bdcb900f8a9")
15:42maxhodaki.e., it's a sequence where the first is a symbol
15:43chouseryes
15:43maxhodakrather than actually evaluating the form
15:43chouserthe reader doesn't evaluate
15:43chousernormally
15:43maxhodakhmm
15:43chouserthat step comes later.
15:43bartjLauJensen: which do you prefer Enlive or Compojure?
15:43maxhodakok, i have to run
15:43maxhodaki'll experiment
15:43chouseruse #=
15:44maxhodakyeah
15:44chouserthat is, try printing #=(com.mongodb.ObjectId. ...) instead
15:44maxhodakthanks, works
15:44LauJensenbartj: They are for completely different purposes. Enlive is half selections (scraping) and half templating. Compojure is just a small layer over Ring providing some helper functionality for dynamic webdevelopment. Moustache would be comparable to Compojure
15:46arohneris there a function in contrib or java for generating a random string of N characters?
15:48bartjarohner: Perhaps try a SHA-1 (or any other hash) of the current time-stamp?
15:49bartjLauJensen: let me rephrase - If you building something like foursquare/twitter which would you use?
15:52LauJensenbartj: If it was my show I'd probably try with Moustache/Enlive, but if I was contracted and paid by the hour, I'd use Scala or C++
15:53TimMcMoustache is an alternative to Compojure, as a Ring wrapper?
15:54tomojmoustache really just seems like a routing library to me
15:54LauJensenTimMc: Yes
15:54LauJensentomoj: Moustache is just routing, but Compojure is so stripped in its 0.4 version, that it adds very little more
15:55fliebelIs there something weby for clojure that wraps a huge Java framework, like spring for example?
15:55tomojbut compojure's routing stuff is out in clutch, right?
15:56tomojso what the hell is compojure? :)
15:56LauJensentomoj: oh they put that in clutch? :) Then Compojure is ...hmm.. imports?
15:56tomojhaha
15:56tomojhmm, I don't see clutch anymore
15:57tomojoh, clutch is the couchdb thing. what was the routing library called?
15:57LauJensenroutjure
15:57tomojclout
15:58tomojhttp://github.com/weavejester/clout
15:58tomojI guess compojure provides a pretty interface over clout
15:59LauJensenI think what happened was, they were splitting compojure up into compojure.hiccup compojure.clout etc, and then lein kept stopping them saying "no *jure names", and then they finally broke down and gave up :(
15:59LauJensenits sad, but its not the first time...
16:00tomojhaha
16:00riddochcI thought lein was banning further *jure names? ;)
16:00riddochcRight, sorry, helps to keep reading.
16:00LauJensenhehe :)
16:03riddochcOn the one hand, if Google implemented partial word search functionality, it presents a possible solution to the rather full software project namespace problem. Search for the sort of library you want, and "jure", and there'd be a better chance of finding a clojure library. ;)
16:04riddochcSo, how long before lein decides to ban "clj-*" names?
16:05LauJensenI think the clj- syntax makes a lot of sense
16:05LauJensenso... 2 weeks? :)
16:07riddochcAs amusing as it is, I'm not sure lein should be enforcing project name policy.
16:09TimMcWas there a flag to disable that behavior, like lein ... --ImNotCreativeEnoughToComeUpWithANameThatDoesntHaveJureInIt ?
16:10tomojclj- seems bad to me
16:10tomojI don't want a bunch of projects clustered right there in tab-completion space
16:10tomoj-clj seems OK though
16:10LauJensentomoj: you got fuzzy completion
16:11tomojnot in bash :(
16:12LauJenseneshell? :)
16:26scottjIs there a form for defining several things at once, like (def a 1 b 2 c 3)?
16:28Chousukeno, but it's pretty easy to make
16:28The-KennyIt'd be just a simple macro with a call to partition
16:29kotarakscottj: (defmacro multi-def [& pairs] `(do ~@(map (fn [[k v]] `(def ~k ~v)) (partition 2 pairs))))
16:30Chousukethough generally globals shouldn't be so numerous that you would need such a construct
16:30Chousukethat is, if writing defs is too much work for you, probably you have too many :)
16:30TimMcheh
17:14digash,(binding [*warn-on-reflection* true] (bit-and 1 (long 2)))
17:14clojurebot0
17:14digashuses reflection
17:14digashbut not here
17:15digash(binding [*warn-on-reflection* true] (bit-and 1 (int 2)))
17:15digashwhy is that?
17:22kotarakdigash: because there is a native method for int, but not for long.
17:22arohnerdigash: bit-and calls the class clojure.lang.Numbers.and(x,y)
17:23arohnerwhich defines arities for (int,int), and (Object, Object), (and a few others) but not (int, long)
17:23korreInteger types is the suported type for clojure.lang.numbers its says
17:24arohnerright, but Number is a boxed class, while long is a primitive
17:25digash,(binding [*warn-on-reflection* true] (+ (long 1) 1))
17:25clojurebot2
17:25digashno reflection
17:26digashi think it should it be patched
17:26arohnerdigash: then patch it
17:27korreso only need to extend clojure.lang.Numbers i gess
17:37arohnerlein is reproducibly downloading two different versions of the same library
17:37arohnerI thought that wasn't supposed to happen?
17:38pedroteixeiraarohner: guess that can happen because you have projects that depend on two different versions
17:44scottjIs clojure.contrib.string a 1.2.0 thing? I've seen several libs that require it and I get a file not found error with clojure&contrib 1.1.0. Doesn't contrib 1.2.0 require clojure 1.2.0?
17:47lancepantzscottj: yes
17:47technomancyarohner: could be a dev-dependency pulling in another version
17:47lancepantzit was moved from contrib for 1.2
17:48scottjlancepantz: thanks
18:04dysingeryo dawg - I heard you like parens
18:04korrei do :D
18:17AWizzArdCan contrib.io help me to download .JPGs via http?
18:22dysingerAWizzArd: use clojure-http-client
18:22dysingeron githubs
18:22dysingeror clojars
18:24AWizzArddysinger: well yes, I have httpunit in my classpath, which can also easily do this, I just thought that maybe a reader+spit or something like that could this job also done
18:25dysingerAWizzArd: it's super ultra easy w/ clojure-http-client
18:25dysingerone line of code
18:26AWizzArdyes, with htmlunit maybe a few more, plus I have nothing to download ;)
18:26AWizzArdbut.. is there a setting for *default-encoding* which basically is like saying "binary"?
18:33lpetithi
18:33lpetitanybody here using ccw and being currently annoyed by the issue #6 "cannot delete file" problem ?
18:34r2q2Hi I'm having issues doing hello world with compojure on google app engine
18:34r2q2right now it can't compile the clj file even though its specified to be there
18:34r2q2or not that it can't but it doesn't compile the clj file
18:35lpetitr2q2: answering to me, or talking about a different issue ?
18:35r2q2Talking about a different issue
18:35r2q2http://github.com/zitterbewegung/main-site-aconsapart
18:35r2q2If someone could point me to a tutorial to a good version of compojure or a good tutorial to use that would be appreciated.
18:37korredo you need a tuturial on compilation?
18:46korreok so are you still here r2q2?
18:46korrei gott it working
18:51r2q2korre: Yea i'm still here sorry
18:51r2q2korre: I didn't see your message
18:52korreso i dont hawe a tuturial butt to get it working you need to add compojureongae.core to namespaces in project.clj
18:53korrei also dident get lein deps to work with [com.google.appengine/appengine-api-1.0-sdk "1.3.4"]
18:53korrei used the jar from my version of the sdk
18:54r2q2ok
18:55r2q2oh i think i know what happened
18:55r2q2my project.clj file doesn't have the correct namespaces.
18:55replacaKirinDave: you coming to the clojure meetup tonight?
18:56TimMcreplaca: Is that somewhere in Europe?
18:56replacaTimMc: no, SF (& there's one in Seattle tonight too)
18:56korreits 1 in the morning in europe so
18:58lancepantzhow many people usually go to the sf meetup
19:00KirinDavereplaca: When/where?
19:00KirinDaveI wasn't invited
19:00tomojhmm, my boss might be in SF tonight
19:01technomancyoops; forgot to post about the seajure meeting
19:01TimMckorre: Point.
19:01technomancyany seattle people: come to http://seajure.technomancy.us tonight!
19:01technomancyor rather: come to the meeting, not just the web site.
19:02TimMcI'll have to settle for just the website. :-(
19:04tomojonly 3 people on the austin clojure.meetup.com waiting list :/
19:08powr-tocHmmm... just been looking at moustache... is it any better than compojure?
19:08KirinDaveThey're different.
19:09powr-tocKirinDave: how so?
19:09KirinDavepowr-toc: Trivially. :)
19:10powr-toclol...
19:10tomojthe main difference I've noticed is routing style
19:10tomojmoustache uses destructuring
19:11powr-toctomoj: yeah... moustache looks like it might be more powerful than compojure... but how about clout?
19:11tomojcompojure uses strings
19:11tomojcompojure uses clout
19:13powr-toctomoj: ahh yeah, I'd forgotten that
19:13tomojI'm not sure whether it's more powerful, but destructuring for routing seems awesome to me
19:14r2q2could i use moustache instead of compojure?
19:14powr-tocI have an app written as a mixture of GWT (with rpc servlets written in clojure) and compojure routes (currently)...
19:14tomojif you like
19:17powr-tocI didn't want to use web.xml and war files for deployment... as I want an easy repl into the thing for maintainance, and I have an aversion to web.xml... so I was forced to wire the thing together by hand with jetty
19:18powr-tocit's not too bad... but I wish there was a DSL that abstracted across servlets and ring handlers, allowing you to do routing across the whole app
19:19powr-tocit's also not entirely dry, as some of the routes are partially repeated for jetty's ServletHolders
19:22powr-tocand I also find compojure's wrap! macro a pain in the arse, as it overwrites the handler with the wrapped version, meaning if you re-evaluate the handler you all of a sudden lose your middlewares and have to eval the wrap! call again :-(
19:23maxhodakprint-dup seems to serialize vectors-of-vectors using clojure.lang.MapEntry/create
19:23maxhodakclojure.lang.MapEntry/create doesn't seem to exist?
19:25korreno i dont se a static method there in 1.1
19:26tomoj,(binding [*print-dup* true] (println [[:foo :bar]]))
19:26clojurebot[[:foo :bar]]
19:26tomoj,(binding [*print-dup* true] (println (seq {:foo :bar})))
19:26clojurebot(#=(clojure.lang.MapEntry/create [:foo :bar]))
19:28tomojso the problem is that maps' seqs don't print-dup readably
19:32maxhodakhmm
19:32maxhodaktomoj: what's the solution? use the 1.2 snapshot?
19:32maxhodakor is it not there either?
19:32maxhodaki guess i could override the print-dup method?
19:33tomojthe 1.2 snapshot I'm using has the same problem
19:33r2q2Now i think i got swank-clojure working at least
19:33tomojit's possible the only solution is not to print-dup maps' seqs.. :/
19:34maxhodakis there's another serialization method?
19:34maxhodaki've written a memoize macro that uses memcached rather than process memory
19:34maxhodakand i need to reliably serialize and deserialize arbitrary data structures
19:34tomojthat will be difficult, I think
19:35maxhodakgrr
19:35korreyea simple maps are easy butt otherwize you need to do something funky
19:35maxhodaki can rewrite my application logic to not use seqs of maps
19:35maxhodakit works for everything else ive tested on now
19:35tomojstructs still seem to be broken :/
19:36maxhodaki'm not using structs anywhere
19:36tomojthat's good
19:40tomojmaybe you could define a print-dup method for MapEntries?
19:40tomojand make it print #=(clojure.lang.MapEntry. k v) instead of /create
19:43tomojit looks like maps and their seqs are Serializable
19:45KirinDave Hmm
19:45KirinDavehttp://news.ycombinator.com/item?id=1402755
19:45KirinDaveI'm having problems stating clearly why an ad-hoc if cascade is worse any more clearly.
19:47defnif I have ((\a \b \c)) how do I map across the inner vals
19:48KirinDaveDo you want to preserve the structure or not?
19:48defnyes
19:48defnpreserve please
19:49tomojarbitrarily deeply nested?
19:49KirinDavedefn: You'd recurse.
19:50defnewwwwww
19:50KirinDavedefn: Would you prefer an uglier method?
19:50defnclearly im approaching this the wrong way
19:50defn:)
19:50KirinDaveI mean, if you have an arbitrary tree of data as lists, you recurse or iterate.
19:51KirinDavedefn: If you hate recursion, you may be in the wrong channel.
19:52defnKirinDave: lol KirinDave -- im just thinking my approach to the problem is wrong because i think there's a way to do this without
19:52KirinDavedefn: Why?
19:52tomojhow would you do that recursion without possibly blowing the stack?
19:53KirinDavetomoj: You can't preserve the structure without a stack
19:53KirinDavei'm willing to bet I could provide that it is so.
19:53tomojoh, hmm
19:53defnthen i dont need to preserve the structure
19:53KirinDave(map my-fn (flatten my-nested-seq))
19:54technomancydefn: or destructure higher up
19:56defnyeah tech
19:57defnbasically i have ((\a \a \r \o \n) ...), and I am going to get the val of each \char which is 1-26, and then add up the value of each name
19:57KirinDaveOh
19:57KirinDaveIs it always depth 1?
19:57defnyes
19:57KirinDaveThen you just map across it.
19:57defnif i flatten i lose the separation between names
19:58KirinDaveYou have a fn that give (\a \a \a) returns your sum
19:58KirinDaveThen say (map my-counter-fun my-collection-of-words)
19:58KirinDaveThat's fixed size.
19:58KirinDaveI was under the impression you had variable unknown depth
20:00TimMcWait wait wait... Clojure doesn't do tail call optimization?
20:01TimMcWTF.
20:03replacaKirinDave: sorry - doing real work :-)
20:04replacaKirinDave: It's at WeatherBill, 420 Bryant @ 7
20:04KirinDaveAh
20:04KirinDave7?
20:04KirinDavefuuu
20:04replacaish
20:04KirinDaveTimMc: When the jvm does it, so will clojure.
20:04KirinDaveTimMc: In the mean time you can use the recur trampoline for self tail recursion.
20:06TimMcHrm... I suppose that is the price to pay for targeting JVM.
20:07tomoja price I'm very willing to pay :)
20:07KirinDaveTimMc: It is a price.
20:08replacaKirinDave: was that "fuuu" a yes or a no :-)
20:08replaca?
20:08KirinDaveToo late
20:08KirinDavecan't go
20:09replacaKirinDave: ah, bummer
20:09replacahas to be later so folks from outside the city can come
20:10KirinDaveI can do it that late if I have warning
20:10KirinDavebut not off the cuff
20:15replacait's organized through a meetup group: http://www.meetup.com/The-Bay-Area-Clojure-User-Group/
20:15ceptorialhi all. i'm just starting to play around in clojure and just tried to do a simple function, but it looks quite ugly/hard to read.. wondering if someone can suggest how to make it more readable http://gist.github.com/424699
20:15replacameeting are once a month, alternating between SF and Mt. View
20:16defni just started a meetup group for Madison, WI -- lonely clojurist seeks friendship, sexps
20:19tomojceptorial: (-> row (rename-keys {:user_id :id}) (select-keys [:id :login :created]) (assoc :type "user"))
20:19tomojthen you can break those into multiple lines so it's readable
20:20tomoj,(doc ->)
20:20clojurebot"([x] [x form] [x form & more]); Threads the expr through the forms. Inserts x as the second item in the first form, making a list of it if it is not a list already. If there are more forms, inserts the first form as the second item in second form, etc."
20:23ceptorialtomoj: very fascinating. the doc language is talking about the list in the way that code is data, right... so in (rename-keys row {:user_id :id}) row is the second "item" of the "list"
20:24tomojright
20:24ceptorialso this mostly works because of some convention that says that seq functions should generally take the seq as the first param?
20:24ceptorialis there a better way to say that / is that written somewhere
20:24tomojbasically, yeah
20:24ceptorial*first argument
20:24tomojexcept, some seq functions don't
20:24tomoje.g. map, filter, etc
20:25tomojso there is also ->>
20:25ceptorialis there an easy way to interleave them
20:25defn(interleave ...)
20:25ceptorialif i had a filter in the middle of those other calls
20:25tomojnot really
20:25tomojI wrote a macro for that once
20:26tomojhttps://gist.github.com/43e7d7d5248e6d639eea
20:26ceptorialactually like (into {} row) in the example
20:26tomojbut it's pretty ugly
20:26tomojdo you really need the (into {} row), anyway?
20:27tomojif clojureql is returning something that doesn't already act like a hash-map... it's dumb
20:27ceptorialyes if i want to modify the struct to remove keys that were part of the original database record
20:27ceptorialwhich it seems that contrib.sql is enforcing
20:27ceptorialeven though at this point that i have the data, i don't care anymore, i want to do other things with it as pure data
20:27tomojcan you do (class row) on the struct that's returned?
20:28tomojoh, I guess I see what you mean
20:28ceptorialclojure.lang.PersistentStructMap
20:29tomojyou would need to do something like (-> (into {} row) (rename-keys ...) ...) I guess
20:29ceptorialright
20:29ceptorialwhy do you think that the macro is ugly?
20:30tomojfor one thing, it requires you to specify -> or ->> every time
20:30tomojwould be better if it would just stick with the last thing you said
20:30tomojbut even if it did that, I'm not sure I'd like it..
20:30tomojhmm, why not a macro that lets you pick with % ?
20:31tomojlike (<3 row (into {} %) (rename-keys % {..}))
20:31ceptorialright
20:31ceptorialwould be slick
20:31tomojI feel like that's been discussed before
20:36ceptorialwell, http://gist.github.com/424699 is working quite nicely. as long as i dont have to use filter or map somewhere inside there
20:36tomojif you do, you'd probably have to break it up with let, I guess
20:38konrIs there a way to find out how many arguments a function requires?
20:42tomojnot really
20:42tomojat least, not that I know of
20:42tomojbut if it was defn'd, you can inspect the metadata
20:43tomoj,(:arglists (meta map))
20:43clojurebot([f coll] [f c1 c2] [f c1 c2 c3] [f c1 c2 c3 & colls])
20:43tomoj,(:arglists (meta (fn [x] x)))
20:43clojurebotnil
20:44konrinteresting! thanks!
20:47tomojnot as simple as just (map count (:arglists (meta f))) unfortunately...
21:00ceptorialtomoj: http://gist.github.com/424699 last two are with a filter
21:00ceptorialis that what you meant by lets
21:02tomojsomething like that
21:02tomojbut don't use -> or ->> unless you actually need them
21:02ceptorialright right
21:02ceptorialjust POC
21:03tomojand let can have multiple bindings
21:03ceptorialif i had filter + map, etc.
21:03ceptorialoh right, and they can read off of each other as well
21:03tomojso e.g. I would write that last as https://gist.github.com/4409a999e2d35b29dec4
21:04ceptorialvery cool
21:04tomojthe (filter :required_param) is just a dummy example to play with style, I guess?
21:05ceptorialyeah
21:05ceptoriali guess it doesn't work on a single map, it would need a seq of maps?
21:05ceptorialwell
21:05ceptorialthat makes sense
21:05tomojyou can filter a map, but not using a keyword as the fn
21:05ceptorialright right
21:06tomojI mean, you can do it, but you won't get anything :)
21:07tomoj,(filter :foo {:foo :bar})
21:07clojurebot()
21:07ceptorialhow would you filter out pairs that had a specific key or value
21:07tomojceptorial: http://www.tbray.org/ongoing/When/200x/2009/12/01/Clojure-Theses#c1259757504.65713
21:07ceptorialfor key you could use dissoc i guess
21:07tomojthat is an enlightening comment by right
21:07tomojer, by rich I mean
21:07tomojin response to #2 on that list, related to your original question
21:08MadWombatHello
21:08tomojfor keys, select-keys works, I think?
21:08tomoj,(filter #(> (val %) 3) {:foo 1 :bar 2 :baz 4 :bing 5})
21:08clojurebot([:baz 4] [:bing 5])
21:09tomojoh, you mean the opposite of select-keys, hmm
21:10MadWombatI am trying to do some dev with GAE and jetty, so far everything works except one annoying little thing, seems like once run-jetty is executed (either forking or not) there is no way to stop it. I can send it .stop, but it doesn't restart the thread, it just suspends it. Any advice?
21:10MadWombats/jetty/ring/
21:10sexpbotI am trying to do some dev with GAE and ring, so far everything works except one annoying little thing, seems like once run-ring is executed (either forking or not) there is no way to stop it. I can send it .stop, but it doesn't restart the thread, it just suspends it. Any advice?
21:10MadWombatdamn
21:11tomoj,(into {} (filter (comp (complement #{:foo :baz}) key) {:foo 3 :bar 4 :baz 5 :bing 6}))
21:11clojurebot{:bar 4, :bing 6}
21:12tomojerr..
21:12tomoj,(into {} (remove (comp #{:foo :baz} key) {:foo 3 :bar 4 :baz 5 :bing 6}))
21:12clojurebot{:bar 4, :bing 6}
21:12replacaturns out the clojure SF meeting started at 6 - my mistake
21:13ceptorialthis language is crazy
21:13ceptorial,(doc comp)
21:13clojurebot"([f] [f g] [f g h] [f1 f2 f3 & fs]); Takes a set of functions and returns a fn that is the composition of those fns. The returned fn takes a variable number of args, applies the rightmost of fns to the args, the next fn (right-to-left) to the result, etc."
21:13ceptorialthat's crazy
21:14hiredmanthere is nothing crazy about function composition
21:15hiredmanit's just crazy hard to do without functions
21:15ceptorialpretty neat
21:17hiredmanhave you seen -> and ->> yet?
21:18ceptorialyeah tomoj just walked me through it: http://gist.github.com/424699
21:18ceptorialvery cool stuff
21:18tomojceptorial: also, try not to do that (-> (->> ) (-> ) ...) stuff :(
21:19ceptoriali supposed https://gist.github.com/4409a999e2d35b29dec4 is the best option?
21:19redalastorAre we getting close to the release of 1.2 or it's just an impression I have?
21:19ceptorialeven if i had filter then map, i could do (->> there for that 2nd let and it would still look pretty good...
21:25konrAnybody knows how to "uninitialize" QT's QApplication so I can launch it again without restarting the JVM? QApplication/exit does the job but then the canvas becomes blank and unresponsive
21:26redalastorkonr: Catch the exception and throw it away.
21:27redalastorkonr: reinitializing Qt does no harm beside throwing an exception.
22:42pedroteixeirait seems that a public macro cannot call a private function, that's it, right?
22:49tomojpedroteixeira: the macro shouldn't expand to something which calls a private function
22:49tomojthe macro itself can call private functions to generate the expansion
22:53pedroteixeiratomoj: never thought about that.. was thinking if there were any patterns to handle that.. only wanted to expose the macro :p
22:55tomojif you're using helper functions behind a macro, it's good practice to expose them anyway
22:55tomojby "behind" I mean "in the expansion of"
22:56tomojso that other people can use them without being forced through your macro
23:02pedroteixeiratomoj: for this case, the function relies on a binding to mark a unit of work.. but ok, users will get an exception if they use it function solely
23:16progskiIs there a way to get the basis of a struct?
23:21pedroteixeiraprogski: basis? you mean its keys?
23:22progskiyep
23:22pedroteixeira,(doc keys)
23:22clojurebot"([map]); Returns a sequence of the map's keys."
23:23pedroteixeiraprogski: AFAIK, a struct is a map
23:23progskiright, what I'm looking for is a way to ask for the basis of a struct, so what keys are required by this struct?
23:24progski(defstruct foo :name)
23:24pedroteixeira(defstruct A :a :b) (keys (struct A))
23:24progskihow can I find out that to create foo I ned to pass name
23:25progskinice, thanks
23:25pedroteixeiraprogski: but you don't need to pass all the args, you can be lazy: (merge (struct A :a 1) {:b 2})
23:25progskiokay, yea I'm asking for purposes of testing
23:26progskiI have a macro that creates a struct
23:26progskiI want to verify it made the right basis
23:26pedroteixeiraprogski: defrecord is more strict, with version 1.2, it seems people will move towards records instead of structs.
23:27progskiyea, I haven't had time to really follow all the new 1.2 stuff, so for now I'm working with structs, I imagine moving from one to the other shouldn't be too painful?
23:28pedroteixeiraprogski: records implements the map interface also. the only annoying thing I'm seeing that seem it generates a java class, one needs to import all types explicitly (since there is no import *)
23:29progskido records have a significant speed increase over stucts?
23:29progskibecause that would be nice
23:29progskiI'm building millions of instances
23:34pedroteixeiraprogski: supposely, accessing the keys (= fields) of a record are faster than keys of a struct.
23:35pedroteixeiraprogski: and guess would save up memory space also. but you might want to confirm with experts in the room
23:35progskihmm, well I am using 1.2, so I might as well take a look since I'm still early in development
23:36pedroteixeira(defrecord A [a b]) (A. 1 2)
23:37progskican I hang metadata on A?
23:37pedroteixeiraprogski: yep.. will be all the same, expect for constructing and importing.
23:38progskicool, okay, you've convinced me to take a look then
23:38pedroteixeirai created a factory macro for make it more dynamic, it might interest you also:
23:38pedroteixeira(defmacro record "Dynamic factory for defrecords." ([name] `(record ~name {}) ) ([name vals-map] `(let [con# (first (.getDeclaredConstructors ~name)) num# (alength (.getParameterTypes con#))] (merge (.newInstance con# (make-array Object num#)) ~vals-map))))
23:39pedroteixeirayou can the use (record A {:a 1})
23:40progskicool, thanks