#clojure log - Oct 16 2009

The Joy of Clojure
Main Clojure site
Google Group
List of all logged dates

0:27 hiredman: damn

0:27 * hiredman looks at passwords in a git diff

0:27 hiredman: :(

0:40 durka42: hiredman: now might be a good time to rotate passwords?

0:40 hiredman: already done

1:44 kylesmith: Does anyone know if there are any bugs w.r.t. structs? I browsed through assembla, but didn't see anything. I have some code that works fine with maps, but if I use structs, everything goes straight to hell.

2:38 gilbertleung: hi

2:39 i'm using clojure.jar and clojure-contrib.jar from the book "Programming Clojure"

2:39 when i try to view source using the (source ...) macro

2:39 in clojure.contrib.repl-utils/source

2:39 all i get is a bunch of copyright statements

2:39 what am i doing wrong?

3:09 shantanu: hi, i am looking for some information on how to encode characters in function comments

3:10 for example, (defn foo "comment here with \" quote marks" [] (bar))

3:11 is there a better way to express the double-quote marks in a comment?

3:12 i want to include code examples in the comment, so i need a simpler way

3:27 cgrand: shantanu: docstrings are strings and thus obey to string escaping rules :-(

3:29 shantanu: @cgrand: hmm, i wish docstrings had Python-like syntax :-)

3:30 well, is it then possible to create a macro? """comment begins here and can have "doube quotes" as well"""

3:30 cgrand: there's a recent thread on the group about adding """ delimited strings to clojure

3:30 shantanu: okay

3:36 cgrand: shantanu: (defmacro add-example [sym example] `(alter-meta! (var ~sym) update-in [:doc] str \newline ~(pr-str example)))

3:36 (defn foo "docstring" [] nil)

3:36 (add-example foo (= (foo) nil))

3:37 shantanu: *wow*

3:37 cgrand: won't work in all cases

3:37 shantanu: okay, the macro makes me dizzy though :-)

3:38 cgrand: (won't work = you won't get exactly what you typed in the docstring)

3:44 AWizzArd: cgrand: no, I saw 2 hours after I posted about the count/hashmap issue that it was fixed 3 days after I compiled a checked out Clojure ;)

3:48 cgrand: :-) still mea maxima culpa

3:58 AWizzArd: technomancy: good morning. Please look into your priv :)

3:59 AndiXng: hi

3:59 little GUI problem:

3:59 (defn -post-init [this]

3:59 (let [btn (JButton. "OK")]

3:59 (.addActionListener btn

3:59 (proxy [ActionListener] []

3:59 (actionPerformed [evt]

3:59 (JOptionPane/showMessageDialog this "blabla")

3:59 ...

4:00 "this" does not refer to the GUI component (JPanel), but to the ActionListener

4:00 is there a kind of "super" in Clojure, or how can I fix that?

4:01 or is "this" even reserved in Clojure?

4:01 cgrand: only in proxy

4:02 hiredman: AndiXng: just change the paramter name of the function

4:02 AWizzArd: AndiXng: you could also try nil instead of this.

4:02 AndiXng: aaah, I see, "this" is reserved

4:02 thanks!

4:02 hm, but with nil the dialog has no parent

4:02 AWizzArd: yes

4:03 AndiXng: which means that it is not always-on-top

4:03 but it works, when renaming the parameter

4:03 thanks

4:03 AWizzArd: ah hiredman, not sleeping. Of course :)

4:04 hiredman: :|

4:06 AndiXng: another question: isn't it possible to override "finalize" in Clojure?

4:06 i found in an old chat log, that it was removed because of performance reasons

4:06 hiredman: what do you mean override?

4:07 what?

4:07 AndiXng: i just want to have a deconstructor (called when GC removed the class), no matter if finalized is overridden or something else

4:07 is it possible?

4:10 hiredman: are you using finalize for resource clean up?

4:11 AndiXng: I have a JavaSound synthesizer open

4:11 in an applet

4:11 when the sound engine class is closed, I want to close the synth

4:12 ok, I could try it within the destroy-method of the applet

4:12 would be the better way anway.

4:12 AWizzArd: Why would that be a better way?

4:12 hiredman: http://my.opera.com/karmazilla/blog/2009/01/14/getting-finalize-right-in-java-is-hard

4:13 AndiXng: no, it would not be better

4:13 because

4:13 the sound engine should be able to close itself, without help from outside

4:13 (if the user forgets to call (close))

4:13 hiredman: how can you close a class?

4:13 you mean call a close method?

4:14 AndiXng: ok:

4:14 javax.sound.midi.Synthesizer

4:14 hiredman: don't paste a whole chunk of code

4:14 AndiXng: has a close method

4:14 hiredman: ok

4:14 AndiXng: and I should call that method before the program exits

4:14 (I have to do that, because JavaSound is quite buggy in Sun's implementation)

4:15 hiredman: have you looked at with-open?

4:15 AndiXng: no

4:15 never heard about that

4:15 give me 10 minutes to read about it

4:16 hiredman: ten minutes?

4:18 sgtzx_: LauJensen: saw your last blog entry.. Good job!

4:18 LauJensen: sgtzx_, thanks :)

4:18 AndiXng: hiredman: too easy for 10 minutes? :-D

4:19 AWizzArd: à propos closing a class.. can I get rid of them? Can I delete/gc classes in ram?

4:19 LauJensen: Anyone here who is advanced enough in math to reason about Mersenne primes with me in private for 5 minz?

4:19 AWizzArd, dropping the reference and waiting isn't enough?

4:20 hiredman: AndiXng: it's a pretty sirt docstring, and the macro's usage us rather inuitive

4:20 LauJensen: ,(doc with-open)

4:20 clojurebot: "([bindings & body]); bindings => [name init ...] Evaluates body in a try expression with names bound to the values of the inits, and a finally clause that calls (.close name) on each name in reverse order."

4:20 hiredman: AWizzArd: like an actually Class class?

4:21 AndiXng: hiredman: yeah, but give me some time to actually understand what it does (I'm very new to Clojure)

4:21 sgtzx_: LauJensen: As a Python developer I know very well of the limitations imposed by the GIL, and I still love Python in a right-tool-for-the-job way. I think the examples you provided were interesting and I hadn't actually done much testing to see how much the scheduling penalty in Python could be (my Py code is mostly not using threads)

4:21 hiredman: AWizzArd: you can, but you need to control the classloader to do so

4:21 sgtzx_: LauJensen There's a reason I use Java for enterprise stuff... :)

4:22 AWizzArd: hiredman: is that complicated?

4:22 LauJensen: sgtzx_, oh ok. The examples all came from the Py community, but I glad you got something out of it

4:22 AWizzArd: The thing I was thinking about: I need a dynamic parser. That is, a parser that gets changed while my program is running.

4:23 hiredman: sorry, I mean, Classes can be GC'ed under those circumstances, not that you can force a GC of them

4:23 AWizzArd: fnparse works good, but for performance reasons javacc would be faster.

4:23 AndiXng: other question inbetween: "(ns com.xenoage.labs.clj.eartraining.panel (:gen-class :extends ...." creates a new subclass for me. but how can I instatiate it? i tried to "(:use com.xenoage.labs.clj.eartraining.panel)" and then "(new applet)" but it tells me that the class applet does not exist

4:23 sgtzx_: LauJensen: Have you thought about CUDA + clojure?

4:23 LauJensen: I.e. utilizing those powerful GPU cores with Clojure

4:23 LauJensen: sgtzx_, Zach Tellman has already put up a great Mandelbrot Vs Clojure piece somewhere, which calcs using the GPU

4:23 AWizzArd: I could have a clojure program writing out the input for javacc. Then in the shell my program would call javacc on the generated input. Then it will call javac and compile the result into its classpath.

4:24 AndiXng: ... ah sorry, I mean "(new panel)" of course

4:24 AWizzArd: Then it can load the fresh parser and begin to use it. But with such a method the old parser(s) would still remain in ram, but they are not needed anymore.

4:24 hiredman: ugh

4:25 AndiXng: for classes you use import, not use

4:25 AndiXng: arrr, yeah, thanks. what stupid question; I'm sorry.

4:25 hiredman: (the ugh was for AWizzArd)

4:26 LauJensen: hehe

4:26 AWizzArd, you're the duct tape programmer right ?

4:27 AWizzArd: Unfortunately all these parser generators have static grammars in mind.

4:28 sgtzx_: LauJensen: http://github.com/ztellman/penumbra/blob/master/src/examples/mandelbrot.clj

4:28 LauJensen: very cool

4:28 AWizzArd: With fnparse I can compose new parsers at runtime, but it is very slow in comparison to javacc.

4:28 hiredman: http://stackoverflow.com/questions/1130869/java-garbage-collection-of-run-time-generated-code

4:28 sgtzx_: LauJensen: is he here? I wanted to ask him how the Penumbra uses the GPU directly... by way of a CUDA wrapper? I'd like to use my NVidia GPU to the maximum

4:29 hiredman: I haven't really messed with classloaders, but I don't look briefly and (famous last words) they did not look very complicated

4:29 AWizzArd: hmm :)

4:29 hiredman: s/don't/did/

4:29 AWizzArd: hmm :(

4:30 ah ok, misread that don't

4:30 LauJensen: sgtzx_, he's on vacation now - I want to do a blog piece taking Penumbra out for a spin, so I'll be tagteaming a little with him in the coming week

4:30 sgtzx_, http://ideolalia.com/exploring-the-mandelbrot-set-with-your-gpu

4:30 sgtzx_: LauJensen: ok, sounds good

4:31 yep saw that one :)

4:31 LauJensen: k, great stuff, he's very crafty

4:31 (a little too crafty with macros sometimes) :)

4:32 hiredman: I think could just (.loadClass (ClassLoader.) "someClass")

4:32 sgtzx_: you know OpenCL? Now clojure bindings for that would be neat

4:32 hiredman: or not

4:32 ClassLoader is abstrac

4:32 AWizzArd: I will look into this. Sounds interesting and may be easy to test.

4:33 sgtzx_: I'm struggling to get my colleagues to look at Clojure though :(

4:33 AWizzArd: In principle i should load some class C with my own loader L, kill all references to L and try to instantiate C.

4:34 sgtzx_: They think it's too far out there, in terms of syntax, "too FP" and also the prefix notation

4:34 LauJensen: sgtzx_, no. I started on some wrappers for JMonkeyEngine though, that has some real potential, then I got sidetracked :)

4:34 sgtzx_: Mind these are a bunch of enterprise programmers

4:34 LauJensen: do you have some clients at your company now that you are developing for in clojure?

4:35 LauJensen: No, everything is painfully slow in Denmark at the moment, I'm afraid it'll be a little while before companies start developing/taking in new consultants again

4:35 sgtzx_: I see.. the recession hit you guys ?

4:36 hiredman: I found an a.i. memo where sussman gets steele to take a chip design class, and for the class project steele made a lisp chip

4:36 LauJensen: At first it lingered while we watched the rest of the world slowing down, we we're gearing up. Then almost overnight everything stopped. All contracts got cancelled/postponed etc.

4:36 sgtzx_: LauJensen: and if you got a nice assignment programming in Scala, would you take it?

4:37 LauJensen: sgtzx_, probably not, but jobs always depend on: the job, the customer, the pricetag :)

4:37 sgtzx_: yeah

4:37 AndiXng: hm, I can't find the problem... http://nopaste.codersnet.org/pastes.php?view=270 but "Unable to resolve classname: panel (applet.clj:9)" - any idea? com.xenoage.labs.clj.eartraining.panel is a ns with (unnamed) :gen-class :extends JPanel (works perfectly)

4:37 LauJensen: hiredman, where do you find that stuff?

4:38 sgtzx_: LauJensen: that's why one of the things I do is .NET development. As long as the end goal is interesting. Right now I got .NET, Java (EE), C (embedded stuff), Python projects being worked on by me and my team

4:39 However .NET forces me to run Windows. I miss OS X.

4:39 hiredman: I was google for on of the λ the ultimate papers and found an mit ftp site with, it looks like, all of the ai memos

4:39 I am currently making a local mirror of all the pdfs

4:40 LauJensen: sgtzx_, I try to focus on delivering quality of the highest degree, which means no/little imperative code. I'm not in a position where I want to compromise that + my reputation :)

4:40 hiredman: ftp://publications.ai.mit.edu/ai-publications/pdf/

4:40 LauJensen: hiredman, you getting into AI now ?

4:40 hiredman: not really

4:40 there is a lot of lisp stuff in there

4:41 LauJensen: k

4:41 hiredman: the problem is there is no way to recover the title of the memo from those pdfs

4:41 LauJensen: no meta data?

4:42 hiredman: so I just have a bunch of AIM-????.pdf

4:42 LauJensen: I'm sure you can fix that with the pl macro ? :)

4:42 hiredman: not that I can tell

4:42 AWizzArd: A compiled clojure-contrib.jar was around 2.5 to 3 mb in size some weeks ago. Now it's 550 kb. Is that right? It seems much less code gets compiled...

4:43 jdz: hiredman: somebody should run OCR on those memos...

4:44 hiredman: I saw a memo on "building a hand like mechanism" so there must be an orc memo in there

4:44 jdz: hiredman: hmm, OCR would not be sufficient in many cases... but those reports good stuff!

4:44 sgtzx_: LauJensen: I also believe in delivering high quality... but I can't starve :)

4:45 Sometimes you have to compromise....imho

4:45 LauJensen: Sometimes... but not now :)

4:46 sgtzx_, It was another story if I was employed by someone, then I would do as my contract stated.

4:46 Maddas: LauJensen: Out of curiosity, why not use Haskell then?

4:46 sgtzx_: Would be nice to have plenty of money so I could just fund myself to play around all day and eventually come up with something cool

4:46 W/o the pressure of making it sell

4:46 hiredman: AWizzArd: I still get jars of around 3 mb

4:46 LauJensen: Maddas, still learning it, ask me in a few months :)

4:47 Maddas: If I don't forget :-)

4:47 LauJensen: hehe

4:47 ambient: btw Lau http://tommih.blogspot.com/2009/10/python-clojure.html

4:47 cgrand: AndiXng: did you compile panel (I guess it's a genclassed namespace)?

4:48 sgtzx_: Lots of side-effects there

4:48 :)

4:48 and mutability

4:49 AWizzArd: hmm okay, then something is going wrong here, thx high

4:50 LauJensen: ambient, clever boy :)

4:50 ambient: i was bored :D

4:50 LauJensen: oh you did that?

4:50 ambient: yeah

4:50 hiredman: clojurebot: clojure?

4:50 clojurebot: clojure is far closer to perfection then python

4:50 hiredman: :/

4:50 than

4:51 ambient: and that still is an advantage to python

4:51 LauJensen: ah ok, then let me clarify: Clever way to post, referring mine then posting yours. The code looks like a dog vomitted on my screen? :)

4:51 AndiXng: cgrand: found the problem. i really have to :use the ns, not to :import the class

4:51 sgtzx_: LauJensen: naw man, it's Python, it's always beautiful :)

4:51 LauJensen: ah ok, guess I missed that :)

4:52 hiredman: clojurebot: python?

4:52 clojurebot: Gabh mo leithscéal?

4:52 sgtzx_: clojurebot: scala?

4:52 hiredman: clojurebot: python is ugly

4:52 clojurebot: In Ordnung

4:52 hiredman: clojurebot: show me scala!

4:52 clojurebot: show is clojure.contrib.repl-utils/show

4:53 hiredman: ~scala 1+1

4:53 clojurebot: Int = 2

4:53 sgtzx_: ~scala hello

4:53 So shy.

4:54 hiredman: ~scala {((x: Any, y: Any) => (f: Function2[Any, Any, Any]) => f(x, y))(1, 2)((x: Any, y: Any) => x)}

4:54 clojurebot: Any = 1

4:54 LauJensen: hiredman, clojurebot is completely safe from blowing up due to overload now, loop/recur etc ?

4:54 sgtzx_: hiredman: are you a Scala fan?

4:54 hiredman: LauJensen: safe is a strong word

4:54 sgtzx_: nope

4:54 LauJensen: especially in a <b> tag

4:55 sgtzx_: why not? :)

4:55 hiredman: clojurebot's scala doesn't handle exceptions properly because when I was implementing it I never bothered to test with bad code

4:55 sgtzx_: it's too complicated

4:56 LauJensen: ,(loop [] (future (loop [] (recur))) (recur))

4:56 That'll get a timeout?

4:56 hiredman: nope

4:56 well, the outer one will

4:57 LauJensen: that's enough though, it will kill the inner one as well ?

4:57 ,(+ 2 2)

4:57 hiredman: LauJensen: nope

4:57 sgtzx_: hiredman: doesn't seem much more complicated than java

4:57 hiredman: apart from the extra syntax w/actors, functional programming

4:58 hiredman: I don't know.. I'm just curious what you guys think

4:58 hiredman: sgtzx_: not really

4:58 scala is still tied to oo

4:59 sgtzx_: hiredman: but OO works very well with business programming

4:59 LauJensen: hehe

4:59 please wake up sgtzx_ :)

4:59 hiredman: *snort*

4:59 sgtzx_: LauJensen: i'm hoping to...

4:59 LauJensen: do you think there's separate clojure and business domains?

4:59 hiredman: scala strikes me as sort of second systeish

5:00 systemish

5:00 sgtzx_: LauJensen: nope

5:00 LauJensen: but our brains think in objects, don't they? it's easy to think up: "ah, let's create a person, right, I want to use that object here and there, maybe let another object inherit from it, ..."

5:01 hiredman: ~tell me about scala

5:01 ambient: i think in bubbles, actually, and streams

5:01 hiredman: damn

5:01 LauJensen: sgtzx_, No I wouldn't say I look at it like that

5:01 hiredman: sgtzx_: what is an object?

5:01 sgtzx_: maybe it's years of brainwashing, my exposure to OO

5:02 jdz: people think in individuals, not objects

5:02 sgtzx_: hiredman: an entity that represents something in my program, it can be modified, asked, and inherited from to create new entities that are slightly different

5:02 hiredman: systemish

5:02 jdz: individuals with properties

5:03 sgtzx_: jdz: sounds like an object to me, object = generic individual of which anew one can be instantiated at will

5:03 hiredman: sgtzx_: so if it can't be modified it's not an object?

5:03 jdz: sgtzx_: nope, that would mean that people have access to cloning

5:03 hiredman: our java objects really objects? they cannot be inherited from, only Classes can be inherited from

5:03 sgtzx_: hiredman: in the conventional sense, I suppose it's not an object, no

5:04 hiredman: are

5:04 jdz: sgtzx_: there is no inheritance in the real world

5:04 hiredman: ~tell me about scala

5:04 clojurebot: scala is also<reply>"we are completely screwed on ==." -- seen in #scala

5:05 sgtzx_: jdz: but it is a nice way to visualize things. You start off with a ball, you inherit from it, add texture and content and call that Lemon

5:05 hiredman: anyway, hanging out in #scala gives the sens that scala is just java made more complex

5:05 opqdonut: sgtzx_: it's a horrible way

5:05 it doesn't show how inheritance is really used

5:05 can you supply a lemon when you were asked for a ball? no.

5:05 hiredman: sgtzx_: so a lemon isa ball?

5:05 jdz: sgtzx_: no, it's not a nice way to visualise things (imho): look what it has brought upon us! (hint: C++ and Java)

5:06 ambient: all the people who use them can't be wrong...

5:06 jdz: lemon can be a ball depending on what you want to do with it

5:06 hiredman: inhertience is nice for doing dispatch type stuff, the problem is people suck at it

5:06 schools don't seem to teach it

5:06 sgtzx_: hiredman: it's a ball, yes

5:06 jdz: but that is not a feature of lemon, but the task at hand

5:06 sgtzx_: hiredman: it just happens to have a texture, and content inside

5:07 hiredman: and most languages allow you to inherit from non-abstract classes

5:07 jdz: sgtzx_: i strongly disagree.

5:07 sgtzx_: hiredman: ok, maybe orange is a better example, it's more resembling a ball

5:07 jdz: sgtzx_: then you first must define what is a ball

5:07 sgtzx_: jdz: yea

5:07 you must

5:07 jdz: sgtzx_: so, what is it?

5:08 sgtzx_: jdz: the details do not matter, you can define an abstract class and specify diameter, perhaps color and some other members

5:08 jdz: sgtzx_: makes no sense at all.

5:08 hiredman: clojurebot: oo sucks

5:08 clojurebot: OO is to programming what astrology is to astronomy

5:08 hiredman: bah

5:08 sgtzx_: jdz: the point is that now all other objects inheriting from ball, such as apple, soccerball, etc are all "balls"

5:09 jdz: sgtzx_: is a cardboard box a ball?

5:09 hiredman: clojurebot: oo sucks is <reply>http://www.sics.se/~joe/bluetail/vol1/v1_oo.html

5:09 clojurebot: In Ordnung

5:09 jdz: sgtzx_: if i play football with it?

5:09 sgtzx_: jdz: no, you wouldn't inherit frmo ball then, because it does not resemble a ball

5:09 jdz: that's your call

5:09 hiredman: is a webserver a ball?

5:10 sgtzx_: hiredman: you can inherit from ball, and tell others that a webserver is a ball, but the men in white coats would come and pick you up

5:10 jdz: sgtzx_: what makes apple a ball, and a box not a ball?

5:10 sgtzx_: jdz: the fact that the programmer knows that it is round, he is the one defining it

5:11 jdz: sgtzx_: not all apples are round.

5:11 hiredman: the other fallacy here is that oo is the only why to have hierachical dispatch

5:11 sgtzx_: jdz: the purpose of this example wasn't to be too detailed

5:11 jdz: sgtzx_: and you have fallen into the same tarpit other OO people have, namely, that a single individual may be many things at once depending on what you want to do with it.

5:11 AWizzArd: How can I achive (defn foo [f] (println #'f))?

5:11 sgtzx_: jdz: but, let's just define that a ball doesn't have to be completely round then, but more or less round

5:12 jdz: sgtzx_: no, that's a wrong approch

5:12 sgtzx_: jdz: what is the right approach?

5:12 AWizzArd: ,(let [f identity] (println "Var:" (var f)))

5:12 clojurebot: java.lang.Exception: Unable to resolve var: f in this context

5:12 jdz: sgtzx_: that a bearing ball must be a perfect sphere, but a football ball can be a backpack

5:14 sgtzx_: jdz: let's say you have a collection, it contains many "things". Let's use cars as an example, you want to pick them out. However the collection also contains soccer balls. What is your approach to this?

5:14 jdz: Cars can be many different things, but they have a few things in common; four wheels, steering wheel etc

5:14 jdz: sgtzx_: not necessarily

5:14 sgtzx_: what is a chair?\

5:15 sgtzx_: is it something with four legs and a horizontal surface, or is it something you can use to sit on?

5:15 sgtzx_: jdz: Let's assume then that this is your factory, and your have 8 different car models, they all have four wheels, steering wheel, brakes, etc

5:15 AWizzArd: And the big question is: if you remove just one atom of it, will it still be a chair?

5:15 sgtzx_: jdz: however some have different colors, some have V6 engines, and some have V8 engines

5:15 AWizzArd: If yes, then one could repeat this step and see what happens :)

5:16 jdz: AWizzArd: right, if we focus on the four-legged-thing, what happens if i break on eoff

5:16 hiredman: sgtzx_: sounds like a bag of parts

5:16 AWizzArd: defining objects in the real world is not objectively possible, always just an opinion.

5:16 sgtzx_: jdz: regarding the chair, it is both... four legs, horizontal surface, sittable.

5:17 AWizzArd: sgtzx_: so if the surface has 1 degree difference from the horizon it's not a chair

5:17 jdz: sgtzx_: and then, break one leg off

5:17 hiredman: what is the differece between that and Collection containing those parts?

5:17 jdz: sgtzx_: what do we get?

5:17 sgtzx_: jdz: something that does not qualify as a chair

5:17 in practical terms, since you cannot sell it / use it

5:17 jdz: sgtzx_: no, it's still a chair, but with one leg broken off~

5:17 !

5:17 sgtzx_: and i can use it

5:17 sgtzx_: c'mon, sit on the side where you have the 3 legs, and no problem

5:18 sgtzx_: jdz: and if I take off the seat?

5:18 jdz: still a chair, or just a few sticks

5:18 jdz: sgtzx_: exactly

5:18 sgtzx_: exactly what? :)

5:19 jdz: sgtzx_: if there's a frame that holds the legs together and you can use to sit on that thing, it's still a chair

5:19 if the seat was what holds the structure together, well, you no longer have a chair

5:19 sgtzx_: jdz: that is being very technical i.e. "how much can we remove before it is no longer a chair". You still end up with some shared aaspects of what a chair must have to be a chair

5:20 jdz: sgtzx_: that's not where i was heading.

5:20 take another example: what is a weapon?

5:20 AWizzArd: break this down to the subatomic level and the question of what is a thing becomes ridiculous.

5:20 jdz: sgtzx_: is table knife a weapon?

5:20 sgtzx_: is chair a weapon?

5:20 sgtzx_: jdz: first... let's do the car example before we forget about it :)

5:20 hiredman: ,(let [basic-car {:wheels 4)] [(assoc basic-car :egine :v8) (assoc basic-car :seats :leather)])

5:20 clojurebot: Unmatched delimiter: )

5:20 hiredman: bah

5:20 AWizzArd: In the end one would have decide exactly how many particles should be bound together to make up a XY.

5:21 hiredman: ,(let [basic-car {:wheels 4}] [(assoc basic-car :egine :v8) (assoc basic-car :seats :leather)])

5:21 clojurebot: [{:egine :v8, :wheels 4} {:seats :leather, :wheels 4}]

5:21 jdz: is car a weapon?

5:21 sgtzx_: and to define the carmodelX, it becomes quite simple

5:21 jdz: i mean: poeople kill with those things...

5:22 ambient: depends on the context

5:22 sgtzx_: hiredman: that is actually quite similar, philosophically speaking, to OO

5:22 jdz: ambient: right.

5:22 hiredman: (assoc basic-car :foor :fiftymikemike)

5:22 roof

5:22 sgtzx_: hiredman: you define something, then you define something else that takes basic-car and adds to it

5:22 hiredman: no

5:22 jdz: sgtzx_: basic-car is a variable name

5:22 sgtzx_: ok then I misunderstood

5:22 hiredman: absolutely not!

5:23 jdz: sgtzx_: you can use "apple" instead

5:23 hiredman: absolutely not!

5:23 bah

5:23 sgtzx_: my question was, let's say you have a bag of things, a collection. You have bicycles in there, cars, soccer balls

5:23 hiredman: irssi ate my line

5:23 sgtzx_: How do you identify all cars in that bag?

5:23 hiredman: oo creates an isa relationship

5:23 sgtzx_: Some of them are different models, your factory has 8 models

5:23 ambient: if they tell me they are a car

5:23 i shall believe them

5:23 sgtzx_: and they all *have* to have 4 wheels, engine, brakes

5:23 otherwise it is not a car

5:23 jdz: sgtzx_: by first defining what is a car and then looking in the collecting for matches.

5:24 sgtzx_: what? a car with 3 wheels is not a car anymore?

5:24 or with 8 wheels?

5:24 hiredman: sgtzx_: have you looked at multimethods?

5:24 sgtzx_: jdz: we assumed that all of the ones at your factory have 4 wheels

5:24 jdz: let's assume that is a "car" for now

5:24 jdz: sgtzx_: well, and if somebody has parked his 6-wheel car in the factory lot, it suddenly is no longer a car?

5:25 hiredman: you can create a dispatch function which can check, does this bag have four wheels, does have a v8, etc ,etc

5:25 sgtzx_: hiredman: yes, i saw that... it's very interesting, but

5:25 jdz: sgtzx_: that assumption of yours is what i'm arguing against.

5:25 ambient: shouldn't you just care if the object has an adapter for the message you're going to send it?

5:25 sgtzx_: hiredman: what if there is another thing in the bag that just happens to have four wheels, v8, as well, but it is a tractor?

5:25 hiredman: i.e. it matched everything, but it is not a car

5:25 hiredman: sgtzx_: if it matched everything then it is by definition a car

5:25 sgtzx_: in OO, you would knwo it's not a car, because it didn't inherit from the abstract Car class

5:26 hiredman: but in reality it isn't... so what do you do?

5:26 AndiXng: any idea if (and why?) the ns "com.xenoage.labs.clj.eartraining.panel" is illegal? "com.xenoage.labs.clj.eartraining.panel2" works (just a "2" at the end). both compiles, but within an applet there is this strange error: http://nopaste.debianforum.de/29386

5:26 jdz: sgtzx_: then your OO is wrong

5:26 sgtzx_: because a tractor IS a kind of a car

5:26 hiredman: sgtzx_: that is just silly

5:26 sgtzx_: jdz: as I said, we assume "car" is something that only your factory makes

5:26 jdz: sgtzx_: tell me something you can do with a car that you cannot do with a tractor?

5:26 sgtzx_: want to call it something else?

5:27 noidi: sgtzx_, instead of thinking in terms of data types, think about functions... write functions which only take the data they _need_, not functions which operate on some data type

5:27 hiredman: the idea of a one to one mapping between objects and physical entities is one the worst things about oo

5:27 noidi: and likewise return the data you have to return, not some type

5:27 sgtzx_: hiredman: could be

5:27 noidi: and then just slice and dice your data so that you can feed it to your functions

5:27 hiredman: is

5:27 sgtzx_: noidi: that actually made sense

5:28 hiredman: but in the example I posed, there was simply a bag of things

5:28 Maddas: jdz: Drive on the highway? ;-)

5:28 sgtzx_: hiredman: some of them were FactoryCars, some were Tractors

5:28 hiredman: now, FactoryCar has 4 wheels, engine. So does Tractors

5:28 jdz: Maddas: you can do it on tractor. never mind the police, just drive through them.

5:28 hiredman: what is the difference bwteen a car and a tractor?

5:28 sgtzx_: hiredman: But we wanted to pick out the FactoryCars

5:29 Maddas: jdz: Point conceeded.

5:29 noidi: if your function does something with wheels and engines, make it take a map with :wheels and :engine fields

5:29 hiredman: what if someone drives the tractor on the road, do we consider it a car then?

5:29 sgtzx_: hiredman: I changed the example to FactoryCar now, to avoid the confusion

5:29 hiredman: It *must* be a car from your factory.

5:29 hiredman: Your factory has 8 models

5:29 hiredman: (assoc :factory :mine)

5:30 jdz: sgtzx_: my point is: one and the same thing (object; instance) can be many things at once. it can be one thing or the other or many at once depending on the context.

5:31 noidi: it's all just data

5:32 sgtzx_: hiredman: and then before you know it, your factory decides to produce tractors as well.

5:32 noidi: you may interpret the same data as representing a tractor or representing a car

5:32 jdz: sgtzx_: i told you in the beginning of this discussion: in real world there are only instances; and there is no inheritance.

5:33 hiredman: sgtzx_: (assoc base :model tractor)

5:33 jdz: sgtzx_: all the classification stuff is purely mental device to optimise storage.

5:33 * cgrand thinks that in real world, we recognize a car because it has some properties (wheels, engine etc.) and supports a set of usual interactions protocols (aka interfaces) which enable anyone to drive any car. There's no Car, there are cars and protocols to operate them.

5:34 jdz: cgrand: correct.

5:34 cgrand: i mean, i agree :)

5:34 LauJensen: hehe

5:34 noidi: sgtzx_, I had a huge culture shock trying to learn functional programming coming from OO, but I think I'm finally over it now

5:35 octe: what would i use to join an array of strings in clojure?

5:35 Chousuke: apply str

5:35 octe: ah

5:35 noidi: sgtzx_, for me the big revelation was to start thinking about the functions instead of data types, like i said

5:35 AndiXng: noidi: i'm still waiting for this state, but i think i'm on the right way ;)

5:35 jdz: octe: or interpose with a space or something else

5:35 octe: and then apply str

5:37 Chousuke: The inheritance model is fine with a simple example like the Car-Tractor one, but then you'll get into trouble if you have your own data that's *almost* like the class that some API you're using requires...

5:37 octe: jdz: thanks

5:37 noidi: instead of artificially imposing a restriction like "this function only operates on tractors", write a function that works on things with wheels

5:37 octe: that's what i wanted to do

5:38 noidi: _if_ it happens to need wheels to do its job :)

5:38 jdz: clojurebot: logs

5:38 clojurebot: logs is http://clojure-log.n01se.net/

5:38 Chousuke: in fact, the data might be functionally equivalent, but since they're different classes they will be incompatible and you'll be :-(

5:38 hiredman: http://gist.github.com/211677

5:39 octe: is there any way to get stacktraces that makes sense?

5:39 hiredman: Chousuke: like how every java lib has its own pair class

5:39 octe: yes, i wonder if they'll ever put a Pair<T1, T2> class into the jdk..

5:40 Chousuke: they should put a Pair *interface* instead ;/

5:40 with .first and .second

5:41 hiredman: .getFirstElement .getSecondElement

5:42 I, mean, this is java we are talking about

5:42 AndiXng: hm... i have two totally identical files (except the namespace), one has the ns "com.xenoage.labs.clj.eartraining.panel", the other "com.xenoage.labs.clj.eartraining.panel2". i tried it for 30 minutes now, the first one always results in http://nopaste.debianforum.de/29386 when using in an applet (desktop app works), the second one always works. is this possible or do you think i'm doing some nonsense here?

5:43 hiredman: how sure are you they are identical?

5:44 if you changed panel2 to panel would the sha1 of both files be the same?

5:44 AndiXng: copy+paste everything, just added 2 to the ns. no self-references within.

5:45 i'll test

5:46 hiredman: and where is the rest of the exception?

5:50 sgtzx_: sorry I was on the phone

5:50 back now

5:50 but I scrolled up and read

5:50 It's definitely a culture shock... OO brainwashed mind -> FP

5:51 noidi: sgtzx_, the important thing to remember is that there's no such thing as data having the wrong type. either you have the needed data or you don't

5:51 hiredman: http://obiecte.blogspot.com/2008/09/oop-sucks.html

5:51 noidi: converting it from one representation to another is easy and cheap in clojure

5:52 sgtzx_: noidi: i am always thinking in practical terms... my brain thinks in OO due to years of exposure

5:52 brb

5:52 noidi: e.g. if you have [[1 2] [3 4]] you can easily convert it to [{:first 1 :second 2} {:first 3 :second 4}] if that's what some function expects

5:54 sgtzx_: back

5:54 noidi: yea I see

5:55 AndiXng: hiredman: this is the whole exception

5:55 hiredman: i'll upload a demo

5:56 noidi: the recently resurfaced sudoku solvers by peter norvig and ron jeffries are imo a great example of how beatiful non-oo code can be

5:56 http://norvig.com/sudoku.html and http://xprogramming.com/xpmag/OkSudoku

5:57 and that is, also imo, much more interesting than whether or not tdd was used :)

5:58 the OO version gets all tangled up with classes, while the non-OO version is succinct and beautiful :)

5:58 sgtzx_: norvig loves python

6:00 LauJensen: hehe, nothing like nests of 'for loops'

6:00 sgtzx_: yea doesn't look very tasteful imho

6:00 noidi: LauJensen, they aren't really for loops, they're generator expressions

6:00 just like clojure's for

6:01 LauJensen: so why the many return paths ?

6:02 noidi: ah yes, he uses regular for loops later on, but they're not nested ;)

6:03 hiredman: http://lambda-the-ultimate.org/node/893 <-- venting on oo

6:04 AndiXng: applet/applet2-problem: currently it seem to work ...?!? i hope, it is a NetBeans (plugin) cache problem or something like that, so forget it for the moment

6:06 jdz: btw, remebered a nice article about modern OO: http://steve-yegge.blogspot.com/2006/03/execution-in-kingdom-of-nouns.html

6:08 noidi: also slightly related :) http://www.kimbly.com/blog/000063.html

6:08 hiredman: http://lambda-the-ultimate.org/node/893#comment-8248 most of that thread is junk, but this is good

6:11 noidi: one of the things that bothers me about oo "philosphically" is that it confuses objects for the real things that they represent

6:12 data about the car is never the real car, no matter if its an instance of the Car class, [4 :ford] or {:wheel-count 4 :model :ford}

6:13 ambient: jdz iirc that was more about java

6:13 jdz: ambient: no, it's about nouns and verbs

6:13 noidi: none of those is "more of a car" than the others :)

6:26 AWizzArd: How can i make an array of 100 Objects? (make-array Object/TYPE 100) doesn't do the job.

6:27 AndiXng: AWizzArd: (make-array Object 100) ?

6:28 rhickey: TYPE is only to get to primitive class through boxed class

6:28 ,Object

6:28 clojurebot: java.lang.Object

6:28 rhickey: ,Long/TYPE

6:28 clojurebot: long

6:28 rhickey: ,Long

6:28 clojurebot: java.lang.Long

6:29 AWizzArd: oki thanks

6:29 AndiXng: btw, both applets (applet and applet2) are working fine now. i suspect a cache bug in netbeans/enclojure

6:32 i think i found the reason for the strange bug

6:33 it seems, as if there is no main method allowed in classes loaded by a clojure applet

6:33 this is strange, but i tested it repeatedly and the file with main method fails

6:35 and the error happens at a strange position ( http://nopaste.debianforum.de/29386 ). i'll try to create a simple example and post the bug to the mailing list.

6:37 however, the error is in the new plugin module, which is available only for java 6 update 14 or higher

6:37 can anybody please test it? http://xenoage.com/temp/clj2/applet/ - should fail with the same error posted 2 lines above

6:39 AWizzArd: AndiXng: I get a NPE, at sun.plugin2.applet.Plugin2Manager.findAppletJDKLevel(Unknown Source)

6:40 AndiXng: exactly

6:40 and this one should work: http://xenoage.com/temp/clj2/applet2/

6:40 AWizzArd: AndiXng: how many LOC of this applet did you write in Clojure?

6:40 AndiXng: it is exactly the same, but with no main method(s)

6:41 about 100 lines

6:41 ambient: new clojure-mode for emacs doesn't work anymore. it requires "swank-clojure-binary" or clojure jar path. upgraded from 1.5 to 1.8 through package-install

6:41 AWizzArd: And the .java loc?

6:41 ambient: do you use jochu or technomancy?

6:41 AndiXng: AWizzArd: 0

6:42 ambient: AWizzArd whichever clojure-install uses

6:42 AWizzArd: AndiXng: that's good, not too many.

6:42 ambient: clojure-mode works, but slime doesn't

6:42 AndiXng: AWizzArd: i think i'll post it as a second example in my applet tutorial (postet some days ago in the mailgroup)

6:43 AWizzArd: AndiXng: yes good, continue to post please. Btw, did you remove the main methods or renamed them?

6:43 AndiXng: AWizzArd: can you verify that http://xenoage.com/temp/clj2/applet2/ works?

6:43 AWizzArd: removed

6:43 AWizzArd: however, they should not be buggy, since they work when i start the program as a standalone app

6:44 AWizzArd: but i'll try

6:44 AWizzArd: yes, applet2 works. I am making funny sounds and bother my workmates :)

6:45 rhickey: AndiXng: "class com.xenolabs.clj.eartraining.applet overrides final method"

6:45 AndiXng: rhickey: yes, this is when you are using java 5 or the old plugin, i guess

6:45 rhickey: and this is indeed interesting. i posted this already on the mailgroup. i think its a bug in clojure (compiler?)

6:46 rhickey: 'cause if you try it with java 6 (>= update 14 i guess) everything is fine

6:48 AWizzArd: renaming also works. it really seems to be the "-main" method which causes the problems.

6:53 AWizzArd: i could workaround the problem by creating a new file containing only the main method. this file is not referenced by the files used within the applet. then, the applet works.

6:57 AWizzArd: Did you test that?

6:59 AndiXng: AWizzArd: yes. in 10 minutes i've finished a small example demonstrating the "-main"-problem. i'll post a link to it here and (if anybody can reproduce the problems) in the mailgroup

6:59 ambient: what are the differences between swank-jonchu and swank-technomancy?

7:11 octe: what would be the easiest way to have a loop counter in a doseq?

7:12 basically what i want to do is: for(int i=0;i<strings.length;i++) print(i +". " + strings[i]);

7:20 AWizzArd: octe: you can use (doseq [[i s] (indexed my-strings)] (println i "and" s))

7:20 indexed sits in clojure.contrib.seq-utils

7:20 ,indexed

7:20 clojurebot: java.lang.Exception: Unable to resolve symbol: indexed in this context

7:21 AWizzArd: ok, the bot doesn't know it, but just (use 'clojure.contrib.seq-utils) in the repl.

7:22 octe: nice, thank you :-)

7:22 jdz: ,(require 'clojure.contrib.seq-utils)

7:22 clojurebot: nil

7:22 jdz: ,indexed

7:22 clojurebot: java.lang.Exception: Unable to resolve symbol: indexed in this context

7:22 jdz: ,clojure.contrib.seq-utils/indexed

7:22 clojurebot: #<seq_utils$indexed__697 clojure.contrib.seq_utils$indexed__697@85097d>

7:22 jdz: ,(doc clojure.contrib.seq-utils/indexed)

7:22 clojurebot: "([s]); Returns a lazy sequence of [index, item] pairs, where items come from 's' and indexes count up from zero. (indexed '(a b c d)) => ([0 a] [1 b] [2 c] [3 d])"

7:26 AndiXng: if anybody has java 6 update 14 or higher and 5 minutes left to verify a bug, please help: http://www.xenoage.com/extern/bugreports/clojure-main-problem.zip

7:26 self-explanatory

7:26 just call build.sh and then open the 3 HTML pages in your browser

7:26 2 should work (nomain and renamedmain) and 1 should fail (main)

7:28 can anybody confirm this?

7:41 ambient: anyone had a problem with ELPA in Emacs where updating clojure-mode-1.5 to clojure-mode-1.8 breaks the system?

7:42 i don't want to delete all clojure directories and re-install but the alternative seems to be a lot of wasted time

8:04 LauJensen: Anyone here who is advanced enough in math to reason about Mersenne primes with me in private for 5 minz?

8:05 vdrab: I'm curious, what is the reason for the different ways of importing/using libraries? i.e., (import '(java.io Something)) vs. (use '[my-lib])

8:05 why won't the latter work with quoted lists as well?

8:05 LauJensen: import for java, use for clojure

8:05 vdrab: right,

8:05 but why the difference between lists vs. vectors?

8:06 ambient: i'd hazard a guess: performance characteristics

8:06 vdrab: how so?

8:06 ambient: ack, nvm

8:06 LauJensen: ambient, for such a small op, what difference could that possible yield?

8:06 * ambient tries to remember not to write stuff on irc while distracted

8:06 vdrab: also, (use 'my-lib) seems to work too

8:07 without the vector

8:07 mikem: vdrab: I think the vector allows for keywords, such as :as, or :only

8:07 vdrab: mikem: and lists don't?

8:08 mikem: vdrab: ah, I was comparing to your last example, (use 'my-lib)

8:08 vdrab: mikem: oh, sure.

8:09 well, it's not a biggie... it's just that most design decisions in clojure I've seen so far are really well thought out, so I wondered what prompted this one

8:09 * mikem has no idea & is still a bit unclear when to use use vs require

8:10 arbscht_: ,(doc use)

8:10 clojurebot: "([& args]); Like 'require, but also refers to each lib's namespace using clojure.core/refer. Use :use in the ns macro in preference to calling this directly. 'use accepts additional options in libspecs: :exclude, :only, :rename. The arguments and semantics for :exclude, :only, and :rename are the same as those documented for clojure.core/refer."

8:11 LauJensen: use interns to your current namespace, require doesn't

8:11 mikem: arbscht_: yep, i read that. I just haven't written enough Clojure yet to completely understand :)

8:11 I'm still green

8:12 vdrab: on a related note, how can I import a single compiled java class (not in a .jar)? I'm pretty sure I specified the class path correctly, but it won't import...

8:14 AndiXng: what is the type hint for a String array?

8:14 arbscht: vdrab: (import 'packagename.Classname) or (import '(packagename Classname))

8:15 vdrab: if you're sure the class path is correct, check again :)

8:15 vdrab: arbscht: I always need a package name?

8:15 arbscht: lol. you're probably right

8:22 rottcodd: AndiXng: my guess would be #^"[Ljava.lang.String;"

8:27 AndiXng: rottcodd: thx

8:47 rhickey: ,(class (into-array ["fred"]))

8:47 clojurebot: [Ljava.lang.String;

8:47 jlilly: what does the -> function do in clojure?

8:48 better question: how can I figure that out myself?

8:48 rhickey: ,(doc ->)

8:48 clojurebot: "([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."

8:48 LauJensen: ,(-> 5 (+ 2) (+ 3))

8:48 clojurebot: 10

8:48 AndiXng: i hoped that the String[] typehint would fix the -main problem, but it is still there

8:49 rhickey: hmpf, clojurebot elides the fact that it is a macro

8:49 jlilly: ,(-> 5 (+ 2) (+ 3) (+ 10))

8:49 clojurebot: 20

8:49 rhickey: ,(macroexpand '(-> 5 (+ 2) (+ 3)))

8:49 clojurebot: (+ (clojure.core/-> 5 (+ 2)) 3)

8:50 jlilly: huh.

8:50 rhickey: ,(macroexpand '(clojure.core/-> 5 (+ 2)))

8:50 clojurebot: (+ 5 2)

8:51 rhickey: so, (+ (+ 5 2) 3)

8:51 jlilly: reminds me a little of reduce, if I'm seeing it right

8:52 rhickey: it is a code reorganizer, not a function

8:52 jlilly: that's kinda hurting my brain this early in the morning.

8:53 rhickey: the best analogy is the threading one, where the initial arg gets passed to the first fn, then that result gets passed to the second, etc

8:54 -> passes it first, ->> passes it last

8:54 jlilly: the threading reference didn't make sense, but that just sorta did.

8:54 so it is kinda like reduce?

8:54 except you provide a variable and forms instead of a function and forms?

8:54 * jlilly struggles.

8:55 chouser: I can see why it might remind you of reduce, but you wouldn't use it in similar circumstances.

8:55 jlilly: (GET "/product/:id"

8:55 (str "You chose product: "

8:55 (-> request :route-params :id)))

8:55 rhickey: ,(->> [1 2 3] (filter odd?) (map str))

8:56 clojurebot: ("1" "3")

8:56 jlilly: that's the context, from the compojure tutorial.

8:56 rhickey: so that take 1,2,3 and maps them to strings, then filters out the odd ones?

8:56 in reverse order b/c you did ->>, right?

8:57 rhickey: not quite, the point of the ->s is to let you read left to right

8:57 chouser: instead of inside out as you usually do.

8:57 rhickey: so filters first, then strs

8:57 jlilly: ,(-> [1 2 3] (filter odd?) (map str))

8:57 clojurebot: java.lang.IllegalArgumentException: Don't know how to create ISeq from: core$str__4257

8:58 jlilly: ,(macroexpand (-> [1 2 3] (filter odd?) (map str)))

8:58 clojurebot: java.lang.RuntimeException: java.lang.IllegalArgumentException: Don't know how to create ISeq from: core$str__4257

8:58 weissj: is there any way to develop a java class and test at the REPL, without having to restart the REPL each time you edit/compile the java file? Some kind of classloader trickery?

8:58 jlilly: that's trying to do (map str (filter odd? [1 2 3])) ?

9:00 chouser: jlilly: note -> vs. ->>

9:00 rhickey: jlilly: since -> puts the arg first, it will try to do (map (filter [1 2 3] odd?) str), which won't work. You an almost never swap -> and ->> since they work with functions that expect their args in different orders. ->> is most useful for the seq functions that expect the seqs last

9:00 chouser: jlilly: your expr would be like (map (filter [1 2 3] odd?) str)

9:00 jlilly: oh!

9:00 -> makes it the first argument.

9:00 not expands into the first function.

9:01 I thought you meant that ->> would do the same as -> except expand into the last form first

9:01 rhickey: ,(-> {:a 1 :b {:c 42}} :b :c)

9:01 clojurebot: 42

9:02 Chousuke: hmm

9:02 ,(->> [1 2 3] (filter odd?) (map str))

9:02 clojurebot: ("1" "3")

9:03 jlilly: so that called the map function with argument :b (which returns {:c 42}) and then called the map function on :c which returns 42?

9:03 chouser: Chousuke: nice! but somehow I think I've seen that somewhere before...

9:03 jlilly: as I understand it, what I would know as dictionaries (python world) are actually function-like.

9:03 chouser: jlilly: yes

9:03 Chousuke: jlilly: no, it called the :b function with the map argument, and then calls :c function with result of that. :P

9:03 jlilly: so if you call ({:key 4} :key) => 4 ?

9:03 chouser: except not "the map function"

9:04 yes

9:04 that's calling the map as a function

9:04 "the map function" is the high-order lazy seq function named 'map'

9:04 jlilly: got it.

9:05 Chousuke: (macroexpand-1 '(-> {:a {:b 1}} :a :b))

9:05 ,(macroexpand-1 '(-> {:a {:b 1}} :a :b))

9:05 clojurebot: (clojure.core/-> (clojure.core/-> {:a {:b 1}} :a) :b)

9:05 chouser: I suppose it's too late to start calling map collections "dictionaries" or "dicts"?

9:05 Chousuke: hashmaps? :)

9:05 chouser: I suppose that implys keys are "words"

9:05 jlilly: so (-> {:a {:b 4}} :a :b) => (({:a {:b 4}} :a) :b)

9:06 I think I've got it now :)

9:06 Chousuke: jlilly: no

9:06 chouser: but hashmap means something more specific... array maps and sorted maps are clearly not hashmaps.

9:06 Chousuke: jlilly: it's (:b (:a {:a {:b 4}}))

9:06 jlilly: Chousuke: ?

9:06 huh.

9:06 chouser: oh, sorry -- I mislead you. :-(

9:06 jlilly: so the keys of a map are also a function?

9:06 Chousuke: jlilly: *keywords* are functions

9:07 they look themselves up in their argument

9:07 jlilly: I see.

9:07 (({:a {:b 4}} :a) :b) -- that's also valid right? Just not what that expansion thing is doing.

9:07 Chousuke: yeah.

9:07 because maps are functions of their keys

9:08 jlilly: also, when would you want to use a keyword as a function and map as an argument rather than the other way around?

9:08 Chousuke: jlilly: for example when the map is not a clojure map

9:08 jlilly: so when its a java thing?

9:08 chouser: or if the map might be nil

9:08 Chousuke: yeah. or when it might not be a map at all, but a set or something

9:08 chouser: ,(:a nil)

9:08 clojurebot: nil

9:08 jlilly: ooh. got it.

9:08 chouser: ,(nil :a)

9:08 clojurebot: java.lang.IllegalArgumentException: Can't call nil

9:09 jlilly: neat! :)

9:09 chouser: or when you want to use ->

9:09 :-)

9:09 Chousuke: -> is a bit weird at first but the way it works is really very simple

9:09 jlilly: (-> request :route-params :id) == (:id (:route-params request)) .. right?

9:09 Chousuke: yeah.

9:10 jlilly: now I just need to figure out what those variables are. hah.

9:10 noidi: hmm.. is -> a monad? :)

9:10 after all, it strings together a bunch of operations

9:10 Chousuke: the best way to learn how -> works is to use macroexpand on it a lot :P

9:10 noidi: no, it's a macro.

9:11 noidi: it has its own DSL that it transforms into Clojure expressions :)

9:11 jlilly: ,(doc #"")

9:11 clojurebot: java.lang.ClassCastException: java.util.regex.Pattern cannot be cast to clojure.lang.Symbol

9:11 noidi: I know that it's just rewriting code

9:11 jlilly: sweet. tracebacks are docs enough :-P

9:12 Chousuke: heh :P

9:12 yeah, #"" is reader syntax for a regex pattern

9:14 jlilly: Chousuke: I just saw yesterday that there are some weird shortcut stuff with #

9:14 wanted to be sure I was reading it right

9:15 I think there's like #() and ^#()

9:15 I think the 1st is an anonymous function, but I forget what the second one is.

9:15 Chousuke: #(foo bar) is a lambda shortcut

9:15 ^foo is (meta foo)

9:15 and #'foo is (var foo)

9:15 chouser: ^foo might be deprecated

9:16 jlilly: I just saw it in the clojure screencast on peepcode.

9:16 which is actually pretty decent. def. worth the $9

9:16 (not for you guys, but still)

9:30 namor: How would you take all but the last element of a collection?

9:31 Chousuke: butlast

9:31 (doc butlast)

9:31 clojurebot: "([coll]); Return a seq of all but the last item in coll, in linear time"

9:31 namor: cool, thx

9:32 BTW, is there some better way to find functions than search the api page?

9:32 chouser: ask in here

9:32 :-)

9:32 namor: :)

9:33 chouser: the pages on clojure.org functions grouped by category

9:33 there's a cheatsheet that some people seem to like

9:33 btw, drop-last is an alternative to butlast

9:34 noidi: namor, (find-doc "related words")

9:53 LauJensen: is take-from-rear-of-seq in core yet?

9:57 chouser: ~ticket #151

9:57 clojurebot: {:url http://tinyurl.com/ygjd5zx, :summary "Function to return last n items of a seq", :status :test, :priority :normal, :created-on "2009-07-12T02:45:06+00:00"}

9:59 LauJensen: no eta on that?

9:59 rhickey: needs a new name I think

9:59 chouser: last-n ?

9:59 rhickey: ok

10:00 chouser: brilliant and original, I know.

10:01 cgrand: lasts ?

10:02 rhickey: cgrand: somehow that makes me think I'll be getting more than one seq

10:02 LauJensen: its 'nth' from behind so to speak right?

10:02 chouser: LauJensen: no, it returns a seq

10:02 LauJensen: ah ok

10:03 rhickey: take-last would be another idea

10:04 LauJensen: rev-take ?

10:04 chouser: those would be different from each other.

10:04 rhickey: LauJensen: not retuned reversed

10:04 chouser: you can already do (take (reverse ...))

10:04 vectors already have subvec

10:04 LauJensen: ok - I'll leave the name-selection to native english speakers :) Just let me know when I can use it

10:05 chouser: take-last would have the same behavior as last-n, right?

10:06 jdz: take n seq :from-end t

10:06 taking from end of inifinite sequences sounds like fun

10:07 chouser: we already tried to stuff this behavior into 'last', but it didn't fit.

10:08 cgrand: there's already drop-last, so take-last seems a good choice

10:10 chouser: Is it worth handling Indexed colls differently? I'm thining not.

10:10 thinking

10:10 rhickey: chouser: from an interface or impl perspective?

10:10 chouser: impl

10:10 well, both.

10:11 if the impl tried to take advantage of Indexed, then there'd be questions about what kind of object to return.

10:11 rhickey: chouser: let's say no to interface, still some advantage to impl

10:12 there is subvec already

10:12 chouser: right

10:13 cgrand: from an impl persepective, Counted is interesting, no?

10:15 chouser: would allow you to keep less of the seq in memory while walking I suppose

10:16 cgrand: if Counted, take-last becomes a drop

10:29 mibu: Just popped in to say congratulations on the second year! The cake looks great.

10:40 namor: Ok, so (seq "abc") returns (\a \b \c). How to get back from (\a \b \c) to "abc"?

10:41 chouser: ,(apply str (seq "abc"))

10:41 clojurebot: "abc"

10:42 namor: Hmm, so str returns a string if you pass it multiple characters as arguments?

10:43 chouser: string always returns a string. it concatonates the string form of each arg

10:43 ,(str \a \b 123 "xyz" Integer)

10:43 clojurebot: "ab123xyzclass java.lang.Integer"

10:43 namor: ah, i get it. thx

10:46 chouser: rhickey: http://www.assembla.com/spaces/clojure/documents/b9iKQQUMir3OzreJe5aVNr/download/take-last.diff

10:51 rhickey: chouser: great - thanks!

10:54 AWizzArd: What should I use instead of doall?

10:54 ,(format "%s" (doall (map inc (range 5))))

10:54 clojurebot: "clojure.lang.LazySeq@1c3e4a2"

10:55 chouser: LauJensen: go go go

10:55 octe: ,(format "%s" (map inc (range 5)))

10:55 clojurebot: "clojure.lang.LazySeq@1c3e4a2"

10:55 octe: ,(format "%s" (apply str (map inc (range 5))))

10:55 clojurebot: "12345"

10:55 octe: ,(apply str (map inc (range 5)))

10:55 chouser: ,(format "%s" (pr-str (map inc (range 5))))

10:55 clojurebot: "12345"

10:55 "(1 2 3 4 5)"

10:55 octe: depends on what you want i assume :-)

10:57 AWizzArd: fine

10:58 jlilly: ,(doc doall)

10:58 clojurebot: "([coll] [n coll]); When lazy sequences are produced via functions that have side effects, any effects other than those needed to produce the first element in the seq do not occur until the seq is consumed. doall can be used to force any effects. Walks through the successive nexts of the seq, retains the head and returns it, thus causing the entire seq to reside in memory at one time."

10:58 jlilly: ,(doc pr-str)

10:58 clojurebot: "([& xs]); pr to a string, returning it"

10:58 jlilly: :-/

10:58 ,(doc pr)

10:58 clojurebot: "([] [x] [x & more]); Prints the object(s) to the output stream that is the current value of *out*. Prints the object(s), separated by spaces if there is more than one. By default, pr and prn print in a way that objects can be read by the reader"

10:59 jlilly: ,(doc println)

10:59 clojurebot: "([& more]); Same as print followed by (newline)"

10:59 jlilly: ,(doc print)

10:59 clojurebot: "([& more]); Prints the object(s) to the output stream that is the current value of *out*. print and println produce output for human consumption."

10:59 jlilly: ahh. print and println are for humans, pr and pr-str are for.. ? Network sockets and such?

11:01 chouser: jlilly: or the repl

11:01 jlilly: chouser: which is for the repl? pr?

11:01 * jlilly would consider the repl to be human consumption.

11:02 chouser: the P in REPL is pr or prn

11:05 jdz: LauJensen: i just made a brian's brain simulator in CL (a very naiive version with board as a 2d array and making new boards in every iteration). it runs tons faster than the Clojure version...

11:05 AWizzArd: I have (binding [*in* (foo)] (let [x 1] ...)). Is it idiomatic (and correct?) to say (binding [*in* (foo), x 1] ...) instead?

11:05 jdz: LauJensen: i'll cooble up some blog entry (when i create a blog)

11:06 chouser: AWizzArd: won't even work unless x is var

11:06 AWizzArd: so, no.

11:06 AWizzArd: oki

11:24 cgrand: chouser: shouldn't take-last returns a lazy seq like drop does?

11:37 chouser: if the input seq is lazy, it will -- except it has to be realized first to know where the end is.

11:40 so it can't ever return an unrealized lazy seq. Only if there were a counted lazy seq could it, and we don't generally have such critters.

11:41 rhickey: chouser: not quite, as a seq from a point on a counted/indexed thing need not be realized, even though the source isn't lazy

11:44 maacl_: LauJensen: you around?

11:44 chouser: so if it had a special case for a counted/indexed coll, it could return an unrealized seq over the end of the collection. As it is, it returns a realized seq of the same.

11:45 cgrand: is that what you were asking for? special cases for different kinds of colls?

11:45 I tried to word the docstring to keep that possibility open.

11:46 a seq over a subvec, a split from a finger tree, whatever...

11:49 kotarak *is* spamming us.

11:49 cgrand: chouser: no, my remark on Counted was simple musing on my part, but yes I'd like take-last to return a lazy-seq and not force realization of its input -- like drop actually does

11:50 ,(class (drop 5 nil))

11:50 clojurebot: clojure.lang.LazySeq

11:50 chouser: cgrand: how can it avoid realizing its input?

11:50 Without Counted there's no way to know what the first item of the output seq should be until you've found the end of the input seq.

11:50 cgrand: surround your take-last's body with lazy-seq

11:51 chouser: oh, delay all work until the first 'rest', then do all of it?

11:51 rhickey: Is there a page yet for the Clojure in Action book?

11:52 chouser: rhickey: I saw a green paper, but I don't know of anything online yet.

11:52 rhickey: I thought I saw a cover somewhere

11:53 cgrand: chouser: yeah, would be consistent with drop

11:53 chouser: there was a cover shot in the green paper

11:53 rhickey: ah

11:53 so no link for the book yet

11:55 chouser: apparently not. can request the green paper: http://ow.ly/ufsr

11:57 pao: a totally uninformed question... would it be possible to have a persistent (on disk) data structure with the semantics already provided by clojure STM implementation?

12:00 AWizzArd: When I want to parallelize (doseq [[a b c] my-lazy-seq] ...), can I then in general do something nicer than (count (pmap (fn [[a b c]] ...) my-lazy-seq))?

12:00 * technomancy wonders what the cover for Clojure in Action will be

12:00 technomancy: they always have the funniest-looking guys on them

12:02 chouser: woman and a baby. does that mean something?

12:02 Chousuke: hm

12:02 why doesn't alter-var-root have a ! at the end? because it already has alter?

12:05 rhickey: http://clojure.blogspot.com/2009/10/clojure-is-two.html

12:07 rys: Happy birthday!

12:07 rottcodd: pao: this might be of interest http://groups.google.com/group/clojure/browse_thread/thread/aa22a709501a64ac/b578f0915b55c4be?#b578f0915b55c4be

12:08 AWizzArd: technomancy: please look into your /msg'es

12:08 pao: rottcodd: thanks... let me read...

12:10 rys: That post just affirms I made the right choice when picking clojure to learn. I chose it primarily for the community around it. I'll find some cake!

12:10 pao: rottcodd: I guess that stuff never ended in official repo...

12:22 namor: When I try to (compile 'hello), I get: java.io.IOException: No such file or directory (hello.clj:1). I'm started clj from the same directory, and if I do it from another dir, the error message changes.. any ideas?

12:22 replaca: rhickey: congrats on Clojure's 2nd b-day!

12:24 Raynes: replaca: I think it's Clojure's 3rd birthday.

12:24 rhickey: replaca: thanks!

12:25 silkodyssey: happy birthday clojure!

12:25 replaca: let's see how it behaves in the terrible twos :-) Might see a lot of tantrums!

12:25 Raynes: rhickey: Is it Clojures 2nd or 3rd birthday?

12:26 If it's the second birthday, the Wikipedia page has been wrong for about 6 months now. :\

12:29 rstehwien: rhickey: Happy Birthday! I'm loving Clojure. Still wrapping my brain around my first Lisp and Functional language but it is a very fun ride.

12:29 rhickey: Raynes: 2 years since first released

12:30 Raynes: Oh, then yeah, the Wikipedia page has been wrong for a long time. :>

12:30 rhickey: Happy Birthday to Clojure. :)

12:30 rhickey: thanks!

12:32 namor: How would you compile a little script of clojure to a classfile? This compilation guide on clojure.org does not work apparently.

12:34 steiger: rhickey: ha ppy birrrth daaay tooo ... your son ? :) congratulations, man.

12:35 namor: how does that not work? use (:gen-class) with the options you like

12:35 namor: steiger, if I try to (compile nsname), I get the error: java.io.IOException: No such file or directory (nsname.clj:1)

12:36 steiger, where nsname is the name of the namespace/file I try to compile.

12:36 Chousuke: is it in the classpath?

12:36 steiger: namor: did you start the Repl with the correct classpath?

12:36 namor: I started it from the directory of the file.

12:37 And if I run it from another directory, the error message changes, so I suppose the classpath is correct.

12:37 AWizzArd: What does a "IllegalStateException: Var clojure.core/push-thread-bindings is unbound" mean? I have a (binding [...] ...) there.

12:37 Chousuke: hmm

12:37 steiger: namor: usually it`s something like: java -cp path/to/clojure.jar:/directory/that/has/your/file clojure.main . that way, java will be able to `see` your file

12:37 hm

12:38 Chousuke: AWizzArd: push-thread-bindings is the new API used by the binding macro :/

12:38 AWizzArd: Ah good, then I have an old clojure.jar on the server. Thanks.

12:39 yup, problem solved :)

12:42 somnium: namor: compiling to an executable .class file and executing a script with clojure.main are different, which are you trying to do?

13:36 cemerick: The warmup time for the JIT is really painful in a thick-client setting. Has anyone tried clojure + gcj?

13:40 chouser: no but it sounds interesting.

13:40 gcj can consume class files?

13:41 cemerick: last I knew -- jar file in, .so or .dll or .exe out

13:41 it's probably more trouble than it's worth. I should just buckle down and write some kind of reasonable offscreen warmup process.

13:42 * technomancy recommends XML sit-ups

13:42 technomancy: http://justlooking.recursion.org/camping-xml-situps.png

13:44 jevgeni: Hi guys. Just wondering - is there some kind of UML for functional languages? How can people communicate ideas to each other? (i.e. Oop langs use sequence diagrams and they naturally map to objects/classes/messages/etc)

13:45 steiger: UML sucks

13:46 chouser: generally rhickey writes one or two very concise and somewhat cyrptic sentences. Then we all stare at them until enlightenment comes to us.

13:46 cemerick: steiger: a little harsh, no?

13:46 chouser: mine too. sorry.

13:46 steiger: cemerick: yeah, well, probably. sorry for that

13:47 jevgeni: steiger: I am not insisting on the uml as long as there is something I can use to explain the coding my friend/wife/cat :)

