#clojure logs

2009-03-09

00:00durka42the API page stays with the latest release
00:01cmvkkhmm, i'm not quite sure how this would work but it's a promising avenue, thanks.
00:04durka42Raynes: re. that quote: i'm not afraid of heights, but i have no idea how to drive a stick
00:04cmvkkhaha, me too.
00:06cmvkkhmm, maybe i could roll my own 'future caching'.
00:06durka42how would that work
00:07cmvkkwell, the closures are called with a number as an argument, which has to increment in the right order. 0, 1, 2, etc.
00:07cmvkkso i could wrap each closure around an agent containing the "next N samples", and keep a list of how far ahead the cache is.
00:08cmvkkthen when the closure gets called with the number that's the end of the cache, I batch calculate another N samples and store them in the cache, in a separate thread.
00:09RaynesI hate how Haskell developers make me feel like Clojure and LISP are useless.
00:09Raynes:\
00:09Rayness/LISP/LISP in general/
00:10cmvkkthe developers tell you that, or you actually feel that way?
00:10p_lRaynes: Clojure just appeared, so most of the time they attitude steems from having few things that CL community haven't
00:10RaynesThe developers tell me that. It's annoying.
00:11Raynescmvkk: Dont think I'd be here if I felt that way :p
00:11p_lthey feel full of themselves because they managed to create a strong community with constant growth. Still, nothing killed Lisp for 50 years...
00:11Raynes"Haskell is better." is what I hear twice a week. :\
00:12replacanot even the lispers :), though they sure tried
00:12RaynesI can't help but shake the feeling that Haskell can only go downhill from where it's at.
00:12RaynesIt's no doubt that developers these days just don't like pure functional programming.
00:12p_lRaynes: functional languages (and in fact, all non "mainstream" languages) are on uphill now
00:23zakwilsonThere are languages for feeling smug, and languages for getting crap done. Clojure is a language for getting crap done.
00:24zakwilsonHaskell can be useful, and CL is quite nice, sometimes, but Clojure can certainly hold its own when it comes to solving whatever ugly, real-world problem you have.
00:25p_lI would say that clojure has simply a big advantage of being JVM hosted :)
00:29zakwilsonThe JVM is part of its advantage, but the language itself is designed around getting stuff done.
00:29timmcdI've got a question; is there a built-in function for adding onto an end of a list?
00:31p_lzakwilson: experienced Haskell, CL or Clojure programmer probably would spend similar time. I had seen someone write his own DHCP proxy in Haskell in short time because nothing worked for his network :)
00:33timmcdSo no, there isn't? If not, I'll just make one of my own. Can't be that hard
00:33durka42there's concat but it needs a list
00:33durka42vectors grow at the end with conj
00:34hiredmantimmcd: you should not add to the end of a list
00:34hiredmanthat is not something the design of linkedlists allows for well
00:35timmcdhiredman, mmk. How would you suggest making an ascending-order function that takes a list and rearranges it into ascending order?
00:35RaynesUse teh vector
00:36hiredman,(sort '(3 2 8 5 3))
00:36clojurebot(2 3 3 5 8)
00:36hiredman~def sort
00:37timmcdThat is a nifty bot...
00:38timmcdBut how would I go about doing it myself? As a learning project?
00:38timmcdLike, I know there is a (. '(1 2 3) size) function
00:38timmcdbut I still made this:
00:38timmcd(defn give-me-length [num x] "Helper for calculatin list-length."
00:38timmcdgrr
00:38timmcdmeh
00:38timmcdWell, I made my on length function for lists
00:39hiredman...
00:39arbscht,(count '(1 2 3))
00:39clojurebot3
00:39timmcd...
00:39timmcd>:P
00:39timmcd,(count '[1 2 3])
00:39clojurebot3
00:39timmcdmeh
00:39timmcdYou people hate me >_>
00:40hiredmantimmcd: are you planning to do a bubble sort or what?
00:40timmcdtimmcd, bubble...sort?
00:40timmcdtimmcd, I'm fairly new to functional programming, and new to Clojure all together
00:40timmcd*hiredman
00:40arbschtbubble sort is a general sorting algorithm
00:41arbschtit isn't unique to functional programming
00:41replacatimmcd: the usual way for accumulating lists (in all lisps) is to build them backwards and then reverse them when you have what you want
00:42timmcdreplaca: Mmk. Thanks
00:42hiredmanin clojure you can use a vector
00:42timmcdThat I can
00:42replacatimmcd: in clojure you tend to use a vector instead cause vectors have fast append, and then you can use (list v) to turn in into a list at the end
00:42hiredmanand leave out the reversing
00:42hiredmanuh
00:42timmcdIs there any reason why you would use a list instead of a vector?
00:42replacaif you really need a list
00:42hiredman(seq v) not (list v)
00:42hiredman,(list [1])
00:42clojurebot([1])
00:42hiredmannot what you want
00:43timmcdYeah
00:43replacahiredman: sorry, you're right
00:43timmcd,(seq v)
00:43clojurebotjava.lang.Exception: Unable to resolve symbol: v in this context
00:43timmcdIs there any reason why you would use a list instead of a vector?
00:44replacatimmcd: when you want to jam a lot of stuff on the front, lists might be faster, but usually, no
00:44timmcdOk
00:44timmcdTHanks
00:44replacaone nice thing about lists is that have multiple versions of them all pointing and different subparts is very efficient
00:44hiredmanif you don't need O(n) access to the middle of the list
00:45replacahiredman: you mean O(1)
00:45hiredmanI do
00:45arbschtyou would use lists to represent clojure code
00:45replacathat, too!
00:46timmcdalso, is there a method for removing an item from a vector? Ie: (drop '[1 2 3] 1) -> [2 3]?
00:46timmcdarbscht: Interesting. Lets say I had a bit of code that calls a variable piece of code that can be changed. Would you store that var. piece of code as a method, or as a list?
00:47replacasort of: (drop 1 [1 2 3])
00:47hiredmanreplaca: that doesn't remove from the vector
00:47replacanote, no quote for literal vectors (or maps)
00:47timmcdand calls this var. code every once inawhile (So its not just once right away)
00:47hiredmandatastruictures in clojure are immutable
00:47hiredmanand drop works on seqs
00:47hiredmannot vectors
00:48hiredman,(doc subvec)
00:48clojurebot"([v start] [v start end]); Returns a persistent vector of the items in vector from start (inclusive) to end (exclusive). If end is not supplied, defaults to (count vector). This operation is O(1) and very fast, as the resulting vector shares structure with the original and no trimming is done."
00:48timmcdSeems to work on vectors for me...
00:48replacacorrect, it returns a seq (a list mapped onto the vector in this case) that represents that drop
00:48hiredmantimmcd: drop calls seq on the vector
00:48timmcdoh yeah it made a seq
00:48hiredman,(seq [1 2 3])
00:48timmcdmy bade
00:48clojurebot(1 2 3)
00:48timmcd*bad
00:48replacaif you need it to stay a vector, subvec is a better bet
00:48arbschttimmcd: sounds like you want a function in that case
00:48timmcdANd drop just removes n amount from the seq
00:49replacayup
00:49timmcdSort of same with subvec
00:49hiredman~def subvec
00:49replacayeah, the argument object always stays the same
00:49timmcdIs it possible to remove N from the vector. Like: (rm [1 2 2 3] 2) -> [1 3]?
00:49hiredmanfilter
00:50timmcd,(doc filter)
00:50clojurebot"([pred coll]); Returns a lazy sequence of the items in coll for which (pred item) returns true. pred must be free of side-effects."
00:50hiredmanbut, again, it works on seqs
00:50hiredmanso you lose the vector
00:50timmcdhrm
00:50timmcdIs there a way to convert sequence to vector? I'm guessing now
00:50timmcd*no*
00:50replacayou can always add the vector back after the fact with (vector alis)
00:50hiredman,(vec (range 5))
00:50clojurebot[0 1 2 3 4]
00:51replacaI sorry, vec
00:51hiredman,(vector 1 2 3)
00:51clojurebot[1 2 3]
00:51timmcd,(vector '(1 2 3))
00:51clojurebot[(1 2 3)]
00:51cmvkkon a side note, i don't find that very intuitive
00:52timmcdI agree
00:52timmcdIs it possible to run a regexp on a vector?
00:52hiredman*shrug*
00:52hiredmanNo
00:52replacatimmcd: what do you mean by that?
00:52hiredmana vector is not a string
00:53RaynesLooky
00:53replacaregexps map to strings, so you could map regexps over strings *in* a vector
00:53timmcdreplaca: I mean using the same regexp syntax to search through and possibly replace bits in vectors
00:53Raynes,(apply vector '(1 2 3))
00:53clojurebot[1 2 3]
00:53Raynes:D
00:53timmcd*claps for Raynes*
00:53RaynesI win.
00:53timmcdLol yup
00:53replacaRaynes: that's just cause I was too lazy to type it :-)
00:54timmcd>_> sure
00:54timmcd^_^
00:54Raynesreplaca: :p
00:54cmvkkif you have a vector of characters you can run a regexp on it, if you convert it to a string first...
00:54RaynesThis is another reason I like Clojure, I've been learning it for a few weeks and I actually stand up against language experts on answering questions. :>
00:54timmcdlol
00:55timmcdI'm still shocked that there is no way to remove a specific item from a vector
00:55replacawe're all noobs here
00:55timmcdI guess you could always just
00:55timmcditerate through the vector till you find what you want
00:55timmcdand remove it
00:55cmvkkyou can use subvec but it's a little unweildy
00:55cmvkkand filter also
00:55Raynes,(apply str [\a\b\c\d])
00:55clojurebot"abcd"
00:56timmcdIs there a way to iterate through vector without converting to seq? dovec vrs. doseq?
00:56durka42,(let [v [1 2 3 4]] (concat (subvec v 0 2) (subvec v 3)))
00:56timmcd,(doc dovec)
00:56clojurebot(1 2 4)
00:56timmcdlol
00:56clojurebotjava.lang.Exception: Unable to resolve var: dovec in this context
00:56timmcdof course
00:56durka42why would you need to do that
00:56RaynesWhat's wrong with.
00:57timmcdwell, to do what you just did
00:57timmcd>_<
00:57Raynes,(remove #(= % "x") ["a" "x"])
00:57clojurebot("a")
00:57replaca(remove #(= % 2) [1 2 3 2 4 5 2 3])
00:57replaca,(remove #(= % 2) [1 2 3 2 4 5 2 3])
00:57clojurebot(1 3 4 5 3)
00:57Raynesreplaca: Great mind think alike.
00:57timmcdo.0
00:57Raynesminds*
00:57replacabut then you need vec again :-)
00:58timmcd,(remove #(= % :foobar) [1 2 :foobar 3 4 5])
00:58clojurebot(1 2 3 4 5)
00:58timmcdah yeah
00:58timmcd,(apply vector (remove #(= % :foobar) [1 2 :foobar 3 4 5])
00:58clojurebotEOF while reading
00:58RaynesI win again!!!
00:58timmcdEOF?
00:58replacatimmcd: I think that most of the time when we're doing first-order things like this, we just use seq, but you have to be careful if you have a conj in there
00:58durka42that's remove by values, but no dice if you just have the index
00:58Raynestimmcd: YOu forgot a paren
00:59RaynesAw.
00:59hiredman,(indexOf [1 2 3 4 5] 3)
00:59clojurebotjava.lang.Exception: Unable to resolve symbol: indexOf in this context
00:59hiredman,(.indexOf [1 2 3 4 5] 3)
00:59clojurebot2
01:01hiredman,(let [v [1 2 3 4 5] i (.indexOf v 3) f (subvec v 0 i) b (subvec v (inc i) (count v)] (reduce conj f b))
01:01clojurebotUnmatched delimiter: ]
01:02hiredman,(let [v [1 2 3 4 5] i (.indexOf v 3) f (subvec v 0 i) b (subvec v (inc i) (count v))] (reduce conj f b))
01:02clojurebot[1 2 4 5]
01:02hiredman,(let [v [1 2 3 4 5] i (.indexOf v 3) f (subvec v 0 i) b (drop i v)] (reduce conj f b))
01:02clojurebot[1 2 3 4 5]
01:02hiredman,(let [v [1 2 3 4 5] i (.indexOf v 3) f (subvec v 0 i) b (drop (inc i) v)] (reduce conj f b))
01:02clojurebot[1 2 4 5]
01:03durka42,(vec (mapcat #(if (not= %2 2) (list %1)) [1 2 2 3] (iterate inc 0)))
01:03clojurebot[1 2 3]
01:03slashus21,(let [v [1] split-list (split-at 0 v)] (concat (split-list 0) (next (split-list 1))))
01:03clojurebot()
01:03slashus21,(let [v [1 2 3 4 5 6] split-list (split-at 3 v)] (concat (split-list 0) (next (split-list 1))))
01:03clojurebot(1 2 3 5 6)
01:04replacasplit-at, cool. I always use take/drop. Is split-at faster?
01:04durka42split-at uses take/drop
01:05durka42hmm, it would be cool if vectors could take vectors of integers as arguments
01:05durka42like in matlab
01:05hiredmanvec is cheating
01:05hiredman~vec is cheating
01:05clojurebotAck. Ack.
01:14slashus21,(let [v [1 2 3 4 5 6] split-list (split-at 3 v)] (concat (first split-list) (next (second split-list))))
01:14clojurebot(1 2 3 5 6)
01:14slashus21prettier way of writing it.
01:22replaca,(let [v [1 2 3 4 5 6] [a b] (split-at 3 v)] (concat a (next b)))
01:22clojurebot(1 2 3 5 6)
01:22replacawith a destructuring bind, ftw! :-)
01:26slashus2replaca: Blasted. You beat me.
01:27replacaslashus2: standing on the shoulders of giants, my friend
01:29slashus2replaca: I am still climbing.
01:30replacaslashus2: yup, that's what makes it fun. It's like Rich has laid out a new territory and we're all exploring
01:30slashus2replaca: I tried to beat him in fixing a bug that I discovered today, but I failed.
01:30RaynesExploratory programming.
01:47Rayneshiredman: Could you make clojurebot so that when someone says " clojurebot: can clojure <insert something here>" it will say, "Yes, Clojure can do that!"
01:48durka42clojurebot: can clojure is <reply>Yes, Clojure can do that!
01:48clojurebotIn Ordnung
01:48durka42clojurebot: can clojure cure cancer?
01:48clojurebotYes, Clojure can do that!
01:48cp2yes
01:48durka42clojurebot: can clojure vec?
01:48clojurebotYes, Clojure can do that!
01:48cp2git clone git://cdc.org/cures/cancer-clj.git
01:49ayrnieuthe folly in that plan is that someone could say "clojurebot: can clojure defeat Chuck Norris?", and then both you and clojurebot will be destroyed for blasphemy.
01:49cp2er
01:49cp2not cdc.org
01:49slashus2clojurebot: Can clojure defeat Check Norris?
01:49clojurebotclojure is cheating
01:50hiredmanugh
01:50durka42clojurebot: can clojure defeat Chuck Norris? is <reply>That is the one thing Clojure can not do.
01:50clojurebotc'est bon!
01:50durka42~can clojure defeat Chuck Norris?
01:50clojurebotYes, Clojure can do that!
01:50hiredmanstill case sensitive
01:50ayrnieuI'll miss you, durka.
01:50hiredman:(
01:52RaynesO.O
01:52Raynesclojurebot: can clojure made the universe implode?
01:52clojurebotYes, Clojure can do that!
01:52RaynesOops :|
01:52slashus2It can even do things that make no sense! wee
02:01slashus2~can clojure give up Christianity for lint?
02:01clojurebotYes, Clojure can do that!
03:11p_lsomeone ported Hakell's FAQ to clojurebot? ;P
03:25alinphi
03:25alinpwhich are the implementations of clojure.lang.IFn ?
03:26cmvkkhttp://github.com/Chouser/clojure-classes/raw/master/graph-w-legend.png
03:27alinpthanks
03:27cmvkkheh, i can't even find IFn on that
03:28alinpI found it
03:28alinp:)
03:28alinpright under Serializable
03:28cmvkkah yes.
03:29alinpso APersistentSet is an implementation of it
03:29cmvkk,(#{:a :b :c} :a)
03:29alinpwhich is an abstract class ...
03:29clojurebot:a
03:30alinpthe thing is that I want to play a bit with clojure classes
03:30cmvkki think that's encouraged
03:30alinptry to do a lazy seq right in java ... if is possible
04:04slashus2Is there a way to do something like a generator function yet? I am guessing streams will add this functionality?
04:05cmvkkwhat do you mean by that?
04:07slashus2I am trying to figure out the best way to implement the genRandom function here http://shootout.alioth.debian.org/gp4/benchmark.php?test=fasta&amp;lang=python&amp;id=2
04:11cmvkkwell you could do like (def *random* (new java.util.Random))
04:11cmvkkthen define genRandom so that it calls (.nextInt *random*) or whatever
04:11cmvkkand does the calculation and returns it
04:11cmvkkoh wait
04:11cmvkkthat's not how that function works at all.
04:12cmvkk:)
04:12slashus2It is a generator function, which mutates seed.
04:12cmvkkright. you can do it with a lazy seq
04:12slashus2That is what I am trying to figure out how to do.
04:13cmvkkit's a matter of defining a function with seed as one of the arguments, then doing a recursive call of the function inside the lazy seq.
04:13cmvkkrebinding seed when you do that.
04:13cmvkki think anyway...
04:14hiredmanI thought I saw something about Random not being thread safe
04:14cmvkkit's probably not.
04:14cmvkkit's some sort of mutable object, so why would it be?
04:15hiredmangoogle seems to think it is
04:16hiredmanolder releases jdk1.4 etc, nay have been unsafe
04:16hiredmanmay
04:17cmvkk~paste
04:17clojurebotlisppaste8, url
04:17lisppaste8To use the lisppaste bot, visit http://paste.lisp.org/new/clojure and enter your paste.
04:18lisppaste8cmvkk pasted "gen-random" at http://paste.lisp.org/display/76687
04:18cmvkkthat's probably slow, but i think that's how you would do it
04:20cmvkkarggh, i hate you "can't await in agent action"! all my plans are ruined forever.
04:22hiredmanalso, send-offs are held till the agent action completes, unless you explicitly release them
04:23cmvkki want agents that send-off to other agents that send-off to other agents. and then wait for them to complete down the line.
04:24cmvkkas long as I use send-off, and as long as I don't have agents that await each other, I don't see what the problem is.
04:24hiredman*shrug*
04:24cmvkkonce again, i demonstrate that i don't really understand clojure's concurrency well enough to implement it correctly.
04:24hiredmanI haven't used agents much
04:25hiredmanwhy are you awaiting?
04:25cmvkkwell it would be a boon in this case, but i need to add it into what's already a fairly complex system of closures calling closures etc.
04:26cmvkkthe plan was for each closure to have a 'future cache', where it would precalculate n values, then when it started to get low, it would send-off to precalculate some more values while still providing cached ones to the calling fn.
04:26cmvkkbut at the very beginning, there aren't any values at all. so we have to await for some of them to get calculated before we can return a value.
04:27hiredmanah
04:27cmvkkI guess, anyway.
04:27cmvkkI suppose I could just have them return nil, then build it in so that if it returns nil, it retries for the value rather than caching it.
04:27hiredmanI have just used a wonderful hammer, so your problem (of course) seems very much like a nail
04:27cmvkkbut that seems like it would end up being a waste of cycles.
04:27cmvkkhmm, do you have a solution?
04:28hiredmanso you have producers and consumers
04:28cmvkkyes, a big long chain of them.
04:28hiredmanconnecting them, a LinkedBlockingQueue
04:28hiredmanwhich, blocks if empty
04:28cmvkkooh
04:29cmvkkthat sounds promising
04:29hiredman~jdoc java.util.concurrent.LinkedBlockingQueue
04:30cmvkkI will look into that. I have issues about going from 'pulling' to 'pushing' which this might entail, but we'll see.
04:30slashus2,(doc seque)
04:30clojurebot"([s] [n-or-q s]); Creates a queued seq on another (presumably lazy) seq s. The queued seq will produce a concrete seq in the background, and can get up to n items ahead of the consumer. n-or-q can be an integer n buffer size, or an instance of java.util.concurrent BlockingQueue. Note that reading from a seque can block if the reader gets ahead of the producer."
04:35cmvkkare these things thread-safe?
04:38hiredmanthat is their primary purpose
04:39cmvkkawesome. I think I can build something on this, thanks.
04:41hiredmanit is very cool
04:43cmvkkfunny that to come up with a viable system I had to eschew clojure's concurrency system in favor of java's...
04:43hiredmaneh
04:44hiredmanjust using a lbq won't make your system concurrent
04:44cmvkkyeah, i know
04:45hiredmanI have been using threadpoolexecutors (which agents are built on) directly mostly, which is why I don't know much about agents
04:45cmvkkthe closure bodies are in a macro, so instead of having the macro put them in closures and call other closures, they'll make the body loop over and over again, adding to a lbq,
04:45cmvkkthen spin that loop off into its own thread, and expose the lbq to what would be the caller.
04:47cmvkki'll have to define an explicit filter for line splits (since we can't have two different things popping off the same queue) but other than that, i shouldn't have to change the framework at all.
04:48hiredmanyou might want to send the closures to be executed on a thread pool instead of just launching them off to there own thread
04:49cmvkkwell the problem with that is that i want them to just loop over and over again, only stopping when the queues they call are empty or the total number of samples has been reached.
04:49cmvkki'm not sure how to do that with a fixed number of threads.
04:49hiredmanah
04:49hiredmanhmmm
04:50cmvkkunless there's a better way than that to make the system 'go'
04:51cmvkklike i said, i don't understand concurrency as well as i ought to
04:51hiredmanI dunno
07:21p_lis there a way to get _java_ source generated from clojure source?
07:28AWizzArdp_l: Clojure code gets compiled directly to the JVMs byte code. There is no output to Java code.
07:28p_lAWizzArd: I know, but I want to get around a task which requires Java *sourcecode*
07:29p_lcause I just know I'll go mad from coding in Java
07:29AWizzArdYou could try to use a decompiler (such as JAD) and use it on the .class files that Clojure produces when you compile your code.
07:29AWizzArdWell, if this is a task, then the teacher will most likely not enjoy the output of a decompiler. It looks horrible :)
07:31p_lwell, my previous assignment code included comments like "How *NOT* to design programs" or "THIS IS FORTRAN!!!"
07:32p_land well... he did write something about "surprise me" for max grade...
07:35p_lI'm going to ask if I can use a different language than Java
07:36AWizzArdThat would be the easiest thing I guess.
07:36AWizzArdYou can maybe impress him if you mention that it is functional programming.
07:37p_lOr I might go with Erlang and say "I'm gonna have one thread per customer simulated" (it's a simulation of a supermarket)
07:38p_lthough Clojure is probably safer in terms of "will it run on teacher's pc"
07:44AWizzArdYou could make a double clickable .jar file out of your Clojure program. It's likely that the teacher already has Java installed on her compi.
07:46p_lAWizzArd: He wants it submitted through BlueJ
07:52cgrayhi, I'm getting a strange error: `java.lang.ClassFormatError: Invalid method Code length 65641 in class file user$eval__2723 (NO_SOURCE_FILE:0)'
07:53cgrayI think it might have something to do with being low on memory...
09:57djpowellcgray: are you attempting to load a large datastructure into clojure with load-file or something?
10:01djpowellif so, then you should 'read' the data in, rather than 'load' it in. reading will return a datastructure; loading will compile the expression into jvm code that returns the datastructure - which might exceed the jvm code size limitations
10:23AWizzArdSpeed comparison: Clojure vs F# and OCaml: http://groups.google.com/group/comp.lang.functional/browse_frm/thread/99b8230c078d9b44/bb739bc7f68c3922
10:40heanolis there anything wrong with this code: http://pastebin.com/d7db29511 ?
10:40heanoli'm trying to use compojure with clojure trunk..
10:43leafwAWizzArd: in that speed comparison, numerous numbers are used with wrappers, no int or double casting.
10:43leafwparticularly in the mand fn
10:44Chouserheanol: it looks to me like core is somehow out of date with itself. you might try a clean and rebuild of clojure.
10:44Chousukeit uses (= 0 i) instead of (zero? i) :)
10:49heanolChouser: didn't help
10:50Chouserheanol: what if you just type the word 'next' at the repl?
10:50Chouserno quotes
10:51heanolhttp://pastebin.com/da37d37e
10:51heanollike that?
10:52danlarkin__heanol: are you still on sourceforge trunk?
10:52Chouserok, now try: (macroexpand '(doseq [i (range 2)] i))
10:53heanoldanlarkin__: doh, yes
10:53Chouserhmph. but how was doseq producing calls to 'next'?
10:53leafwquestion about atomatic type inference: do constructors do it? Does make-array do it? I think the latter doesn't.
10:54heanolChouser: (loop* [sq__3547 (clojure.core/seq (range 2))] (clojure.core/when sq__3547 (clojure.core/let [i (clojure.core/first sq__3547)] (clojure.core/when true (clojure.core/when true (do i)) (recur (clojure.core/rest sq__3547))))))
10:55Chouseryeah, see -- your doseq is calling 'rest' not 'next'.
10:55Chouserare you using a pre-compiled compojure?
10:55heanolChouser: nope, i compiled it myself from trunk
10:56heanolhowever, after using clojure from the google code svn instead
10:56heanoli get another error..
10:56heanolCaused by: java.lang.Exception: Unable to resolve symbol: lazy-cons in this context
10:57heanoli assume they're not compatible then :p
10:57leafwuse lazy-cat instead
10:57leafwlazy-cons was removed.
10:57Chouserlazy-cat is not the same as lazy-cons
10:58heanolhmm.. i was using clojure-contrib from sourceforge too
10:58Chouser(lazy-cons [1 2] [3 4]) ==> ([1 2] 3 4)
10:59Chouser(lazy-cat [1 2] [3 4]) ==> (1 2 3 4)
11:02gnuvinceWhen's rhickey leaving for London?
11:03rhickeygnuvince: tomorrow
11:03gnuvinceok
11:03gnuvinceBreak a leg!
11:03rhickeythanks
11:09rhickeyanyone coming to QCon London or this meetup? http://www.meetup.com/Londonjavacommunity/calendar/9672764/
11:09HolcxjoI'll be there on Thursday
11:10rhickeyHolcxjo: cool!
11:10HolcxjoDon't have that sort of money for QCon
11:10HolcxjoLet me know what sort of amicable question you want me to feed you. ;-)
12:09leafwkotarak
12:11cgrayone thing I'm curious about is why zip is not in the core library... it's so useful for functional programming...
12:12cgrayor am I missing it?
12:12Chouser,(map vector [1 2 3] [4 5 6])
12:12clojurebot([1 4] [2 5] [3 6])
12:12Chouser,(map list [1 2 3] [4 5 6])
12:12clojurebot((1 4) (2 5) (3 6))
12:12Chouser,(map hash-map [1 2 3] [4 5 6])
12:12clojurebot({1 4} {2 5} {3 6})
12:12Chousercgray: you just have to be more specific. :-)
12:13cgrayneato
12:14Chousukehmm
12:14Chousuke,(zipmap [1 2] [3 4])
12:14clojurebot{2 4, 1 3}
12:14Chousukeah, right, that was the difference :)
12:15cgraythat also doesn't work like zip with keys that are the same
12:15cgray,(zipmap [1 1] [3 4])
12:15clojurebot{1 4}
12:15Chouserright, because it's producing a single map -- keys must be unique
12:15Chouser(map hash-map ...) produces a seq of hash-maps.
12:16Chousuke,(reduce merge {} (map hash-map [1 2] [3 4]))
12:16clojurebot{2 4, 1 3}
12:16Chouser,(map hash-map [1 2 3] [4 5 6] [7 8 9] '[a b c])
12:16clojurebot({1 4, 7 a} {2 5, 8 b} {3 6, 9 c})
12:17Chousukehmm
12:17Chousuke,(reduce into {} (map hash-map [1 2] [3 4]))
12:17clojurebot{2 4, 1 3}
12:17Chousukeyay
12:18Chousuke,(reduce into [] (map hash-map [1 2] [3 4]))
12:18clojurebot[[1 3] [2 4]]
12:36timmcdHello
12:36timmcd^_^
12:37leafwanybody uses gorilla here -- it keeps opening a new Scratch buffer for every single evaluation, which is a pain
12:37gnuvinceEver since rhickey posted his "On the importance of recognizing and using maps", my head has been spinning
12:37timmcdxD
12:40timmcdWhat shows more skill; coding the FizzBuzz challenge with an if/and, or multiple ifs? xD
12:42hiredmanI have to wonder, how many people who ask about type hinting (on clojure reddit comment threads) are using ruby
12:43gnuvincetimmcd: I say multiples. Writing it with if/and can obscure the meaing
12:44gnuvincetimmcd: 3 ifs make it plainly clear, even if it violates DRY a little bit.
12:44timmcdMmk, thanks.
12:44gnuvincetimmcd: that's just me.
12:44timmcdThanks
12:44timmcdI'll be looking into internships once I finish high-school
12:44gnuvincehiredman: I also really like the "lacking proper tail call optimization is a showstopper" crowd.
12:45hiredman$%#@$%
12:46hiredmanwell, it's just reddit, it's not real life or anything
12:47timmcdhiredman: Whats wrong with Ruby?
12:47hiredmantimmcd: slow
12:47timmcdThats true
12:47timmcdWas helpful for learning the basics of OO for me tho
12:47hiredmanbut people still use it
12:47timmcdOOP, even >_<
12:47gnuvincex = 10 if false; print x => nil
12:47timmcdIsn't JRuby sort of like Clojure? Built ontop of the JVM?
12:47hiredmanclojure is faster then ruby without type hints
12:48hiredman~google jruby and clojure
12:48clojurebotFirst, out of 5730 results is:
12:48clojurebotInfoQ: JRuby and Clojure - A Good Match?
12:48clojurebothttp://www.infoq.com/news/2009/02/jruby-clojure
12:49hiredmantimmcd: my point is, performance is a non-issue and they should stop being doody heads
12:49timmcdOne reason why I want a job in a compiled language: http://xkcd.com/303/
12:50timmcd^_^
12:50timmcdhiredman, Totally.
12:50hiredmanclojure is compiled :)
12:50hiredmaneverything you type at a repl is compiled to jvm byte code and then execute
12:51timmcdYeah I kno
12:51timmcd*Know
12:51hiredmanI think the clojure answer would be something like "sorry, busy profiling"
12:52timmcdIs there a simple 'not' sort of operator in Clojure? Ie, in Ruby it ould be: if 0 != 1 ...
12:52timmcd,(doc not)
12:52clojurebot"([x]); Returns true if x is logical false, false otherwise."
12:52hiredmanthere is not and not=
12:52timmcd>_< silly e
12:52timmcd*me
12:52hiredman,(doc not=)
12:52clojurebot"([x] [x y] [x y & more]); Same as (not (= obj1 obj2))"
12:58timmcdMy father, as a part of my homeschool curriculum, made me go through part of SICP, but then we switched over to giving me tasks to complete in Ruby, since I stubbornly love Ruby.
12:58timmcdBut now I realise how much I missed Scheme
12:59timmcd*realize, even.
13:01gnuvincehiredman: trudat; java -Xrunhprof:cpu=times is *so* long to run
13:03timmcdg2g
13:03timmcdCya peeps!
13:27lisppaste8hiredman pasted "consume (queue backed lazy-seq)" at http://paste.lisp.org/display/76706
14:18timmcdHello
14:18timmcdI was wondering; how would I store code for later running?
14:18cmvkkwhat do you mean?
14:18timmcdI am working on an interactive-fiction engine in Clojure, and I want 'commands' to just be mappings with
14:18timmcd:callname and :function
14:18timmcdand then something like
14:18timmcd(do (get command :function))
14:19cmvkkif you want to do it that way, you can just store a function in :function
14:19cmvkkand call it ((get command :function))
14:19cmvkk(assoc command :function (fn [] ...))
14:19timmcdAh okay
14:19timmcdThanks ^_^
14:20timmcduser=> (def x {:callname "hi", :function (fn [] (println "hello"))})
14:20timmcd,(def x {:callname "hi", :function (fn [] (println "hello"))})
14:20clojurebotDENIED
14:20cmvkkyeah, you can't def in here
14:20timmcdDenied?!
14:20timmcdboo
14:20timmcdbut anyway
14:20timmcddoing that gives me
14:21timmcd{:callname "hi", :function #<user$fn__51 user$fn__51@3ded59>}
14:21cmvkkyep.
14:21timmcduser=> (do (get x :function)
14:21timmcdDoesnt execute the fn
14:21timmcdit just shows that bit of oddnes
14:21timmcdsame with just (get x :function)
14:21cmvkkyou gotta wrap it in an extra set of parens.
14:21timmcd#<user$fn__51 user$fn__51@3ded59>
14:21cmvkk((get x :function))
14:21timmcdah
14:21WizardofWestmarcbah beaten to the punch *shakes fist*
14:22timmcdhehe
14:22WizardofWestmarcif you have something return a function object like you just saw
14:22cmvkkout of curiosity, what are you doing that (defn hello [] ...) isn't good enough?
14:22WizardofWestmarcput another set of parens around it and it'll treat it as a first element in clojure code, aka a function
14:23timmcdWell, I just wanted my commands in my if-engine to be small mappings instead of functions
14:23slashus2cmvkk: Yesterday when I was talking about streams: http://clojure.org/streams to mimic the exact functionality of the python function as a generator.
14:23timmcdthat way I can loop through the vector of commands (which are just mappings) when doing input parsing
14:23timmcdand look at the callnames to see if it matches the input
14:23hiredmanerm
14:24hiredman(fn ...) is a function
14:24timmcdI know
14:24timmcdBut its not a named function
14:24hiredman"I just wanted my commands in my if-engine to be small mappings instead of functions"
14:24timmcdRight?
14:24hiredmanok, sure
14:24timmcdI meant the 'commands' variables
14:24timmcdIe:
14:25timmcd(def command-sayhi {:callname "hi", :function (fn [] ...)})
14:25cmvkkyou're taking a string, and you want to call a specific function based on the value of the string.
14:25cmvkkit makes sense...
14:26cmvkkthe other way to do it would be to make a defmulti and write your commands as methods that dispatch on the st--
14:26cmvkkand you left.
14:26hiredman^-
14:26slashus2heh
14:28WizardofWestmarcGood advice scared him off <_<
14:29cmvkki rewrote my backend with a linkedblockingqueue and although it seems more concurrent it doesn't actually run any faster :(
14:32cmvkkoh well. at least it will run faster for someone with 4 cores.
14:34hiredmanhow many cores do you have?
14:35cmvkkjust two.
15:03Lau_of_DKGood evening gentlemen
15:04kotarakSalut, Monsieur le Lau de DK.
15:09cgrandGuten Abend Herr Lau von DK!
15:09Lau_of_DKcgrand mon ami!
15:10gnuvinceOh no! The French are here!
15:11Lau_of_DKQuick, everbody hide your snails!
15:17ambienthello, what would be a good problem to solve if i wanted to teach myself clojure?
15:17Lau_of_DKhttp://projecteuler.net/, problems 1 - 50
15:18ambientLau_of_DK: i'd rather know the algorithm beforehand, but ok :)
15:18WizardofWestmarc^^
15:18WizardofWestmarcthat was aimed at Lau :P
15:18ambientit's just the language im interested in learning
15:18WizardofWestmarcright but solving problems is a godo way to learn it
15:18WizardofWestmarconce you solve it, there's a wiki page with other people's solutions
15:19WizardofWestmarcso you can see how they did it to compare against your own
15:19ambientok, i'll do that then
15:19Lau_of_DKgood, next question
15:21bitbcktWhat is the in-flight velocity of an unladen swallow?
15:21WizardofWestmarcAfrican or European?
15:22Lau_of_DKBefore or after lunch ?
15:22WizardofWestmarcand a theater around here actually showed that as a Midnight movie last weekend
15:22bitbcktWhat? I don't know that!
15:23dnolenambient: converting an existing a previous program you wrote that you find useful into Clojure is another way to learn Clojure which will yield it's own insights.
15:24gnuvincednolen: definitely agree with that.
15:24gnuvinceI took a Python program I wrote and made a Clojure version: shorter, faster and less fragile (IMO)
15:24ambientim not just so sure how robust clojure is in graphics and bitstreams
15:25Lau_of_DKclojurebot: sofiaba?
15:25clojurebotTitim gan �ir� ort.
15:25ambientlot of stuff i've done uses libraries extensively
15:25WizardofWestmarcdnolen and gnuvince: True but it yields entirely different insights then doing fresh code
15:25gnuvinceLau_of_DK: doing declarative stuff is a lot easier and clean in Clojure than in Python
15:25hiredmanclojurebot: java interop?
15:25clojurebotjava interop is http://clojure.org/java_interop
15:25Lau_of_DKambient: http://wiki.github.com/Lau-of-DK/sofiaba
15:25WizardofWestmarcand IME at least it's better to gain the new code insight first, then use that information to explore rewriting old code from another language
15:25Lau_of_DKclojurebot: sofiaba is http://wiki.github.com/Lau-of-DK/sofiaba
15:25clojurebotIn Ordnung
15:25Lau_of_DKgnuvince: I know
15:27hiredmanambient: clojure has access to anything java
15:29dnolenambient: what kind of "robustness" are you looking for?
15:29ambientdnolen: the language itself containing a way to do the stuff i want
15:30Lau_of_DKclojure is more robust than rock
15:30hiredman~clojure is also more robust than rock
15:30clojurebotIn Ordnung
15:30WizardofWestmarcBleh, Algorithms in a Nutshell needs to get here so I can work on it and convert the examples to clojure.
15:30gnuvinceambient: you'll most likely need to go through libs in Java, but does that really affect robustness?
15:30hiredmanjava interop is a major part of clojure
15:31ambienti don't really know anything about clojure so i digress
15:31hiredmanhttp://clojure.org/rationale
15:31hiredmanclojurebot: rationale?
15:31clojurebotIt's greek to me.
15:31hiredmanclojurebot: rationale is http://clojure.org/rationale
15:31clojurebot'Sea, mhuise.
15:31WizardofWestmarcambient: what is your current programming background?
15:32WizardofWestmarcRich has several presentation videos that are excellent, but which offer the most is heavily dependent on where you're coming from.
15:32ambienti think what i meant was how easy it is in clojure to use java classes
15:32WizardofWestmarcvery
15:32ambientwell that's good then
15:32WizardofWestmarcproxy was the only thing that slowed me down at all, but that was because I was being obtuse :P
15:33dnolenambient: mind-blowing trivial.
15:33dnolenmind-blowingly i mean.
15:33WizardofWestmarcany java lib is fully useable via Clojure
15:33ambienti'm just really learning lisp and clojure seems like the best variant for me
15:33hiredman,(LinkedBlockingQueue.)
15:33clojurebot#<LinkedBlockingQueue []>
15:33WizardofWestmarcambient: do you have background in java already?
15:34ambientWizardofWestmarc: some
15:34hiredmanthat is the equiv of: new LinkedBlockingQueue(); in java
15:34WizardofWestmarcthen when you've got some time, I recommend checking out clojure.blip.tv and watching the two videos on Clojure for Java programmers
15:34ambientWizardofWestmarc: i tried that but for some reason firefox+ubuntu x64+flash-nonfree wont show them
15:35WizardofWestmarcsome of the syntax is out of date now but the general feel and such is still useful for the core mindset of clojure
15:35WizardofWestmarcah
15:35WizardofWestmarccan you play .mov files?
15:35hiredmanambient: blip.tv will let you download the .mov file
15:35ambientok i try that then
15:35WizardofWestmarc:)
15:36WizardofWestmarcand if you find you like Clojure enough to expect to keep using it, the Programming Clojure book, even in beta form, is already very good
15:37slashus21I was reading the book and he uses lazy-cons in it. He does mention that he is using the development version of clojure at the first, and recently lazy-cons went the way of the dodo.
15:37gnuvinceslashus21: he'll fix it.
15:38gnuvinceif it's not already done in beta-8
15:38WizardofWestmarcwasn't that fixed in Beta 8?
15:38WizardofWestmarchaven't had a chance to actually read 8 yet to see
15:38slashus21I am reading beta-8
15:38dnolenit was fixed.
15:38dnolenthere may be a couple of places where it's missing
15:38dnolenbut the actually lazy section uses lazy-seq
15:40slashus21P.g. 158
15:40slashus21wait
15:40slashus21that is lazy-cat
15:40slashus21I misread
15:40slashus21sorry
15:40WizardofWestmarceasy to do :)
15:42catch23anyone here use compojure and know what is the switch for forcing clj files to be reloaded on every request (so i can see changes on the fly)
15:50cemerickhey, I just noticed the type fn. I guess I can ditch my type-of fn, finally. :-)
15:51cemericknot sure about the type being part of the metadata, tho
15:51hiredmanI am not sure about all this type checking
15:51bitbcktI'm not sure about all this typing.
15:58danlarkinpeople do love their types
16:00cemerickhiredman: has nothing to do with type-checking -- the only place I have a :type field is in a multimethod-heavy lib.
16:01hiredmancemerick: why not, you know, dispatch on the existence of keys in the map?
16:02rhickeyAWizzArd: are you here?
16:03cemerickhiredman: because the keys are the same in many cases
16:03hiredman*shrug*
16:05hiredmanit seems like you are deciding to treat something as a square if it has a square label on it, regardless of if it has the properties of a square or not
16:07cemerickwell, we're hardly working with simple bags of values. Determining the appropriate :type for a particular object is a significant part of the processing of the application -- hardly something you'd want to check again on every multimethod dispatch.
16:08hiredmanI guess that makes sense, but I still do not like it
16:09cemerickwhat would an alternative be -- assuming identical keys and a potentially very involved process for determining "type"?
16:10hiredmansimplify the process for determining type :P
16:10dnolenhiredman: separation of type and what properties an object may or may not have is a good thing, for example you have the very real problem that multiple inheritance attempts to solve, for example, perhaps something has the :type ::event-protocol. This may have absolutely nothing to do with the properties the structure has, but rather the type dictates behavior.
16:13AWizzArdrhickey: yes
16:28cemerickhiredman: let me know when you manage to turn lead into gold ;-)
16:28hiredmanwill do
16:29cemerickdnolen: our circumstance is somewhat similar, insofar as the objects in question can play multiple "roles" depending on the configuration of the system -- so given config A, the :type of some set of objects is computed to be X, but under config B, the :type is computed to be Y
16:30WizardofWestmarchm
16:30WizardofWestmarcsounds like you guys are doing AoPish things
16:31WizardofWestmarcis there any way to do multimethods based on something other then a component of what you are passing in?
16:32dnolencemerick: that sounds very useful, as it's a far too common requirement in software projects with multiple deployment envrionments ;)
16:32cemerickWizardofWestmarc: I'll let you know what bucket we fit into when we finish figuring out how to do what we want to do! :-)
16:33cemerickWizardofWestmarc: the :type tag is really just the cached result of a lot of computation.
16:34durka42WizardofWestmarc: what else would you dispatch on?
16:34cemerickdnolen: one of these days, I hope to be able to demo some parts of it
16:35hiredmanWizardofWestmarc: the mulitmethod takes a fn to dispatch, so uh, you could do anything technically
16:36dnolencemerick: In less powerful languages you either have to hack together a shell script, or write some gnarly inline logic. Much better to change/augment the type and use multimethods. It sounds cool, looking forward to hearing more.
16:36WizardofWestmarcthe idea is if you have some environmental variables or the like then you can control how it fires by anything, not necessarily as mentioned above, type
16:36WizardofWestmarcjust... whatever
16:37WizardofWestmarcContextL is the Common Lisp version of AoP if you want to see an example in a Lisp style language
16:37durka42(= CoP AoP)?
16:38WizardofWestmarcThat's my impression
16:38cemerickdnolen: it's by no means generally-applicable. It's the back end to what is currently a very gnarly DSL for controlling a document analysis engine.
16:38p_lCoP != AoP
16:38cemerickWizardofWestmarc: yeah, we do that already -- not suitable in the particular case where we use :type tags though.
16:39p_lto quote a certain person, after presentic AspectJ to Lisp users: "You know what, when I show this to Java programmers they stand up and give applause"
16:39AWizzArdWizardofWestmarc: (defmulti foo (fn [_ _] (rand-int 2))) (defmethod foo 0 [x y] (+ x y)) (defmethod foo 1 [x y] (* x y)). And then call a few times (foo 5 10).
16:40hiredmanit caches
16:44durka42hiredman: it doesn't appear to cache...
16:45hiredmaneh
16:45hiredmanI thought it did
17:09hiredmanclojure needs some kind of anamorphic brand identifier
17:09hiredmansomething the japanese can make anime out of
17:11cmvkkclojure-tan?
17:11ayrnieuthis was a mistake that Ruby made early on: they decide on a rock instead of a cute anime girl named 'Ruby'.
17:12WizardofWestmarcheh
17:12ayrnieu(yes, she was proposed. I supported her.)
17:12ayrnieuRuby-tan can be a spokesperson. Only pragprog got anything out of the rock.
17:13hiredmanor foxkeh: http://www.foxkeh.com/
17:13cmvkki thought you meant like this: http://en.wikipedia.org/wiki/OS-tan
17:14hiredmanI dunno about that anamophic
17:15hiredmanalternatively, clojurbeot needs a logo
17:16danlarkin-1 for anime logo
17:17hiredmannot anime, just something japanese people can latch onto and obsess about and make anime about
17:19WizardofWestmarcpfft, the current symbol could be a crazy symbol of power that channels dark anime magic
17:19WizardofWestmarc<_<
17:19danlarkina mascot would be fun, not sure what kind of figure I identify with clojure though
17:20pjstadiga futuristic ninja robot
17:20cmvkkthat can turn into a car.
17:20hiredmanwoa
17:20pjstadigonly if it flips out and kills people
17:21hiredmana flock of futuristic ninja robots
17:21hiredmanyou know, for concurrent fliping and killing
17:21pjstadigSoftware Transactional Flipping-Out-and-Killing
17:22hiredmanso the clojure ? with a bunch of little robots crawling over it
17:29maaclIs this the right place to ask about clojure-mode ?
17:30Chouse1maacl: probably the best IRC channel for it, anyway.
17:30maaclI keep getting "File error: Cannot open load file, clojure-auto" - I have set the load-path correctly
17:36maaclany ideas ?
17:38Chouse1must not be any emacs users here tonight.
17:39jbondesonmaacl: paste the clojure section of your .emacs file
17:40jbondesonoh, wait... i know what it is.
17:41jbondesonyou have (require 'clojure-auto) in there?
17:41jbondesonshould be (require 'clojure-mode) followed by (require 'swank-clojure-autoload)
17:43maacljbondeson: I will give that a try
17:47maacljbondeson: that worked, thanks
17:48jbondesonno problem
18:02lpetitHello
18:03AWizzArdhe lpe
18:03lpetitDo you know if an equivalent of the aand function described in "On Lisp" is already present in some form in clojure or clojure contrib ?
18:04cmvkkthe closest thing is probably if-let
18:14hiredmanhttp://www.thelastcitadel.com/_media/clojure.png?cache=cache
18:14cmvkkheh
18:14hiredmanvery rough, of course
18:14cmvkkyou'll get sued by whatever toy company made those robots
18:15hiredmanand I think whoever makes that robot toy may take issue
18:15hiredmanyeah
18:15lpetitWell, if-let is a bit too verbose for what I have in mind. Here is my problem : I have a lot of nested tests to verify that every nested call doesn't return nil. If a nested call returns nil, I skip the computation. So something like
18:15lpetit(when-let [page (aand (PlatformUI/getWorkbench) (.getActiveWorkbenchWindow it) (.getActivePage it)]
18:15lpetit ... ...)
18:15lpetitinstead of nested when-let or if-let would be great
18:15cmvkkwell you can just define aand as a macro on top of if-let in that case.
18:16cmvkkit should just be a direct copy out of the book with the exception that you have to do the variable capture explicitly
18:16cmvkkon the other hand:
18:17cmvkkif you don't expect any of those clauses inside aand to return nil, you might be better off using -> or doto or something
18:18lpetitYes, but the whole point is that I'm calling Eclipse APIs where at each call there is the possibility to reach a null value, and it is ok to then not do anything and just quietly quit without doing anything
18:19cmvkkokay, so you definitely want to short-circuit on nil. In that case, you'll have to roll your own macro.
18:19lpetityes
18:21hiredman,(-> nil (#(and % (.getBytes 5)) (#(and % (count %)))
18:21clojurebotEOF while reading
18:21hiredman,(-> nil (#(and % (.getBytes 5)) (#(and % (count %))))
18:21clojurebotEOF while reading
18:21cmvkkheh
18:21lpetitsome languages have a special dotted notation for this short-circuit stuff. It's dot followed by a question mark : myObject.?myParam.?myParamParam.?myProperty and if one of the steps returns nil, instead of throwing an equivalent of NPE, then nothing happens at all. Maybe I could write a variant of -> named ->? that could follow the same pattern ?
18:22cmvkkthat would also work.
18:22hiredman,(-> nil (#(and % (.getBytes 5))) (#(and % (count %)))
18:22clojurebotEOF while reading
18:22hiredman,(-> nil (#(and % (.getBytes 5))) (#(and % (count %))))
18:22clojurebotnil
18:22hiredmangeez
18:22hiredman,(-> "ab" (#(and % (.getBytes 5))) (#(and % (count %))))
18:22clojurebotjava.lang.IllegalArgumentException: No matching field found: getBytes for class java.lang.Integer
18:22cmvkkreally it would just be a macro around -> that does what hiredman is trying to do implicitly.
18:22cmvkkwrapping each clause in an and.
18:22hiredman,(-> "ab" (#(and % (.getBytes %))) (#(and % (count %))))
18:22clojurebot2
18:22durka42you could also just wrap the -> in a catch
18:23cmvkkthen have a nil value throw an exception?
18:23durka42,(-> nil #(.getBytes %))
18:23clojurebotjava.lang.NullPointerException
18:24lpetit,(-> nil .toString)
18:24cmvkkah, I guess I was thinking more generally.
18:24clojurebotjava.lang.NullPointerException
18:24durka42,(try (-> nil #(.getBytes %)) (catch NullPointerException npe nil))
18:24clojurebotI don't understand.
18:24cmvkknot every clojure function you might use in something like that would throw a nullpointerexception on nil.
18:24Chousukedurka42: it doesn't allow catching stuff :)
18:24durka42yeah, i thought i remembered that
18:25durka42but it allows binding, which has try in it
18:25durka42cmvkk: true
18:25lpetitWell, catching an exception would also work if a NullPointerException happens inside a function call (not related to one level returning nil), so this could hide bugs in called functions
18:25cmvkkthat's true too.
18:25cmvkkhmm, the best method is probably just to use and.
18:26lpetitYes, I'll write ->? as an exercise, with the property of short-circuiting on nil
18:27cmvkkthat actually sounds like a pretty useful function...
18:28hiredman,(try (catch))
18:28clojurebothiredman: Pardon?
18:28Chousuke->? is maybe not the best name
18:28Chousukesince ? is for predicates
18:28cmvkkyeah.
18:29cmvkkand-> makes more sense to me.
18:29Chousukemaybe-> :P
18:29hiredman&&->
18:30cmvkkis that even a legal symbol?
18:30Chousukesure.
18:30hiredman,&&->
18:30clojurebotjava.lang.Exception: Unable to resolve symbol: &&-> in this context
18:30Chousuke,'&&->
18:30clojurebot&&->
18:30hiredmanhttp://andand.rubyforge.org/ "guarded method invocation or safe navigation method."
18:31Chousukemaybe ?->
18:31fyuryuanyone had problems with gen-class aksing for a Java class to have a <init> method?: NoSuchMethodError: my.ns.JavaClass.<init>(Ljava/lang/Integer) ?
18:31lpetitYes, the maybe monad may be the right way to do that ...
18:31hiredmanfyuryu: pastebin it
18:34lpetitChousuke: Well, && also has a particular meaning in java ... ?-> is better, as you suggested
18:35Chousukeit looks like a weird smiley though :D
18:35durka42=> (with-monad maybe-m ((m-lift 3 ->) "ab" #(.getBytes %) count))
18:35durka422
18:36durka42=> (with-monad maybe-m ((m-lift 3 ->) nil #(.getBytes %) count))
18:36durka42nil
18:36Chousukehuh, m-lift works for macros too?
18:36durka42apparently
18:36durka42but you have to tell it how many arguments to take
18:36Chousukewell, yeah
18:37lisppaste8fyuryu pasted "gen-class - extending java class" at http://paste.lisp.org/display/76719
18:38durka42fyuryu: you told gen-class to expect two constructors, and only wrote one
18:40hiredmanand I am pretty sure you init function needs to take the same args as the constructor
18:41fyuryudurka42: are you sure that's it? gen-class expects a map of new-ctor signature to sig. of the class you're extending
18:42fyuryuor my reading comprehension is near 0% today...
18:43kotarakfyuryu: takes it an int or a java.lang.Integer?
18:44kotarakyou can use verbatim int in the contructor map.
18:44fyuryukotarak: int, is that a problem?
18:44fyuryuoh
18:44hiredmanfyuryu: your init function
18:44hiredman"If supplied, names a function that will be called with the arguments to the constructor."
18:44hiredmanfrom the :init section of gen-class
18:46fyuryukotarak: changed the type to "int" and it compiled
18:46kotarakJava fun. :)
18:47fyuryuthanks guys
18:52fyuryuahhh, damn it. The doc even mentions primitive types
18:54fyuryudidn't read the "introduction" part, because I thought it just explains what it gen-class does. That'l teach me
19:02kotarakfyuryu: I learned about it by looking at the source, when I needed Void/TYPE. "Huh? I can simply write void?"
19:23lpetitThere it is : http://paste.lisp.org/display/76725
19:24lpetitComments welcome, I'm faaar from a macro (and lisp in general) expert
19:32cmvkkis there a reason why 'runtime macros' won't work in clojure?
19:32Chousukewhat do you mean with runtime macros? :)
19:32cmvkki.e. a macro whose expansion is determined by the actual value of one of its arguments
19:33Chousukemacro expansion happens at compile-time
19:33cmvkkthey worked in CL i'm pretty sure (but wouldn't expand until runtime)
19:33cmvkkhmm, so that feature just isn't implemented.
19:34kotaraklpetit: It also stops on false.
19:34Chousukeisn't a runtime macro a function? :)
19:34cmvkkin CL a macro would be expanded at compile time if possible, otherwise it would be expanded as soon as the value of its argument was known. perhaps that isn't feasable in clojure.
19:34cmvkkin this case, the behavior i was hoping for wouldn't be:
19:34ChousukeI think it'd be confusing :/
19:35cmvkkthe macro call appeared in code body that would be in a closure. I was hoping it would expand when the function that returns the closure was called, meaning that layer of indirection would be eliminated for that particular closure instance.
19:36lpetitkotarak: you're right, it's not good enough then.
19:36cmvkkbasically, the code will be called a million times in a row, but for each instance of the call, the argument is always going to be the same value.
19:36kotaraklpetit: I would not use nil for transferring error information.
19:36lisppaste8Rayne pasted "current cparser (not relevant)." at http://paste.lisp.org/display/76727
19:37lpetitkotarak: sure, it's for the case where the code one may want to write would just stop on nil, by writing a cascade of (when-let) calls
19:37dnolencmvkk: i'm pretty sure that Clojure's macro system and CL's macro system are almost identical in capability. They both involve the reader, not runtime magic. someone correct me if I'm wrong of course.
19:37cmvkkdnolen i thought so too, but the fact that this doesn't work leads me to believe otherwise...
19:37cmvkkmaybe i'm wrong about CL being able to do this?
19:38dnolencmvkk: i think you should paste or post your macro ;)
19:39lisppaste8cmvkk pasted "macro vs. fn" at http://paste.lisp.org/display/76728
19:40cmvkkW and Wn are exactly the same, only W is a macro. note that Wn returns the correct answer while W returns the wrong one.
19:40cmvkkwhich leads me to believe that accessing (class wav) from within the macro is impossible.
19:40kotarakcmvkk: why does this need to be a macro? (= (class ..) ..) should be (instance? ...)
19:40cmvkkkotarak you're right about the second thing.
19:41cmvkkthe reason i want it to be a macro is that the expanded code is going to be called hundreds of thousands of times in a row on the exact same object
19:41cmvkkand having that indirection in there when it isn't really necessary will slow the program down
19:43dreishcmvkk: Are you sure? Do you have benchmarks on this?
19:43dreishcmvkk: The JVM is really good about inlining code when it will actually improve performance.
19:43cmvkknope! i only expect it to improve performance by a small margin.
19:43cmvkkit mostly just bothers me because i know it CAN be resolved only once.
19:44dreishcmvkk: Well, by all means don't take my word for it, but I expect it won't help to make it a macro.
19:44lisppaste8cemerick pasted "ancestors doesn't report superclass' parents, but isa? still works?" at http://paste.lisp.org/display/76730
19:44cemerickThe above is very strange to me ^^^
19:45kotarakcmvkk: why not a function which returns a function specialized on the argument, which is then used? (defn W [wav] (cond (instance? Queue wav) #(.take wav) (instance? Atom wav) #(deref atom) (fn? wav) #(wav %) ..) Something like that?
19:45dnolencmvkk, functions calls are insalcmvkk, the main problem is that your macro is assuming the local wav is evaluated, this isn't true.
19:45cemerickit seems like (ancestors String) should include all ancestors of Object as well
19:45dnolenoops
19:45dnolensorry
19:45hiredmanuh
19:46hiredmanhmmm
19:46hiredmancemerick: did you try calling ancestors on Object again?
19:46lisppaste8cemerick annotated #76730 "forgot to include result of (ancestors Object)" at http://paste.lisp.org/display/76730#1
19:46lisppaste8dnolen pasted "for cmvkk" at http://paste.lisp.org/display/76731
19:47cemerickhiredman: yeah, it includes ::bar
19:47hiredman*shrug*
19:47dnolencmvkk: this takes 24.96 ms on my machine, I wouldn't worry about performance.
19:47hiredmandnolen: well, it adds up
19:47cemerickrhickey: is this behaviour of ancestors expected, or a bug? (see paste above)
19:48cmvkki AM worried about performance. i already removed a single function call per element, and with 5 elements, that sped the program up 7%.
19:48cmvkkthat's 16 seconds to 15 seconds.
19:48cmvkkit's not that big of a deal really...
19:48cmvkkbut I still find it sort of annoying.
19:49dnolencmvkk: sure, if you really want to write the proper macro, evaluate wav, it's unevaluated, that's why yr macro doesn't work.
19:49cmvkkwith eval you mean?
19:51kotarakclojurebot: eval
19:51clojureboteval is sometimes useful - but only sometimes
19:51kotarakyou can't eval the argument of a function
19:52cmvkkkotarak: that is indeed the case.
19:52kotarakcmvkk: Is that point that you want to inline things?
19:52cmvkkkotarak: ...! there's something available to do just that isn't there.
19:52kotarakdefinline
19:53kotarak(doc definline)
19:53clojurebotExperimental - like defmacro, except defines a named function whose body is the expansion, calls to which may be expanded inline as if it were a macro. Cannot be used with variadic (&) args.; arglists ([name & decl])
19:53cmvkkyep. i forgot about that.
20:01lpetitok corrected version of ?-> : http://paste.lisp.org/display/76725#1
20:59dnolenanyone messed around with trampolines?
21:00danlarkindnolen: I have... pretty useful
21:02dnolendanlarkin: I'm assuming this has to be solved with a trampoline, say I have a function, and I want to recur, but I want to recur twice with in a do form, once with (first tree) and again with the (rest tree). loop/recur won't work because recur has to be in the tail position.
21:03danlarkindnolen: trampolining won't work either
21:03cmvkkyou can't solve that with trampoline either, I don't think.
21:04dnolendanlarkin: cmvkk: a better way to do it then?
21:04danlarkinrefactor your algorithm
21:04cmvkkjust recur normally.
21:04cmvkkor that...
21:04cmvkki was thinking "tree recursion takes up stack space, and that's all there is to it" but maybe you can refactor?
21:05cmvkkmy understanding of recursive algorithms is less than complete.
21:05danlarkinyou could possibly use a zipper, depending on what you're doing
21:06dreishYou can't avoid accumulating some kind of stack somewhere, because your algorithm requires backtracking.
21:07dreish(Or, what cmvkk said.)
21:57cooldude127what's with this place tonight?
21:57cmvkkall the problems have been solved.
21:57cooldude127WOOHOO!
21:57cooldude127why aren't we partying?
21:57cmvkktoo busy coding.
21:57Chouserit would be a sad day
21:58cooldude127i was busy coding earlier, but not i'm just bored
21:58slashus2We would just solve them again.
21:58cooldude127s/not/now
21:58cmvkki'm considering the merits of solving my 'runtime expansion' problem in the craziest way possible.
21:59cooldude127cmvkk: please explain this problem, give us something to do
21:59cmvkkwell you won't be able to do anything about it
21:59cooldude127NO
22:00cmvkki want a function that returns a closure that accesses its enclosed variables (args to the outer fn) differently based on their type. originally i was going to do that with a runtime macro but it didn't work.
22:00cmvkkSO: what if i wrapped defn around a macro that takes the closure body, duplicates it by (number-of-args x number-of-possible-types),
22:00cooldude127wait a runtime macro?
22:00cmvkkthen combs through the code and replaces the macro with the correct expansion manually for every possible combination?
22:01cmvkkthen the outer fn returns the proper closure based on its args types the normal way, at run time.
22:01cmvkkit would work, but the macro would be generating expanded code on the order of 25x its original size.
22:01cmvkkit doesn't seem worth it...
22:06cooldude127cmvkk: this is almost certainly a sign that you're doing something the wrong way. if it gets that ugly, there has to be a better way
22:07cmvkkin this case there's not, other than "don't bother at all". it was mostly a matter of unnecessary optimisation.
22:08cooldude127yeah i've been there
22:08cooldude127trying to get too fancy
22:09cmvkkmore like "getting things to run fast at all".
22:10cooldude127oh
22:10cmvkkit's supposed to be generating audio, but even simple waveforms take twice as long as real time to generate.
22:10cmvkkand for complicated stuff, think one minute for every ten seconds of music.
22:55cooldude127is there a way to just remove a namespace from an image? i want to make sure my functions are in the right order without loading a new image
22:55cooldude127s/image/instance
22:55cooldude127i guess is better terminology
22:58cooldude127answer: remove-ns (i think)
23:13durka42(doc remove-ns)
23:13clojurebotRemoves the namespace named by the symbol. Use with caution. Cannot be used to remove the clojure namespace.; arglists ([sym])
23:13durka42i don't think that's what you want
23:13durka42oh, maybe it is
23:28gnuvince_Wow
23:28gnuvince_Seen in the comments of a Scala video from JAOO: "DLL hell was nothing compared to Closures."
23:29Chouserso... unrelated.
23:34Chouserthere's not a 'alter' or 'update' fn for thread-local bindings, is there? Just 'set!'.