#clojure log - Oct 21 2008

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

0:00 crathman: is there a random function? (or do I need to use Java's?)

0:02 sohail: underneath, is lazy-cons an iterator?

0:02 arohner: crathman: use java's

0:03 sohail: what do you mean by iterator?

0:03 sohail: like Java's Iterator interface

0:04 arohner: it looks like LazyCons just implements the clojure seq interface, but seq is a java iterator

0:20 sohail: yep, that's what I'd expect

0:23 Chouser: crathman: or (rand-int 10)

0:23 Java iterators mutate, don't they? Seqs don't.

0:23 crathman: Chouser: thanks

0:24 arohner: Chouser: ASeq.java has a function called iterate() that returns an Iterator

0:25 Chouser: ah, so they provide an iterator, but aren't iterators themselves?

0:25 arohner: looks that way. ASeq does not implement iterator

1:53 Pupeno: Good morning.

2:16 Lau_of_DK: Morning gents

5:46 Is dotimes purely for side effects, or can I do something similar to :collecting i in it ?

6:10 Anybody remotely awake?

6:10 tWip: yes

6:10 Lau_of_DK: Good, just checking, good to see you again :)

6:10 (truth is, I just solved it)

6:14 ccmtaylor: Lau_of_DK: try for: (for [i (range 10)] i)

6:20 Lau_of_DK: user=> lst

6:20 ((1 2 3) (1 2 3 4) (1 2 4 5 6) (1 2 3 4 5))

6:20 If I have a list of lists - How do I reduce it, so that I only retain the one with the longest count ?

6:27 hoeck: Lau_of_DK: (reduce #(if (< (count %) (count %2)) %2 %1) foo)

6:27 oops, where foo == your list-of-lists

6:28 Lau_of_DK: And that works with more than 2 ?

6:29 hoeck: yes

6:29 Lau_of_DK: Thanks alot Hoeck!

6:31 alvin-x: would somebody mind commenting on the style of the code here: http://paste.lisp.org/display/68926

6:31 i started writing clojure yesterday

6:32 hoeck: Lau_of_DK: always a pleasure to help you!

6:32 Lau_of_DK: Glad you feel that way! :)

6:40 hoeck: alvin-x: looks good!, maybe convert the single-arg anonymous functions into #()-style for better readability

6:41 AlephInf: alvin-x: also you can say (ObjectName. bean-name) instead of the (new ..) if you prefer, Also, don't need the nil in the else of the (if .. ) since it defaults to nil anyway.

6:42 alvin-x: hoeck: i didn't see anything yet on clojure.org about #()-style... can you give me a link?

6:42 jdz: AlephInf: in which case one should use 'when'

6:43 and #( reader is not always better than fn

6:44 Lau_of_DK: Hoeck :) Can you lend a hand again please.

6:44 user=> (combos 41)

6:44 6

6:44 user=> (reduce max (map #(combos %) (range 1 45)))

6:44 java.lang.IllegalArgumentException: Wrong number of args passed to: combos--5722$fn

6:44 I dont get it - I get this error whenever I call combos from another func

6:46 jdz: Lau_of_DK: you can safely replace (map #(combos %) ...) witch (map combos ...)

6:46 Lau_of_DK: oh

6:46 jdz: Lau_of_DK: that's in case it accepts only one argument.

6:46 Lau_of_DK: from the error message it looks like it wants more

6:46 Lau_of_DK: Same error

6:47 As you can see from my manual call to combo, it takes 1 integer

6:47 hoeck: Lau_of_DK: can you paste combos, cause combos--5722$fn looks like an inner function of combos

6:47 Lau_of_DK: I sur ecan

6:47 jdz: just what i would suggest next...

6:48 lisppaste8: Lau_of_DK pasted "Prime components" at http://paste.lisp.org/display/68927

6:50 jdz: Lau_of_DK: look at your recur expression

6:50 oh wait, scratch that

6:51 Lau_of_DK: Could this be bcause partition might throw nil ?

6:51 jdz: but it seems to me that loop's and function's recur points conflict...

6:52 Lau_of_DK: If you try (combo 17) or (combo 41) you'll get good results

6:52 jdz: (which seems unlikely)

6:52 Lau_of_DK: I think its partition

6:52 (combo 2) throws the same error

6:52 jdz: i think it's reduce

6:52 Lau_of_DK: How do I work around it ?

6:53 thats right, it might be reduce

6:53 yes

6:53 that was it

6:53 hoeck: alvin-x: Anonymous function literal, http://clojure.org/reader

6:53 Lau_of_DK: by initiating th vector result with [(list n)]

6:54 the problem is solved

6:54 Thanks guys, you ask good questions

6:55 jdz: Lau_of_DK: the way you have written your function leaves no space for optimizations (e.g., memoization)

6:56 and I might be talking nonsense, of course

6:56 just ignore

6:56 Lau_of_DK: No no youre right

6:56 Im working on that atm

6:57 jdz: Lau_of_DK: and instead of writing (doall (take-while ...)) you should have just written (take n)?

6:57 (or at least (doall (take n ...))

7:01 * hoeck pasted an annotation for avlin-x http://paste.lisp.org/display/68926#1

7:02 * hoeck wonders about the lazy lisppaste bot

7:05 alvin-x: hoeck: thanks, that's a good place to shorten the fn

7:06 what's the usual tab/indent width level here... 2? or, is there some style guide?

7:06 ach, tab/indent width*

7:07 jdz: alvin-x: i'd guess it's the usual lisp style, which happens to be mostly 2 spaces

7:10 Lau_of_DK: jdz, do all forces computation, which speeds up things ALOT when we get into the higher numbers

7:21 alvin-x: i tried a lot of other dynamic JVM languages before sitting down to write something in clojure; i don't miss any of them now.

7:33 Chouser: alvin-x: did you see (doc bean)? It might help you out (or might not if I'm misunderstanding your goal)

7:38 alvin-x: Dunno if you saw my comment before your client logged off. Do you know about (doc bean)?

7:39 alvin-x: Chouser: i saw it :) brb

7:40 Chouser: ok

8:01 alvin-x: Chouser: sorry, something came up at work. My goal is to have a few easy to use functions for calling remote JMX beans; you'll see the normal java code i'd have to write here: http://java.sun.com/javase/technologies/core/mntr-mgmt/javamanagement/best-practices.jsp#mozTocId805713 ("Code without a proxy").

8:03 (I can't use the proxy example there, as I don't have java interfaces. Not sure if it would work if I wrote the interfaces myself.)

8:05 I'm a middleware sysadmin, working on a short term solution for monitoring some app servers.

8:09 jdz: Lau_of_DK: my comment was not about doall, but about 'take' instead of 'take-while'

8:20 Lau_of_DK: can I assign a glob-var in a local scope, with some syntax tricks?

8:37 achim_p: Lau_of_DK: binding perhaps?

8:39 (in case thread-locally shadowing the value is enough ...)

8:41 AWizzArd: Moin Leute

8:46 btw, is it normal that it takes several hours until a posting appears in the google group?

8:46 jdz: when collecting stuff in loop, is it better to use cons + reverse at the end with lists or conj with vectors?

8:46 cemerick: AWizzArd: yeah, it can take a long time. It's sporadic, especially if you post via email.

8:47 AWizzArd: jdz: I would suggest vectors in general

8:47 H4ns: AWizzArd: i think the group silently drops postings from email addresses that are not members

8:47 lisppaste8: Lau_of_DK pasted "Optimize me! (primes)" at http://paste.lisp.org/display/68933

8:47 H4ns: AWizzArd: has bitten me multiple times, that.

8:47 AWizzArd: I see

8:47 Lau_of_DK: Friends - I need help! :)

8:48 AWizzArd: also when I joined the group.. it took hours until the member counter went up

8:48 Lau_of_DK: This seems to generate correct results. Try (combos 17) (combos 41) and so on. (euler-50 1000) also runs pretty descently. But the target is 1000000 and here I experience incredible slowdowns

8:48 How do I optimize this ?

8:50 AWizzArd: cemerick: also a map could be nice for you.. you would not need to reverse it, depending on your algorithm

8:50 and if you use just numbers it will have around O(1) access time, as the hashes will always go into unit buckets

8:51 lisppaste8: Lau_of_DK annotated #68933 with "Forgot a little something" at http://paste.lisp.org/display/68933#1

8:51 AWizzArd: Lau_of_DK: your indentation style is truly unique... ;-)

8:52 Lau_of_DK: Yes, its Notepad++ at its best - Sitting at work atm :)

8:53 AWizzArd: Btw, in slime+clojure the auto indentation style of IF is not so nice. Is that only for me?

8:53 Lau_of_DK: I'll tell you if you optimize my routine

9:01 * achim_p would like to get paid for doing project euler at work ;)