13:47 * technomancy doesn't think there's much about FP that precludes drawing diagrams

13:47 cemerick: jevgeni: not that I'm aware of. The units of interest are generally much smaller, so there's less of a need for formalisms. That said, some lingua franca in that area would be welcome.

13:47 rhickey: protocols will help organize things quite a bit, I think

13:48 technomancy: the non-ridiculous parts of UML are really not much more than that anyway.

13:48 cemerick: technomancy: yeah, the problem is that everyone makes their pretty pictures differently.

13:49 chouser: jevgeni: we use class inheritence diagrams sometimes: http://tinyurl.com/clojure-classes

13:49 I suppose that's out of date again

13:49 * rhickey loves omnigraffle, has many dozen diagrams of the Clojure design, none UML

13:49 technomancy: as long as everyone understands that a cylinder is a database and a cloud is a network, that's good enough for me. =)

13:50 jevgeni: chouser: that's nice. thanks for showing it

13:51 chouser: Haskellers just define obscure unicode symbols as infix functions and then promptly drop straight into mathematical notation.

13:52 rhickey: jevgeni: that diagram is broken down in these tutorial slides: http://clojure.googlegroups.com/web/tutorial.pdf

13:52 jevgeni: rhickey: do you use omnigraffle for designing clojure programs as well?

