#clojure log - Nov 11 2009

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

0:01 timothypratley: what's a usage for (ints ...)?

0:03 ,(ints (make-array Object 1))

0:03 clojurebot: java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [I

0:03 timothypratley: Is that intended? I can't think of a scenario where "ints" would do anything useful, but it must exit for a reason :)

0:05 technomancy: it's not useful for pure-clojure; it's intended for java interop

0:05 timothypratley: I just need something for a test I'm writing, any ideas?

0:06 (otherwise I'll just leave it out)

0:07 _ato: timothypratley: ints is usually used for type-hinting

0:09 timothypratley: _ato: ints type hint is different from ints function

0:10 ,(doc ints)

0:10 clojurebot: "([xs]); Casts to int[]"

0:10 _ato: ala (defn foo [int-array] (let [local-array (ints int-array)] ...))

0:11 similar to how you'd do the same thing with int, to perevent boxing

0:11 at least that's what I always assumed it was for

0:13 don't think you can test that, as there's no way to know whether it got unboxed ;)

0:14 timothypratley: hmmm ok good :)

0:14 thanks

0:15 ,(ints (int-array 1))

0:15 clojurebot: #<int[] [I@9f017d>

0:15 timothypratley: I wonder if that's a false sense of security

0:45 codyK: anyone using maven together with swank-clojure-project?

0:46 I'm a little confused about how swank-clojure-binary should be getting set, since maven seems to keep jars in a single repo rather than in the individual project directories

0:52 hrrm, looks like perhaps doing mvn clojure:swank on commandline and then connecting to it from emacs is the way to go

1:44 twbray: Watching thousands of lines of +PrintGCDetails output... what fun

4:07 michaeljaaka: Hi!

4:16 Is there any live?

4:17 Just curious

4:19 Chousuke: I guess it's silent time right now :P

4:30 somnium: question for silent time: why is eval frowned upon?

4:31 ~eval

4:31 clojurebot: eval is evil

4:31 michaeljaaka: eval

4:31 ~do

4:31 clojurebot: Titim gan éirí ort.

4:31 michaeljaaka: hmmm bot could be an intteractvie help

4:32 somnium: he speaks irish when you confuse him

4:32 michaeljaaka: instead of looking into doc I would type here a function name and get an answer

4:32 somnium: he does that already

4:32 michaeljaaka: how?

4:32 somnium: ,(doc eval)

4:32 clojurebot: DENIED

4:32 somnium: he really doesn't like eval I guess

4:32 michaeljaaka: .(doc do)

4:33 .(doc ->)

4:33 hmmm

4:33 doc ->

4:33 somnium: I have a list of expressions like '(+ foo bar baz), and foo bar baz gets looked up in the database and replaced, and I call map eval

4:33 michaeljaaka: doc do

4:33 somnium: it works like a charm but eval makes me feel dirty

4:33 (doc do)

4:33 clojurebot: Titim gan éirí ort.

4:33 somnium: ,(doc do)

4:33 clojurebot: I don't understand.

4:33 somnium: ,(doc ->)

4:33 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."

4:34 michaeljaaka: doc let

4:39 raek: why use eval when one have macros?

4:40 anyway, I haven't used eval this far...

4:40 but it *is* there, which means you are free to use it

4:41 somnium: its in a layout like: {:title "foo" 1 id-1 2 id 2 :func '(+ (- foo bar baz))}

4:41 raek: why not #(+ (- foo bar bax)) ?

4:41 where is the code created?

4:41 somnium: because foo bar baz don't exist

4:42 they have to be resolved at runtime

4:42 its similar to a macro, but the information isn't available at compile time

4:42 raek: ah, then perhaps eval is best the way

4:42 somnium: its quite convenient in any case

4:43 raek: my personal opinion is that you should use it

4:43 as long as you control the code generation

4:47 but this is just my opinion, more experienced people might have different ones

5:13 piccolino: Any feedback on my little CSV library would be helpful. http://github.com/davidsantiago/clojure-csv

5:14 Maddas: raek: Why would macros change anything about the need for eval?

5:14 Oh, sorry, this was addressed just afterwards.

5:23 raek: piccolino: sounds like a useful lib

5:24 piccolino: my first real clojure code.

5:27 raek: looks good :)

5:27 piccolino: Thanks.

5:28 raek: however, it's good to have doc and author metadata in (ns ...)

5:28 piccolino: For all the functions?

5:28 raek: like the various clojure.contrib libs have

5:29 no, a general description of the whole file

5:29 like:

5:29 hiredman: clojurebot: web dev?

5:29 clojurebot: web dev is the worst dev

5:29 piccolino: Oh yeah, OK.

5:29 I'll look at how to do that.

5:29 raek: otherwise, it's well documented

5:31 (ns

5:31 #^{:author "Stephen C. Gilardi",

5:31 :doc "def.clj provides variants of def that make including doc strings and

5:31 making private definitions more succinct."}

5:31 clojure.contrib.def)

5:31 like that ^

5:32 clojure.contrib uses that alot

5:32 maybe you should add the csv code there...

5:33 piccolino: To clojure-contrib?

5:33 raek: simple data formats are good candidates for clojure-contrib. imho

5:33 yes

5:33 piccolino: Hm, well, glad to do that, if they'll have it.

5:34 raek: one of the things I love about clojure is how easy it is to parse data in a lazy way

5:35 piccolino: Yeah, I originally wrote it not lazy, without even thinking about it.

5:35 And then changing it to be lazy was pretty easy, very little change.

5:37 raek: how does the output look like? seqs of seqs of strings?

5:37 piccolino: The output of a CSV parse is a sequence of vectors of strings.

5:38 Each vector of strings is a row.

5:45 raek: I really like that clojure libs tend to be build to emmit data in *simple* data structures

5:46 piccolino: Yeah, you should see somnium's MongoDB library.

5:46 It's fantastic. Just turns clojure data structures in MongoDB documents and vice versa.

5:48 Goodnight.

5:48 somnium: glad you like it, but that's more thanks to mongodb's data format than my efforts

5:48 piccolino: And thanks for your help.

5:48 somnium, that's true, but we were praising clojure here.

5:48 You couldn't do the same thing with Scala or Java.

5:49 somnium: true, the scala mongo code I've seen doesn't look pleasant

5:49 but that might be scala's fault

5:49 clojurebot: tell me about scala

5:49 clojurebot: Scala often gets in the way when trying to write neat code -- seen in #scala

5:50 piccolino: I thought it was just the static typing. You can't really take some data struture you made and use in your code, and have it automatically be turned into mongo stuff. Very easily.

5:52 somnium: I started on scala once or twice, but it always gave me a headache. (I just wanted to try out Lift, really)

5:52 piccolino: Yeah, I found Scala just before Clojure.

5:52 Didn't really feel like it was saving me much time and effort over Java after a while.

5:53 somnium: clojurebot: tell me about scala

5:53 clojurebot: {((x: Any, y: Any) => (f: Function2[Any, Any, Any]) => f(x, y))(1, 2)((x: Any, y: Any) => x)}

5:53 somnium: ^ my head hurts

5:53 piccolino: Love that type inference.

5:53 That was what killed me. I sure had to type out a lot of types for a language that had type inference.

7:28 AWizzArd: ~max people

7:28 clojurebot: max people is 197

8:09 raek: (into {} (map fn-making-pairs coll))

8:09 is this ideomatic?

8:11 somnium: fn-making-pairs is returning vectors?

8:12 raek: yes

8:13 a sequence of vectors of size 2

8:15 somnium: then it works fine with fn-making-pairs

8:16 as I'm sure you're aware

8:16 raek: there's also: (merge (map fn-making-maps coll))

8:16 somnium: that would create a vector though

8:16 raek: if fn-making-maps returns {<key> <value>}

8:17 somnium: ah, yes, didn't notice you changed the name

8:17 raek: somnium: which?

8:17 ok

8:18 so, are both equally good?

8:18 somnium: I think it depends more on the function

8:18 I mean, if you have this function, and you want to make it into a vector or a map, what you showed was fine

8:19 chouser: raek: I think into is preferred

8:19 raek: also, the function would only return a signle key-value pair

8:19 somnium: raek: I would go with chouser on this one

8:20 chouser: at least right now on HEAD, into uses transients and so is likely faster

8:20 raek: ok, thanks!

8:20 maybe merge is better when merging maps with more associations

8:21 then I'll continue to use into...

8:23 chouser: right, if you already have fn-making-maps and esp. if it can return larger maps then clearly you need to use merge

8:23 well, (apply merge (map ...)) right? But without those constraints I think 'into' is more common.

8:34 raek: chouser: ah, yes. forgot apply

8:36 chouser: 'merge' could use transients