9:02 AWizzArd: I guess this Euler stuff is only interesting to young people, and only for some time.

9:02 gnuvince: Project Euler is pretty fun to learn a language.

9:02 AWizzArd: yeah

9:03 however, I mean it's nothing that you would like to do the coming four years

9:03 Lau_of_DK: achim_p, you can come work here, Ive resigned my position :)

9:03 achim_p: that's true for work in general, in my case

9:09 Lau_of_DK: any takers?

9:12 Somebody do a Sieve or something! :)

9:15 AWizzArd: Lau_of_DK: can you develop a newsready for the Clojure google group? So that I can read messages and keep track of which I already read, without the need to use my browser for that?

9:15 newsreader

9:15 Lau_of_DK: You dont like Thunderbird?

9:18 AWizzArd: i like it, but GG doesn't offer nntp

9:18 H4ns: AWizzArd: i read the group in my mail reader

9:18 AWizzArd: nntp is so 1990ies

9:19 AWizzArd: H4ns: how do you do it?

9:19 H4ns: AWizzArd: with my eyes! :)

9:19 achim_p: Lau_of_DK: if you'd bother translating your algorithm to plain english, i'd give it a shot in a couple of minutes, but first i'll have to wrestle with john nash some more

9:19 H4ns: AWizzArd: you can have the group send the articles by mail

9:19 Lau_of_DK: AWizzArd, I had Googlegroup in my Thunderbird inbox

9:19 Worked like a charm

9:19 John Nash ?

9:20 achim_p: yeah, he's here on my desk

9:21 jdz: can anybody quickly tell how to create a Java byte array (byte[])?

9:23 AWizzArd: I just would have preferred if I could see all news ever written in that group.

9:23 achim_p: jdz: make-array with Byte/TYPE, or to-array on a collection of bytes should work

9:24 jdz: achim_p: well, what's the Byte/TYPE magic?

9:25 achim_p: that's java weirdness. there are some types which are both primitives and class-based types in java

9:25 a byte isn't directly an instance of Byte, as far as i understand it

9:25 jdz: achim_p: ok, something like (make-array (. Byte TYPE) 4096), right?

9:26 Lau_of_DK: or (to-array ...)=

9:26 cemerick: (make-array Byte/TYPE 4096) is fine

9:26 jdz: Lau_of_DK: the point is i want to create an empty buffer..

9:26 cemerick: static fields and functions can use the slash notation

9:26 jdz: cemerick: oh, cool. didn't know that.

9:27 thanks guys.

9:27 (it works :)

9:29 lisppaste8: Lau_of_DK pasted "Optimize me! (primes)" at http://paste.lisp.org/display/68934

9:29 Lau_of_DK: Ok, thats pretty well commented, I think! :)

9:32 fogus: Has anyone used the J text editor in the past?

9:32 cemerick: fogus: isn't it just a vehicle for ABCL?

9:33 fogus: Yes, but I wonder if it would be possible (nevermind worthwhile) to use Clojure as a stand in

9:34 cemerick: possible, maybe. I don't remember there being much worthwhile in J itself (although ABCL is quite the conformance-engineering feat).

9:35 fogus: That was the crux of my question... usefulness.

9:35 cemerick: I think there could be a lot of possibility in building a framework on top of netbeans to allow for clojure-driven scripting, UI construction, etc. I'm sure the enclojure guys have thought a lot about this.

9:37 lisppaste8: jdz pasted "Reading .gz files (if anybody cares)" at http://paste.lisp.org/display/68935

9:39 jdz: i think the Clojure's slurp function could be better defined using slurp-byte-stream

9:40 maybe i'll look into java.nio if there's anything useful for this purpose

9:41 never done anything with it, though. only heard good rumors.

9:43 and then there is a bug in my code. it does not handle the case if the first read from stream returns -1