13:53 thx for link, I've not seen this tutorial yet

13:53 rhickey: jevgeni: eventually there may be a video, but it was 5 hrs

13:56 * jevgeni thinks he is spoiled with oop

13:56 jevgeni: I we take any typical use case, then it lays into declarative languages very well. is there any guidelines how to lay the story into FP languages?

13:57 s/I/If

13:57 cemerick: jevgeni: most if not all of OOP is decidedly not declarative. Totally not an answer to your question, but it sounds like you're mixing up terminology in general.

13:58 chouser: jevgeni: I don't know that it's really so different. You'll still have bundles of related data and operations to perform on them.

13:59 jevgeni: sorry, I meant imperative :)

13:59 cemerick: nevermind, then :-)

13:59 chouser: Perhaps the main difference is the design needs to differentiate between values and identity. Other differences include: the operations don't generally live with the data (though they can), and the data is immutable.

14:05 jevgeni: Could you recommend me a book which can teach me how to design FP programs?

14:06 if there any..

14:06 steiger: jevgeni: how to design programs .

14:06 jevgeni: htdp.org -- it uses scheme, though

14:06 jevgeni: if you want something more hardcore, try structure and interpretation of computer programs

14:06 jevgeni: steiger: thanks!

14:07 steiger: jevgeni: you`re welcome. good luck with the book, it's very very good imo, if not the best on the subject

14:10 technomancy: so it looks like you cannot add your own metadata to test vars with deftest

14:10 * technomancy is finding himself in a position where he wants to do just that

14:11 slyrus_: where are queues described in the closure docs? I see them referred to in some of the API section, but don't see them in datastructures or sequences

14:11 jevgeni: sicp is interesting, yes, but it is more about the math, rather than about designing some domain-specific solutions..

14:11 technomancy: right now I'm wrapping deftest with a macro, but it would be great if you could use regular deftest for that

14:11 LauJensen: sicp is more about math?? :)

14:12 jevgeni: LauJensen: well, at least first chapter is full with math or I'm mixing up something:)

14:12 technomancy: that would allow categorizing tests by arbitrary metadata so you could have unit tests vs integration tests etc; and be able to run just your fast tests on their own

14:12 LauJensen: jevgeni, you're mixing it up my friend

14:12 steiger: jevgeni: sicp is hardcore in it's problem-solving. it`s for the real sharp mind (not my case). htdp focus more on the design of programs by working with more simple problems