8:42 somnium: (reduce conj {} ...) seems to be very slightly faster than (reduce into {} ...)

8:43 (2/10s of a second per 1,000,000 on my old laptop), I guess into is firing up a new loop on every iteration?

8:52 chouser: somnium: for a large number of small maps, conj appears to be faster. For a small number of large maps, into seems faster.

8:53 either could overtake the other as the functions mature.

8:56 somnium: chouser: good to know, thanks

8:56 chouser: *sigh* http://golang.org/

8:56 somnium: I saw that

8:57 I thought, that could make a great platform for clojure :)

8:57 if only it could link to C libs

8:57 (I'm not sure that it can't, but it wasn't mentioned anywhere)

8:58 blackdog`: why the sigh chouser? another missed opportunity, or ...

8:59 chouser: it comes bundled with libs. like a "simple regex lib" that understands . but not (?>X)

9:00 blackdog`: it's still experimental i guess,

9:00 they do mention regex needs more advanced functioality

9:00 cemerick: I don't quite grok its raison d'être

9:01 chouser: well, that's more a datapoint suggesting the state of the useful libraries.

9:02 somnium: it seems kind of like D with message passing (though D can link to C AFAIK)

9:02 chouser: languages already demand so much of their users: leran the primitives, learn the semantics, learn the data types, learn the APIs, learn the configuration and deployment environments, and so on.

9:02 cemerick: yeah, I was going to say, they're a little nuts when they say that "No major systems language has emerged in over a decade". D is quite a big leap forward, and has some degree of momentum.

9:03 plus the C linkage, as somnium said

9:03 chouser: it seems to me that new languages should strive to reduce that set while making their differences as clear and beneficial as positive.

9:05 instead we get this kind of thing -- learn all the above, plus our own new syntax, plus you'll have to re-write regex and xml parsers and parser generators and just everything from scratch.

9:05 fogus_: The approach to language design is typically, look at the big pile of paradigms, pick a few, tweak a few things here and there. Tada... ne language

9:06 * rhickey just dropped in - are we talking about Go?

9:06 fogus_: rhickey: yep

9:06 chouser: good guess!

9:06 they asked me why I sighed.

9:06 rhickey: Google is sure squatting on some terms with Closure and Go

9:07 cemerick: the FAQ makes it sound like they'd like to stop writing C at google. I'll bet they have far different requirements in that context than any of us do.

9:07 chouser: yeah, you'd think they'd know more about SEO

9:07 AWizzArd: what is it about this Go thing?

9:07 cemerick: chouser: don't worry, they'll make sure the results are How They Should Be.

9:07 chouser: cemerick: heh

9:07 fogus_: They know all about SEO... my guess is that golang will be the #1 hit for "Go" any day now

9:08 chouser: oh, how nice! the standard lib inluces a PNG image decoder

9:08 fogus_: cemerick: beat me to it ;)

9:08 * chouser rolls his eyes and tries to pretend it doesn't exist.

9:08 cemerick: chouser: is that a big deal?

9:09 chouser: cemerick: it's goofy. I guess if you have to build all your libraries from scratch, you have to start somewhere. Maybe png image decoders (but apparently not jpeg?) is where you start. *shrug*

9:11 "goroutines"

9:11 * chouser giggles

9:11 cemerick: all those billions in advertising funny-money will pay for a lot of go coding monkeys in some random google playground. I'll bet libraries won't be a problem soon enough.

9:12 chouser: cemerick: could be, and would still be unfortunate.

9:12 cemerick: I agree.

9:12 This is the sort of thing that happens when an organization simply has too much money.

9:12 chouser: cemerick: if that happens, I'll probably have to learn it eventually, though I've managed to avoid learning PHP so far.

9:12 Chousuke_: Go actually didn't seem too bad.

9:13 chouser: that won't last though -- the shop I work for has a lot of PHP. ...it's just a matter of time now...

9:13 cemerick: chouser: well, you're a PL masochist, AFAICT :-)

9:14 gbt: at least you're not being pushed onto cobol *sob*

9:14 chouser: gbt: good point

9:16 suddenly a day of writing unit tests in clojure doesn't look so bad. Thanks, Google!

9:16 gbt: well at least my misfortune wasn't met with snickers ;)

9:17 Chousuke: At least Go has the right idea about interfaces.

9:17 It'll be interesting to see if anyone actually starts using it.

9:20 fogus_: The best part so far appears to be the .go file extension. That looks pretty cool.

9:20 chouser: the fact that "why does go not have macros" isn't even on the list is telling.

9:21 somnium: I wonder if this is that language yegge was blogging about

9:21 chouser: nah, yegge was talking about his own version of javascript

9:28 ordnungs`: hi all

9:28 chouser: ordnungs`: hello

9:34 * ordnungswidrig is sorting his irc connections

9:34 ordnungswidrig: just another day, just another programming language is born

9:37 rhickey: new language, new backend for cinc

9:43 ordnungswidrig: cinc?

9:44 chouser: ordnungswidrig: http://blog.n01se.net/?p=41

9:47 adityo: hello folks

9:47 jabley: ordnungswidrig: turtles

9:47 chouser: heh

9:47 adityo: ,(import '(java.util UUID))

9:47 clojurebot: java.util.UUID

9:47 adityo: ,(. UUID randomUUID)

9:47 clojurebot: #<UUID ab96c396-0685-4cc5-9a2c-161b42cb2f29>

9:48 adityo: but when i do the same thing inside a ns and file, i am getting an error

9:48 chouser: that format sure is tenacious

9:49 adityo: what error?

9:51 adityo: chouser: java.lang.IllegalArgumentException: Don't know how to create ISeq from: Symbol

9:51 chouser: adityo: from the 'import' line, right? are you doing it inside an 'ns' block?

9:53 adityo: chouser: sorry my bad, got the issue, my function didnt have the args []

9:53 * adityo feels very stupid

9:53 chouser: np.

9:53 gbt: I'm waiting for the day when I don't feel stupid :)

9:53 chouser: ,(UUID/randomUUID)

9:53 clojurebot: #<UUID 1e245222-746c-4ae1-889a-8ea118f68c86>

9:54 chouser: btw, that ^^^ is the preferred form for static method calls these days.

9:55 adityo: yes i changed it to that form

9:56 chouser: oh dear http://en.wikipedia.org/wiki/Go!_(programming_language)

10:00 ordnungswidrig: As long as they dont call is gojure....

10:00 chouser: heh

10:01 ordnungswidrig: is cinc a current project or will is be addressed "later", say after clojure 2.0 or like that?

10:02 chouser: ordnungswidrig: much of the work rhickey has been doing lately (reify, deftype, protocols) will directly support cinc

10:02 he's also mentioned though that he wants at least more release before those go into the master branch.

10:03 ordnungswidrig: sounds reasonable

10:05 AWizzArd: I think when the changes of New go into Master it is maybe time for a new release, such as 1.1 or something like that?

10:06 cemerick: I confess I don't see an obvious use case for protocols in my work, although it's entirely possible I'm not grokking them fully.

10:06 chouser: AWizzArd: I think 1.1 is going to happen before the 'new' branch merge.