9:45 aperotte: hello everyone, had a question. I read in the api that there are some subtleties in how clojure deals with protected members of classes. If a library requires that I subclass and set a protected member that was inherited from a superclass, is this something that's possible?

9:46 specifically, I'm trying to translate the Hello World jME tutorial into clojure http://www.jmonkeyengine.com/wiki/doku.php?id=starter:hello_world

9:47 lisppaste8: jdz annotated #68935 with "Updated version of slurp-byte-stream (almost untested)" at http://paste.lisp.org/display/68935#1

9:48 jdz: i long for fill-pointers a bit

9:51 Pupeno-G: Was there a special name to give to a file inside a jar so that Clojure would pick it up and run it automatically without a little main in Java?

9:52 Chouser: user.clj

9:52 Pupeno-G: Chouser: so, how does it work? there's a little main already in Clojure.jar?

9:55 Chouser: I think you still need to specify clojure.lang.Script on the command line

9:55 Pupeno-G: Chouser: oh, ok.

9:55 Understood now.

9:58 Chouser: aperotte: you can overload protected methods using proxy

10:46 aperotte: Chooser: thanks. I'm going to give it another go.

10:49 Chooser: Are you saying that I should just override it to make it public? What's happening in my particular case is that there's a super-class that defines a protected member, that is inherited by the class the library expects me to extend. So the protected member isn't even defined in the class I'm inheriting from, it's defined in the class it inherits from.

10:50 rhickey: Hi all from Nashville airport - on my way back from Lisp 50

10:50 Chouser: aperotte: and is this member a method you want to override, or a field you're trying to set or something?

10:50 rhickey: Hi! How'd it go?

10:51 aperotte: rhickey: I'm new, but hello anyway :)

10:51 rhickey: It went great. A really long day, I didn't talk until almost 8pm (started at 8:30 am)!

10:51 aperotte: Chouser: It's a field, that is itself an object that I'd like to call a method on

10:52 rhickey: Lots of seminal Lispers talked about the history, lots of reminiscing

10:53 Chouser: aperotte: ah. hm... I'm sure it's possible, but it may not be pretty.

10:53 AWizzArd: hi Rich

10:53 rhickey: Pascal Costanza's the only talk about current work in CL, Will Clinger on the state of Scheme

10:53 Then, last, Clojure, about which many of them knew nothing

10:54 AWizzArd: this will change in 2009... it will be a well known secret :-)

10:54 asbjxrn: Don't know too much about the programme, but with a name like Lisp 50, it's not that strange that it was a look back.

10:54 aperotte: Chouser: haha ... thanks, that makes me feel better. I thought I was just missing something simple.

10:54 rhickey: Lots of skepticism at the start, but by the end I got so much good feedback , essentially validation that this is the right way to bring Lisp forward - make a break, address current problems etc

10:54 gnuvince: rhickey: what did the heavy weights (Gabriel, Steele) think?

10:54 asbjxrn: I thought it would be reasonably well known today, at least among lispers.

10:56 rhickey: There were lots of nice compliments during questions and after - had a long conversation with JoL White and others

10:56 gnuvince: rhickey: was your presentation video-taped?

10:57 (or video-digitalized, I'm not sure how to say that in a world where tapes almost don't exist anymore)

10:57 rhickey: I still have never gotten any feedback from Guy Steele - he left during the panel that followed my talks and wasn't at either of the Lisper dinners, although I saw him gesturing with 2 thumbs up during part of my presentation, but he may have just been agreeing with a particular point I made

10:58 Dan Weinreb has become a fan, and was talking it up to many others before my talk

10:59 Overall I think it went great - it represents such a sea change for that community but they were very gracious in accepting the new ideas

10:59 Of course, in 45 minutes I can barely scratch the surface of Clojure

10:59 gnuvince: Good job :)

10:59 aperotte: Congratulations

11:00 Chouser: aperotte: you might need gen-class -- look at the :exposes feature

11:01 rhickey: There was videotaping and I signed a release... but I think the Boston Lisp talk was more comprehensive, if 4x as long

11:02 gnuvince: rhickey: it's still nice to have this, that's another Clojure post on reddit ;)

11:03 AWizzArd: grats

11:03 rhickey: thanks

11:03 lisppaste8: jdz annotated #68935 with "The correct version of slurp-byte-stream (hopefully :)" at http://paste.lisp.org/display/68935#2

11:04 aperotte: Chouser: thanks, I'll take a look

11:04 Chouser: rhickey: Sounds great. Soak it up! In another couple years you may have to be spending all your time on standards committees as everyone tries their own implementations of the Next Big Language. :-)

11:05 cemerick: rhickey: congrats on the trip/talk going so well.

11:05 rhickey: Chouser: I'm hoping the community will stay focused on the core implementation, as they have for Python and Ruby

11:06 cemerick: yeah, I think we can dispose with the standards committees :-P

11:06 rhickey: One thing was clear - standards stopped innovation in Lisp. Steele and Gabriel's talk enumerated so many dialects before the standards

11:07 Chouser: That's an excellent point. Did everyone "get" it?

11:07 AWizzArd: well yes, today it seems languages benefit from a dictator *g*

11:07 asbjxrn: Many dialects may not be what you want, though?

11:07 Did scheme fare that much better?

11:07 H4ns: asbjxrn: as hardware and environments change, language innovation is needed to cope with that

11:08 Chouser: Well a good dictator is hugely imporant, but I think an open-source implementation makes it possible. The codebase *is* the standard.

11:08 rhickey: asbjxrn: It's less the dialects than the innovation - I think we can innovate in few dialects, but can't innovate a standard - it's fixed

11:08 asbjxrn: I definately agree.

11:08 The trick is to get innovation without forks.

11:09 rhickey: Chouser: right, but differs from an actual standard in not being fixed on paper

11:10 asbjxrn: Being open source and not wanting forks forces the core to be responsive to the community

11:12 asbjxrn: Yup, and so far you're doing great :) I'm not critizising (sp?), I'm just not sure that many lisp dialiects are better than one. I would assume that it would reduce the number of usable libraries.

11:13 rhickey: asbjxrn: well, I expect Scheme and CL to continue indefinitely

11:13 asbjxrn: But of course I do see the point that once the standard is printed, you're stuck. I just think that lisp may have been so fragmented that a common spec was good.