14:12 cemerick: jevgeni: programming is applied math + logic, within some degree of approximation.

14:13 csteinbach: jevgeni: the first chapter of SICP is not at all representative of the rest of the book

14:13 jevgeni: skip to chapter 2 if your

14:13 jevgeni: not big on math

14:15 steiger: cemerick: i'd say that in most of the time, logic is much more important than the other areas of math for coding

14:15 cemerick: yeah, it depends on what you're doing, of course

14:17 technomancy: ivy fans: is it pretty easy to create a maven-style artifact that defines transitive dependencies using ivy?

14:17 jevgeni: I do mostly the integration of different systems, not so much math at all, I would say

14:25 piccolino: Hey guys, I'm trying to get a MacPort for clojure-contrib accepted. Is there any way we could do a release, or at least a 1.0 branch in github, so that it can pull a stable set of code?

14:26 technomancy: piccolino: you know about the 1.0-compatible branch, right?

14:26 piccolino: Yes, but the description seemed to indicate that that was going to have ongoing development, just development that is still compatible with 1.0.

14:26 technomancy: it has the occasional backport, but I think it's pretty stable.

14:27 it's not technically a release, but I think it's pretty safe to treat it as such

14:27 piccolino: OK, I'll try to convince them then.

14:27 technomancy: it's only had one commit since June