10:07 somnium: is a 1.1 rc close? (only issues I've had have been naming, c.c.test-is -> c.test, -> c.c.walk c.walk)

10:09 ordnungswidrig: how can I macroexpand in the repl?

10:09 rhickey: cemerick: do you use interfaces?

10:10 chouser: ,(macroexpand-1 '(dosync a b))

10:10 clojurebot: (clojure.core/sync nil a b)

10:10 somnium: ordnungswidrig: are you using slime?

10:10 ordnungswidrig: chouser: Doh! I missed the '

10:10 somnium: yes

10:11 cemerick: rhickey: certainly. But then, I'm happy enough to use deftype or reify as necessary. I'm rarely consuming others' libraries, so I don't often need to 'inject' interface impls for a given type.

10:12 somnium: ordnungswidrig: C-c C-m macroexpands the expression at point into a new buffer

10:12 rhickey: cemerick: really? - you never wished, say, String, could play along with an API you built without putting in an if(x instanceof String) ... ?

10:12 chouser: 'defprotocol' can't be used to *define* a host interface, right? The only time I've bothered to define interfaces, they need to be consumable by Java.

10:12 oh, except for finger trees. that will use protocols

10:13 rhickey: chouser: no, defprotocol will be completely dynamic

10:13 ordnungswidrig: somnium: oh, nice. Didn't know this would work in the repl, too.

10:14 rhickey: In any OO shop I've been in, our own libraries and apps had become large enough that saying 'just derive from MyInterface' was no longer workable

10:15 cemerick: rhickey: I'm sure it happens occasionally, but I can't say it's frequent enough to become irritating. I might have simply internalized the pain, tho. :-)

10:15 Chousuke: rhickey: Could there be a way to generate a Java interface from a protocol though?

10:15 cemerick: The functional footprint of our Java codebase is rapidly shrinking relative to our clojure codebase. That makes things easier :-)

10:15 rhickey: Chousuke: quite possibly

10:16 cemerick: are you using multimethods?

10:16 cemerick: rhickey: yes, but often not dispatching on a single arg's type :-)

10:17 * cemerick is in the 10%!!!! :-P

10:17 rhickey: hmpf

10:20 cemerick: I wouldn't fret about it -- if it makes it easier to build and maintain the core data structures, that well worth the price of admission for me.

10:21 chouser: how many requests have been made to backport bug fixes or features to Clojure 1.0?

10:21 Chousuke: I suppose protocols will still break a dependency on Java. It should help porting eg. contrib to other Clojure hosts if libraries in contrib defined protocols and then used those instead of direct JVM calls.

10:21 rhickey: cemerick: I predict deftype+ defprotocol will be huge

10:21 cemerick: I'm sure. Part of my issue is that I'm so married to interfaces mentally, that I'm sure I'm not seeing the big picture.

10:22 rhickey: they are just more powerful interfaces

10:22 don' t require derivation

10:22 dynamic

10:22 can be applied to existing classes

10:22 can be partially inplemented

10:23 can mixin implementations mechanically

10:23 cemerick: The a-ha moment is surely just around the bend for me.

10:23 rhickey: reified

10:23 looks like I can do pre and post conditions at the protocol level too

10:23 chouser: I see one patch and recall zero other requests in the last 6 months. I guess I'm not shocked, but a bit surprised.

10:24 rhickey: chouser: yeah, seems like as always, some people use download, others master/trunk

10:24 of course, if there were more releases with bigger/breaking changes there might be more interest in bugfixes on a release branch

10:24 ol3: how do i define a 'private' value (e.g. like defn-)

10:24 cemerick: too much fantastic stuff keeps going into HEAD

10:25 that's the sort of dynamic that makes the python moratorium seem like absolute lunacy to me.

10:25 chouser: apparently 1.0 is good enough without fixes for anyone that doesn't want HEAD

10:26 ol3: there's stuff in clojure.contrib.def or you can just (def #^{:private true} foo)

10:26 ol3: chouser: thank you

10:27 chouser: rhickey: pre/post for any method?

10:27 rhickey: so, we need names for the protocol predicate equivalents instanceof and isAssignableFrom

10:27 chouser: yeah

10:28 chouser: oh, and in defprotocol rather than in implement? very nice.

10:28 rhickey: I went with extend for (extend atype aprotocol ...)

10:28 so maybe (extends? aprotocol atype)

10:28 and (implements? aprotocol aninstance)

10:29 chouser: I like 'extends?' -- points to types not instance for me.

10:30 rhickey: satisfies? an option instead of implements?

10:30 for instance case

10:30 AWizzArd: hmm

10:30 chouser: 'isa?' retains a moment of doubt for me, while 'instance?' is clear.

10:31 defn`: Am I being stupid? (defn myfunction [n] (reduce + (range 1 n)))

10:31 opqdonut: isa? pci? usb?

10:31 :)

10:31 defn`: oh god -- it's too early

10:31 nvm

10:33 rhickey: so, for instances: satisfies?, implements? something-else?

10:34 chouser: "implements" in Java is about classes on both sides

10:34 fogus_: rhickey: typeof? ?

10:35 chouser: it's too bad "instance" is inaccurate

10:35 esj: quacks_like?

10:35 chouser: heh

10:35 somnium: handles? ?

10:36 mtm_: follows? (as in follows the protocol)

10:37 chouser: (def a-foo (Foo)) (type a-foo) ==> ::Foo

10:37 djork: hmm, my boss is on the phone with assembla for some kind of pitch

10:37 defn`: Hmmm, how to calculate the number of divisors...

10:37 The efficient way, that is..

10:38 chouser: the instance case will mean the same as #(extends? %1 (type %2)) right?

10:39 Chousuke: how about "understands?"

10:40 ordnungswidrig: defn`: efficient would be using prime factors.

10:40 Chousuke: adheres?

10:41 chouser: "provides?"

10:41 rhickey: chouser: it's slightly trickier than that, because sometimes a type is a Class, and thus a path to supers, and someting a keyword :my.ns/MyType, and not. extends? answers the question, "has someone said (extends MyType AProtcol ...)?", not, "does an instance of MyType satisfy the protocol?" (since they could due to class-based implementation)

10:42 getting an answer to the second question requires an instance right now

10:47 chouser: that is certianly trickier.

10:47 * chouser reread a few more times...

10:49 rhickey: the instance one is more important

10:50 compare instance? usage with .isAssignableFrom (never wrapped)

10:51 chouser: (instance? X a) implies (.x-method a) will work. (satisfies? ::X a) will imply (x-fn a) will work?

10:52 rhickey: chouser: where X is a protocol?, yes

10:53 chouser: oh, we don't use keywords for naming protocols? (skimming the Protocols page again...)

10:54 rhickey: subject to dynamic redefs - I've made it tolerant so that if you originally defprotocol P with foo and bar methods, extend some types to implement it, then redef P with baz, those impls will still work for foo and ba, but fail for baz calls, until you re-extend

10:54 chouser: ah, I see.

10:54 rhickey: protocols get top-level var names, so just Protocol

10:55 detypes get keyword names, since var name is factory fn

10:55 deftypes

10:55 chouser: but the dynamic redef issue there is separate from your earlier statement about trickiness that I'm still trying to grok.

10:56 rhickey: given some keyword ::MyType, there isn't a path to the implementing class, and thus its supers

10:58 chouser: (satisfies? Number 5) will be false because Number is a class not a protocol?

10:58 rhickey: so if you said (deftype Type [a b c] [Interface] ...) (extend Protocol Interface) then (extends? Protocol ::Type) -> false

10:59 satisfies?/extends?/implements? etc are only about protocols as first arg, not intertwined with type system

10:59 chouser: so my example is either false or it throws something?

11:00 rhickey: oops, sorry (extend Interface Protocol ...) above

11:00 chouser: throws something

11:00 or nil

11:01 I really want a separate set of predicates, and to encourage the use of protocols, it can completely isolate you from the host class system

11:02 chouser: that'll be important, so I'm on board. Just have to cut these new neural pathways...

11:03 rhickey: I guess satisfies? is better than implements?

11:05 follows?, supports?, conforms?, complies?, heeds?, obeys?, observes?

11:06 fogus_: panders? caters? fits-the-bill?

11:06 rhickey: pander? hah

11:07 defn`: accommodates? harmonizes? integrates? suits?

11:08 fogus_: (head explodes)

11:08 Maddas: tries-really-hard?

11:08 chouser: fogus_: Mine's already in shambles, trying to pick up the pieces.

11:09 fogus_: ,(head explodes)

11:09 clojurebot: java.lang.Exception: Unable to resolve symbol: head in this context

11:09 fogus_: :p

11:09 the-kenny: ,(explode :head)

11:09 clojurebot: java.lang.Exception: Unable to resolve symbol: explode in this context

11:09 the-kenny: :(

11:11 mtm: ixnay on 'observes?' Sounds too much like an event watcher

11:11 osaunders: Is there such a thing as a lisp where code is written as a tree instead of lists?

11:11 chouser: ,(isa? ::head ::exploded)

11:11 clojurebot: true

11:12 chouser: osaunders: lists are used to build trees

11:12 Chousuke: osaunders: there's misc which uses maps

11:12 ordnungswidrig: hmmm, can I determine the arity of a function at runtime?

11:12 chouser: osaunders: you can think of each list as a node, each element can be a symbol (leaf) or another list (child tree)

11:13 fogus_: richhickey: IMHO satisfies? is the most self-evident (so far)

11:13 whoops, this is not github

11:14 osaunders: chouser: There's a difference though. Tree nodes may contain other tree nodes but that's not the same as child nodes.

11:15 Chousuke: but a tree which has a tree as a node is is in effect a bigger tree :P

11:15 osaunders: The difference is nested lists are a fixed structure but a tree makes up something more akin to a graph.

11:15 AWizzArd: I am not a native speaker, but maybe complies? is also ok?

11:16 ordnungswidrig: AWizzArd: "complies to", it is?

11:16 AWizzArd: genügt?

11:16 for example

11:17 osaunders: Anyway I think I got my answer: no.

11:17 Chousuke: AWizzArd: you conform to a protocol, but comply with standards :)

11:17 ordnungswidrig: Chousuke: the point goes to you.

11:18 complies-with? would by, um, long

11:21 fogus_: ,(:arglists (meta (var +)))

11:21 clojurebot: ([] [x] [x y] [x y & more])

11:21 fogus_: ordnungswidrig: ^^^

11:22 ordnungswidrig: fogus_: thanks, that is what I was looking for

11:23 chouser: ,(:arglists (meta (var defmulti))) ; beware

11:23 clojurebot: ([name docstring? attr-map? dispatch-fn & options])

11:24 Chousuke: ordnungswidrig: you can't trust arglists :)

11:25 (alter-meta! #'+ assoc :arglists '(chousuke was here))

11:25 ,(alter-meta! #'+ assoc :arglists '(chousuke was here))

11:25 clojurebot: {:ns #<Namespace clojure.core>, :name +, :file "clojure/core.clj", :line 654, :arglists (chousuke was here), :inline-arities #{2}, :inline #<core$fn__4440 clojure.core$fn__4440@b374f9>, :doc "Returns the sum of nums. (+) returns 0."}

11:25 Chousuke: (doc +)

11:25 clojurebot: "(chousuke was here); Returns the sum of nums. (+) returns 0."

11:26 ordnungswidrig: Chousuke: I trust them on the repl for debugging. I don't expect them to be manipulated.

11:26 :-)

11:26 Chousuke: ordnungswidrig: some Clojure arglists are, though.

11:26 like defmulti's

11:27 ordnungswidrig: Chousuke: I mangle with some higher order functions and I got lost on what the arity of some composition of them was.

11:27 Chousuke: so this helps me to check that I think correctly

11:27 Chousuke: also anonymous functions don't have the metadata.

11:27 anyway

11:27 ordnungswidrig: Chousuke: hmm

11:27 Chousuke: chouser: didn't you have some code that uses reflection to figure out the arity?

11:27 ordnungswidrig: Chousuke: I see

11:28 chouser: yeah, I didn't write it, but I've posted it

11:28 ordnungswidrig: chouser: say, I "found" it?

11:28 Chousuke: is there some factoid for it?

11:30 ordnungswidrig: Is a (defn foo [r] ((comp a b) r)) equivalent to (def foo (comp a b)) ?

11:31 chouser: clojurebot: count arities?

11:31 clojurebot: Huh?

11:31 Chousuke: ordnungswidrig: yes and no.

11:31 ordnungswidrig: Chousuke: besides docs, meta information and such

11:31 chouser: clojurebot: count arities is<reply>To count arities see http://groups.google.com/group/clojure/msg/fb9930ba2a25d2dd

11:31 Chousuke: ordnungswidrig: then yes

11:31 chouser: clojurebot: count arities?

11:32 did I kill him?

11:32 Chousuke: except the latter will also accept more than one argument if the composition supports it.

11:32 clojurebot: ping

11:32 hm.

11:32 chouser: ordnungswidrig: anyway, there's a link to another approach to getting the arities of a fn.

11:33 clojurebot: Titim gan éirí ort.

11:33 PONG!

11:33 Chousuke: It's alive!

11:33 fogus_: ordnungswidrig: Even with reflection you're still bound by implementation details.

11:33 chouser: clojurebot: count arities?

11:33 clojurebot: No entiendo

11:34 Chousuke: I think you needed to add some spaces between the is and the <reply>

11:34 :P

11:34 chouser: ah

11:34 ordnungswidrig: fogus_: I know, I just wanted to make sure a higher-order-function-result would accept the number of arguments I tought.

11:34 chouser: clojurebot: count arities is http://groups.google.com/group/clojure/msg/fb9930ba2a25d2dd

11:34 clojurebot: Roger.

11:47 blackdog`: chouser: where is the source of clojurebot?

11:48 chouser: clojurebot: where are you?

11:48 clojurebot: http://github.com/hiredman/clojurebot/tree/master

11:48 blackdog`: ha :) fantastic

12:02 maacl: java.util.concurrent Executors expects a Runnable How do I pass it a Clojure function that takes a parameter? it works fine passing a function name but if I pass it a function including a param like (foo "bar") it breaks.

12:04 chouser: try #(foo "bar")

12:07 maacl: chouser: thanks :-)

13:49 cemerick: anyone care to share experiences with swarmiji?

13:50 rhickey: what to call the protocol implementation method map? these can be obtained explicitly, and can be used as mixins. Basically a map of :methodname -> fn

13:51 cemerick: It looks like a really pleasant alternative to JMS + couch (our current setup) w.r.t. the programming model, but (unless I'm missing something) a lot of the coordination lands on you, rather than the messaging container.

13:54 chouser: "method map" isn't too overloaded

13:55 technomancy: swarmiji struck me as pretty simplistic. you could probably build your own implementation in the time it would take to adapt your app to it.

13:56 it's up to you to ensure that jobs actually finish, etc.

13:56 cemerick: yeah, that was my point w.r.t. coordination

13:56 glad I'm not totally off the mark

13:56 dysinger: swarmiji just like ruby nanite is fire and forget

13:57 doesn't provide for tracking work

13:57 technomancy: also the coding style drove me nuts when I was reading through it, but I'm really OCD about that kind of thing.

13:57 cemerick: I'm not particularly looking to migrate at all -- just making sure I'm not missing opportunities. JMS works like a champ, but isn't super-friendly on the clojure side of things

13:57 rhickey: chouser: needs to connect to things like (find-protocol-method-map p x)

13:58 dysinger: cemerick: I am working on this problem actively for our needs.

13:59 cemerick: dysinger: I'm particularly interested in hornetq, and its claims of providing a pure REST api shortly. That would make for a pretty easy way to switch between in-house deployments and something like SQS.

13:59 dysinger: I think we'll see more and more distributed compute tools around clojure shortly

13:59 cemerick: I know rhickey has thought some about abstract queue interfaces, but he's busy :-)

13:59 dysinger: I got managed jvms w/ erlang messaging going last night.

13:59 but that's not my focus - just playing around.

13:59 rhickey: jinterface?

14:00 dysinger: y

14:01 erlang starts jvm and monitors it / restarts it if needed. jvm uses erlang messaging via jinterface. jvm clients use jinterface to talk to distributed erlang managed jvms.

14:01 service is .... repl !

14:01 rhickey: I always wanted to fiddle with that

14:01 dysinger: I love that you don't have to classify services - the service is repl.

14:07 cemerick: jinterface is tantalizing, but I've no interest in getting into erlang at all (hands are plenty full otherwise). It's a thought for the future though, esp. since we're using couch anyway.

14:55 rhickey: protocols are up! http://github.com/richhickey/clojure/commit/766b248f7d097c2c62e809ef6de2e6afd3850fc9

14:55 feedback welcome

14:58 chouser: whee!

15:00 headius: dysinger: SuperTaz on #jruby wants to talk about your job req

15:14 tomoj: is contains? O(log_32 n) for sets?

15:15 Chousuke: hm.

15:15 (doc contains?)

15:15 clojurebot: "([coll key]); Returns true if key is present in the given collection, otherwise returns false. Note that for numerically indexed collections like vectors and Java arrays, this tests if the numeric key is within the range of indexes. 'contains?' operates constant or logarithmic time; it will not perform a linear search for a value. See also 'some'."

15:15 Chousuke: so, probably :P

15:16 chouser: tomoj: log32 for hash-sets, log2 for sorted sets. I think.

15:17 ordnungswidrig: why doesnt this work: (#({:a %}) :foo) whereas ((fn [x] { :a x }) :foo) does?

15:17 chouser: #(x) is (fn [] (x)) not (fn [] x)

15:18 ordnungswidrig: chouser: uh

15:18 chouser: not enough? :-)

15:18 ordnungswidrig: chouser: ah

15:18 the-kenny: What's the purpose of defprotocol? I see all these nice commits, but there are no use-cases and such things... That's what I'm missing

15:18 ordnungswidrig: chouser: how would I then generate a map?

15:19 Chousuke: the-kenny: They're for interfaces.

15:19 chouser: ordnungswidrig: #(hash-map :a %) or (fn [x] {:a x})

15:19 Chousuke: the-kenny: only, they're more powerful than java interfaces :)

15:19 ordnungswidrig: chouser: I see

15:20 Chousuke: the-kenny: but I think having a "native" construct for specifying interfaces is valuable. Reduces dependency on java.

15:20 I mean, even if defprotocol had no other use.

15:20 which it likely does :P

15:21 ordnungswidrig: Chousuke: does have or does not?!

15:21 Chousuke: does have

15:22 ordnungswidrig: Chousuke: for example?

15:23 chouser: ordnungswidrig: you've seen the assembla page?

15:24 ordnungswidrig: chouser: nope

15:25 chouser: ordnungswidrig: http://www.assembla.com/wiki/show/clojure/Protocols

15:26 ordnungswidrig: chouser: fun stuff

15:30 chouser: rhickey: does reify not accept a list of interfaces?

15:31 oh, nm, arg order changed

15:32 rhickey: sorry about that, yes, since no longer 'new', name can go first

15:33 chouser: yep, np.

15:33 thanks for the comment in Compiler.java. :-)

15:35 hiredman: "just realized that the current system I have is fatally flawed"

15:35 poor fnparse :(

15:36 rhickey: reify docs here: http://www.assembla.com/wiki/show/clojure/Datatypes

15:45 chouser: could reify be faster than the old newnew?

15:47 it appears to be.

15:49 ordnungswidrig: is there a idiom for (if (fn? a) (a) a)

15:50 hiredman: trampoline

15:50 maybe?

15:51 ordnungswidrig: a is either a function or a value

15:51 hiredman: ,(trampoline (fn [] :a))

15:51 clojurebot: :a

15:51 hiredman: ,(trampoline :a)

15:51 clojurebot: java.lang.IllegalArgumentException: Wrong number of args passed to keyword: :a

15:51 hiredman: :(

15:51 ,(trampoline identity (fn [] :a))

15:51 clojurebot: :a

15:51 hiredman: ,(trampoline identity :a)

15:51 clojurebot: :a

15:51 hiredman: :D

15:52 tomoj: ,(trampoline identity (fn [] (fn [] :b)))

15:52 clojurebot: :b

15:52 hiredman: yeah, well, …

15:52 ordnungswidrig: hiredman: now with (fn [x] :b)

15:53 hiredman: doesnt look more idiomatic then (if (fn? a) (a) a) to me

15:53 tomoj: (if (fn? a) (a) a) seems perfectly fine to me

15:53 couldn't imagine a clearer way to write it

15:53 ordnungswidrig: tomoj: so im my case it'd be (fn [a x] (if (fn? a) (a x) a))

15:53 tomoj: looks good

15:54 tomoj: except, hmm

15:54 ,(fn? :a)

15:54 clojurebot: false

15:54 tomoj: ,(fn? {})

15:54 clojurebot: false

15:55 tomoj: dunno if you want those

15:55 ordnungswidrig: ,(ifn? {})

15:55 clojurebot: true

15:55 ordnungswidrig: ,(ifn? :a)

15:55 clojurebot: true

15:55 tomoj: aha

15:55 ordnungswidrig: tomoj: but sure :-)

15:55 tomoj: guess fn? is better anyway, otherwise you wont be able to pass keywords, maps, etc as values

15:57 ordnungswidrig: tomoj: oh. I didn't think of this. This explains a weird error I'm chasing for days... *doh*

15:58 hiredman: http://gwolf.org/blog/piespy-modelling-irc-interactions <-- I smell a new clojurebot feature

15:58 tomoj: if I use nailgun can I use clojure as a scripting language? like, executable .clj files? that sounds nice..

15:58 ordnungswidrig: tomoj: btw, you're from austin?

15:58 tomoj: ordnungswidrig: yup

15:59 hiredman: #! is setup as a comment just for that purpose

15:59 ordnungswidrig: tomoj: how is car2go going? I'm from Ulm and I worked as a contractor for Daimler/TSS in Ulm who built the *um* fine peace of software for that :)

16:00 tomoj: ordnungswidrig: never heard of it till now

16:00 but hmm.. I don't have a car, and I've always wanted a smart car

16:01 ordnungswidrig: tomoj: oh man, they failed on marketing this one

16:01 tomoj: you don't want a smart :) At last not the ones they provide in Ulm. But the concept is great!

16:02 tomoj: trying to discover whether there are any locations near campus, and failing

16:03 ordnungswidrig: tomoj: unless you are a registered driver they do not provide many information. Usability could be done better on the website.

16:04 tomoj: there is no map on the website?

16:05 tomoj: couldn't find one, anyway

16:05 maybe I'm just dumb

16:05 oh, now I found it :)

16:05 ordnungswidrig: tomoj: then you're smarter than me!

16:06 chouser: ah, nm -- I was misreading my notes. reify is the same speed as old new new

16:06 tomoj: looks like they're all downtown, far enough away that I'd have to ride the bus to get to them :(

16:08 ordnungswidrig: tomoj: in ulm the area is ok. in fact ulm is like twin town, neu-ulm on the other side of the river. and at first neu-ulm was out of area.

16:51 hiredman: clojurebot: latex \sum_{n=1}^\infty 2^{-n}

16:57 cemerick: hiredman: that's sick :-D

16:58 mikehogye: is there a way to get clojure.main to run a script from a file that is not on the classpath?

16:58 "java -cp clojure.jar -h" indicates that "path" can be a file or resource

16:58 rhickey: so, who's tried protocols?

16:59 chouser: rhickey: started. got distracted. :-/

16:59 mikehogye: but I keep getting "Could not locate blah__init.class or blah.clj on classpath"

16:59 rhickey: I'm finding their dynamic nature to be a lot of fun

17:00 cemerick: I'm always ~5 days behind :-P

17:01 rhickey: when backed with :on interface, speed as good as using the interface directly, so not really a tradeoff to write to protocols

17:01 mikehogye: hmm ... apparently I'm doing something else dumb -- a simple test case works fine

17:01 rhickey: and their dynamic lookup much much faster than multimethods

17:02 cemerick: rhickey: I actually just thought of a use case, so maybe I'll be of some use after all.

17:02 rhickey: cemerick: cool

17:03 cemerick: rhickey: BTW, are you planning on having good and proper name support in deftype, etc., by the time new is merged into master?

17:03 rhickey: cemerick: good and proper?

17:03 cemerick: dashed-name, etc

17:04 rhickey: I've been thinking about that, I'd hare for people to be marrying the munging algorithm on the Java side, but there might not be a Java side...

17:04 Chousuke: hiredman: what's with the near-illegible colour though? :/

17:04 rhickey: I'd hate for

17:04 cemerick: it's obviously window-dressing, but it's just odd to see camelCased keywords

17:05 hiredman: Chousuke: it's fixed

17:05 that was just the color in the example I was following

17:05 cemerick: rhickey: I'd say, if you're using non-Java names, that a decision you need to live with the consequences of

17:05 nothing stopping people from using Java names if interop is a priority for them.

17:06 rhickey: cemerick: but then I need to document and fix the munging scheme

17:06 so far there are no human consumers of the munging, so it can be quite verbose and ugly

17:06 cemerick: rhickey: well, that's a cost that only you can evaluate at this point. I don't know that you need to make it pretty, though.

17:07 e.g. if you're putting dashed-names etc. in your deftype slots, I wouldn't expect them to be usable from Java at all anyway

17:07 rhickey: what if it was limited to dash-becomes_underscore?

17:07 mikehogye: never mind; found my problem

17:08 cemerick: as opposed to supporting all of the naming possibilities like embedded:colons, etc?

17:08 rhickey: yeah

17:09 cemerick: I think that's a fine compromise. Long term, though, I'd assume you'd like to keep allowable names, etc., totally independent of host restrictions. i.e. if you need to have a host-friendly name, stick to underscores, or target one host explicitly.

17:10 Chousuke: maybe an option somewhere to specify a "host name"? :/

17:10 rhickey: what's the url syntax for line#s in github source view?

17:10 chouser: you can click on a line

17:10 I think it's #L012

17:10 rhickey: http://github.com/richhickey/clojure/blob/master/src/jvm/clojure/lang/Compiler.java#L2487

17:11 cemerick: I'm guessing the biggest difficulty will be encountered by anyone creating macros and such on top of deftype/defclass.

17:11 rhickey: oh, see, I think that's totally sane as-is

17:11 Chousuke: I suppose it would complicate things much if the thing has two names, one on the clojure side and another on the host side.

17:12 _ato: think most people are used to that munging from stack traces

17:12 cemerick: i.e. no need to clean it up AFAIC

17:13 Chousuke: I think something like that will be necessary eventually. Who knows what'll happen when the objc host backend is built? :-P

17:15 drewr: you can click on the line number in the margin too

17:19 _ato: http://kenai.com/projects/jruby/pages/CompilerNameMangling

17:19 thye have less cases though

17:22 raek: so, if I want to try protocols, where should I begin?

17:22 or rather, what kind of stuff can I use it for?

17:37 headius: rhickey: it would be nice if we could start to agree on mangling conventions

17:37 I've brought this up with scala guys, but they apparently don't have any standard even now

17:38 hoeck1: raek: I would start with reading http://www.assembla.com/wiki/show/clojure/Protocols

17:39 raek: in fact, I did, but its too late here right now, so I'm going to try them out tomorrow

17:45 tomoj: what is this ":on barMethod" thing?

17:45 seems unexplained

17:46 hiredman: uh

17:46 its :on AnInterface isn't it?

17:46 you can implement a protocol on an interface

17:46 well

17:46 define, not implement

17:47 krumholt_: I read the article about protocols . can someone explain to me in 1 or 2 sentences what kind of problem protocols address?

17:47 tomoj: there is also a ":on barMethod" in the example

17:48 chouser: rhickey: deftype implements a interface but not a protocol, right?

17:49 hiredman: krumholt_: you can name a set of opertions on some thing

17:49 a protocol for dealing with something

17:49 _ato: krumholt_: basically it's like multimethods dispatched on type, but multiple methods can be grouped together under the one name and it's performs much faster

17:50 Chousuke: krumholt_: consider the Clojure Seq abstraction.

17:50 krumholt_: so it's a nicer way to express common multimethod usecase

17:50 Chousuke: krumholt_: As far as I understand this stuff, that will become a protocol

17:50 _ato: krumholt_: sort of like a more dynamic version of javas interfaces

17:51 krumholt_: ok thanks everyone. i think i get the idea

17:51 hiredman: well, a protocol is a set of ops, and a multimethod is a single op

17:52 Chousuke: just to add to the mix, the design document also mentions multiprotocols :P

17:53 hiredman: I'm not too clear on extending protocols

17:53 _ato: tomoj: maybe :on barMethod lets you alias a java interface method to a clojure function name or something

17:54 hiredman: but I guess you just make a new protocol with the same set of ops?

17:54 chouser: _ato: I think that's right

17:56 _ato: "By default, methods of the protocol map to methods of the same name in the interface. A different mapping can be provided on a per-method basis using :on inside the signature."

17:56 ^ from the defprotocol docstring

17:56 hiredman: hmmm

18:01 drewr: are there any pastes with a good protocol eg?

18:05 chouser: no return types on protocol methods?

18:06 no protocols on protocols?

18:07 I must not be thinking about this correctly.

18:07 oh -- no types on any of the args?

18:08 _ato: chouser: what would a protocol on a protocol do?

18:09 chouser: well -- maybe "on" is the wrong word. If something is a Car it will provide all the methods that a Vehicle does, plus some Car-specific ones.

18:10 the-kenny: hm... I think clojure-mode ignores (setq indent-tab-mode nil), strange.

18:10 chouser: So am I not supposed to capture that when I defprotocol, but just hope/assume that anything extending Car will also extend Vehicle?

18:11 Chousuke: chouser: I don't think you're supposed to have protocols for Cars and Vehicles :/

18:11 I mean, they should be split so that you could implement both with no overlap.

18:12 chouser: where does the "start" method go? One or the other? both?

18:12 bah. gotta go.

18:13 hiredman: if there is any question, it goes on the more specific

18:13 or Vehicles->StartableVehicles->Cars

18:14 Chousuke: Movingthings - Motorised things - Wheely things

18:14 _ato: yeah, it's not inheritance

18:15 it's a "protocol"

18:15 eg you could start things that aren't vehicles

18:15 technomancy: the-kenny: it's not that clojure-mode ignores it; it's just that it becomes buffer-local when you set it

18:15 _mst: I remember looking at how Compojure implemented multiple backends for sessions (file, memory, database, ...) and thinking it could use something a bit like this

18:16 technomancy: the-kenny: (set-default 'indent-tabs-mode nil)

18:16 _mst: not really inheritence, just a way of expressing the required interface in code and making it possible/easy to provide custom implementations

18:16 the-kenny: technomancy: Oh, ok. I wasn't aware of that.

18:17 _ato: if I'm "getting it" right the idea is composition is better than extension

18:17 hiredman: well, you can implement protocols on interfaces which are heritable

18:17 _ato: hiredman: right, but I think that's only to support java interop

18:18 you're not supposed to use that to "get" inheritance

18:18 hiredman: interface inheritence is ok, implementation inheritence is bad

18:18 the-kenny: technomancy: hm.. that doesn't work.

18:19 technomancy: it might only take effect for new buffers?

18:19 the-kenny: I just restarted emacs

18:20 _ato: I think the key is to think of it more like duck-typing... who cares whether something is a car or a vehicle as long as it's "startable"

18:20 hiredman: if you look at the java side of clojure the tree is deep interfaces, shallow implementation sharing

18:21 so you have a long chain of interfaces, and at the end maybe one abstract class with some common code and then a single concrete class

18:22 _ato: "#

18:22 *

18:23 # While avoiding some of the drawbacks implementing an interface creates an instanceof type relationship and hierarchy"

18:23 hiredman: *shrug*

18:24 _ato: I dunno maybe we just wait for Rich to give a talk on it and clear up what is good and proper :p

18:24 hiredman: I am not using clojure's code base as argument from authority, but as an example of what I think works well

18:25 _ato: the fact remains, interfaces are heritable, and you can implement protocols :on interfaces

18:25 bah

18:25 s/implement/define/

18:27 _ato: yeah, I'm not necessarily disagreeing with you, just that's my interpretation of why Rich has apparently made protocols themselves not heritable

18:28 hiredman: ~latex sum \limits_{k=1}^N k^2

18:28 :(

18:29 ~latex \sum \limits_{k=1}^N k^2

18:30 the-kenny: Google Charts can do LaTeX? Wow

18:30 hiredman: _ato: I think inheritence matters less in clojure because clojure is dynamic and has first class functions

18:31 so using inheritence for types is nixed, and you can mix in implementations via functions

18:32 krumholt_: when do i need :use and :import in the ns macro? is it correct that use is for clojure code and import for java code?

18:32 hiredman: yes

18:32 krumholt_: ok thanks

18:33 hiredman: http://github.com/hiredman/clojurebot/blob/master/hiredman/clojurebot/latex.clj#L1

18:34 qed: Could someone step me through something?

18:34 I know that lazy-cons isn't the way to do this anymore, but:

18:34 (def triangles (lazy-cons 0 (map + triangles (iterate inc 1))))

18:36 hiredman: I, uh, well using lazy-cons there would be silly even if it still existed

18:36 you may as well (def triangles (cons (map + triangles (iterate inc 1))))

18:36 er

18:37 (def triangles (cons 0 (map + triangles (iterate inc 1))))

18:37 qed: that's chouser's code

18:37 hiredman: :(

18:37 qed: hiredman: could you explain to me how you might write that with lazy-cat?

18:37 or a completely different problem, i just dont see how it works

18:38 hiredman: lazy-cat?

18:38 qed: nod

18:38 hiredman: (lazy-cat [0] (map ...))

18:39 lazy-cat just concats sequences

18:39 qed: ps your code didn't work

18:39 _ato: (lazy-cat xs ys zs) === (concat (lazy-seq xs) (lazy-seq ys) (lazy-seq zs))

18:39 hiredman: so you give it sequences

18:39 qed: hiredman: but you can use it to create an infinite seq right?

18:39 hiredman: no

18:39 _ato: qed: maybe you want lazy-seq

18:39 hiredman: not lazy-cat

18:39 qed: what do you mean didn't work?

18:40 qed: (def triangles (cons (map + triangles (iterate inc 1)))) blows up

18:40 hiredman: qed: please notice the correction I pasted right after

18:40 qed: oh d'oh, sorry

18:41 _ato: hiredman: that doesn't work either as triangles is unbound in the right-hand side

18:41 that's probably why chouser used lazy-cons

18:41 qed: lazy-seq is the new lazy-cons, right?

18:41 hiredman: no

18:42 qed: where did lazy-cons go?

18:42 _ato: (def triangles (lazy-seq (cons 0 (map + triangles (iterate inc 1)))))

18:42 http://clojure.org/lazy

18:42 qed: thanks _ato

18:43 _mst: also worth noting that that version necessarily hangs on to the head of the seq...

18:44 qed: (next triangles)

18:44 oops

18:44 technomancy: nil

18:45 qed: technomancy: :)

18:45 _ato: could you step me through what's happening in your function?

18:46 hiredman: (it's not a function)

18:46 qed: im aware, but surely you understand what im sasking

18:46 asking*

18:46 somnium: is there any need to use lazy-seq with map?

18:46 _ato: qed: lazy-seq is a macro that doesn't execute it's body until first/rest is called on it

18:47 somnium: in this case yes, because triangles (as the map argument) doesn't exist yet

18:48 ,(do (lazy-seq (println "hi")) nil)

18:48 clojurebot: nil

18:48 _ato: ,(do (first (lazy-seq (println "hi"))) nil)

18:48 clojurebot: hi

18:49 hiredman: without looking at the code, I think you should collapse it into a call to interate

18:49 iterate

18:49 (iterate some-function 0) can surely get you the same result

18:50 _mst: maybe (iterate some-function [0 1]) since you need to track two pieces of state

18:50 hiredman: _mst: are you sure?

18:51 _mst: nope :)

18:51 hiredman: there are two sequences in the map, sure

18:51 _mst: but I have it in my head you need to track a running integer (from 1) and the last triangle number you saw

18:52 first attempt: (map first (iterate (fn [[t i]] [(+ t i) (inc i)]) [0 1]))

18:52 _ato: ,(take 10 (map #(/ (* % (inc %)) 2) (iterate inc 0)))

18:52 clojurebot: (0 1 3 6 10 15 21 28 36 45)

18:52 _mst: tricky :)

18:53 qed: nice :)

18:53 _ato: http://en.wikipedia.org/wiki/Triangular_number :-P

18:53 hiredman: (list (- (* n n) (* m m)) (* 2 m n) (+ (* n n) (* m m))

18:53 I just don't remember what m and n are supposed to be

18:54 somnium: that one is pleasingly symmetrical somehow

18:54 hiredman: clojurebot: latex \frac{-1\pm\sqrt{8x+1}}{2}

18:57 http://en.wikipedia.org/wiki/Pythagorean_triple

18:58 it occurs to me I might confused as to which euler this is

19:01 qed: #12

19:02 1 + 2 + 3 + 4 = 10, 10 is div by 1 2 5 and 10

19:03 which triangle number has 500 divisors

19:03 err > 500 div

19:04 I started with (defn gen-tri-num [n] (reduce + (range 1 (+ n 1))))

19:05 then i was going to calc the number of divisors for each tri-num i generated

19:05 that's where i got stuck -- not sure the best way to do that

19:07 hiredman: http://gist.github.com/232449 one of the more amusing bits from my eulering

19:07 I don't recall what made me call it totally useless

19:09 qed: maybe that it's incredibly useful?

19:10 hiredman: reverse psychology?

19:10 tomoj: I never got that one

19:11 took way too long

19:11 qed: reverse psychology is even less rigorous than forward psychology

19:12 hiredman: clojurebot: reverse psychology is even less rigorous than forward psychology

19:12 clojurebot: In Ordnung

19:12 qed: :)

19:12 clojurebot: reverse psychology

19:12 clojurebot: reverse psychology is even less rigorous than forward psychology

19:23 tomoj: damn your divisor function is SO much faster than mine

19:26 qed: ugh i just signed an NDA

19:26 i kick myself everytime i do that

20:36 hiredman: clojurebot: hydra?

20:36 clojurebot: Excuse me?

20:41 penthief: I've just done clojure-install from emacs, and it worked, but after restarting I get 'symbol's value as variable is void "package-activated-list"' when I type M-x slime

21:24 chouser: rhickey: so I'm trying to redo finger trees with protocols

21:25 I implement a lot of clojure interfaces

21:25 does that mean (until clojure's interfaces are themselves protocols) that I need to create one protocol per interface

21:30 and instead of a reify on a couple interfaces, I need to extend a huge list of uninheriting protocols.

21:32 hiredman: I gtalk's sms gateway and appengine's xmpp support could get me a repl of sorts on my phone

21:33 I think

21:33 tomoj: good luck typing sexp's on your phone

21:33 hiredman: :P

21:34 I'm trying to think of something I can do with that

21:35 tomoj: hmm.. if you take paredit and navigation operations and separate them from self-insert stuff, I wonder how many operations you wind up with

21:37 rhickey: chouser: can you give me an example?

21:38 I think while Clojure's abstractions are interfaces you can just implement them (in e.g. deftypes)

21:38 if you introduce your own abstractions, you can do so with protocols

21:39 no need to wrap Clojure's interfaces with protocols before Clojure does

21:39 but what do you mean by uninheriting?

21:40 hiredman: protocols don't inherit

21:40 I think, is what he means

21:45 djork: what is ->> and why is penumbra using it ?

21:45 hiredman: ->> is newish

21:45 djork: hmm

21:45 ok

21:45 hiredman: like -> but the other side

21:45 djork: like, the last few weeks?

21:45 hiredman: ,(doc ->>)

21:45 clojurebot: "([x form] [x form & more]); Threads the expr through the forms. Inserts x as the last 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 last item in second form, etc."

21:46 hiredman: djork: more like months I think

22:02 chouser: Ok, so I can use deftype to implement existing interfaces, and then extend it with my own protocols

22:02 dreish: Is there any good documentation for ns yet?

22:03 djork: hmm, I want to believe in penumbra :)

22:03 hiredman: (doc ns) seems to have all the bits

22:03 clojurebot: "([name & references]); Sets *ns* to the namespace named by name (unevaluated), creating it if needed. references can be zero or more of: (:refer-clojure ...) (:require ...) (:use ...) (:import ...) (:load ...) (:gen-class) with the syntax of refer-clojure/require/use/import/load/gen-class respectively, except the arguments are unevaluated and need not be quoted. (:gen-class ...), when supplied, defaults to :name correspo

22:03 dreish: Seriously? That's not even close to complete.

22:04 hiredman: dreish: what do you mean?

22:04 tomoj: hehe

22:04 hiredman: (doc use)

22:04 tomoj: all the bits are there, they're just scattered about and difficult (for me) to understand

22:04 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."

22:04 djork: seems clear to me

22:04 tomoj: would be nice to have some examples of all the different ways to use all the subforms

22:04 dreish: What tomoj said. Which I guess isn't the same as being undocumented.

22:05 tomoj: someone had suggested before setting up examples of all the core functions

22:05 wonder if anything came of that

22:05 dreish: I find myself using ns mainly by guess-and-fix because the docs are just a tangle of spaghetti.

22:05 djork: I think the docs just need a bit more hyperlinking.

22:05 tomoj: yes, guess-and-fix indeed :)

22:06 djork: I actually found it pretty helpful to just sit down and read the docs from the beginning. It's better than most languages.

22:07 dreish: Yeah, I generally don't work that way once I'm past the basics.

22:07 djork: maybe it's time for clojure.contrib.examples :)

22:07 or cheat

22:08 dreish: Or just a thorough, third-party reference to the language.

22:08 djork: http://cheat.errtheblog.com/

22:08 dreish: have you tried this yet? http://jnb.ociweb.com/jnb/jnbMar2009.html

22:08 it's very good

22:09 dreish: djork: Thanks for the reminder. I've seen that, but forgot about it.

22:09 djork: how about cheat sheets for different areas of clojure

22:09 dreish: I vaguely remember some inaccuracies, I think, but that could have been a long time ago, or a different document.

22:10 Doesn't seem to cover ns, though.

22:11 What I'm wondering, specifically, is whether there's a way to include several libs at the top dot level without saying :use over and over.

22:12 I.e., to replace (:use [util]) (:use [server-lib]) (:use [clojure.contrib.def]), which seems pretty gross to me.

22:12 djork: what would you want to shorten, for example...

22:12 tomoj: (:use util server-lib clojure.contrib.def) doesn't work?

22:12 dreish: I don't think so. I thought it complained about no such thing as util.server-lib.

22:12 tomoj: single-segment names are bad, I think

22:13 dreish: Thanks, mom.

22:13 :-P

22:13 djork: single-segment names aren't just bad... they don't work in some cases (I believe)

22:14 nforrest: I've read that in clojure, list element access is O(n) and prepending to a list is O(1). I understand how that works (it's a linked list). However, I've also heard that vector element access is O(1) and appending to a vector is also O(1). What sort of data structure allows you to achieve that kind of performance?

22:14 djork: dresh, consult (doc require)

22:14 it's big

22:14 dreish: I'm not into languages that tell me to sit up straight. Clojure hasn't seemed much like that to me so far.

22:14 tomoj: I'm imagining a webapp that automatically indexes all the interns in clojure.* and clojure.contrib.* and lets people submit examples, maybe with vote up/down

22:15 djork: nice idea

22:15 tomoj: why are single-segment names bad, again? I forget

22:16 arohner_: nforrest: it's not technically O(1), it's O(log sub 32)

22:16 tomoj: man "clojure" is so difficult to make punny names with :(

22:16 nforrest: Oh, I see.

22:16 tomoj: log_32 is practically constant, though

22:16 nforrest: That seems much more possible.

22:16 Thanks.

22:16 arohner_: there are some blog posts somewhere about the clojure datastructures

22:17 dreish: tomoj: Apparently (:use util server-lib clojure.contrib.def) does work. I must have had an extra pair of something when I tried that. Thanks.

22:17 djork: what, clojure makes for awesome puns :)

22:17 tomoj: and then you can do like

22:17 djork: my toy mud is called "dunjeon"

22:17 tomoj: (:use [util :only (foo)] server-lib ...)

22:17 hmm, yeah, hadn't thought about that kind of pun yet

22:18 need to find a phonetic dictionary to search through for zh and soft g

22:18 djork: yeah just throw some j replacements in there and you're done

22:19 tomoj: :)

22:23 qed: what is a 'coll' in clojure?

22:23 like any form of a list? can a seq be a coll?

22:24 is a seq a coll?

22:24 tomoj: I think 'coll' means any x for which (sequential? x) is true

22:25 rhickey_: ,(coll? (seq [1 2 3]))

22:25 clojurebot: true

22:25 qed: thanks rich, tomoj

22:25 tomoj: oh, hmm

22:26 count's parameter is called "coll" in the docs but it works on non-persistent collections too

22:26 qed: rhickey_: is that the same rationale behind forcing the programmer to create (seq "abcd") before cons'ing on it?

22:26 onto*

22:26 like (cons 1 (seq "abcd"))

22:26 tomoj: oh, {} is not sequential

22:26 but it is a coll

22:27 * qed nods

22:27 tomoj: what's the interface for seqables?

22:27 and, is there a predicate for that?

22:27 rhickey_: Seqable

22:28 tomoj: I always thought sequential? checked for seqability

22:39 djork: maybe this falls under "premature optimization" but I am wondering about the performance implications of frequently calling conj or assoc on large vectors or maps

22:40 chouser: djork: it is premature. when you find you need it, look at transients

22:40 djork: those are new, aren't they?

22:41 chouser: newish

22:49 djork: wow the JVM exhibits a really wild range of performance

22:49 79 ms, 30 ms, 2.6 ms

22:49 not a cached lazy seq or anything

22:50 starting from scratch with a ref of a vec of 100K strings

22:50 chouser: deftype can't implement a protocol, right?

22:54 rhickey_: chouser: nope

22:55 I've thought about supporting extends there, since why should interfaces get preference?

22:56 but it could get confusing, the difference between Java-like methods and real fns

22:56 chouser: so confused already

22:56 rhickey_: oh no!

22:56 chouser: I'm starting from http://tinyurl.com/ylx4j3k/finger_tree.clj#LID18

22:56 rhickey_: what's confusing?

22:56 chouser: a pile of interfaces

22:57 that starting point uses interfaces in a couple different ways, and I think converting to protocol/deftype is forcing me to tease apart the reasons.

22:59 Some of those interfaces, like IDigit mearly aggregate other interfaces. No way to do that with protocols, right?

22:59 djork: wow, clojure is a better Java :)

22:59 rhickey_: not so far, but doing that doesn't really save you much in the implementing

22:59 chouser: right

22:59 just a few words.

23:00 take none of this as criticism -- I don't understand well enough to complain yet.

23:00 rhickey_: and you can put multiple protocols in a single extend

23:00 chouser: :-)

23:00 right

23:00 ok, setting that aside.

23:02 IDoubleSeq does that but also adds a couple methods. So I should replace that with a defprotocol that leaves out the interfaces and just defines the two methods.

23:02 rhickey_: right, the real reason for aggregating protocols is to combine multiple dependent contracts, but that has some implementation issues

23:02 yes, best to think of the Clojure interfaces as interop, and your new abstractions with protocols

23:03 chouser: ok, so I think I'm ok on through IDeepTree. That extends IPersistentCollection for interop and defines three methods that are just accessors to data fields.

23:03 rhickey_: it will be really nice when you can interop with the Clojure abstractions through protocols

23:04 chouser: yes!

23:04 but I should understand this anyway.

23:04 I might have to explain it to someone.

23:04 in Chapter 10.

23:04 ok, because there are new data items, that will call for deftype

23:06 I can use deftype's IPersistentMap auto-impl to access them, so I don't need hand-written accessor methods for IDeepTree

23:06 rhickey_: right, most of your factory fns on newnew can become deftypes with factory fns

23:07 chouser: But I need to support IPersistentCollection, and since that's an interface not a protocol, those methods have to be defined inside the deftype

23:08 rhickey_: right, but some of your new stuff can share impls, like measureFns/More/Pop betwen empty/single

23:08 mixins are really easy with protocols

23:08 and clean, no incidental hierarchy

23:09 chouser: just merge maps as needed, right?

23:09 rhickey_: yeah

23:09 extend is an ordinary fn

23:09 and the method maps just kw->fn

23:10 chouser: ok, but I'll have some DeepTree methods that must be in deftype (for IPersistentCollection) and others in extend for my own protocol stuff.

23:10 rhickey_: you can reuse an impl wholesale, just (extend type proto map)

23:10 yes, having methods not 'in' will be commonplace with protocols

23:11 but at least will be sets, vs independent multimethods

23:12 chouser: it just seems odd that some methods must be in deftype while others can't be.

23:12 rhickey_: in a pure Clojure design the deftypes might have no methods at all

23:12 chouser: right, that makes sense to me.

23:12 hiredman: excellent

23:12 rhickey_: so, the methods there are just interop

23:12 chouser: I guess it's the interop nature that's forcing some of the methods into deftype.

23:13 rhickey_: one problem is the use of the word method, since they are methods in very different senses, and the Java ones are not first-class

23:13 chouser: the methods in extend will be able to use the deftype :kw accessors, and call the deftype methods

23:13 rhickey_: maybe we should use another term for protocol fns

23:14 chouser: kw accessors yes, methods will need (.foo x)

23:14 hiredman: operations

23:14 rhickey_: although that's the case inside deftype too, no real class scope for methods

23:14 hiredman: maybe

23:15 chouser: the methods in deftype will be able to call any protocol methods via the defprotocol-created functions

23:15 and of course access their own fields.

23:15 rhickey_: chouser: sure

23:15 chouser: ok.

23:15 thanks for walking me through that. I think I'm back on top of it again.

23:15 rhickey_: but the point of making (:kw x) as fast as dot was so that protocol methods are not at a disadvantage

23:16 chouser: cool

23:16 chouser: it reminds me so much of math -- makes sense until you try to do the homework.

23:17 rhickey_: hah

23:17 chouser: once you can do it on your own *then* you know you've got.

23:17 got it.

23:17 rhickey_: well, converting something is hard too, since you've already got one mental model

23:18 on a green field design deftype + protocols should be sweet

23:18 chouser: and the interop here is perhaps deeper than will be common

23:19 will I have a problem getting the default IPersistentMap methods in my deftype that also implements custom IPersistentCollection methods?

23:19 rhickey_: it will be straightforward to make protocols that correspond to (and are :on) the existing interfaces

23:19 chouser: yes

23:20 there isn't a way to pick and choose bits of the impl, as it can be difficult to determine what will work together

23:20 so, either I do it or you do

23:20 but not some of each

23:21 but you've already done it

23:21 just add some dots

23:23 gotta crash - good luck!

23:23 chouser: so my deftype for IDeepTree needs to include accessor methods

23:23 like I have now

23:24 rhickey_: if you don't take the IPersistentMap impl, you'll still get keyword accessors

23:24 chouser: well, I

23:25 well, I'll let you sleep. I probably won't get that far tonight anyway.

23:25 thanks again.

23:25 rhickey_: tomorrow then...

23:26 tomoj: this deftype/protocol stuff is still a total mystery to me

23:26 hiredman: so :on is something of a red herring

23:28 chouser: well, it allows you to bridge existing interfaces into the defprotocol/extend system

23:28 but yeah, I guess it's an interop feature on an other native construct.

23:28 hiredman: sure, but it sounds like the idea is that for existing interfaces you will just use deftype directly

23:31 chouser: oh, I see what you're saying

23:32 instead of putting some methods into the deftype I ought to be able to make a bridge protocol for IPersistentCollection and implement them with 'extend' like all my other methods.

23:33 except

23:33 no, that should be right.

23:40 except not in this case, because the whole point is to let people do (count my-finger-tree), but 'count' is not yet a protocol method -- it wants to call .count on an actual IPersistentCollection object, so having my own kind of thing that uses defprotocol/extend won't help.

23:40 it needs to be an actual intance of a Java class that extends IPersistentCollection, so I need to have those methods in the deftype.

23:47 hiredman: I haven't looked at my reader in a few weeks, maybe I should update it

23:53 tomoj: what's a good way to make your code configurable?

23:53 without making people need to wrap everything in a binding

23:54 hiredman: pass an argument

23:54 tomoj: ah, yes

23:54 hmm

23:55 I guess that would mean I'd have to wrap all my tests inside a macro or something

23:55 hiredman: usually the first thing I do with a binding heavy api is start wrapping stuff in (defn foo [some-resource args] (binding [*resource* some-resource] ...))

23:55 tomoj: or pass the same parameter over and over again

23:56 I'm working on htmlunit tests with clojure.test and want to set a global root-url

Logging service provided by n01se.net