11:14 AWizzArd: In my opinion Clojure has the greatest potential to become more or less the best programming language.

11:15 gnuvince: I don't know about "best" (or even what it means), but I agree that if I had to put money on a relatively unknown language that would become extremely popular in the coming years, Clojure would be it.

11:16 AWizzArd: Since I began doing Common Lisp in 2003 this (Clojure) is what excited me most.

11:17 This is especially amazing, because typically every 3 months someone comes to show his/her new Lisp, and it is always total useless $#|~

11:18 asbjxrn: I thought that nick looked familiar...

11:19 Chouser: AWizzArd: you mean like arc? :-)

11:20 asbjxrn: Hang around in comp.lang.lisp for a while, and you'll see a handful, it's not just arc.

11:20 AWizzArd: Chouser: well yes, only that the development of Arc took just 4 years. Paul Graham managed to come up with a little improved scheme. Wow. *sigh*

11:21 gnuvince: I guess it takes a lot of time to come up with shorter names

11:21 Chouser: gnuvince: not just that -- it has a reader macro for [ ]

11:22 gnuvince: Chouser: right.

11:23 Chouser: :-)

11:34 asbjxrn: Uhm, clojure equivalent of progn?

11:34 jdz: do

11:36 asbjxrn: Thanks, I was sure I had tried that before with moderate success. Probably confused with a lazy sequence operation inside the do or something. That still trips me up every now and then

11:36 (Having to use doall, for sideeffect stuff, that is.)

11:41 Chouser: Heh. "do" is the one use of "do" that's not for side-effects.

11:43 jdz: does anybody have a bit of sample concurrency code? i want to have a small pool of workers, then loop over my data set giving work to the first available worker (and waiting for a free one if all workers are busy).

11:46 AWizzArd: jdz: (pmap ...)

11:46 it is like map, only that it divides the mapping to all available processors

11:46 look at its code in the boot.clj

11:47 jdz: AWizzArd: thanks. i was already looking at java.util.concurrent.SynchronousQueue :)

12:00 AWizzArd: How can I count the number of occurrences of an object in a collection?