14:28 and that was a bugfi

14:28 x

14:28 piccolino: Yeah, I saw that. It's just hard to keep track of what exact code a given user has if the branch is changing.

14:29 If the port says "This is 1.0," but the code can be different depending on when it's pulled, it might not pick up those bug fixes later, etc.

14:30 technomancy: contrib is kind of a "bucket o' stuff"... you just kind of have to roll with that.

14:32 piccolino: Yeah, unfortunately it also appears to be Clojure's standard library, since almost everythign I see on github depends on it.

14:33 technomancy: yeah, that wasn't the intention, but I think you really can't have a language as small as Clojure without a standard library... so that's what it's become.

14:35 piccolino: Yeah. I'd just like Clojure to be as easy to get rolling with as Scala, because right now, it's kind of a pain to get set up.

14:36 technomancy: it will improve as more people start to realize automated dependency management is necessary.

14:37 piccolino: But don't you have to start cutting releases for that?

14:37 technomancy: you can use snapshots if you have push access to a server.

14:38 froog: technomancy: I wanted to ask if you could change/add lazy-seq to the clojure mode. right now 'lazy-cons' is mentioned twice.

14:38 technomancy: hah; really?

14:38 I'll take it out; thanks

14:39 froog: technomancy: thanks, I was contemplating setting up my own git branch, but this is such an easy fix :)