12:00 Chouser: (count (filter #{an-obj} coll)) ?

12:01 AWizzArd: Sure, but I mean there is nothing like that in the standard lib yet, right?

12:02 cemerick: no, but it seems like something simple enough to not include in the stdlib (IMO)

12:03 asbjxrn: That hash lookup trick is almost too sneaky, though.

12:04 Chouser: one of my gripes about CL (not that anyone should care what a noob like me thinks about CL) is the overwhelming number of built-in functions.

12:04 asbjxrn: yes, except that it's "an idiom" now. It should be documented as such, I suppose.

12:04 cemerick: Chouser: agreed.

12:04 asbjxrn: You don't have to use them all ;)

12:04 jdz: Chouser: how is that different from java's standard lib?

12:04 gnuvince: Hmmm

12:04 After the API page, there ought to be an Idioms page

12:04 cemerick: I wouldn't say that there's anything sneaky about certain objects implementing IFn.

12:04 gnuvince: That'd be nice

12:05 Chouser: asbjxrn: no, but to write "correct" code you have to know about them all.

12:05 jdz: Chouser: how' s that different from Java' s standard lib?

12:06 asbjxrn: No, I like the hash as function idea, I use it a lot to lookup stuff. I've never thought of using it as an argument to filter, though. I had a little "huh" moment there.

12:06 Chouser: and it seemed to me that reading CL code without a manual at your fingertips would be impossible until I had been at it for a long time.

12:06 gnuvince: jdz: he meant built-in as in the global namespace.

12:06 jdz: gnuvince: what do namespaces have to do with it?

12:06 Chouser: yeah, the global namespace is certainly part of it.

12:07 gnuvince: jdz: look at PHP with its 4,000 functions in the same namespace.

12:07 Chouser: jdz: I'm not exactly a proponent of Java either, though I imagine the same question could be asked about any standard lib.

12:07 jdz: gnuvince: isn't that the problem of not having any name-separation capabilty?

12:08 Chouser: you can' t program C if you don' t know stdlib. same with CL.

12:09 Chouser: One little difference (and I don't know how important this is) is macros. In C or Java you may not know what a function does, but you know the args are evaluated and you may be able to "black-box" it for a moment in your mind while trying to get your bearins in the rest of the code.

12:09 Not so with lisps.

12:11 jdz: Chouser: well, with lisp you have nice developement environment that can instantly tell you whether the symbol is a function or a macro

12:11 and then there are naming conventions.

12:11 and in most cases you don' t even care

12:12 Chouser: yeah, that's what I meant about "tools". I guess I was often reading code on a printed page.

12:22 AWizzArd: Is there a correct way to express (defn foo ([n []] 5) ([n [x & xs]] 6))? What I want is: (foo something empty-col) ==> 5 and (foo something col-with-something-inside) ==> 6

12:23 jdz: AWizzArd: you want functional language style pattern matching?

12:25 AWizzArd: you can go a bit along the way with destructuring, but there is no pattern matching in Clojure as far as i know

12:25 Chouser: (defn foo [n [x & xs :as allxs]] (if (seq allxs) 6 5))

12:26 I believe that's idiomatic. I don't know of any "correct" name for xs or allxs.

12:28 asbjxrn: How is that different form (defn foo [n x] (if (seq x) 6 5)) ?

12:29 Chouser: it's not, unless you want to destructure the seq into x and xs

12:30 which clearly aren't being used in this example, but I assumed AWizzArd wanted them for his actual code -- thought I'd show how to use :as in that case.

12:36 AWizzArd: asbjxrn: and also (seq x) is true only if x is a list. But not if x is a vector

12:38 Chouser: no, (seq []) is true

12:39 AWizzArd: ah okay, I read (seq? x)

12:39 asbjxrn: ? In my repl (seq []) is nil.

12:39 Chouser: seq returns a seq object (acts like true) for any non-empty collection. For empty collections seq returns nil.

12:40 yes, seq? is a bit different -- it returns true for ISequences like lists, lazy-cons, etc.

12:41 and as you meant, seq? returns false for vectors, maps, etc. whether empty or not.

12:43 danlarkin: and is this reasonable? (seq? '()) == false

12:43 AWizzArd: Chouser: I think that's what I said.. (seq? x) is only true if x is a list.

12:44 Chouser: AWizzArd: or if x is a lazy-cons or other ISequence.

12:46 danlarkin: hm, I think not. EmptyList probably should implement ISeq.

12:49 cemerick: Chouser: Yes, definitely. I've hit that one a couple of times.

12:51 Chouser: http://groups.google.com/group/clojure/browse_frm/thread/1ca1e57ce509b81c

12:51 I guess I'm wrong.

12:51 cemerick: well, well

12:55 lisppaste8: achim annotated #68832 with "... with partitioning" at http://paste.lisp.org/display/68832#1

12:56 danlarkin: Interesting

13:05 lisppaste8: achim annotated #68832 with "correction" at http://paste.lisp.org/display/68832#2

13:22 fyuryu: is dispatch based on meta data considered a good practice?

13:30 Lau_of_DK: Evening gents

13:32 danlarkin: afternoon

13:35 billc: are there logs of the #clojure irc channel available?

13:36 fyuryu: billc: http://clojure-log.n01se.net/

13:36 billc: fyuryu: thanks!

13:36 duck1123: that really should be part of the channel's topic

13:37 Lau_of_DK: Has anybody had some luck optimizing my routine from earlier today ?

13:52 Alright, lets say I have a nested list like this

13:52 user=> (take 5 lst)

13:52 (((1000 1001 1002) (4330 4331 4332) (7660 7661 7662)) ((1001 1002 1003) (4331 4332 4333) (7661 7662 7663)) ((1002 1003 1004) (4332 4333 4334) (7662 7663 7664)) ((1003 1004 1005) (4333 4334 4335) (7663 7664 7665)) ((1004 1005 1006) (4334 4335 4336) (7664 7665 7666)))

13:53 And I want to filter out those lists wherein all 3 numbers are prime. (filter #(every? prime? %) ) doesnt work on nested lists, so what are my options?

13:56 danlarkin: nest your filters?

13:57 Lau_of_DK: Maybe. I'd prefer some sort of flatmap solution

13:57 This wouldnt even be a problem if I could get partition to work with concat, its because Im conjoing seqs

13:58 devinus: dos clojure support OOP?

13:59 does*

13:59 danlarkin: devinus: it supports encapsulation, type hierarchies...

13:59 devinus: danlarkin: what about reflection capabilities?

13:59 danlarkin: and if you really need to you can make a custom object by using the gen-class functions

13:59 AWizzArd: devinus: Clojure gives you building material to implement oop the way you like it, if you want.

14:00 devinus: but Paul Graham explained: functional programming + macros outperform oop

14:00 danlarkin: devinus: what sort of reflection? clojure has the concept of metadata

14:00 devinus: danlarkin: could you find the name of your function out within the function?

14:01 AWizzArd: devinus: you can simply use a map, where the keys are the fields of your class, and the information *what* class you want goes into metadata.

14:01 devinus: Clojure supports macros. You can even write a function from which you can see the source code during runtime.

14:03 just expand it into a defn and write the source code into the metadata

14:03 cemerick: devinus: remember that clojure is hosted on java, and has a lot of ways to interoperate with java artifacts

14:04 Chouser: fyuryu: I don't think you should automatically rule out dispatch on meta-data if it makes sense for your situation.

14:05 danlarkin: Lau_of_DK: how about this: (filter #(every? (fn [coll] (every? prime? coll)) %) lst)

14:06 Lau_of_DK: it's a naive algorithm, though, I admit

14:06 Lau_of_DK: naive?

14:07 danlarkin: Lau_of_DK: inefficient

14:07 Chouser: looks ok to me.

14:07 I think "every?" will bail as soon as it gets a false.

14:08 indeed it does.

14:08 Lau_of_DK: user=> lst

14:08 ((2 3 5 7) (11 17 41 8) (2 4 6 8))

14:08 user=> (filter #(every? (fn [coll] (every? prime? coll)) %) lst)

14:09 Then throws illegal argument exception

14:09 Chouser: you'd want "prime?" to remember it's conclusions (memoize)

14:09 Lau_of_DK: How do I do that Chouser ?

14:09 danlarkin: Lau_of_DK: store it in a hash

14:09 Chouser: clojure.contrib.memoize

14:10 Lau_of_DK: k thanks - any insights into why the filter breaks on that list of lists

14:10 danlarkin: Lau_of_DK: can you paste your prime? function so I can test?

14:11 Lau_of_DK: http://clojure-euler.wikispaces.com/The+Optimal+Toolkit

14:15 wwmorgan_: Lau_of_DK: the first and second lists that you posted have different levels of nesting

14:15 Lau_of_DK: hang on

14:15 the first is the correct, I made the 2.nd by hand

14:16 (defn euler-49

14:16 []

14:16 (filter #(every? (fn [coll] (every? prime? coll)) %)

14:16 (loop [ n 1000 result [] ]

14:16 (if (< n (- 9999 3330))

14:16 (recur (inc n) (conj result (partition 3 3330 (range n 9999))))

14:16 result))))

14:16 returns "nil"

14:16 That doesnt seem very likely ?

14:20 If I remove the filter and go through the sequence, I can see that partition is making mistakes

14:21 Its not putting 3330 between the offsets...

14:21 oh wait

14:21 Yes it is, I thought it to be the offset between each item, not each list, my bad

14:21 I'll rework it

14:25 Ok, I got everything working now, thanks alot for the input everybody

14:27 danlarkin: Lau_of_DK: how did you end up using filter?

14:27 Lau_of_DK: changed the nesting away from partition, so (filter #(every? prime? %) ...) works

14:28 But you taught me a new thing :)

14:32 danlarkin: Lau_of_DK: cool!

14:34 tWip: a project euler wiki? that makes me sad

14:34 Lau_of_DK: tWip, why ?

14:34 tWip: I find that the most fun part of it trying to solve things yourself

14:34 gnuvince: People will just get the solution pre-made instead of researching it.

14:34 Yeah

14:34 Lau_of_DK: hehe

14:35 fogus: That doesn't stop you from figuring these solutions yourself

14:35 Lau_of_DK: Gentlemen, you dont have to follow those solution (some of them are not very bright)

14:35 gnuvince: It's absolutely infuriating at times, but so nice when you finally get a solution working in less that 18 hours.

14:35 Lau_of_DK: Its meant as an inspiration to use Clojure in different ways, especially good for newbies

14:35 tWip: agreed

14:35 with what gnuvince said, that is

14:35 Lau_of_DK: No later than today, I pointed a first-timer in Clojure to the wiki, which gave him an easy start

14:40 fyuryu: Chouser: I'm considering it but something in me whispers "don't do it!"

14:42 Chouser: fyuryu: I by no means feel I have a complete sense of when to use metadata, but one thing to hang onto is the concept of equality.

14:43 arbscht: gnuvince: it's also fun to improve upon other solutions, or find ones better than yours

14:43 Chouser: If a particular piece of data for an object can be different but you would still want them to be equal, then it must be metadata.

15:14 Lau_of_DK: Now that the filter works, I get an output like ((1234 4321 1234) (2345 5432 2345))

15:15 I've made a routine that checks if every number is a permutation of 2 others, so

15:15 (permutation? 1234 4321 3214)

15:15 true

15:15 (permutation? 1234 3456 3646)

15:15 false

15:15 How do I filter for permutations?

15:16 wwmorgan_: (filter (partial apply permutations?) coll-of-colls)

15:18 Lau_of_DK: My goodness

15:18 danlarkin: wwmorgan_: tricky

15:18 Lau_of_DK: That worked...

15:19 AWizzArd: how can I do (num "123") ==> 123 ?

15:20 Chouser: (Integer. "123")

15:20 wwmorgan_: AWizzArd: is arbitrary precision required?

15:20 Chouser: That's a constructor of the Integer class.

15:21 AWizzArd: wwmorgan_: please show both ways if possible :-)

15:21 wwmorgan_: Lau_of_DK: how are you detecting numeric permutations? There's an awesome fast algorithm for that.

15:22 Lau_of_DK: (defn permutation?

15:22 [x y z]

15:22 (let [test (apply sorted-set (str x y z))]

15:22 (= (count test) (count (str x)))))

15:22 wwmorgan_: AWizzArd: (BigInteger. "12323849728239473") => 12323849728239473

15:23 since you're solving the euler problem, I guess it's OK that (permutation? 1 11 111) returns true

15:24 AWizzArd: wwmorgan_: why is it (BigInteger. ) and not (.BigInteger)? Why is it (.hashCode) and not (hashCode.)?

15:24 danlarkin: (ClassName.) is syntax for (new ClassName)

15:25 wwmorgan_: (.method object) or (.field object) is syntax for (. object field) or (. object method)

15:27 Lau_of_DK: wwmorgan_, do you have something better?

15:28 wwmorgan_: I don't know which would be faster, given that (permutations? 1 11 111) => true is acceptable

15:28 Lau_of_DK: If you want that to return false is just a matter of checking (what I assume) that all args are same length

15:30 wwmorgan_: pasting...

15:32 gnuvince: How about (= (sort xs) (sort ys))?

15:34 wwmorgan_: nm on the paste. What you do is allocate an array of the first 10 primes, then, for each number, map each digit to the respective prime and multiply all the digits together. If every number has the same product, by the Fundamental Theorem of Arithmetic, the numbers are permutations, and if they don't, they're not

15:35 so not only is it O(n) in the number of digits, you can fall out early without even looking at later numbers

16:02 danlarkin: clojure/partial is totally sweet

16:04 Chouser: seems kinda old-school to me. I usually prefer #()

16:06 but take you're pick -- whatever works! :-)

16:06 gnuvince: partial is gonna appeal to the Haskellers

16:06 Lau_of_DK: partial is nasty

16:06 wwmorgan_: (partial even?) takes more characters than #(even? %) but I think it's slightly more readable

16:07 kotarak: #() is more powerfull since you can choose the argument positions.

16:07 gnuvince: wwmorgan_: yeah, but who would use either one? :) (filter even? (range 20))

16:08 wwmorgan_: gnuvince: whoops, you're right. Change my example to (partial = foo) and #(= foo %)

16:08 Lau_of_DK: Anybody here know of a Java func to load an entire website into a string or something like that

16:08 (slurp www.slashdot.org)

16:08 ?

16:09 gnuvince: wwmorgan_: fwiw, I'd use the latter, because it's shorter and clearer IMO.

16:09 Chouser: partial might win me over for varargs. (partial + 10) vs. #(apply + 10 %&)

16:10 chmu_: Is there an eager (map) in clojure. I had some trouble with map and I/O.

16:11 Chouser: wrap any lazy thing in (doall ...) to make it eager.

16:11 hoeck: Lau_of_DK: look at http_client.clj in the google groups

16:11 wwmorgan_: chmu_: you may want to look at doseq for I/O as well

16:11 Lau_of_DK: hoeck, thanks

16:11 hoeck, did you have a crack at this? :) http://paste.lisp.org/display/68934

16:12 chmu_: thanks

16:19 devinus: can you use dashes in fn names?

16:19 Chouser: yes

16:19 gnuvince: devinus: yes.

16:20 devinus: dashes are the standard way to separate words in an identifier in Lisp languages.

16:22 devinus: can you use underscores and Capital letters

16:22 or even other identifiers, since, really, only parens are needed

16:23 like (look@something ...)

16:23 (compute$amt ...)

16:23 (%ofsomething ...)

16:23 Chouser: you can use underscores and capitals, but if you're doing so for any reason other than interacting with Java, you'll have to put up with people calling your code ugly. :-)

16:23 devinus: (pinch&poke ...) ?

16:23 gnuvince: devinus: I don't know the complete list, but underscore and capitals are definitely permitted, slashes are OK

16:24 devinus: ok

16:24 Chouser: aren't slashes reserved for namespace separation?

16:24 gnuvince: Yes for ampersands.

16:24 Oh right.

16:24 Sorry

16:24 Chouser: question marks are frequently used at the end of a function name to indicate it returns boolean

16:25 ! at the end suggests it mutates something

16:25 gnuvince: ok

16:25 I got the list

16:25 devinus: i know set!

16:25 gnuvince: alphanumeric, *, +, !, -, _, ?

16:25 devinus: i'm going to have to manually check for everything else

16:25 Chouser: gnuvince: nice, thanks!

16:26 gnuvince: http://clojure.org/reader

16:26 Under "Symbols"

16:28 devinus: does clojure work under java 7?

16:31 hoeck: Lau_of_DK: ahh, i see, euler number 50, i have already a primfac function at hands from my early clojure hackings

16:32 Lau_of_DK: but that has to wait until tomorrow, need some sleep

16:32 Lau_of_DK: Okay :) Sleep tight

16:35 devinus: Ok, so you can use these symbols: ! # $ & * . = + ?

16:36 oh and :

16:37 and |

16:37 You cannot use these symbols in a fn: ~ ` @ % / \ < > [ ] { } ( )

16:37 and here's a really curious one

16:37 you can define some var with a period in it

16:37 (def some.var 3)

16:37 but when you try to access it you cannot

16:38 Chouser: dots are reserved for java interop when you try to access them

16:38 would be nice to get a warning when you try to def it, I suppose.

16:39 wwmorgan_: (var-get (var some.var))

16:39 Chouser: ewww

16:39 :-)

16:39 wwmorgan_: ya thats a good one

16:40 devinus: it would also be nice to be able to use ~ ` @ % / \ < > { } in variable names

16:40 especially @

16:40 ~ too would be nice for approximations

16:40 ~area-of-disk

16:40 is @ used in clojure?

16:41 Chouser: ~ and ~@ are used for inserting stuff in back-quote expressions

16:41 (usually used when writing macros)

16:41 danlarkin: It'd be nice to name things like str->int

16:43 devinus: mmm indeed

16:43 i like that

16:43 wwmorgan_: (defn str->int [s] (Integer. s)) (str->int "123") => 123

16:44 danlarkin: oh... so then < and > are legal in identifiers.. that's what I get for opening my mouth before I check.. d'oh

16:45 wwmorgan_: but it looks like > is reserved though, so I think don't do that

16:45 Chouser: wwmorgan_: why do you say that?

16:45 -> is just a regular macro in boot.clj

16:45 I used xml-> so if that's bad I should change it.

16:46 wwmorgan_: Chouser: I was going off http://clojure.org/reader but you're right

16:47 the -> macro makes it clear that > is supported

16:55 Lau_of_DK: I've used xml-> in a larger program without any problems

18:34 AWizzArd: Without trying it in the repl, if you say (def x (agent [10 20 30])) and then (send x map inc), what do you expect, to what will @x evaluate?

18:35 gnuvince_: [11 21 31]?

18:35 AWizzArd: I agree

18:35 Chouser: after you give it sufficient time to execute?

18:35 AWizzArd: yes

18:36 Chouser: (11 21 31)?

18:36 AWizzArd: I think so, yeah

18:36 Chouser: lazy seq

18:36 AWizzArd: now try it please

18:37 Chouser: ah, of course.

18:37 AWizzArd: enlighten me please

18:37 Chouser: the agent gets passed as the first arg

18:38 (map @x inc)

18:38 AWizzArd: try: (send x #(map inc %))

18:39 AWizzArd: right, thanks

18:57 The code of (dispatch ...) is not written in Clojure, right? Used by send and send-off for example.

19:05 Chouser: right, dispatch is a method of the Agent class, written in Java.

19:08 AWizzArd: would be interesting to know what happens if there is a blocking agent in a send-off

19:25 lisppaste8: achim annotated #68934 with "..." at http://paste.lisp.org/display/68934#1

20:13 gnuvince_: lukego: Luke Gorrie?

20:20 lukego: howdy

20:21 gnuvince_: Nice to meet you :)

20:21 lukego: hey I've been your neighbour in #lisp for years and years :)

20:22 I saw the clojure talk at OOPSLA yesterday so thought I'd take it for a test drive :)

20:22 gnuvince_: Nice to see you here.

20:23 drewc: lukego: how was lisp50? (jerk)

20:23 * drewc would have loved to be there.

20:23 lukego: drewc: overall very good but some low moments. subject of upcoming blog entry :)

20:23 drewc: looking forward to reading it :)

20:24 gnuvince_: lukego: so I guess that means you're no longer in Thailand

20:25 lukego: I'm in LA en route to New Zealand and Australia at the moment, more or less, but still moving around quite a lot at this stage. I could use a year off this travel business but not quite yet :)

20:26 the error message is a bit unfriendly when swank-clojure-jar-path is set wrong (NoClassDefFoundError). probably obvious to java people but "file not found" wasn't my first thought

20:30 sohail: lukego, I had the same problem :-)

20:30 lukego: what did you do about it? :)

20:31 jao: /whois sohail

20:31

20:31 oop

20:31 s

20:31 gnuvince_: lukego: rhickey said he was working towards making error messages less arcane

20:31 sohail: lukego, I moved the setting around in the file according to the documentation

20:31 and then stared at the file name for a long time

20:32 then finally saw that I was off by a directory

20:32 lukego: this isn't really a clojure error message, it's the JVM reporting that it can't find the entry class to clojure (because I had the wrong path to clojure.jar set)

20:32 sohail: ya

20:32 lukego: right, me too

20:32 I thought you meant you had a solution to the travel problem, not the jvm problem :)

20:33 sohail: ah

20:33 * sohail currently works from home

20:48 drewc: sohail: that is a good solution

20:48 wfm too

20:49 sohail: drewc, good work if you can get it :-)