14:39 technomancy: froog: sure; pushing as we speak. =)

14:40 piccolino: What does that mean? Snapshots? Aren't those releases?

14:40 technomancy: piccolino: snapshots are artifacts from between formal releases

14:40 piccolino: Right.

14:40 For what I'm talking about, even snapshots would be great.

14:41 technomancy: I guess you could call them ad-hoc releases

14:41 piccolino: They're a release in the sense of "some named version of the code that won't change again."

14:41 technomancy: that'll do the trick

14:41 Stuart Sierra has big plans for setting up a repo for this kind of thing.

14:42 drewr: I use an ad hoc ivy repo for that

14:42 http://ivy.draines.com/

14:43 if there's no official release then I create a signature based on the commit and date

14:43 technomancy: it'd be nice to have a community-maintained one; something like rubyforge

14:43 I suspect this is what Stuart has in mind

14:43 drewr: clearly

14:43 technomancy: so each person doesn't need to maintain their own

14:44 drewr: just saying that idea can be expanded to something community-wide

14:45 piccolino: That would be great.

14:46 drewr: we're all going at it

14:46 hopefully the different vectors will converge at something awesome

14:47 froog: technomancy: got it, works great

14:48 technomancy: my only issue with Stuart's approach is that he thinks Maven's XML format is reasonable and expects clojure hackers to learn it, while I would rather have people write sexps.

14:48 but I guess it's up to me then to make the wrapper work well. =)

14:49 danlarkin: wooo corkscrew!

14:49 technomancy: if only maven didn't have this crazy plexus dependency that would be easy. =)

14:51 danlarkin: you're our only hope, techno-man kenobi

14:51 technomancy: hehe

14:54 piccolino: Has this been discussed on a blog somewhere or anything like that?

15:02 technomancy: drewr: is it pretty easy to publish maven-compatible artifacts with ivy?

15:38 Kjellski: Hi there =)

15:39 chouser: hello

15:40 Kjellski: I was just asking myself, is there a function already in clojure or clojure contrib, that can be used to ensure that all elements in a vector are continuous numbers? from the first on are just "inc"ed like: [ 24 25 26 27] => true and [ 2 3 5 ] => false

15:42 chouser: not that I know of, but should be simple enough to write.

15:42 technomancy: ,(reduce #(and %1 (< %1 %2) %2) [1 2 3])

15:42 clojurebot: 3

15:42 cemerick: I wonder: is anyone tracking the impact of changes in clojure.core on performance (on any level, microbenchmark or no)?

15:42 Chousuke: you can try (= (take (count v) (iterate inc (first v))) v

15:42 technomancy: ,(reduce #(and %1 (< %1 %2) %2) [1 2 1])

15:42 clojurebot: false

15:43 Chousuke: < is not enough

15:43 and you don't need to reduce, you can just apply it :)

15:43 technomancy: true. and it's ugly. but it's close. =)

15:43 Chousuke: ,(apply < [1 2 3])

15:43 clojurebot: true

15:43 Kjellski: Sure... but just thought I´m too stupid to find ^^

15:43 damned... thats neat.... ^^ I´ll use the second version ^^

15:44 Chousuke: it doesn't do what you need though.

15:44 Kjellski: No?

15:44 technomancy: oh, I missed the continuous part

15:44 Chousuke: ,(apply < [1 2 4])

15:44 clojurebot: true

15:44 chouser: ,(every? (fn [[a b]] (== (inc a) b)) (partition 2 1 [4 5 5 7]))

15:44 clojurebot: false

15:45 chouser: short circuits, which reduce can't.

15:45 serp_: ,(count 5)

15:45 clojurebot: java.lang.UnsupportedOperationException: count not supported on this type: Integer

15:45 Chousuke: (let [v [1 2 3]] (= (take (count v) (iterate inc (first v))) v))

15:45 ,(let [v [1 2 3]] (= (take (count v) (iterate inc (first v))) v))

15:45 clojurebot: true

15:45 Kjellski: I see ... and try to understand ^^

15:46 Chousuke: the (take (count v) ... ) is a wart though. I wonder if there's any way to get rid of it.

15:46 serp_: ,(take 5 (iterate inc 0))

15:46 clojurebot: (0 1 2 3 4)

15:46 serp_: ,(take 5 (iterate #(+ %1 10) 0))

15:46 clojurebot: (0 10 20 30 40)

15:46 serp_: neat

15:47 Chousuke: (every? true? (map = (iterate inc 5) [5 6 7]))

15:47 jeflkjsfdl

15:47 ,(every? true? (map = (iterate inc 5) [5 6 7]))

15:47 clojurebot: true

15:47 serp_: ,(take 2 [1 2 3])

15:47 clojurebot: (1 2)

15:51 Kjellski: I just don´t get how this works... (let [v [1 2 3]] (= (take (count v) (iterate inc (first v))) v))

15:52 chouser: compares your original collection with a seq of the same length counting from its first value

15:53 could be (= v (range (first v) (+ (first v) (count v)))) if that makes more sense to you

15:54 Kjellski: Got it, thanks!

15:55 Is it right, that from the first false on, the second vectors next element wouldn´t be produced, due to its lazyness?

15:56 ... in the iterate example...

15:57 chouser: yes

15:57 Kjellski: k, thanks.

15:58 chouser: hm

15:58 well, that's what I would have thought...

15:58 Kjellski: ^^, but?

15:59 chouser: still looking, hang on. :-)

15:59 Kjellski: kk

16:00 don333: ,(apply < [2 3 5])

16:00 clojurebot: true

16:00 chouser: ok, yes that's true, but it can be broken pretty subtly

16:01 made untrue I mean.

16:01 ,(= '(1 2 3 4 5) (lazy-cat [1 9 9] (do (println "got here") [4 5])))

16:01 clojurebot: false

16:01 chouser: ,(= [1 2 3 4 5] (lazy-cat [1 9 9] (do (println "got here") [4 5])))

16:01 clojurebot: got here

16:02 chouser: because the iterate example had a lazy seq first (as returned by take), it will use lazy-seq's 'equiv' which is lazy.

16:04 but if v had been first then it would depend on the type of v -- a vector being non-lazy starts of by comparing the sizes of the two args, which forces the whole lazy seq

16:04 Kjellski: Okay, so this your example, both of the vectors are only as long as the values continue to be true?

16:05 Sorry for my english... seems to be wrong grammar... ^^

16:15 chouser: in my last two examples, on the second one was comparing a vector (= a-vector a-lazy-seq)

16:15 in that case the lazy-seq always gets forced

16:16 Kjellski: Okay. I need more practice ...

16:17 Chousuke: chouser: that's somewhat surprising :/

16:17 ,(= [1 2 3] (iterate inc 1))

16:17 boom :P

16:17 clojurebot: java.lang.OutOfMemoryError: Java heap space

16:18 Chousuke: ,(= (iterate inc 1) [1 2 3])

16:18 clojurebot: false

16:19 Kjellski: ^^ with the order from Chousuke my heap explodes too ...

16:20 Why?

16:21 Chousuke: apparently the .equals method for a vector forces its argument.

16:21 but the .equals method for a lazy seq doesn't.

16:21 chouser: .equiv, but yeah.

16:21 Chousuke: and if you force an infinite sequence... boom :P

16:21 chouser: vectors compare size first, which is what you want if comparing two vectors

16:22 Chousuke: I think maybe it should have a check for this case.

16:22 chouser: I suppose it should ask it's arg if it's Counted first

16:22 Chousuke: it's not going to be too expensive. :)

16:23 Kjellski: I agree... ^^ ... at least for beginners like me :)

16:24 kylesmith_: cemerick: ping

16:24 Chousuke: it also makes it difficult to write code that may need to compare two arbitrary collections :P

16:24 chouser: rhickey: want a ticket for that?

16:27 Kjellski: So, thanks again and cya again... I´m off =)

16:27 cemerick: kylesmith_: pong

16:31 kylesmith_: cemerick: if you're having problems with jvm warmup, you can try lowering -XX:CompileThreshold=10000

16:35 cemerick: kylesmith_: yeah, I saw that -- there's a lot of options around controlling the JIT, but I'm leery of messing around with them on a whim. Unintended consequences and all that. It definitely calls for some experimentation, though.

16:37 chouser: cemerick: just write a little thing in C that throws up a splash screen while the jvm gets going.

16:37 * chouser runs away.

16:39 cemerick: oh, we've got a splash screen we can hide behind if need be (we use the NetBeans RCP). I just hate the prospect of letting it sit there for ~30s while we warm things up.

16:39 chouser: whoa

16:39 yeah

16:40 that's too much for a splash screen.

16:40 you need more of a mini-game

16:40 cemerick: 30s is probably an exaggeration, but that's the highest I've seen the initial action take in the UI.

16:45 * slyrus_ keeps forgetting he's not writing CL code...

16:45 slyrus_: where's prog1??

16:45 technomancy: slyrus_: in the 1980s where it belongs. =)

16:45 chouser: what is that, (let [x y] .... x) ?

16:45 slyrus_: correct chouser

16:45 chouser: where .... is all side-effecty?

16:46 * slyrus_ hangs his had in shame

16:46 slyrus_: s/had/head/

16:46 chouser: :-)

16:47 cemerick: slyrus_: it's OK man, it's gonna be O–K. :-)

16:49 slyrus_: so, I've been trying to convert some of my lisp code to clojure. probably a bad idea, but, hey, gotta start somewhere. lots of side effects. i think i need to rewire my brain.