20:50 drewc: sohail: indeed :)

20:51 sohail: drewc, the next step is to stop working

20:51 that one is proving hard

20:52 drewc: yeah, that one is a little tougher.

20:53 well, there's a few easy ways, but they are not at all pleasant.

20:53 sohail: or legal

21:30 gnuvince_: I'm trying to solve #4 of Project Euler with Clojure, but I always get a StackOverflowError

21:31 Could anyone take a quick look?

21:34 Chouser: where is it?

21:34 gnuvince_: Chouser: just trying something with loop/recur first...

21:35 Chouser: ok

21:37 gnuvince_: Ah

21:37 There we go

21:38 ~paste

21:38 @pastebin

21:39 lisppaste8: pastebi

21:39 lisppaste8: pastebin

21:39 lisppaste8: paste

21:39 damn, what's the frigging command?

21:41 lisppaste8: gnuvince pasted "Euler #4: how does that look?" at http://paste.lisp.org/display/68966

21:41 gnuvince_: Chouser: there it is.

21:42 How does it look?

21:44 drewc: lisppaste8: url?

21:44 lisppaste8: To use the lisppaste bot, visit http://paste.lisp.org/new/clojure and enter your paste.

21:44 drewc: :)

21:52 * gnuvince_ dislikes that Clojure has no integer power function

21:54 lisppaste8: sunwukong annotated #68966 with "How about this?" at http://paste.lisp.org/display/68966#1

21:55 gnuvince_: sunwukong: good one

21:56 Chouser: gnuvince_: yeah.

22:04 lukego: hm so my first idea for a closure program is something that's hard to do in a functional language :-) any tips on a simple graph data structure?

22:06 Chouser: hm! a graph built of persistent data structures?

22:06 gnuvince_: lukego: how many people were present during Rich's presentation?

22:06 lukego: need an indirection somewhere

22:07 well it was a small workshop. I'd estimate 50

22:08 gnuvince_: Not bad

22:09 Chouser: hash with "id" keys, each val is a vector of adjecent node ids?

22:09 that would be a directed graph, I suppose.

22:09 lukego: he did very well in telling the audience "This, this, and this have to be removed from Lisp in this day and age. This, this and this have to be added" to an audience that includes Guy Steele, Dick Gabriel, etc :)

22:10 must be an amazing salesman to have made me install a JVM

22:11 gnuvince_: lukego: you're not the only one :)

22:12 Although I must admit that it *is* astonishing what people on the mailing list say they're doing with a language that's only one year old.

22:14 sohail: gnuvince_, what are they saying they are doing?

22:15 gnuvince_: sohail: people using it to build GUIs, web sites, database applications and whatnot.

22:15 sohail: lukego, what did he say has to be added?

22:15 lukego: concurrency primitives, living on a popular virtual machine are what come to mind

22:19 sohail: lukego, did he talk about how he expects people to live without inheritance and other OOP goodies?

22:20 (I know the multiple-dispatch is very general, which is cool)

22:20 gnuvince_: sohail: which goodies?

22:21 lukego: no, I heard this talk was very much shorter than what's usual. but Im a CLOS'trophobe and always have been anyway

22:21 * sohail recently wrote a code transformer and found CLOS quite useful

22:22 sohail: gnuvince_, none really!

22:22 gnuvince_: lukego: you can go to clojure.blip.tv and watch the Boston Lisp User Group presentation

22:22 It's three hours long

22:23 lukego: I'm a bit bummed by lack of mutation for graphs right now :)

22:25 sohail: lukego, do it in Java ;-)

22:25 lukego: gah :)

22:26 danlarkin: lukego: what do you need mutations for? graphs are just representations of data

22:27 or are you talking about the graphing code itself?

22:27 lukego: well I need some kind of an indirection to represent the circularity. names might do nicely

22:27 I mean graph as in nodes and vertices

22:28 danlarkin: DAG?

22:29 lukego: a circuit, so more like a DG

22:30 I'm thinking a nice representation is probably a dictionary of named vertices, with edges being represented as symbols (vertex names)

22:31 Chouser: you might find keywords to be a comfortable alternative to symbols

22:31 danlarkin: how about just a map of edges, {:a :b, :b :c, :c :d}

22:37 lukego: it's a circuit so the vertexes need type information, i.e. they need to be able to compute output values from input values (to implement AND, NOT, etc)

22:41 danlarkin: lukego: I don't quite understand, could you give an example?

22:41 lukego: soon :)

22:42 arohner: is there a macro that collects the results from several expressions?

22:42 danlarkin: it's been a while since I took formal automata in university :-D

22:43 arohner: like (accumulate (foo) (bar) (baz)), and then returns the list of return values from the expressions?

22:43 danlarkin: (list (expr1) (expr2)) ?

22:43 arohner: oh, duh

22:43 thanks

22:43 danlarkin: arohner: :)

23:28 AlephInf: Hello, the clojure.org front page says "Every feature supported by Clojure is supported at runtime." I don't understand what it implies. Isn't it always true? I am a lisp newbie, so may be I missing something.

23:29 arohner: I think that means there is no difference between compile time and run time, like say, C

23:31 AlephInf: So to twist that statement around, is it fair to say that all the clojure features are also supported at "compile time". That means macros can use agents, STMs and all the clojure goodness?

23:33 arohner: yes, sort of

23:33 macros return code

23:34 and that code can make calls to agents, STMs etc

23:34 lukego: how do I find out what I can do with strings? is there a "who specializes"? I want to know how to concat them :)

23:35 arohner: also, macros are expanded when the function that uses the macro is eval'd

23:39 AlephInf: arohner: thanks. I guess I'll have to try attacking On Lisp again.

23:40 arohner: yeah, so do I

23:42 danlarkin: lukego: still waiting on your digraph example :D

23:42 lukego: I'm still trying to write it :)

23:43 arohner: lukego: what is 'who specializes'? Is that a CL thing?

23:43 lukego: but here's an example that was prepared earlier: http://mitpress.mit.edu/sicp/full-text/sicp/book/node64.html

23:44 arohner: yes. it means "give me a list of methods that dispatch on type <x>" e.g. tell me every method that wants a string. (iirc anyway)

23:45 arohner: that sounds pretty cool

23:45 lukego: it's in the family of cross-reference facilities who-calls, who-binds, who-sets, etc

23:45 `C-c C-w ...' in SLIME :)

23:45 arohner: this is my first exposure to slime, and I'm just happy with C-c C-d C-d

23:46 danlarkin: lukego: are the who-* functions part of SLIME?

23:47 lukego: that I don't know. ideally they're just bindings but in the old days at least there was a lot of hairy stuff in the per-implementation backends

23:50 danlarkin: they're not in ANSI CL, at least

23:53 lukego: a common-ish extension though. cmucl, sbcl, clozurecl at least support them

23:55 danlarkin: yeah it seems neat

23:56 lukego: how do I get a var that I can set! at the repl?

23:56 arohner: lukego: def

23:56 but you can only set! inside of a binding

23:58 lukego: I want to have something that looks like a "global variable" to the repl and Emacs commands. maybe I'm on the wrong track. can you give a hint?

23:58 it does not have to be shared with other threads

23:58 arohner: that sounds like you want a var

23:58 lukego: isn't that what I have?

23:59 arohner: yeah

23:59 lukego: (def foo 1) (set! foo 2) worketh not

23:59 arohner: right, your set can only appear inside the "scope" of a (binding)

Logging service provided by n01se.net