16:49 for example...

16:49 lisppaste8: slyrus pasted "non-clojurey clojure code" at http://paste.lisp.org/display/88766

16:50 chouser: heh. looks converted.

16:50 Chousuke: yeah :P

16:50 chouser: slyrus_: do you know about letfn?

16:50 hiredman: people (not me) have 30 to 40 second OS boot speeds these days, so it's hard come to grips with the jvm taking a minute to start up

16:51 Chousuke: and the ref is overkill anyway. an atom would suffice, if you really want to do it like that

16:51 chouser: slyrus_: so you're making a local ref, using it to do some computation and then throwing it away?

16:51 slyrus_: chouser: yes, i just like the fact that i can use let for functions too

16:51 yep

16:51 chouser: yeah, don't do that. :-)

16:52 Chousuke: you don't even need the nested let though, as far as I can tell :/

16:52 as far as I know you can refer to earlier bindings in it in later bindings.

16:53 chouser: If you don't mind getting a bit off course, I highly recommend doing some projecteuler puzzles purely functionally

16:53 they start simple and get tougher -- after a couple dozen problems you'll find your brain has been rewired for you.

16:54 Chousuke: and then you start forgetting that things aren't always immutable :(

16:54 chouser: yep

16:54 slyrus_: thanks chouser, will do

17:01 lisppaste8: slyrus annotated #88766 "v2" at http://paste.lisp.org/display/88766#1

17:02 slyrus_: looks like i need to find some time over the weekend for some puzzles...

17:02 thanks for the tips though. now back to work...

17:07 neotyk: while working on one of projecteuler problems I improved contrib/math/lcm

17:08 what do I need to do to get http://github.com/neotyk/clojure-contrib/commit/b70d0c0fd16f6ea6b963fceb39b6d60f1ca55e95 in contrib?

17:08 I've already requested pull

17:08 technomancy: have you read http://clojure.org/patches ?

17:09 neotyk: kind off

17:10 technomancy: http://clojure.org/contributing also

17:10 neotyk: it's really small change, signing CA and sending is 10 fold more effort than this patch

17:11 technomancy: according to some projects, (GNU in particular) patches under a certain size are not actually copyrightable, but I don't know Rich's stance on that.

18:10 ol3`````: x

18:12 hiredman: clojurebot: ticket #151

18:12 clojurebot: {:url http://tinyurl.com/ygjd5zx, :summary "Function to return last n items of a seq", :status :fixed, :priority :normal, :created-on "2009-07-12T02:45:06+00:00"}

18:14 durka42: hiredman: how do you deal with "magically" updating clojurebot without having it disconnect?

18:15 is it just that you never change the actual onMessage function anymore?

18:16 hiredman: durka42: yeah, I never touch that stuff

18:16 I pull it out of proxy and into normal function application as fast as possible

18:17 durka42: i see

18:17 hiredman: and do any kind of abstraction stuff via functions

18:35 kylesmith: Are structs always faster than hashmaps? Structs are ~4% slower on my machine.

19:09 dreish: kylesmith: 4% slower at what?

19:11 kylesmith: it's a variation on constraint propagation.

19:11 so on each iteration, new candidates are being created, and other are being eliminated

19:12 I'm assuming the 4% is because the entire struct is being copied each time.

19:12 dreish: I think last time I microbenchmarked it, structs were more than twice as fast for creation than equivalent hash maps.

19:13 I think that was with 52 keys -- a-z + aa-zz.

19:13 kylesmith: I literally replaced a call to (hash-map ...) with (struct-map ...) and it was 4% slower.

19:14 my keys are just integers

19:14 dreish: If you can, use struct (without keys; vals must be in order) instead of struct-map.

19:15 kylesmith: well, I only know one key/val initially. One key/val pair gets added on each iteration.

19:15 dreish: That doesn't sound very struct-like.

19:16 kylesmith: it's not, but I wanted to benchmark it anyway.

19:17 dreish: Well, if you use a tool for something it wasn't intended for, it's probably not going to be very impressive.

19:18 kylesmith: structs are just maps with shared keys, right?

19:19 dreish: A struct is implemented as a Java array, plus a Clojure hash of keys to integers. The integers are indices into the array.

19:19 The key->int hash is created once and shared among all instances.

19:20 That allows you to create new ones very quickly using the struct function, since it's just populating an array with your args, and copying the ref to the struct basis (the key->int hash).

19:21 And it also allows you to create marginally faster accessors, though hashes are already pretty hard to improve on for lookup performance.

19:21 kylesmith: I could probably try vectors, since my keys are already integers...

19:22 dreish: I was wondering whether I should ask whether they were consecutive integers ...

19:22 kylesmith: yeah, I can enforce them to be consecutive

19:41 technomancy: ,(partition 2 [1 2 3])

19:41 he's deserted us!

19:41 anyway, the return value is ((1 2))

19:41 which is strange

19:41 I would expect it to be ((1 2) (3))

19:42 I guess the docstring only specifies what happens to incomplete lists if a pad collection is supplied

19:46 Chousuke: technomancy: that's the defined behaviour. you need to pad the sequence yourself

19:47 technomancy: Chousuke: I understand, it's just surprising to me.

19:47 didn't expect it to let elements just disappear

19:48 Chousuke: it makes sense though. you can ensure that you get items of exactly the required size.

19:49 and if you need to handle uneven sequences, you just add n-1 items as padding.

19:49 technomancy: what I really want is "partition coll into n pieces", which partition almost gets me

19:50 Chousuke: ,(doc partition-all)

19:50 hm

19:50 that's in contrib, anyway

19:50 technomancy: I'll look in seq-utils; thanks

19:50 ah, perfect; thanks

20:16 tomoj: is there anything like defvar in clojure?

20:17 besides (declare foo) (if-not (.isBound #'foo) (def foo bar))

20:17 technomancy: defonce maybe?

20:17 Chousuke: there's something called defvar in contrib

20:17 tomoj: defonce looks right, thanks

20:18 I want it so I can recompile in slime without wiping out all my vars (possibly leaving a running jetty server which AFAIK I have no way to stop)

20:18 technomancy: it's nice how the clojure version is actually named after what it does, unlike CL. =)

20:19 tomoj: yeah, I use defonce all the time for that

20:19 tomoj: yeah I always had to lookup which one was which in CL

20:22 technomancy: ivy fans: is there a way to set the version in ivy.xml?

20:22 the version of your project, that is... rather than of a dependency

20:26 tomoj: technomancy: revision on the info tag, maybe?

20:28 technomancy: tomoj: thanks!

20:29 doesn't look like you can use revision="{version}" style replacement in there though. =\

20:29 bummer to have to hard-code it.

20:35 tomoj: it looks like clojureql is not hardcoding it

20:36 I don't understand ant or ivy much at all yet, but it looks like the publish task dynamically grabs the version from a .properties file for ivy:publish

20:36 * technomancy uses maven normally, but I'm trying to convince this other project to quit keeping jars in git

20:37 technomancy: this git repository took me 40 minutes to upload since it had so many jars in it!

20:38 ah, I had the interpolation syntax wrong

20:39 somnium: I still just use ant and a build.xml generator - hoping some compelling 'clojure-clouds' project emerges soon...

20:41 technomancy: executable XML is such a bad idea. =\

20:41 tomoj: I was just going to say, I want something with no XML :)

20:41 technomancy: tomoj: I've got a backburner project for that

20:41 http://github.com/technomancy/corkscrew

20:41 all sexp-based

20:41 tomoj: wasn't there something in the clojure book like this?

20:41 technomancy: doesn't currently work since maven has some crazy classloader issues

20:41 tomoj: yeah, but that's just an ant clone

20:42 and ant is an interpreter for an insane XML dialect

20:42 so I fail to see the value

20:42 I mean, other than as a teaching exercise

20:45 somnium: ant's got variables, macros, and control constructs...

20:47 technomancy: what more could you want? =)

20:47 somnium: is there a particular reason java doesn't have some tool called 'jake' instead of 3-major xml-dialects?

20:48 (if it had STM and first-class functions ant would almost be a poor man's clojure)

20:49 tomoj: "clojure" doesn't seem particularly friendly for naming projects :(

20:50 e.g. what would make/rake/jake be called for clojure?

20:50 clojake?

20:51 Chousuke: "cloak" :P

20:51 somnium: "jury"

20:52 ambient: something you can type fast

20:52 with qwerty

20:52 somnium: I've got a couple macros immitating ruby's 'flay' tentatively titled 'perjure'

20:52 gonna run out of jure words soon

20:52 Chousuke: fortunately.

20:52 ambient: oh, thee of little faith

20:52 :D

20:53 Chousuke: the puns are getting old

20:57 tomoj: the only ones I have in my words file are: abjure, conjure, injure, perjure

20:57 somnium: conjure's publicly taken

20:58 tomoj: oh we can also take -sure words and use j instead, like compojure

20:58 somnium: injure would be a cool name for a hostile-repl library

21:00 tomoj: that gives: expojure, leijure, meajure, pleajure, treajure

21:00 hiredman: :(

21:00 somnium: liejure looks norwegian to me

21:00 hiredman: clojurebot: Xiphojure?

21:00 clojurebot: Titim gan éirí ort.

21:01 somnium: plenty of cl-words, maybe that'll be the new trend

21:01 tomoj: but cl looks like common lisp

21:01 hiredman: clojurebot: Xiphojura?

21:01 clojurebot: 2009:Jan:29:16:03:17 <hiredman> I call Xiphojura

21:02 somnium: clobber, clogs, clint eastwood... there's some potential

21:03 tomoj: I've just been doing xxxx-clj

21:03 Luyt: I'm a big fan of Clint's films

21:03 Especially some westerns

21:03 ambient: you could try other languages, i dont know any french but bonjour sounds a lot like bonjure to me

21:03 somnium: clojure-du-jour

21:04 * tomoj searches jbovlaste

21:04 Luyt: plat-du-jour!

21:04 "Joe Kidd" is one of Clint's greatest films

21:05 somnium: I liked Dirty Harry

21:05 If we could get him as an evangelist, he could do webcasts called "Clint on Clojure"

21:06 tomoj: looks like "klojur" means something like "local seriousness" in lojban

22:31 aldebrn: Greetings friends. I have downloaded jline-0.9.94 and clojure-1.0.0 and am attempting to run "java -cp jline-0.9.94.jar:clojure-1.0.0.jar jline.ConsoleRunner clojure.lang.Repl" but Java complainx that it can't find a class "jline/ConsoleRunner"?

22:32 scottj: os? I'm not sure if windows has a different syntax for classpath, maybe ; instead of :

22:33 aldebrn: Aha, WinXp

22:33 Trying it on my laptop instead of workstation at work

22:35 Ah, I attempted ; instead of : in Cygwin xterm, didn't work, but works in Windows cmd! Thanks scottj

23:10 j3ff86: hey i got a question. (take n [collection]) returns the first n indexes from a collection, is there a function similar to take that lets you choose what indexes you want to take from?

23:22 tomoj: I don't know of one, but you can combine drop and take

23:22 j3ff86: haha thats exactly what im doing

23:23 tomoj: for vectors there is subvec

23:24 j3ff86: ooh yeah

23:24 tomoj: and subvec says it's O(1)

23:26 j3ff86: that works better, thanks

23:41 dmiller7: Is there an easy way to determine all the :use & :require dependencies in clojure-contrib?

23:50 technomancy: dmiller7: http://github.com/hiredman/clojure-dependency-grapher maybe?

23:52 dmiller7: technomancy: Looks like what the doctor ordered. Taking two aspirin. Will call in the morning.

23:52 technomancy: thanks.

23:55 technomancy: thank hiredman. =)

Logging service provided by n01se.net