#clojure log - Mar 22 2009

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

0:01 cmvkk: hmm. using seque slows my program runs from 40 to 55 seconds at best, and causes them to never finish at all at worst.

0:03 hiredman: interesting

0:05 slashus2: cmvkk: You using the latest svn?

0:06 cmvkk: oh, probably not... but it's gotta be closer

0:06 close*

0:06 slashus2: There was a recent release so that shouldn't matter.

0:06 cmvkk: has seque changed a lot recently?

0:06 slashus2: cmvkk: There was a bug in it that was fixed a few weeks ago.

0:07 cmvkk: slashus2, that sounds promising

0:07 heh:

0:07 user=> (time (dorun (take 1000000 (map + (iterate inc 0) (iterate inc 0)))))

0:07 "Elapsed time: 2104.119907 msecs"

0:07 user=> (time (dorun (take 1000000 (map + (seque (iterate inc 0)) (seque (iterate inc 0))))))

0:07 "Elapsed time: 42286.409766 msecs"

0:08 maybe that's a misuse...?

0:08 hiredman: well, seque is going to add overhead

0:08 cmvkk: yeah

0:09 well, that's why that example is so much worse than my actual program, which was only 5/4ths off

0:09 or 1/5th off, i mean

0:50 cconstantine: cmvkk: this reflection thing sounds interesting...

0:50 cmvkk: i always forget about it then it turns out to be helpful.

0:50 cconstantine: what is it?

0:51 cmvkk: it's what happens when the compiler doesn't know what class an object belongs to when you call its method.

0:51 try putting (set! *warn-on-reflection* true) at the top of a program

0:51 and it will tell you all the places reflection occurs in the program.

0:51 cconstantine: interesting

0:53 what would the warning look like?

0:53 cmvkk: for example: "Reflection warning, line: 33 - call to isDigit can't be resolved."

0:54 cconstantine: thats on a compiled .clj file?

0:54 cmvkk: not a precompiled clj. Just a script that's run. although reflection occurs in precompiled files also i guess

0:55 cconstantine: ok. I"m not getting it

0:55 I'm still hunting inefficiencies in my prime generator

0:56 cmvkk: well if you aren't getting any of those warnings then there probably isn't a reflection issue

0:56 replaca: cconstantine: the warning's going to happen when the program is compiled, but all clojure scripts are compiled

0:56 cconstantine: ok, so it should happen on evaluation of the defn, not the call to the func

0:57 replaca: cconstantine: yeah

0:58 hiredman: actually the reflection check happens at compile time (but clojure code is always compiled, AOT or JIT)

0:59 at least from what I remember of a conversation in heere it happens at compile time

0:59 cconstantine: hehe

0:59 hiredman: bah

0:59 I really am not paying close enough attention

1:00 cmvkk: heh

1:00 replaca: yeah, but generally that will appear to be the same time you're evalig the defn unless you're using AOT or paying *really* close attention

1:00 *evalig => evaling

1:01 cconstantine: ok

1:01 it would make me feel better if I could invoke the warning... example?

1:01 hiredman: to get rid of reflection you use type hinting

1:02 cconstantine: I'm not seeing it from eval of the defns through the calls to them so I'm most likely not in a reflection situation

1:02 pstickne: isn't there a gob of Object access floating around in compiled code? (as type hinting no raising an exception when it's incompat)

1:02 hiredman: ,(binding [*warn-on-reflection* true] (let [a "a"] (.length a)))

1:02 clojurebot: 1

1:02 hiredman: bah

1:03 cmvkk: hiredman i was trying that and couldn't get it to work, heh.

1:03 hiredman: I think the easiest way is passing through the function interface

1:03 (defn f [a] (.lenght a)) then (f "foo")

1:03 length

1:04 cmvkk: (binding [*warn-on-reflection* true] ((fn [a] (.length a)) "foo"))

1:04 cconstantine: ok, I got it :)

1:04 cmvkk: crud i forgot the comma

1:04 cconstantine: thanks :)

1:05 pstickne: ,(binding [*warn-on-reflection* true] ((fn [a] (.length a)) "foo"))

1:05 clojurebot: 3

1:05 hiredman: no dice

1:05 * pstickne shrugs

1:05 cmvkk: heh

1:05 well it works if you set! it...at least in my repl.

1:05 cconstantine: clojurebot might not be reporting the stderr/stdout that the warning goes to

1:05 pstickne: it might be being snuffed by the bot. not sure how it handles output.

1:06 hiredman: you should get stderr and stdout output from clojurebot

1:06 cmvkk: nope. looks like 'binding' just isn't good enough for *warn-on-reflection*

1:06 pstickne: hmm, that doesn't work here in the repl (with binding)

1:07 Raynes: Not working in my REPL either.

1:07 hiredman: it may need set!

1:07 Raynes: So we know it's no cigar. My REPL is superior to all of yours.

1:07 pstickne: it works with set! here

1:07 what is the type annotation syntax again?

1:08 Raynes: I should write a graphical front-end to the REPL.

1:08 Like the one Factor uses.

1:08 pstickne: (it's called emacs ;-)

1:08 cconstantine: hehe

1:08 Raynes: pstickne: No I mean graphical graphical. Like press buttan thing happan.

1:09 replaca: is it really necessary for the compiler to emit 235 lines of exception backtrace just to tell me I spelled String wrong?

1:09 Raynes: replaca: Sadly yes :|

1:09 cmvkk: it's useful

1:09 replaca: Raynes: I don't think it really is

1:09 Raynes: cmvkk: It's annoying too >.>

1:09 It does it to me in Netbeans.

1:09 hiredman: a stack trace will save you some day

1:09 replaca: unless maybe you're debugging the compiler

1:10 no, the compiler should just work

1:10 * Raynes scrolls up 10 thousand lines to see what his last error message was.

1:10 Raynes: hiredman: But stacktrace can be turned on. :)

1:10 replaca: when my code throws an exception, that's a different thing

1:10 * cconstantine can make his former-TA friends cringe by claiming 'there is a bug in the compiler'

1:11 pstickne: oh, annotations work on . calls but not other stuff? :(

1:11 replaca: but a lot of lines of the form "clojure.lang.Compiler.analyze" aren't going to help me spell string any better!

1:11 pstickne: you can use them ahead of the symbol on a binding form

1:11 hiredman: pstickne: method calls are the places where hints are needed

1:12 pstickne: ((fn [#^String a] (+ a 2)) "foo") :(

1:12 replaca: pstickne: or "let"s

1:12 hiredman: ,:(

1:12 clojurebot: Invalid token: :

1:12 pstickne: vs. ((fn [#^String a] (.boogaboo a)) "foo")

1:12 hiredman: ,(keyword "(")

1:12 clojurebot: :(

1:12 * hiredman chorttles

1:12 pstickne: poor clojurebot :(

1:13 cconstantine: did he just frown?

1:13 pstickne: it looked lit it to me

1:13 *like

1:13 cconstantine: hehe

1:14 replaca: ,(keyword ")") ; let's keep it positive!

1:14 clojurebot: :)

1:14 Raynes: ,(keyword "p")

1:14 clojurebot: :p

1:14 no

1:14 cconstantine: no?

1:15 clojurebot: no, I was not frowning

1:15 pstickne: (elisa?)

1:15 replaca: hiredman: are you operating him behind the scenes?

1:15 Raynes: Yes.

1:16 He is trying to trip us out.

1:16 Were smarter than he previously expected.

1:16 Hurry quick, grab his wallet while he's in Clojurebot!

1:16 cconstantine: so, what's he difference between (lazy-seq (cons a b)) and (cons a (lazy-seq b)) ?

1:16 replaca: is it like "being John Malkovitch"?

1:16 hiredman: ,(doc lazy-seq)

1:16 clojurebot: "([& body]); Takes a body of expressions that returns an ISeq or nil, and yields a Seqable object that will invoke the body only the first time seq is called, and will cache the result and return it on all subsequent seq calls. Any closed over locals will be cleared prior to the tail call of body."

1:16 cmvkk: it's more like the wizard of oz.

1:17 hiredman: the body of the lazy-seq call is not evaluated until you call first on the lazy-seq

1:17 replaca: there was a great sppof someone did a long time ago where Richard Stallman was the wizard of oz

1:17 hiredman: generally you see (lazy-seq (cons a b)) with b being a call to the function that generates the lazy-seq

1:18 pstickne: replaca: "spoof"? ^^

1:18 hiredman: so it's sort of like a recursive function

1:19 cconstantine: hiredman: so... with (lazy-seq (cons a b)) both a and b are evaulated when first is called, and (cons a (lazy-seq b)) b is only evaulated on (rest)?

1:19 replaca: it was a usenet post mashing up Gibson and the wizard of oz

1:19 hiredman: cconstantine: nope, it would have to (first (rest ...))

1:20 on b

1:20 replaca: in the end it turns out that the reason the emerald city is green is because stallman only has only grayscale but he wired it up to the green channel

1:20 Raynes: http://vmkit.llvm.org/ This is neat.

1:20 hiredman: that is the main change between pre and post lazy

1:20 cconstantine: replaca: oh, I lived there awhile... it's green because everything is wet all the time and growing

1:21 pstickne: is there a nice way to make "case classes" or "discriminate types" in clojure? currently I am using {:kind blablah ...}

1:21 replaca: cconstantine: cconstantine you mean in oz or in seattle?

1:21 hiredman: ,(do (rest (cons :a (lazy-seq (prinln :foo))))) nil)

1:21 clojurebot: java.lang.Exception: Unable to resolve symbol: prinln in this context

1:21 cconstantine: replaca: seattle

1:22 hiredman: ,(do (rest (cons :a (lazy-seq (println :foo))))) nil)

1:22 clojurebot: ()

1:22 replaca: cconstantine: this was oz

1:22 cconstantine: replaca: ah

1:22 hiredman: ,(do (first (rest (cons :a (lazy-seq (println :foo)))))) nil)

1:22 clojurebot: :foo

1:22 cconstantine: replaca: sorry, I failed tracking

1:22 replaca: cconstantine: yellow brick road and all :-)

1:22 cconstantine: right

1:22 hiredman: ,(doc type)

1:22 clojurebot: "([x]); Returns the :type metadata of x, or its Class if none"

1:22 cconstantine: hiredman: ok, I'm gonna need to study those two things abit

1:23 hiredman: ,nil

1:23 clojurebot: DENIED

1:23 hiredman: hmmm

1:23 ,(do nil)

1:23 clojurebot: nil

1:24 pstickne: hiredman: :(

1:24 cconstantine: hiredman: so, either way you get a lazy sequence... right?

1:24 pstickne: ohh. hmm.

1:25 hiredman: cconstantine: lazy-seq on the outisde is fully lazy, cons on the outside is less lazy

1:25 cconstantine: hiredman: so cons on the outside might compute an extra s-expr?

1:26 hiredman: actually

1:26 pstickne: hiredman: sneaky.

1:27 hiredman: it would not matter two much, I think after the very firt element they behave the same

1:27 lazy-seq on the outside is definetly more consistent and the idomatic style

1:28 pstickne: hiredman: now I have to go and switch conj with merge :(

1:28 or at least flip the order

1:28 cconstantine: hiredman: on first inspection cons on the outside seems more straight forward to me

1:28 hiredman: cconstantine: cons on the outisde is more similar to the pre-fully-lazy style

1:28 cconstantine: hiredman: but I might still suffer from having a C style programming mind

1:29 hiredman: lazy-seq is a lazy layer that wraps your infinite list and makes it lazy

1:30 pstickne: okay, so now suppose I have a bunch of these hash-maps objects floating about. what is a good way to indicate that function x operates on that 'type'?

1:30 (or group)

1:30 hiredman: (defn F [n] (cons n (F (inc n))))

1:30 cconstantine: hiredman: ok

1:31 hiredman: F would create an infinte series of cons sells, but non-lazy

1:31 cconstantine: hiredman: that never returns on (f 1) right?

1:31 hiredman: (defn F [n] (lazy-seq (cons n (F (inc n)))))

1:31 cconstantine: yeah it goes foreaver

1:31 the new F is now lazy

1:32 but not the best example I think

1:32 pstickne: I think that makes sense.

1:32 It's similar to using delay/force.

1:32 cconstantine: ok... I can play with putting printlns in and doing first/rest combos on it

1:33 pstickne: lazy sequences are awesome for backtracking parsers :p

1:34 hiredman: the problem there is the (inc n) would happen when you call rest (I think) instead of ideally (first (rest ...))

1:35 or (seq (rest ...)) for that matter

1:35 cconstantine: oooo delay/force looks interesting

1:37 hiredman: ~def delay

1:38 interesting

1:38 I think lazy-seq uses the :once metadata too

1:39 cconstantine: lazy-seq claims to only evaluate (rest ...) (or maybe (first (rest ...)) ) once

1:39 hiredman: it evals first once

1:39 rest never evals anything

1:40 unless you do it less then right

1:40 ,(doc rest)

1:40 clojurebot: "([coll]); Returns a possibly empty seq of the items after the first. Calls seq on its argument."

1:40 hiredman: huh

1:40 ,(doc next)

1:40 clojurebot: "([coll]); Returns a seq of the items after the first. Calls seq on its argument. If there are no more items, returns nil."

1:40 hiredman: hmmmm

1:41 ,(class (rest (range 100)))

1:41 clojurebot: clojure.lang.Range

1:41 hiredman: ,(class (next (range 100)))

1:41 cconstantine: hahahah! if I leave the lazy-seq prime around it's super-fast the next time I used it :)

1:41 clojurebot: clojure.lang.Range

1:41 hiredman: cconstantine: yeah, well, it's cached

1:41 cconstantine: w00t :)

1:42 hiredman: ,(class (next (iterate inc 0)))

1:42 clojurebot: clojure.lang.Cons

1:42 cconstantine: and that cache.... could it ever cause java to run out of memory?

1:42 hiredman: ,(class (rest (iterate inc 0)))

1:42 clojurebot: clojure.lang.LazySeq

1:42 hiredman: hmmmm

1:42 cconstantine: like if I were to pre-cache primes on compile

1:42 hiredman: the docstring for rest apears to be off

1:42 cconstantine: well, of course the cache is in memory

1:43 so a large cache would use all the memory

1:43 cconstantine: hiredman: well.. normally caches have a fixed size and clean themselfs up when memory is needed for other things

1:44 or at the very least have a fixed size

1:45 hiredman: that is a behaviour of somethings called caches, but not a property needed to be a cache

1:45 in this case it means computed once, and held on to as long as a reference to the result exists

1:47 cconstantine: hiredman: ok... so if I keep it around as a var I could 'leak' memory

1:48 hiredman: not leak

1:48 it's there, you have a reference to it, you can get to it

1:48 cconstantine: leak in the sense that it's memory thats set aside for something. If that thing is never used....

1:49 you're right... not leaked in the strict sense

1:49 hiredman: if the seq is never used then, being a lazy-seq, it be there

1:50 er

1:50 it won't

1:50 but if you are using a lazy infinite seq, it is best not to hang on to the head of the seq

1:50 cconstantine: I'm thinking: I could pre-cache a bunch of primes at compile-time and make the prime generator seem really fast at runtime

1:51 hiredman: cconstantine: type out a bunch of primes in a list then concat that with a lazy-seq of primes

1:52 cconstantine: yeah

1:52 hiredman: ,(concant '(1 2 3 4) (take 5 (iterate inc 5)))

1:52 clojurebot: java.lang.Exception: Unable to resolve symbol: concant in this context

1:52 hiredman: ,(concat '(1 2 3 4) (take 5 (iterate inc 5)))

1:52 clojurebot: (1 2 3 4 5 6 7 8 9)

1:53 hiredman: prime the pump so to speak

1:53 cconstantine: hehe, yeah :)

1:55 would it be cheating to say... precompute the solution to http://projecteuler.net/index.php?section=problems&id=3 at compile time and claim it's super-fast because it only has to do a cache lookup at runtime?

1:56 Raynes: Why do people have to complain about parentheses so much?

1:56 It's annoying.

1:56 No worse than 10 thousand curly braces in a 3 thousand line file. :|

1:57 cconstantine: Raynes: I think it's fair to say there are no more parens than (+ parens curlies) in C

1:57 zakwilson: They don't know what it is they're looking at.

1:57 Raynes: cconstantine: Huh?

1:57 zakwilson: Explaining that *everything* is an expression that has a value might help.

1:58 cconstantine: Raynes: if you were to count all the parentheses and curly braces in a C program, and count the parentheses in a similar lisp program you would get roughly the same number

1:59 Raynes: Considering the lines you would save writing the program in Clojure, that might be true.

2:01 "I was flirting a bit with the ??? and looking at Clojure. While I am not that impressed (LFE is better :-)) there was some interesting stuff in the Rationale:..."

2:01 I can't figure out what the ??? is :(

2:02 replaca: LFE == Lisp Flavored Erlang here?

2:03 Raynes: Yes.

2:03 hiredman: no

2:03 Raynes: Was from the Erlang mailing list.

2:03 I stalk them sometimes.

2:03 hiredman: mostly it has been used to mean left-fold-enumerator

2:03 * Raynes pokes hiredman

2:04 hiredman: Raynes is relatively new and may have missed that

2:04 at one point rhickey was looking at LFEs for safe resource consumption in clojure

2:05 replaca: ahh

2:05 hiredman: but I think he decided that is was to complex to expect people to use

2:05 scopes are the future, but they are not in trunk yet

2:05 ~scopes

2:05 clojurebot: Gabh mo leithsc�al?

2:06 hiredman: ~scope

2:06 clojurebot: scope is at http://paste.lisp.org/display/73838

2:06 Raynes: hiredman: Where is your "Thank you rich!" in my group post? I don't know your real name.

2:08 hiredman: Raynes: /whois hiredman

2:08 Raynes: Of you suck.

2:08 Oh*

2:09 hiredman: ...

2:09 cconstantine: I really don't understand that scope thing

2:10 hiredman: cconstantine: the idea is you can register things to be run when you exit the dynamic scope of the (scope ...)

2:11 pstickne: (so it's stack-based like 'with' or 'using'?)

2:11 cconstantine: ah, I see

2:11 hiredman: you can register things to run if you exit with no exceptions thrown, or with exceptions thrown

2:11 Raynes: Oh that's cool.

2:11 hiredman: or regardless

2:11 pstickne: hiredman: isn't it just a special-form of try-catch? or can you bind events later?

2:11 hiredman: pstickne: later...?

2:11 pstickne: (which would be more akin to obj-c autorelease-pools)

2:12 sure :)

2:12 hiredman: so you could make a function open-file which would attach close file to the enclosing scope, and throw an error if not used in a file

2:12 er

2:12 not used in a scope

2:13 pstickne: why not just (open-file [do stuff here]) ?

2:13 hiredman: pstickne: scope is more general

2:13 pstickne: ruby has that idiom: open("foo") {|f| use_f_here} # f closed here

2:14 hiredman: scope would allow you to put resource clean up inside the function that creates the resource

2:14 pstickne: like open-file (macro)

2:14 or fn-caller

2:14 hiredman: erm

2:14 I do not believe so

2:15 pstickne: imagine: (open-resource function-to-call)

2:15 hiredman: and what does that do?

2:15 what does it return?

2:15 pstickne: then open-resource opens and closes the resource (this is a non-dynamic stack-based scope)

2:15 hiredman: what function-to-call does

2:16 hiredman: hmmm

2:16 scope still seems nice

2:16 nicer

2:16 pstickne: needless to say, it's not good for resources opened here and used there :p

2:17 slashus2: The duck stream reader from contrib is really nice.

2:17 pstickne: slashus2: what does it do?

2:17 slashus2: very useful

2:18 hiredman: it helps with dealing with all of javas various IO classes

2:18 pstickne: hiredman: if you had a more dynamic scope, maybe ... (scope .... (attach cleanup) ...);

2:18 oh, not Java IO :(

2:18 hiredman: pstickne: uh, that is exactly what scope does

2:18 pstickne: then like obj-c autorelease pools :p

2:19 hiredman: (defn open-file [f] ... (when-scope :exits (.close f))) (scope do stuff (open-file "foo") do more stuff)

2:20 replaca: Q: How do I hint a "char[]"? #^Character[] doesn't seem to do what I want.

2:20 hiredman: ,(into-array Character/TYPE [\a \b])

2:20 clojurebot: #<char[] [C@965654>

2:20 slashus2: pstickne: reader from duck-streams: Attempts to coerce its argument into an open java.io.BufferedReader. Argument may be an instance of Reader, BufferedReader, InputStream, File, URI, URL, or String.

2:21 hiredman: ,(class (into-array Character/TYPE [\a \b]))

2:21 clojurebot: [C

2:21 Chairos: I understand clojure-contrib has a sql library? Do you have to write your own sql as strings, or can you write sql in clojure, and thus manipulate the query structure easily with code?

2:21 replaca: hiredman: are you saying I've got to convert it and then it will know?

2:21 hiredman: Chairos: you what clojureql, which is not in contrib

2:22 ~clojureql

2:22 clojurebot: clojureql is a quite impressive piece of work

2:22 pstickne: slashus2: crazy :)

2:22 hiredman: bah

2:22 ~clojureql

2:22 clojurebot: clojureql is http://github.com/Lau-of-DK/clojureql/tree/master

2:22 replaca: hiredman: but if I'm in this routine, it should already be a char[]

2:22 hiredman: replaca: I am saying nothing

2:22 replaca: oh, ok

2:22 hiredman: just doodling on the wall

2:23 Chairos: aha

2:23 my googling didn't find that

2:23 excellent

2:23 hiredman: replaca: I would ask, why type hint it as Character[] if it is a char[]

2:23 I think there was a thread about type hinting arrays on the group

2:24 replaca: cause the compolier pukes all over #^char or #^char[]

2:24 hiredman: try [C

2:24 replaca: I asked the same thing of myself :-)

2:24 I did, the compiler really hates that!

2:24 slashus2: replaca: does #^chars work?

2:24 replaca: but maybe if I put it in a map

2:25 slashus2: 1 sec, let me try

2:26 slashus2 wins the prize! I never would have guessed that. :-)

2:26 slashus2: thanks!

2:26 slashus2: yey

2:26 * cconstantine wonders what the prize is.

2:26 slashus2: replaca: It works with #^floats #^strings I think too among others.

2:27 I don't know about strings :-|

2:27 pstickne: (type #^{:type :x} (struct-map x :foo :bar)) ;-(

2:27 replaca: slashus2: hmm, doesn't seem right somehow.

2:27 #^String

2:27 pstickne: that returns a PersistentStructMap -- why?

2:27 replaca: I've got that all over

2:27 hiredman: ,(type #^{:type :x} (struct-map x :foo :bar))

2:27 clojurebot: java.lang.Exception: Unable to resolve symbol: x in this context

2:28 hiredman: ,(type #^{:type :x} {:a :b})

2:28 clojurebot: :x

2:28 pstickne: ,(type #^{:type :baz} (struct-map (defstruct x :foo) :foo :bar))

2:28 clojurebot: DENIED

2:28 pstickne: :(

2:29 slashus2: replaca: from http://clojure.org/java_interop -> Type hints for primitive arrays - #^ints, #^floats, #^longs, #^doubles

2:30 pstickne: ,(type #^{:type :baz} (struct-map (create-struct :foo) :foo :bar))

2:30 clojurebot: clojure.lang.PersistentStructMap

2:30 hiredman: ,(let [a (struct-map (create-struct :foo) :foo :bar)] (type #^{:type :x} a))

2:30 clojurebot: clojure.lang.PersistentStructMap

2:31 hiredman: ,(let [a (struct-map (create-struct :foo) :foo :bar)] (type (with-meta a {:type :x}))

2:31 clojurebot: EOF while reading

2:31 hiredman: ,(let [a (struct-map (create-struct :foo) :foo :bar)] (type (with-meta a {:type :x})))

2:31 clojurebot: :x

2:31 pstickne: I was kind of hoping create/def struct would attach some semblance of a type by default too :(

2:31 hiredman: *shrug*

2:31 pstickne: (heck, I don't even know why I am using them :-)

2:31 "it's all just maps" I suppose

2:32 replaca: slashus2: wow, that was two lines down off the bottom of my browser (since I was looking at the type tag section just above.) :-)

2:32 hiredman: ,(meta #^{:type :x} (struct-map x :foo :bar))

2:32 clojurebot: java.lang.Exception: Unable to resolve symbol: x in this context

2:33 hiredman: ,(meta #^{:type :x} (struct-map (create-struct :foo) :foo :bar))

2:33 clojurebot: nil

2:33 hiredman: ,(meta (with-meta (struct-map (create-struct :foo) :foo :bar) {:type :x}))

2:33 clojurebot: {:type :x}

2:33 hiredman: *shrug*

2:33 nascent16: i'm bit of a lisp newbie, but let's say I want to have a database api that doesn't define its operating functions until we're told that we're acting on a particular api, so like (db/use "mydb.db" (put key value) (println (get key))) would print the value i stored

2:34 pstickne: hiredman: is using meta for this purpose "good"?

2:35 nascent16: i think i need to use a macro for "db/use" since the db/get and db/put functions wouldn't be defined at parse time

2:35 hiredman: pstickne: what purpose?

2:36 nascent16: / is used for namespaces in clojure

2:37 but sure

2:37 you can do that

2:37 nascent16: hiredman: i know, i'm putting all these in a namespace

2:37 ok

2:37 hiredman: it;s kind of silly though

2:37 nascent16: yeah?

2:37 pstickne: hiredman: tell different object-types apart :p

2:38 hiredman: pstickne: that is the whole reason the type function exists

2:38 so it can be used this way

2:38 nascent16: get and put may as well be functions

2:38 pstickne: I need to understand the entire object system in clojure better :(

2:39 hiredman: pstickne: this is my clojure object system: ick, no

2:39 pstickne: Is there a multi-method or something else dispatched on type to add 'custom' printers?

2:39 hiredman: :(

2:39 hiredman: yeah

2:39 nascent16: hiredman: that's what i have right now, db/get and db/put are functions, but they aren't defined until db/use is called so that they can be bound to a database object with let

2:39 hiredman: ,(doc print-method)

2:39 clojurebot: "; "

2:39 hiredman: ~def print-method

2:40 slashus2: no doc :-(

2:40 replaca: Ah, a night spent with type tags just double the speed of the pretty printer. Yay!

2:40 hiredman: I think it's print-method

2:40 pstickne: yeah :)

2:40 but I have no idea what writer is supposed to be :-/

2:41 replaca: I think it's supposed to be any java.io.Writer

2:41 like *out*

2:42 hiredman: ,(class *out*)

2:42 clojurebot: java.io.StringWriter

2:42 replaca: that's because clojurebot has it bound

2:42 hiredman: at the repl it is a java.io.OutputStreamWriter

2:42 nascent16: so what i have now is (defmacro use ([database & expressions] `(let [db (<open database stuff>)] (defn put ....) (defn get....) (do expressions))))

2:42 but that doesn't work

2:43 replaca: and in Slime it's a proxy

2:43 nascent16: Unable to resolve symbol: db in this context

2:43 hiredman: ugh

2:43 don't use defn

2:44 you you have a set or parens you would only need you where writing a multimethod

2:44 or multifn I should say

2:44 pstickne: yay! my first method dispatch!

2:45 hiredman: nascent16: you have picked a bad first macro

2:45 pstickne: hiredman: so you're not a fan of the clojure of the hierarchy and all?

2:45 nascent16: haha

2:46 hiredman: pstickne: I haven't used it

2:46 it annoys me to see trying to implememnt an oop system on top of clojure

2:47 pstickne: barring some performance reasons and possibly a place to collect some documentation, is there a reason for structures? (e.g. am I missing something crucial?)

2:47 hiredman: nascent16: you are going to need to do stuff like symbol capturing and what not

2:47 pstickne: hiredman: multi-dispatch is OO by default :p

2:47 replaca: pstickne: that's basically it

2:47 slashus2: polymorphism

2:47 hiredman: pstickne: uh clojure's multi-dsispatch can dispatch on any function

2:48 up to and including the time of day

2:48 slashus2: polymorphism is just a subset of features within the OO paradigm

2:48 just one*

2:48 pstickne: hiredman: so you'd say it offers polymorphic behavior capabilities based upon abstract data types? ;-)

2:48 hiredman: slashus2: OO is a subset of polymorphism

2:48 replaca: a nice thing in clojure is that you can pick nd choose the OO features you want

2:49 pstickne: not if you're dealing with Java :)

2:49 slashus2: hiredman: You know what I meant. Just said it backward.

2:49 pstickne: (which is the white elephant)

2:49 nascent16: hiredman: interesting. meaning, i have no idea what that means. off to google for a bit :)

2:50 hiredman: pstickne: we aren't dealing with java, we are dealing with clojure's multimethods

2:57 pstickne: is all meta information forever kept with an object?

2:57 hiredman: ~def c.l.IMeta

2:59 ,(let [x {} y (with-meta x {})] (identical? x y))

2:59 clojurebot: false

2:59 hiredman: I think adding metadata makes a new object, so removing would too

3:00 ,(let [x {} y (with-meta x {})] (= x y))

3:00 clojurebot: true

3:00 slashus2: ,(let [x {} y (with-meta x {}) z y] (identical? y z))

3:00 clojurebot: true

3:01 hiredman: well

3:01 duh

3:01 slashus2: I thought I was doing something else there.

3:04 hiredman: minding the shop without Chouser makes me nervous, he should have corrected me about something by now

3:15 replaca: time for sleep. G'night all!

3:22 hiredman: ,(int \?)

3:22 clojurebot: 601

3:25 cmvkk: that's a pretty high number for a character

3:26 hiredman: ,(char 345)

3:26 clojurebot: \?

3:26 hiredman: ,(char 1342)

3:26 clojurebot: \?

3:26 cmvkk: is it unicode?

3:27 ,(char 0xAC00)

3:27 clojurebot: \?

3:27 hiredman: java is unicode, so is clojure

3:27 cmvkk: hmm, so it is.

3:27 hiredman: wow

3:27 I didn't know unicode had korean as vowel consonant pairs

3:27 er, consonant vowel

3:27 p_l: hiredman: try some of the combining characters :D

3:27 cmvkk: it has all the syllables. it would be really hard to write otherwise...

3:27 hiredman: I guess it would have to

3:27 cmvkk: ,(char 0xAC01)

3:27 clojurebot: \?

3:28 hiredman: gak

3:28 gahk?

3:28 cmvkk: and the best part is, all the vowels/consonants are at deliberate intervals. so if you know the constituent parts of the syllable, you can figure out the code by math.\

3:28 hiredman: gahg

3:28 interesting

3:28 cmvkk: ,(char (+ 0xAC00 0x1B))

3:28 clojurebot: \?

3:29 cmvkk: ,(char (+ 0xAC00 0x1C))

3:29 clojurebot: \?

3:29 hiredman: cute

3:31 I guess someone had their thinking cap on

3:32 cmvkk: it takes up more space that way i guess. various combinations don't actually exist, so their codes just have blank spaces or whatever

3:36 nascent16: Ok, I learned all about symbol capture, but now I have new problems :)

3:37 let's say i want to use a java class in a macro ie: (import '(tokyocabinet HDB)) (defmacro open ([file] (let [db (HDB.)] .....)))

3:37 waith

3:37 that's not right

3:38 (import '(tokyocabinet HDB)) (defmacro open ([file] `(let [db (~HDB.)] .....)))

3:38 that complains that the class cannot be found

3:40 but HDB is defined, I can print it out

3:40 it doesn't let me construct a new one though

3:40 hiredman: (~HDB.)

3:40 cmvkk: not sure why you need a ~ there

3:40 hiredman: that is not right

3:40 nascent16: ok

3:41 don't i need the ~ to refer to a symbol that was defined outside of my macro?

3:41 hiredman: also you are putting extra parens around your macro body

3:41 well

3:41 cmvkk: hiredman it might be multiple arity

3:41 hiredman: around the arglist and body

3:41 cmvkk: care to make a wager?

3:41 cmvkk: well i don't know...that's how it would look

3:41 hiredman: yes, that is why he doesn't get an error

3:42 but it is incorrect, and should corrected before too long

3:42 slashus2: db#

3:43 nascent16: yeah, you also need to do db#, sorry

3:43 but that doesn't solve the ClassNotFound thing with HDB

3:43 cmvkk: did you try it without the ~

3:43 nascent16: yeah, same error... wasn't expecting that

3:43 cmvkk: hmm

3:43 Raynes: I have a Bologna and Banana pepper sandwich with yellow mustard.

3:43 nascent16: oh wait

3:44 nope

3:44 i'm an idiot

3:44 hiredman: nascent16: does (HDB.) work on the repl?

3:44 nascent16: it does outside of a macro

3:44 hiredman: nascent16: pastebin your whole macro

3:44 lisppaste8: url?

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

3:44 nascent16: sweet, it works without the "~"

3:45 hiredman: nascent16: you need to remove some parens

3:45 nascent16: i did

3:45 hiredman: or you should

3:45 good

3:45 p_l: oo, there's a tokyocabinet binding for java? :)

3:46 hiredman: when writing macros I often find it is easier to write a function that returns a data structure first

3:46 and then when the data structure is the corrent form, switch to a macro

3:47 cmvkk: hiredman isn't it easier to just use macroexpand

3:47 especially when you expect your input to not be evaluated

3:47 hiredman: cmvkk: sometimes

3:47 nascent16: p_l: there is, it's part of the tokyocabinet project

3:47 hiredman: depends on the situation

3:47 nascent16: http://pastebin.com/mba6a8a0

3:47 hiredman: I often end up with helper functions

3:47 (for the macor)

3:47 nascent16: now it's giving me a " Can't refer to qualified var that doesn't exist"

3:48 Raynes: nascent16: Don't use pastebin.com use http://paste.lisp.org/new/clojure (there is a reason ;) )

3:49 cmvkk: you probably don't want to import your class inside the expander code

3:49 hiredman: nascent16: lets see the whole exception

3:49 lisppaste8: nascent16 pasted "tokyo" at http://paste.lisp.org/display/77412

3:50 nascent16: hiredman: on the repl, i only get one line: java.lang.Exception: Can't refer to qualified var that doesn't exist (NO_SOURCE_FILE:2)

3:51 slashus2: nascent16: put ~'[key value] and ~'[key]

3:51 nascent16: Raynes: that pastebin thing is pretty cool

3:51 slashus2: ah, that makes sense

3:51 hiredman: ~google tokyocabinet

3:51 clojurebot: First, out of 12800 results is:

3:51 ??????????? Tokyo Cabinet

3:51 http://tokyocabinet.sourceforge.net/

3:53 nascent16: for those of us who don't know japanese: tokyocabinet.sourceforge.net/spex-en.html

3:53 hiredman: and you are closing the database

3:53 oh

3:54 do ~@body

3:54 ugh

3:54 don't use defn in there

3:54 nascent16: ok

3:54 what should i use?

3:54 hiredman: (let [get (fn ...)])

3:54 like that

3:55 you will need to ~'get

3:56 nascent16: I think you would be better off just writing a wrapper around with-open

3:56 nascent16: with-open eh

3:56 hiredman: that opens the database and binds *db* to a hdb instance

3:56 slashus2: This is probably a terrible example (defmacro add-them [] `(defn addum ~'[one two] ~'(+ one two)))

3:56 hiredman: and then get and put just normal functions that read from *db*

3:58 nascent16: hmm, that doesn't seem cleaner to me... what if i have multiple threads reading from multiple databases? they would step on each other, wouldn't they?

3:59 hiredman: uh

3:59 no

3:59 well, that depends on the library

4:00 the way you are writting it would not help with multithreading if the java lib you are using doesn't handle multithreading

4:00 nascent16: i'm just talking about the clojure side

4:00 hiredman: ~def with-open

4:03 nascent16: ok, i think with-open looks like a solid starting point

4:03 thanks

4:04 lisppaste8: hiredman annotated #77412 "using with-open" at http://paste.lisp.org/display/77412#1

4:05 hiredman: something like that, much simpler

4:05 slashus2: hiredman: Is this the correct way to do this, or is there a better way? (defmacro add-them [third] `(defn addum [~'one ~'two] (+ ~'one ~'two ~third))) I am just playing around.

4:05 hiredman: uh

4:05 slashus2: Just doing ~'[one two] seems to work at the last

4:06 hiredman: that is sick

4:07 (defmacro add-them [third] `(defn addnum [one# two#] (+ one# two# ~third)))

4:07 capturing symbols with ~' is to avoided

4:07 use gensyms

4:07 ,`one#

4:07 clojurebot: one__1989__auto__

4:07 slashus2: I was looking at some code in compojure

4:08 nascent16: hiredman: that does look better... quite nifty actually

4:08 hiredman: I must warn you, I have no idea if it works

4:09 slashus2: hiredman: The code I was looking at in compojure changed from using ~' to using autogensyms

4:09 hiredman: good

4:09 nascent16: haha, well i can find that out pretty quickly

4:13 hiredman: come to think of it, you may runto issues with clojure's use macro

4:13 ,(doc use)

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

4:13 slashus2: hiredman: http://tinyurl.com/cpqoon <-- at the bottom of the stable version of compojure defservice

4:13 I was looking at that as an example. That is why I wrote my code the way I did, but I see that it is changed in the development branch.

4:14 hiredman: well, there are times when you want to capturing a symbol like what I just did

4:25 nascent16: hiredman: you did ~body instead of ~@body... any particular reason?

4:29 lisppaste8: nascent16 annotated #77412 "with-open version that works" at http://paste.lisp.org/display/77412#2

4:29 nascent16: the only changes i really needed were to use ~@body and to use backtick instead of quote for getting at *db*

4:49 hiredman: nascent16: not paying close enough attention

7:33 melwin: Hello...? Sorry, may I ask - what's the clojuromatic way of defining function-local function definitions? Is it with let and fn? As in reduced example: (defn x [] (let [fun (fn [] 1)] (fun)))

7:37 Carke: right that's how it's done

7:38 melwin: Cool, thanks a lot.

7:38 te: Lau_of_DK: We need to talk

7:38 Lau_of_DK: you registered Clabango! /me stabs you

7:38 Lau_of_DK: I was totally going to grab that

7:38 Lau_of_DK: Clabango.com, or Github?

7:39 te: Clabango.com

7:39 both gave me a laugh by the way

7:39 :)

7:39 Lau_of_DK: Yea me too - Its pjstadig you should be angry with though :)

7:39 te: That bastard

7:39 Lau_of_DK: ~ it was feeling all ready to buy it, when suddenly...

7:39 te: Clabango is such a great name

7:39 clojurebot: CLABANGO!

7:40 te: It's light-hearted, memorable, it's a verb

7:41 it's like twitter, only with less sexual connotations

7:41 im sorry but from the first time i heard "twitter", i thought of "diddling"

7:41 it's a crappy name IMO

9:58 hjlee: ,(doc doc)

9:58 clojurebot: "([name]); Prints documentation for a var or special form given its name"

11:10 * Chouse1 settles in for the ilc tutorial.

11:11 digash`: Chouser_: hi, i am the guy in the front row.

11:16 Chouser_: digash`: hi

11:44 Mec: is it faster during runtime to use macros over functions?

11:46 Chouser_: probably, but you're second-guessing hotspot

11:47 don't use a macro for only that reason without profiling and demonstrating it actually helps.

11:47 and if you do find it helps, consider definline

11:47 Mec: ok

11:57 will a :while break an entire for expression or just the nearest loop it's placed to

11:58 Chouser_: nearest (and sub) loop

11:58 Mec: excelent

12:01 digash`: ,(def *bla* (ref []))

12:01 clojurebot: DENIED

12:01 digash`: ,`[~ @*bla*]

12:01 clojurebot: java.lang.Exception: Unable to resolve symbol: *bla* in this context

12:02 Chouser_: ,(let [x (atom 5)] `(do ~@x))

12:02 clojurebot: java.lang.IllegalArgumentException: Don't know how to create ISeq from: Atom

12:02 Chouser_: ,(let [x (atom 5)] `(do ~ @x))

12:02 clojurebot: (do 5)

12:02 digash`: Chouser_: cool

12:02 Chouser_: brilliant -- hadn't occurred to me.

12:03 thickey_: i like that clojurebot is helping during the presentation!

12:06 Mec: hmm a macro expanding to (when true (if true ...)) doesnt seem right

12:07 digash`: ,(let [x (atom 5)] `(do ~,@x))

12:07 clojurebot: (do 5)

12:07 digash`: :)

12:07 Chouser_: heh

12:08 Mec: which macro?

12:08 Mec: ,(macroexpand '(for [a (range 5)] a))

12:08 clojurebot: (let* [iter__4470__auto__ (clojure.core/fn iter__2021 [s__2022] (clojure.core/lazy-seq (clojure.core/loop [s__2022 s__2022] (clojure.core/when-first [a s__2022] (clojure.core/cons a (iter__2021 (clojure.core/rest s__2022)))))))] (iter__4470__auto__ (range 5)))

12:08 Chouser_: Mec: or perhaps more importantly, which version of ... yeah.

12:08 Mec: looks like the newer version doesnt

12:09 bleh i want the newer version but i'm really not looking forward to realearning lazy sequences

12:12 Chouser_: ,(get '{a 1 a 2 a 3 a 4 a 5 a 6 a 7 a 8} 'a)

12:12 clojurebot: 1

12:12 Chouser_: ,(get '{a 1 a 2 a 3 a 4 a 5 a 6 a 7 a 8 a 9} 'a)

12:12 clojurebot: 9

12:13 Chouser_: don't rely on that, by the way, not that I know how you could.

12:15 Mec: well that's bizare, i thought the last occurances was always taken

12:16 Chouser_: ,(class '{a 1 a 2 a 3 a 4 a 5 a 6 a 7 a 8})

12:16 clojurebot: clojure.lang.PersistentArrayMap

12:16 Chouser_: ,(class '{a 1 a 2 a 3 a 4 a 5 a 6 a 7 a 8 a 9})

12:16 clojurebot: clojure.lang.PersistentArrayMap

12:16 Chouser_: hm

12:17 anyway, arraymaps act slightly differently than hashmaps, but not in any way that you should rely on.

12:19 Mec: huh, i thought {} was for hashmaps, hadnt even heard of arraymaps till now

12:21 mgarriss: getting this error (using slime mode in emacs for clojure): Exception in thread "Swank REPL Thread" java.lang.VerifyError: Cannot inherit from final class

12:25 Mec: which clojure page is most up to date? lazy lazier lazier1

12:26 thickey_: Mec: lazy

12:26 Mec: thanks

12:26 StartsWithK: should every future deref go in try block? http://paste.pocoo.org/show/109046/ so it prevents cancellation exceptions

12:30 Chouser_: StartsWithK: like agent actions?

12:32 fanda: hello all!

12:32 just a small suggestion: genclass.clj in src\clj\clojure\

12:32 would be nicer if renamed to core_genclass.clj since it is loaded by core and to maintain consistency with print and proxy

12:32 StartsWithK: Chouser: yes, agent does .cancle on future before its done, and @f then fails, this will not fail if i do (.cancle f false)

12:32 el*

12:34 fanda: otherwise all other libraries have correctly non-core names :-)

12:35 StartsWithK: what im trying to do is, i create a future, then you can deref it or not, but if you don't and i create another future, i would like to cancel the one no one needed and replace it with a new one

12:35 Chouser_: fanda: you're just talking about the file name?

12:36 fanda: yes, just the file name

12:36 nothing big :-)

12:36 for the sake of symmetry, i guess

12:47 digash`: ,`()

12:59 SethTisue: hi. does the clojure REPL have something like Common Lisp's *, **, *** for accessing the results of the forms you just typed?

13:00 StartsWithK: *1, *2, *3

13:00 SethTisue: great, it works, thanks

13:00 Mec: what would commonlisp make of (* * *)

13:01 SethTisue: that would work since it's a Lisp-2

13:01 I'm at the Clojure tutorial Rich is giving at the International Lisp Conference. trying stuff out

13:01 Mec: what if the last result was a function tho would it call multiply or the result

13:02 te: SethTisue: cool

13:02 SethTisue: it would call multiply. in CL the function namespace is separate from the namespace for variables

13:03 te: SethTisue: what is CL?

13:03 Mec: commonlisp

13:03 p_l: te: Common Lisp

13:03 pstickne: Complicated Lisp

13:03 :)

13:03 Mec: lol

13:03 te: lol I kid

13:03 What is this CL everyone keeps going on about?

13:04 Mec: i dunno that id care for a lisp-2

13:04 te: Coronal Lobotomy?

13:04 p_l: te: Your speech doesn't not compute, please specify continuation: 1) troll 2) genuine question

13:04 te: 1

13:05 Mec: doesnt not?

13:05 te: does not*

13:05 SethTisue: I was hoping I could type a form into the repl and then ask to see the disassembled bytecode the compiler generated

13:06 p_l: Mec: computation failure ;-)

13:06 SethTisue: Rich told me I need to use the AOT compiler and then use javap to get the disassembly

13:06 before I write a little script that does that

13:06 does anyone have one lying around?

13:06 te: SethTisue: You're motivated

13:08 SethTisue: You scare me

13:10 cconstantine: I'm getting a 'java.lang.OutOfMemoryError: GC overhead limit exceeded' from my clojure program.... does that mean I'm doing things horribly wrong?

13:10 Mec: are you keeping around the head of an infinite sequence while processing it?

13:11 ,`()

13:11 cconstantine: Mec: Nope

13:11 SethTisue: haha, someone just reported the r1337 bug to Rich about 10 minutes ago

13:11 1337 is a good bug number

13:11 Mec: cconstantine: thats usually what im guilty of :D

13:11 SethTisue: I mean revision number

13:11 cmvkk: man i noticed we were coming up on that

13:12 cconstantine: Mec: It's just a lot of fast-running lazy sequences

13:12 cmvkk: are you actually at this thing, SethTisue? like in a room IRCing it up with us over wi-fi?

13:13 SethTisue: y

13:13 lunch break

13:18 cconstantine: Is it possible that I'm allocating faster than the GC can clean it up?

13:19 cmvkk: it doesn't seem likely

13:20 the GC will run when necessary, stopping the program to do so.

13:21 cconstantine: ok

13:22 cmvkk: on the other hand:

13:22 "

13:22 The parallel collector will throw an OutOfMemoryError if too much time is being spent in garbage collection: if more than 98% of the total time is spent in garbage collection and less than 2% of the heap is recovered, an OutOfMemoryError will be thrown."

13:22 what exactly is your program doing?

13:23 cconstantine: remember my counter thing from yesterday?

13:23 cmvkk: kind of

13:24 lisppaste8: cconstantine pasted "Prime seive" at http://paste.lisp.org/display/77421

13:24 cconstantine: it's a lazy sequence like range

13:25 I've created a lazy sequence of primes, and each prime found means a new counter is created and put in the seive

13:26 cmvkk: so you're allocating an object for every prime

13:26 cconstantine: yeah, every prime is a cons

13:28 SethTisue: sound like someone's working on Project Euler

13:30 cmvkk: each prime is a lazy-seq, and maybe you're holding onto the head of that from the hash map? i can't tell

13:30 cconstantine: SethTisue: hehe, yeah. using it to learn clojure

13:31 cmvkk: could this be a (lazy-seq (cons ...)) vs. (cons (lazy-seq ...)) thing?

13:32 cmvkk: i don't think so...a variation there wouldn't cause an out of memory error

13:32 or at least i can't think of why it would

13:32 pstickne: in a defmethod, is there a way to "match any"?

13:33 Chouser_: :default

13:33 pstickne: thanks

13:35 cmvkk: are you replacing every seive in your hash map, though?

13:35 cconstantine: cmvkk: I should be

13:35 cmvkk: if not, then the hash map is holding on to the heads of all those lazy-seqs.

13:36 cconstantine: the hash-map is just a set of counters for every previous known prime, the key being the first number in the seq

13:36 cmvkk: right. so as you go along, you're checking every counter in the map to see if it contains your current prime candidate?

13:37 cconstantine: cmvkk: just the lowest

13:37 cmvkk: just the lowest counter? does that work?

13:38 cconstantine: it should?

13:38 cmvkk: i'll take your word for it, i don't know anything about this algorithm

13:39 but you should look into making sure you aren't expanding those counters while holding the head.

13:39 cconstantine: I've experimented with remembering the head of the primes lazy-seq and I can watch the java process eat progressively more memory. I"m not seeing what I pasted eat more memory

13:39 pstickne: is there a way to bind the value of a matcher (e.g. :default) to a variable?

13:40 cmvkk: cconstantine: and the fact that it's not an 'out of heap space' error, but a 'GC overhead limit' error seems suspicious

13:40 thickey_: ilc: should he not be using map as a symbol there?

13:40 cconstantine: cmvkk: yeah, if it was just a "no more memory" kinda thing that would be one thing

13:42 Chouser_: thickey_: nor 'keys' nor 'vals', I would think

13:42 thickey_: Chouser_: thanks

13:42 pstickne: oh, dear :(

13:43 default doesn't work in compound matcher?

13:43 Chouser_: pstickne: right. known issue

13:43 pstickne: :-/

13:43 best work-arounds?

13:44 cconstantine: cmvkk: This is a standard seive, execpt that instead of marking/removing non-primes in an array of numbers, I'm keeping a counter around for each prime.

13:44 pstickne: wow. *sniff*

13:44 Chouser_: pstickne: http://groups.google.com/group/clojure/browse_thread/thread/9793367d342fd2ce

13:45 eee: e includes the original list, too?

13:45 Chouser_: eee: ilc slides?

13:45 pnkfelix: ilc: d not bound in 3rd ex?

13:46 eee: yeah, slides

13:46 thickey_: pnkfelix: correct

13:46 eee: seems counter intuitive to english . . .but useful

13:46 pstickne: *sigh*

13:46 this makes multi-dispatch almost worthless to me :(

13:47 eee: would have thought it would be a litst with a b c d

13:49 scgilardi: http://home.pipeline.com/~hbaker1/ObjectIdentity.html

13:49 SethTisue: btw the ILC tutorial slides are at http://clojure.googlegroups.com/web/tutorial.pdf

13:49 slashus2: pstickne: Use derive

13:49 from Programming Clojure: (derive ::Savings ::Account) (derive ::Checking ::Account)

13:51 pstickne: slashus2: I don't think it makes sense here. I have {:type :unary :op ...} and {:type :binary :op ...} and a defmulti expr-op

13:51 Chouser_: (derive ::any ::unary)

13:52 pstickne: I do see how this helps :(

13:52 I was wanting to match (defmethod expr-op [:binary :default] [expr] (bin-lookup (expr :op)))

13:53 in this case I could reduce the scope of the match,

13:53 eee: is he saying "nil punting?"

13:53 thickey_: nil punning

13:53 pstickne: but then (defmethod expr-op [:unary "-"] [_] -) doesn't work

13:54 slashus2: pstickne: What does your defmulti definition look like

13:54 pstickne: (defmulti op-lookup (fn [expr] [(type expr) (expr :op)])) ;- non-working way

13:55 eee: i just googled nil-punning. anyone got a quick definition?

13:56 pstickne: (I've been using expr-op in place of op-lookup in the channel)

13:56 pnkfelix: I infer its CL's use of nil to denote many different conditions, dep on context

13:56 SethTisue: I think it refers to code that to be a little more concise assumes an empty list (or sequence, I guess? don't understand the sequence stuff yet) counts as false in a boolean context

13:57 thickey_: he will probably touch on nil punning again

13:57 Mec: how big can the heap space grow? i've had out of memory errors without getting anywhere close to actually being out of memory

13:57 Chouser_: slashus2: I describe a bit of it here: http://blog.n01se.net/?p=39

13:58 eee: does (seq eos) mean empty list?

13:58 Chouser_: Mec: java has command-line args to set memory limits

13:58 eee: ,(println "hello")

13:58 clojurebot: hello

13:58 eee: ,(println first '(1 2))

13:59 clojurebot: #<core$first__3090 clojure.core$first__3090@d81cda> (1 2)

13:59 eee: ,(println (first [1 2]))

13:59 clojurebot: 1

13:59 eee: ,(println (first (seq eos)))

13:59 clojurebot: java.lang.Exception: Unable to resolve symbol: eos in this context

13:59 eee: oh I thought that was a real thing

14:00 scgilardi: (seq eos) -> nil means that "the value you get when you ask for more and the sequence is exhausted", when passed to seq, will produce nil

14:00 eee: ,(println (first (seq ())))

14:00 pnkfelix: I think its a placeholder for some end-of-sequence

14:00 clojurebot: nil

14:00 eee: yeah

14:00 pnkfelix: and such end-of-sequences have many different posible representations

14:01 eee: ,(println (first (list 1 2 3)))

14:01 clojurebot: 1

14:01 eee: is there a different way to get a list than to say list?

14:01 pstickne: ,'(1 2 3)

14:01 clojurebot: (1 2 3)

14:01 pnkfelix: Is there an apropos function?

14:02 eee: ,(println (first ,'(1 2 3)))

14:02 Chouser_: ,(seq (list))

14:02 clojurebot: 1

14:02 nil

14:02 scgilardi: ,(find-doc "ns-")

14:02 Chouser_: ,(seq ())

14:02 clojurebot: ------------------------- clojure.core/ns-aliases ([ns]) Returns a map of the aliases for the namespace. ------------------------- clojure.core/ns-imports ([ns]) Returns a map of the import mappings for the namespace. ------------------------- clojure.core/ns-interns ([ns]) Returns a map of the intern mappings for the namespace. ------------------------- clojure.core/ns-map ([ns]) Returns a map of all the mappings

14:02 scgilardi: whoops

14:02 clojurebot: nil

14:02 Chouser_: :-)

14:02 eee: conj does different things depending on collection?

14:02 pnkfelix: hmm. Looks like find-doc itself loks like a nice apropos. :)

14:03 Chouser_: eee: yes

14:03 eee: that seems to contradict the F*I thing to me

14:03 pnkfelix: oh but find-doc matches the doc-strings (as well as the identifiers (?))

14:03 Chouser_: pnkfelix: yep

14:04 SethTisue: ,(conj (1 2) 3)

14:04 clojurebot: java.lang.ClassCastException: java.lang.Integer cannot be cast to clojure.lang.IFn

14:04 SethTisue: ,(conj '(1 2) 3)

14:04 clojurebot: (3 1 2)

14:04 SethTisue: ,(conj [1 2] 3)

14:04 clojurebot: [1 2 3]

14:04 SethTisue: I'll need to get used to that...

14:04 Chouser_: ,(conj {:a 1 :b 2} [:c 3])

14:04 clojurebot: {:c 3, :a 1, :b 2}

14:05 SethTisue: how come seq is a no-op on lists, but not on vectors?

14:06 ,(class '(1 2 3))

14:06 clojurebot: clojure.lang.PersistentList

14:06 SethTisue: ,(class (seq '(1 2 3))

14:06 clojurebot: EOF while reading

14:06 SethTisue: ,(class (seq '(1 2 3)))

14:06 clojurebot: clojure.lang.PersistentList

14:06 SethTisue: but then

14:06 ,(class [1 2 3])

14:06 clojurebot: clojure.lang.LazilyPersistentVector

14:06 SethTisue: ,(class (seq [1 2 3]))

14:06 clojurebot: clojure.lang.APersistentVector$Seq

14:07 pnkfelix: SethTisue: perhaps to support laziness?

14:07 eee: happens to be

14:07 SethTisue: ohhhh

14:07 pnkfelix: SethTisue: building a vector would requiring traversing the whole structure...

14:07 SethTisue: to support efficient iteration

14:07 Chouser_: yes, efficiency, not laziness

14:08 pnkfelix: ah okay

14:08 eee: why can you make a vector like this: [1 2 3] but not a list like (1 2 3) . . . because clj doesn't know you aren't trying to eval . . . but it's asymmetric

14:09 scgilardi: symbols and lists don't evaluate to themselves

14:09 the're special that way

14:09 Chouser_: eee: yes, because you need *some* way to ask for a fn call

14:09 lists are it.

14:09 cmvkk: '(1 2 3) is easy enough

14:09 Chouser_: but (list ...) and (vector ...) are symmetric

14:09 eee: should have been like this: v(1 2 3) and l(1 2 3)

14:09 how nice

14:10 now I can have s(1 2 3), too

14:10 DavidSJ: How does (:b m) work?

14:10 Is :b callable? And if so, is that unique to keywords, or what?

14:10 cmvkk: keywords are functions of their maps.

14:10 eee: ,'(1 2 3) ... I'll have ti remember that

14:10 clojurebot: (1 2 3)

14:10 DavidSJ: OK, but can't maps have keys that aren't keywords?

14:11 cmvkk: yeah, in that case you can't call a map by its key.

14:11 DavidSJ: Ah, thanks.

14:11 cmvkk: you can do (m :b) though, for any key

14:11 Mec: ,('a {'a 2})

14:11 clojurebot: 2

14:11 eee: (list [1 2 3])

14:11 DavidSJ: ok

14:11 eee: ,(list [1 2 3])

14:11 clojurebot: ([1 2 3])

14:11 eee: nope

14:11 ,(vector 1 2 3)

14:11 clojurebot: [1 2 3]

14:12 SethTisue: so (:b m) and (m :b) mean the same thing?!

14:12 Mec: yes

14:12 cmvkk: effectively

14:12 SethTisue: whoa

14:12 Chouser_: SethTisue: when m is a map, yes

14:12 pnkfelix: SethTisue: in a context where m denotes a map object? Appearso

14:12 Chouser_: if m is nil, (:b m) returns nil (m :b) throws an exception

14:13 eee: doesn't seem right that they are same . . . because map is not always a bijection

14:13 cmvkk: i'm still annoyed that using cons stops the result from being a list

14:13 Mec: is the reader just checking if either expression is a map?

14:13 Chouser_: Mec: no, it's a runtime eval thing, not reader

14:13 scgilardi: ,(:my-key 3)

14:13 clojurebot: nil

14:13 DavidSJ: Is there sometimes confusion of the sort (if x ...), where x is expected to be False or true, and is sometimes nil?

14:14 Mec: ,('a 3)

14:14 clojurebot: nil

14:14 Mec: weird

14:14 DavidSJ: But where nil *should* be treated as the true case?

14:14 Chouser_: eee: we're reversing the args of the lookup, not the key/val order of the entries

14:14 scgilardi: nil can never be treated as the true case

14:14 eee: oh

14:14 i get it

14:14 cmvkk: you can do (or x (nil? x)) I guess

14:15 eee: so now what about cons?

14:15 you lose that it was a list?

14:15 cmvkk: ,(list? (cons 'a (list 'b 'c)))

14:15 clojurebot: false

14:15 eee: what is the type then?

14:15 cmvkk: Cons

14:15 DavidSJ: Right, cmvkk, but is that a mistake that occurs often?

14:15 due to there being two false values

14:16 cmvkk: i can't think of a situation where you'd want nil to be true right off the bat

14:16 DavidSJ: i.e. someone forgets to account for that possibility

14:16 ok

14:16 SethTisue: however

14:16 cmvkk: predicates generally return true or false, and non-predicates typically don't return false that often

14:16 SethTisue: ,(list? (conj '(1 2) 3))

14:16 clojurebot: true

14:16 SethTisue: what is cons, then?

14:17 pstickne: ,(cons? (cons 'a (list 'b 'c)))

14:17 clojurebot: java.lang.Exception: Unable to resolve symbol: cons? in this context

14:17 pstickne: I lose :p

14:17 cmvkk: ,(instance? clojure.lang.Cons (cons 'a (list 'b 'c)))

14:17 clojurebot: true

14:19 DavidSJ: ,(instance? Cons (cons 'a (list 'b 'c)))

14:19 clojurebot: java.lang.Exception: Unable to resolve symbol: Cons in this context

14:19 DavidSJ: oh, it's clojure.lang

14:19 not Java.lang

14:19 eee: can you downcast?

14:19 DavidSJ: :)

14:19 eee: (seq 1 2 3)

14:19 ,(seq 1 2 3)

14:19 clojurebot: java.lang.IllegalArgumentException: Wrong number of args passed to: core$seq

14:20 SethTisue: apparently cons is a sequence thing, not a list thing

14:20 eee: ,(seq ,'(1 2 3))

14:20 clojurebot: (1 2 3)

14:20 cmvkk: yes.

14:20 ,(seq? (cons 'a (list 'b 'c)))

14:20 clojurebot: true

14:20 eee: ,(list? (seq ,'(1 2 3)))

14:20 clojurebot: true

14:21 SethTisue: OK, so cons works on all sequences. but in the case of lists, why doesn't it just do the same thing as cons in traditional Lisps?

14:21 Chouser_: SethTisue: might be a good one to ask aloud. :-)

14:21 cmvkk: i think it's more efficient that way

14:25 SethTisue: I'm looking through the documentation

14:25 and I see that count is O(1) on lists

14:25 maybe that's the efficiency issue

14:25 in CL and Scheme, getting the length of a list is O(n)

14:25 eee: so you may have to find out the type of a sequence

14:25 to figure out what to do

14:26 there's no analogue to template specialization

14:26 ...or ..."what's the analogue to template specialization?"

14:27 Chouser_: eee: if you're sure you want to do something different for one type than another, you may want to use a multimethod or check the arg type manually.

14:27 eee: I think the point is that this happens less often than you might think.

14:27 Mec: SethTisue: count is O(n) if a list hasnt been counted yet

14:27 scgilardi: amortized O(1)

14:27 Chouser_: Mec: PersistentLists are always counted

14:27 DavidSJ: I suppose guaranteeing O(1) would be impossible in Scheme or Lisp because the CDR can change without the cons knowing.

14:28 eee: checking the type is a runtime check

14:28 Chouser_: DavidSJ: excellent point

14:28 pstickne: eee: except a multi-method can't match any on more than one param :(

14:28 Chouser_: pstickne: not true

14:28 SethTisue: the doc simply says, count is O(1). no qualifications, just a flat out statement. it sounds like they are counted when constructed

14:28 Mec: i meant sequence not lists, a lazy sequence may not have been counted yet

14:28 pstickne: Chouser_: (defmethod x [:default :something] ...? ) ;- what am I missing?

14:28 scgilardi: Chouser_ is correct. It's O(1). I was thinking of the hash code which is calculated when needed.

14:30 eee: ,(countedp ,'())

14:30 clojurebot: java.lang.Exception: Unable to resolve symbol: countedp in this context

14:30 Mec: ,(let [x (range 100000)] (time (count x)) (time (count x)))

14:30 clojurebot: 100000

14:30 Chouser_: pstickne: you can match, you just can't have a default for one of the multi-args but not all when you have an open set of types

14:30 clojurebot: "Elapsed time: 0.02 msecs" "Elapsed time: 0.0060 msecs"

14:30 Chouser_: ,(counted? ())

14:30 clojurebot: true

14:30 eee: ,(counted? ,'())

14:30 clojurebot: true

14:30 pnkfelix: seems like count should be O(1) only for counted? things

14:30 eee: ahhhhh now I know what the controversy is

14:30 Mec: ,(counted? (range 10))

14:30 clojurebot: true

14:30 eee: () is broken

14:30 SethTisue: I guess I just got my answer on why Cons exists separate from IPersistentList. Cons is not counted so it's more space-efficient

14:30 pnkfelix: Since I just attempts to apply it to a cycle

14:31 eee: should be a function with no args including it's name

14:31 () should return nil because it's a function.

14:31 but clj breaks that

14:32 digash`: () is not a function call

14:32 Chouser_: well, () could throw an error because you forgot to specify which function to call

14:32 eee: that would work, too

14:32 Chouser_: but that's not very useful, so it's an empty list. :-)

14:32 Mec: thats nice to know, better than writing '()

14:33 DavidSJ: ,(reversible? ())

14:33 clojurebot: false

14:33 digash`: () is more idiomatic, according to Rich

14:33 DavidSJ: ,(reversible '(1 2 3))

14:33 clojurebot: java.lang.Exception: Unable to resolve symbol: reversible in this context

14:33 DavidSJ: ,(reversible? '(1 2 3))

14:33 clojurebot: false

14:34 DavidSJ: ,(reversible? [1 2 3])

14:34 clojurebot: true

14:34 digash`: the same as {} []

14:35 Mec: ,(reverse '(1 2 3)

14:35 clojurebot: EOF while reading

14:35 Mec: ,(reverse '(1 2 3))

14:35 clojurebot: (3 2 1)

14:35 Mec: so why doesnt reversible? work

14:35 SethTisue: reversible? asks whether its reversible in O(1), I think

14:35 Mec: (doc reversible?)

14:35 clojurebot: Returns true if coll implements Reversible; arglists ([coll])

14:36 dreish: Whether you can call rseq on it.

14:36 ,(rseq '(1 2 3))

14:36 clojurebot: java.lang.ClassCastException: clojure.lang.PersistentList cannot be cast to clojure.lang.Reversible

14:36 SethTisue: (doc rseq)

14:36 clojurebot: Returns, in constant time, a seq of the items in rev (which can be a vector or sorted-map), in reverse order. If rev is empty returns nil; arglists ([rev])

14:36 dreish: ,(rseq [1 2 3])

14:36 clojurebot: (3 2 1)

14:36 SethTisue: I'm still getting used to not assuming something is a list when I see parens in the repl output

14:37 Mec: how do you download from google code? the downloads is blank but there are deffinitly files under source

14:37 SethTisue: ,(class (rseq [1 2 3]))

14:37 clojurebot: clojure.lang.APersistentVector$RSeq

14:37 cmvkk: you have to use SVN, Mec

14:37 dreish: I just use Kevin O'neill's git mirror.

14:37 Mec: boo not current snapshot zips?

14:38 cmvkk: no such thing, as far as I know

14:38 just latest release builds, and SVN or git

14:38 dreish: github has zips

14:38 Chouser_: sure there's a recent .zip release.

14:38 dreish: http://github.com/kevinoneill/clojure/tree/master and click on download

14:38 Chouser_: http://code.google.com/p/clojure/downloads/list

14:39 digash`: http://tapestry.formos.com/bamboo/browse/CLJ;jsessionid=C4BE2E3CBD3992711C615C7A575CB4A3

14:39 eee: is there a "metadata-included-equal?" function?

14:40 Chouser_: no, though you could compare the metadata separately

14:40 eee: or "(equal-including-meta?"

14:40 Chouser_: (and (= a b) (= ^a ^b))

14:40 eee: oh

14:40 Chouser_: never seen that used or needed

14:40 eee: maybe someone just thinks their objects are equal right now

14:40 and they just don't know about the bug

14:41 dreish: What bug?

14:41 eee: in their code

14:41 dreish: Metadata doesn't affect equality. That's pretty much the definition of metadata.

14:41 eee: that they didn't remember that meta data not included in check

14:41 dreish: You should not check metadata for equality.

14:41 If you do, you're almost certainly misusing it.

14:42 eee: i can see your point

14:42 totally

14:42 otherwise it's not called meta data

14:42 te: whoa shit. the hottest girl i went to high school with wants to take me out

14:42 eee: it's just data

14:42 te: this girl was just in playboy

14:42 * te dances

14:42 danlarkin: te: *OT alarm*

14:43 te: exit, stage left

14:43 danlarkin: i forked Madison, so zip your lip

14:43 ;)

14:43 sellout: Too bad the channel's not on the projector at the moment.

14:43 danlarkin: te: cool! what'll you add?

14:43 te: danlarkin: haven't read through the source much yet, but i'm excited to get in there and poke around

14:44 danlarkin: only one problem

14:44 you need to rename it Clabango

14:44 danlarkin: no can do

14:44 eee: i wonder if we get to fill out a survey

14:44 te: danlarkin: awww why not?

14:44 cconstantine: what're you guys at?

14:45 sellout: ILC

14:45 scgilardi: 5 hour talk on Clojure by Rich at the Internation Lisp Conference, this year in Cambridge, MA

14:45 cconstantine: aahhh

14:45 cmvkk: what slide are you on

14:45 scgilardi: 51-ish

14:45 sellout: 54

14:46 cmvkk: so you're almost done

14:46 eee: i'm not paying enough attention now, i fear. . . .that we are chatting

14:46 sellout: cmvkk: I dunno ... we have over 2 hours left.

14:46 te: scgilardi: sellout: is there a channelo?

14:46 Chouser_: these are new slides

14:46 te: I wasn't formally invited

14:46 cmvkk: different from the ones someone linked earlier?

14:47 te: link me please

14:47 slashus2: ~clabango

14:47 cmvkk: java interfaces? a la carte hierarchies?

14:47 clojurebot: clabango is http://github.com/danlarkin/madison/tree/master

14:47 SethTisue: same as link I sent earlier

14:47 Chouser_: oh, um ... I guess these are the new ones on google group files

14:47 SethTisue: http://clojure.googlegroups.com/web/tutorial.pdf?gda=wpkXdz4AAAC2LrkjeC7f10uHiY7GOiyxfbmym9_39wWPz8-Z2OGMtMwgAOBOKqa5ZS2rRu2OVUrjsKXVs-X7bdXZc5buSfmx

14:47 te: danlarkin: I know this is a low priority, but you might consider bundling the dependencies

14:47 cmvkk: it only goes up to 70, is what I meant. I assume after that there will be extensive Q&A

14:48 te: I think it'd do a whole lot for newbs

14:48 cmvkk: and maybe some ants unless that already happened

14:48 sellout: Or hands-on, maybe

14:48 scgilardi: He mentioned giving the "state" talk for the last 90 minutes. Maybe those will be from another set of slides.

14:48 danlarkin: te: I will not bundle deps, I don't think it's the Right Thing To Do(TM(TM)

14:49 te: danlarkin: I think you should give users the optiohn

14:49 option

14:49 </opinion>

14:49 danlarkin: I have no plans to

14:49 te: I'll do it then :)

14:50 eee: i stayed up late cause i read that we'd be playing along and I had to set up my environment. anyone know if we'll be writing a program? I'm starting to guess not

14:50 te: Clojure is still a pretty small community -- the "build a sweet dynamic website" tutorial is still the key to opening up any new lang's userbase IMHO

14:50 cmvkk: i find it sad that all the cutting edge people care about anymore is building dynamic web apps.

14:51 there's so much more to programming!

14:51 pnkfelix: eee: there's always the 30min break to spend hacking. :)

14:51 eee: same here

14:51 te: cmvkk: i think in clojure's case building a dynamic web app can be very instructive as to how clojure works to build "stuff"

14:51 or the advantages to using it

14:51 jhawk28: there is some hard core p2p

14:52 eee: i actually thought he'd be walking us through programming . . . .and I almost asked if it was ok that I didn't have emacs yet

14:53 te: Elitist attitudes and arrogant old developers continue to be a problem for the CL userbase

14:53 pnkfelix: eee: I am actually hoping to find someone to help me fix my emacs setup... the clojure-mode.el does not seem quite right in my context

14:53 te: Haskell has done a marvelous job of not sucking ass

14:53 Clojure can do the same with a helping hand here and there

14:53 IMO

14:53 p_l: te: I haven't seen much of elitist attitude and arrogant old developers... but I heard it was like that few years ago...

14:54 eee: talk != "tutorial"

14:54 dreish: te: Funny you should mention that. I pretty much expect Haskell to end up in the same place as CL in several more years.

14:54 te: Maybe it's changed, but I'll be damned if I still don't see the same old names on lisp blogs talking about how YOU'RE DOING IT WRONG!

14:55 dreish: save your prophecy

14:55 dreish: I respect your opinion, but I don't take much stock in prediction

14:55 especially with tech in general

14:55 Lau_of_DK: danlarkin, bundling dependencies it The Right Thing To Do (tm)

14:56 dreish: Fine, whatever.

14:56 te: Lau_of_DK to the rescue

14:56 p_l: te: Well, I avoid c.l.l and certain blogs and keep it to #lisp... the community there is much nicer :D

14:56 jhawk28: danlarkin:

14:56 danlarkin: is there a sample app to demonstrate Madison?

14:56 Lau_of_DK: What has given an inferior OS like Windows 95% marketshare? They bundle stuff and make it simple. Linux is greater in every aspect, but because we still have mainstreamed all the little tricks that we all use, its written of as "complicated"

14:56 te: why did Rails blow up?

14:56 Lau_of_DK: You just put Madison in the category

14:57 te: they showed you the blog webapp in a few lines

14:57 that's why

14:57 danlarkin: jhawk28: no, not yet... it's not really ready for general use yet

14:57 p_l: Lau_of_DK: windows bundless much less than 10yo linux distro...

14:57 te: p_l: that's another topic altogether

14:57 what Lau_of_DK is saying is essentially true

14:57 Lau_of_DK: truely

14:57 te: simple sells

14:58 p_l: te: I think what really made Windows such a success is that making apps for it wasn't hard

14:58 jhawk28: danlarkin: have you been able to do anything with dynamic database models?

14:58 dreish: Lau_of_DK: It has high market share because developers target it, and developers target it because it has high market share. MS has historically focused more of its efforts on the developer side of that than on making Windows pleasant to use.

14:58 Lau_of_DK: p_l youre off topic

14:58 danlarkin: Lau_of_DK, te: I think a framework bundling deps is a mistake. An end user program, sure, but not a program for programmers

14:58 Lau_of_DK: Forget Windows, forget Linux, focus on manipulating danlarkin into bundling all those dependencies

14:59 te: if this is an academic exercise for you then sit back and enjoy the ride, but personally I would like to see Clojure gain some developers and grow up into a beautiful lang

14:59 dreish: Lau_of_DK: You brought it up. :-P

14:59 Lau_of_DK: And now Im bringing it down

14:59 te: Clojure has so much promise. The decisions of developers today will affect the potential devs of tomorrow

14:59 cmvkk: this is free software, danlarkin doesn't need to bundle anything. someone can just fork the project, pull every update from the original, and make a bundled-with-deps version.

14:59 jhawk28: cmvkk: use apache ivy for deps

15:00 SethTisue: hungry plumber?

15:00 te: cmvkk: I'm doing it, but it doesn't usurp the fact that bundling and making things newb-friendly will help Clojure in the long run

15:00 danlarkin: jhawk28: Madison doesn't have the "M" part of MVC yet. It's coming though, for sure. John Hume's clj-record looks very interesting

15:00 Lau_of_DK: Fine fine... I have 'Clabango' on Github, I can make that a bundled Madison

15:00 cmvkk: heh

15:00 te: Lau_of_DK: booya!

15:00 Lau_of_DK: Man - whats keeping Open Source down? Lazy developers

15:01 eee: i'd just prefer to see it, vice just hear about it.

15:01 Lau_of_DK: Not going the last 5 mm to complete the job

15:01 digash`: ,(isa? String Object)

15:01 te: Lau_of_DK: was that in jest?

15:01 clojurebot: true

15:01 Lau_of_DK: Look at ClojureQL for instance

15:01 te: Lau_of_DK: I hope you're not kidding, because I agree

15:01 pnkfelix: SethTisue: multiple inheritance

15:01 eee: so many practical questions would pop up

15:01 Lau_of_DK: te, Im not kidding, and ClojureQL is my project, so Im guilty also :(


15:02 cmvkk: but Lau...those 5mm are *boring*

15:02 Lau_of_DK: Although I will say, ClojureQl is quite fantastic in its own right

15:02 te: I really just want to choke when I think about how many great projects there are out there that don't know a goddamn thing about helping people use their code

15:02 Lau_of_DK: Yea its a shame, although Compojure has really picked up the pace lately

15:02 te: Yeah -- very big surprise tbph

15:03 Lau_of_DK: And technomancy's little tricks with Concourse was just fantastivc

15:03 te: I didn't expect it

15:03 Lau_of_DK: minus the v though

15:03 te: amen

15:03 Technomancy == pure awesome.

15:03 Lau_of_DK: Yea, pillar of the community

15:03 te: Languages blow up because of people like that, and what they do isn't so special

15:03 they just instruct people on how to use their cool ideas

15:04 like Lau_of_DK said: the extra 5mm

15:04 Lau_of_DK: Its just like that :)

15:04 pnkfelix: is there a way for me to install a hierarchy I have created as the global hierarchy? (sounds dangerous i admit)

15:05 te: Lau_of_DK: we should start a site that basically focuses on writing documentation for open source projects

15:05 and reward people who contribute with something

15:05 Lau_of_DK: And write it in Compojure just to punish Danlarkin for his i'll choises

15:05 te: lol

15:05 Lau_of_DK: te... thats actually a very very awesome idea

15:05 Best Ive heard all year I think

15:06 ieure: How can I parse XML from a string?

15:06 Lau_of_DK: "This site was written in Compojure, simple because Danlarkin needs to be taught a lesson"

15:06 te: lol

15:06 Lau_of_DK: ieure, zip-filter

15:06 te: Lau_of_DK++

15:06 danlarkin: hahah

15:06 you'll get yours!!

15:06 * te hides

15:06 te: okay but serious dan -- bundle your code -- don't be an MITurd

15:06 Lau_of_DK: te, I'll get to work, on getting a virtual server set up somewhere and get compojure launched on it

15:06 haha

15:07 clojurebot: danlarkin is an MITurd

15:07 clojurebot: Ack. Ack.

15:07 te: Laulol

15:07 Lau_of_DK: danlarkin, Its up to you to redeem your image

15:07 ...by way of bundling

15:07 danlarkin: clojurebot: forget danlarkin

15:07 clojurebot: I forgot danlarkin

15:07 danlarkin: redeemed!

15:07 Lau_of_DK: hmm, nope, till a turd :)

15:07 +s

15:07 te: look i don't care if you bundle it -- but update your docs with how to get Madison running for the complete and utter noob

15:07 that's how you get on Hacker News

15:07 that's how you get on reddit, etc.

15:08 that shit grows languages

15:08 danlarkin: te: but I don't want to get on HN/reddit

15:08 cmvkk: to be fair, it's probably too early for that

15:08 Chouser_: ieure: (clojure.contrib.lazy-xml/parse-trim (java.io.StringReader. "<foo />"))

15:08 Lau_of_DK: cmvkk, I'll drop you a private MSG next time we want your oppinion, thanks in advance :)

15:08 te: yeah I guess I'm just speaking in principle -- I repsect dan's judgement-- the guy is obviously damned smart

15:08 cmvkk: don't worry, i'll give it no matter what.

15:08 pnkfelix: I'm getting an exception when I invoke (derive :a :b)

15:08 Lau_of_DK: hehe

15:08 Good :)

15:08 danlarkin: te: the project is not complete. "utter noobs" trying to use madison would just be disappointed

15:08 pnkfelix: ,(derive :a :b)

15:08 clojurebot: java.lang.Exception: Assert failed: (namespace parent)

15:08 ieure: Chouser_, I think zip-filter might be the way to go, since I need to traverse the tree to extract a value.

15:08 Chouser_: pnkfelix: (derive ::a ::b)

15:08 te: danlarkin: yeah I understand man -- just trying to impart the little wisdom I have

15:09 Chouser_: ieure: you'll still need to parse the xml string first

15:09 pnkfelix: oh I see; I misparsed the documentation

15:09 (thought "namespace-qualified" only applied to the symbol)

15:09 te: docs = win, getting started step-by-step = win

15:09 those things are so incredibly important to the success of a community

15:09 * te volunteers for community cheerleader

15:11 Chouser_: I wonder if we could do an ad-hoc workshop after the talks.

15:11 cmvkk: what would you do?

15:11 eee: i would LOVE that

15:11 please!

15:12 Chouser_: i dunno. do what you want, I guess. projecteuler?

15:12 eee: when

15:12 cmvkk: ants? the ant farm? it's clojure's killer app.

15:12 te: lol fuck that

15:12 eee: i want to start with a blinking curser

15:12 cmvkk: heh

15:12 eee: and we do something that makes stuff pop up on the screen

15:12 from thin air

15:12 te: those are called dioramamas

15:12 eee: not look at existing code

15:12 te: dioramas

15:13 cmvkk: civil war battle dioramas

15:13 eee: talk about something . . .then code it

15:13 te: i dont like that idea

15:13 eee: battle . . . .we can implement battleship

15:13 is clojure

15:13 te: how about talk THROUGH coding something

15:13 eee: in clohjure

15:13 that's what I mean

15:13 te: come up with an intersting project, and then everyone work together to suggest how to do it

15:13 explain why

15:13 eee: let's make multiplayer battleship

15:14 cmvkk: that might take longer than the time you have

15:14 Chouser_: "pop up on screen" implies GUI? that implies time spent on java lib spelunking

15:14 Lau_of_DK: ~sofiaba?

15:14 clojurebot: sofiaba is http://wiki.github.com/Lau-of-DK/sofiaba

15:14 * te launches the JVM

15:14 * te waits 6 hours

15:14 * te starts coding

15:14 eee: that's what he argues make clojure useful

15:14 Lau_of_DK: eee Could you contribute a mid-sized battlecruiser please?

15:15 te: Lau_of_DK: only if you say "Battlecruiser operational" in a russian accent

15:15 Lau_of_DK: Oh I will :)

15:15 * te kisses you

15:15 te: (in a gay way)

15:15 * Lau_of_DK strikes te dead

15:15 * Lau_of_DK in a manly way

15:15 * te dances in a firey eternity

15:16 te: (im a maniac, maniac...)

15:16 Lau_of_DK: I think we just broke #clojure

15:17 te: Lau_of_DK: will you be my new best IRC friend

15:17 Lau_of_DK: No Chousers much better at that stuff :|

15:18 te: Lau_of_DK: aw come on

15:18 we share the same open source politcal belief system

15:18 we must be friends

15:19 hola durka42

15:19 durka42: hi te

15:19 te: how goes it

15:20 durka42: not bad

15:20 heading back to school

15:20 te: glad to hear it

15:20 oh really

15:20 i just finished with spring break as well

15:20 UW Madison

15:20 you?

15:20 durka42: swarthmore

15:20 was just visiting family for the weekend

15:20 te: ah great school

15:21 durka42: i agree

15:21 eee: when we doing the lab?

15:22 or just chatting?

15:22 i'm in

15:23 Chouser_: I don't know if we can use this space

15:23 technik: that was unintentionally funny

15:24 * durka42 has to catch a train

15:29 eee: why this not work? (new java.awt.JFrame)

15:29 ieure: Getting this when I (use 'clojure.contrib.zip-filter) in the REPL: "java.lang.IllegalStateException: descendants already refers to: #'clojure.core/descendants in namespace: weevil (NO_SOURCE_FILE:0)"

15:29 Ideas?

15:30 SethTisue: javax.swing.JFrame or java.awt.Frame

15:30 Chouser_: ieure: yeah. core added 'descendants' after zip-filter already had it

15:30 you might want (require '[clojure.contrib.zip-filter :as zf])

15:31 eee: Seth . . . not work

15:31 my type ahead says it should

15:32 user=> (new java.swing.JFrame "sdgsdfg") java.lang.ClassNotFoundException: java.swing.JFrame (NO_SOURCE_FILE:11)

15:32 pnkfelix: still need javax

15:32 eee: awt Frame worked

15:32 pnkfelix: swing is in javax. not java

15:32 SethTisue: javax.swing not java.swing

15:33 ieure: Chouser_, Okay, cool. Thanks.

15:33 Sorry about the n00b questions.

15:33 eee: oh

15:33 my type ahead lies

15:34 Chouser_: ieure: not a problem

15:35 eee: i guess there's a bug in the rlwrap

15:39 hiredman: busy morning

15:51 ~ping!

15:51 clojurebot: PONG!

16:00 eee: hello

16:01 hiredman: whatever you do don't say that to clojurebot

16:01 eee: now that I can make a JFrame . . . what's the most succinct way to set it visible

16:01 pnkfelix: .show method ?

16:01 eee: setVisible(true)

16:01 this is what I was hoping to learn today

16:01 practical hands on

16:01 hiredman: I usually make JFrames using a doto

16:01 eee: cool

16:01 pnkfelix: but that's Java library stuff; its nothign to do wit hClojure

16:02 digash`: eee: take a look at the ant.clj example

16:02 eee: well, it's Rich's arg for putting it in jvm

16:02 hiredman: ,(doto (JFrame.) (.setSize 800 600) (.setVisible true))

16:02 clojurebot: java.lang.IllegalArgumentException: Unable to resolve classname: JFrame

16:02 eee: vice making new lang for PLT-Scheme

16:02 hiredman: clojurebot: ignore that

16:02 clojurebot: Titim gan �ir� ort.

16:02 eee: so that seems like what we should cover . . . how it's actually useful

16:03 thanks

16:03 pnkfelix: I think the Java interop slides were meant to cover that

16:03 DavidSJ: Is there something like SLIME for Clojure?

16:03 eee: slides slides

16:03 pnkfelix: someone who knows Swing (e.g., not me) would be able to take that and run with it

16:03 hiredman: DavidSJ: there is slime for clojure, which is sort of like slime :P

16:03 eee: some people need to be walked through stuff

16:03 DavidSJ: oh, cool

16:03 eee: me for e.g.

16:03 pnkfelix: (this is why I was careful to clarify that I knew Java the lang but not Java the libraries)

16:03 eee: "tutorial"

16:03 hiredman: but I am not an emacs user so I cannot really help with that

16:03 eee: i am not either

16:04 DavidSJ: I got this in my *inferior-lisp* when I tried na�vely though: user=> java.lang.Exception: Unable to resolve symbol: progn in this context (NO_SOURCE_FILE:1)

16:04 eee: i am just using rlwrap

16:04 DavidSJ: Do I need to update my slime?

16:04 oh, ok

16:04 I guess I'll ask Google.

16:04 SethTisue: I'm reading ant.clj and learning a lot

16:04 hiredman: I imagine all the emacs clojure guys are at ilc

16:04 eee: how would that be used with the "new" operator>

16:05 hoeck: DavidSJ: http://github.com/jochu/swank-clojure/tree/master

16:05 pnkfelix: I would actually like for one of the emacs clojure guys to help me with me config

16:05 hiredman: eee: (new JFrame) and (JFrame.) are the same

16:05 eee: cool! my first productive use of clojure

16:05 hiredman: ,(macroexpand '(JFrame.))

16:05 eee: something someone can see!

16:05 clojurebot: (new JFrame)

16:05 pnkfelix: but I forgot until just now, so I guess I will wait until after 3rd sesion to ask

16:05 DavidSJ: Great hoeck, thanks.

16:05 let's try that...

16:06 hiredman: symbols with a '.' at the end are treated as calls to new

16:06 symbols with a '.' at the begining are treated as method calls

16:07 SethTisue: pnkfelix: I have swank-clojure and slime up and running in Emacs on my Mac. I'm not an expert on it obviously (1st day using it) but I could show you my config.

16:08 eee: thanks hired

16:08 that helps me remember it

16:08 pnkfelix: SethTisue: okay I would appreciate that; lets talk at 5pm?

16:08 thickey_: http://clojure.googlegroups.com/web/StateAndIdentity.pdf

16:09 hiredman: is this talk #2?

16:09 pnkfelix: SethTisue: caveat: I am not a slime user so getting that set up may be more hell than its worth. We'll see at 5pm

16:09 SethTisue: pnkfelix: sure. I'm in back row, on aisle, plaid shirt, mac laptop.

16:09 thickey_: hiredman: session 3

16:09 cmvkk: if i put the head of a lazy-seq inside an atom, but there aren't anymore references to the atom, the whole thing will be garbage collected, right?

16:10 Chouser_: cmvkk: sure

16:10 cmvkk: an atom is just another object

16:10 cmvkk: okay, that's what I thought

16:10 I'm running out of heap space and it isn't immediately apparent to me why

16:11 but what i'm doing new is introducing a construct that uses atoms to allow for mutual recursion between lazy-seqs.

16:18 eee: how do I erase my type-ahead history in rlwrap?

16:19 clj script

16:21 Chouser_: eee: maybe ~/.java_history ?

16:22 eee: i found it

16:22 its

16:22 .jline-clojure.lang.Repl.history maybe

16:22 Chouser_: eee: you can set it via rlwrap command-line

16:22 jline!?

16:22 eee: no

16:22 that was before

16:23 all this stuff is on the web site

16:23 so far

16:24 pnkfelix: eee: reading web site was (unfortunately) not prereq for attendance

16:24 eee: yup

16:24 well said

16:26 i'd like to see how to set up the ant simulator

16:26 so I can mess with it

16:26 think we'll get to that?

16:27 Chouser_: should be plenty of QA

16:28 eee: i like how he just explained that. time is a dimension, too. and what's cool, is you can trace it back by recording all the state transitions

16:28 thickey_: next Clojure t-shirts: "The future is a function of the past."

16:29 eee: good idea!

16:29 Chouser_: thickey_: excellent.

16:29 or "time happened"

16:30 agriffis: "time happens"

16:30 eee: decision making from snapshots is called "causal inference error"

16:32 mattrepl: thickey_: awesome! is that really going to happen? I'd be happy to pitch in to cover up front costs, and I recommend american apparel tshirts, very comfy

16:33 Chouser_: mattrepl: http://www.zazzle.com/clojure

16:34 (clojure 'lisp)

16:34 eee: test test

16:34 cool

16:34 Chouser_: ^^^ the future is a function of the past

16:34 mattrepl: Chouser_: thanks

16:34 thickey_: =)

16:34 eee: slow network

16:35 te: I'm buying "DON'T BE SO EAGER"

16:35 brilliant

16:35 eee: the eager one is the best

16:36 te: I have a good one:

16:36 "Call Paul Graham, we built a better Arc"

16:36 mattrepl: excellent, looks like zazzle has AA shirts available

16:36 te: -Clojure-

16:36 mattrepl: ouch

16:36 durka42: ooh clojure buttons

16:37 te: has anyone here read Hackers and Painters?

16:37 to those of you who have read it: Did you feel like a whiny 18 year old while reading the first 4 chapters?

16:38 P. Graham whines too much about high school.

16:38 Grow a pair, nerdboy.

16:40 * digash` does not see pg at the ilc2009

16:41 cmvkk: he's too busy being a millionaire. can't fault him for that...

16:41 te: i really liked PG until I realized he doesn't know how to stfu

16:41 \the guy blogs about the most inane shit

16:42 pnkfelix: ilc: how wide can the branching get here?

16:42 ilc: 32 ways in worst case? Is that right?

16:42 te: log32n

16:43 Mec: when adding a map to a funciton definition, can you not also have a single arg version?

16:43 hiredman: huh?

16:43 te: ...

16:43 Chouser_: Mec: adding a map in what way?

16:45 gnuvince_: ~seen cgrand

16:45 clojurebot: cgrand was last seen joining #clojure, 744 minutes ago

16:45 hiredman: (first time that has ever worked)

16:46 Mec: hmm i see them doing it in the waterfront code but i cant get it to work at all

16:49 hiredman: Mec: example please

16:50 eee: wf never worked at all for me

16:50 i gave up

16:50 Mec: ya i just get an error, let me put one of their functions up on pastey

16:50 Chouser_: "you are not the king of time" --clojure

16:50 lisppaste8: Mec pasted "untitled" at http://paste.lisp.org/display/77428

16:50 thickey_: i love that he said "i am" right after that

16:51 eee: "the King of not being the King of time"

16:51 Chouser_: thickey_: huh, missed that.

16:51 oh, the meta-data attr-map arg of defn

16:51 Mec: that's what you're talking about?

16:52 hiredman: Mec: so you are trying to attach test metadata?

16:59 Mec: ah thats metadata, ok nvm then

16:59 eee: I wonder what data structures PostgressQL and Oracle use

17:00 can use a db with ANY language

17:00 Chouser_: eee: in memory or on disk?

17:00 eee: either way

17:00 db supports both

17:02 p_l: I dunno about Oracle, but Postgres ultimately boils everything to object database afaik

17:03 possibly the same for Ingres

17:10 slashus2: I know this might be a silly question, but what is the best way to create an event-driven API in clojure? (e.g. twisted, pircbot)

17:11 StartsWithK: there is (assoc-in {:a {:b 3}} [:a :b] 4) but, why is there no (dissoc-in {:a {:b 3}} [:a :b]) -> {:a {}}

17:11 and how is the best way to do it then

17:11 slashus2: StartsWithK: Just use update-in

17:12 and use dissoc

17:12 StartsWithK: update will make :b nil at best

17:13 dissoc will work only for first level

17:14 eee: he's right. oracle works . . . used every day

17:14 slashus2: StartsWithK: (dosync (alter memo-database update-in [channel] dissoc sender)) something like this

17:14 agriffis: http://clojure.org/sequences refers to fnseq which doesn't appear on http://clojure.org/api ?

17:14 eee: doesn't that make regular old java competitive in the future if used with oracle?

17:15 Chouser_: agriffis: it's a new special form

17:15 thickey_: (update-in {:a {:x {:q 1 :r 2}}} [:a :x] dissoc :q)

17:15 agriffis: Chouser_: ah, the link is wrong then

17:15 Chouser_: but it's not documented on the special forms page yet, either. :-/

17:16 StartsWithK: thickey_: thansk, that helped

17:16 ks*

17:16 thickey_: StartsWithK: np

17:20 eee: wait a sec

17:20 is ensure a type of lock?

17:21 slashus2: ~def ensure

17:21 eee: value will not change for how long?

17:21 Chouser_: eee: no, not a lock -- it's a request to the current transaction

17:21 eee: ensures the value doesn't change

17:22 sounds like a lock to me

17:22 Mec: what's the point of using find?

17:22 Chouser_: it asks that if the ensured ref changes (by something else) before the end of this transaction, retry this transaction please

17:22 cmvkk: it brings it in as part of the dosync...it's like setting a ref to itself.

17:22 eee: i see

17:22 retry once?

17:22 sellout: eee: no, it means if there's another transaction that modifies it while the current transaction is running, one fo them will fail.

17:22 (fail, and retry)

17:23 slashus2: What is a concrete example of needing this?

17:23 eee: i'd have to work through a scenario . . . too casually defined right now for m

17:23 e

17:24 if you open a transaction

17:24 and then I open a transaction

17:24 and then I ensure

17:24 and then you try to change data

17:24 what happens

17:24 I retry

17:24 or I win

17:24 and you retry

17:24 Chouser_: yes

17:24 sellout: one of those two ;)

17:25 eee: great

17:25 :(

17:25 i don't get it

17:25 sellout: eee: it's unimportant which.

17:25 eee: well I did an ensure

17:25 and you didn't

17:25 so I don't see what it's for

17:25 pnkfelix: eee: you can't observe the change during the txn

17:25 sellout: eee: an ensure is for if you read, but don't modify, a value.

17:25 slashus2: Is there an example of code using ensure somewhere?

17:26 So just derefing a ref inside of a transaction doesn't ensure that you will see it in a consistent state?

17:27 eee: who knows

17:27 sellout: Correct.

17:27 eee: you have to read the docs. this isn;t a tutorial

17:27 even tho on tutorial day :)

17:27 Mec: slashus2: what do you mean by event-driven api?

17:27 Chouser_: slashus2: no, it'll be a consistent state -- at a snapshot point in time

17:28 * sellout needs to type faster

17:28 Chouser_: slashus2: it may have changed since, but unless you care, don't 'ensure'

17:28 sellout: slashus2: It works like selects do in most DBs.

17:29 eee: ensure sounds like double-checked locking bug

17:29 i look at state

17:29 and it's good

17:29 so then I do something

17:29 assuming it's still good

17:29 so for that to work, your transaction should fail

17:29 pnkfelix: eee: like the example of wanting to make sure that at most one account goes to negative balance

17:30 slashus2: Mec: I mean like pircbot or a GUI event binding.

17:30 Mec: just like a way to register/call events and whatnot?

17:31 slashus2: Mec: I guess call backs would be the way.

17:31 lisppaste8: Mec pasted "Events" at http://paste.lisp.org/display/77430

17:31 Mec: thats the simplest way i can think of to concurrently do events

17:31 slashus2: neat

17:32 Why did you use an atom instead of a ref?

17:33 Mec: hellifiknow, that's how memoize is implemented

17:33 Chouser_: uncoordinated. that looks correct to me

17:34 Mec: whats the diff between ref and atom?

17:34 SethTisue: is an atom like a ref where if you want to change it the change implicitly is wrapped in a little transaction?

17:34 Chouser_: SethTisue: semantically that's pretty close. you need a transaction and refs when you have more than one ref involved in the transaction.

17:35 slashus2: So when you don't want serial events?

17:37 Chouser_: changes to an atom are serialized, but only on the one thing

17:37 slashus2: It won't be multiple all or nothing, just one.

17:38 Chouser_: if I want to update two refs in one transaction, such that either both or neither happen, I must use refs. If I only ever care about one at a time, I may be able to use atoms.

17:39 slashus2: Is it more efficient if you are only going to be modifying one ref to just use an atom?

17:40 Chouser_: yes, but it's a property of the reference type itself, not the change action (the transaction). So if this particular reference will ever be coordinated with others, it should be a ref -- otherwise an atom is fine.

17:41 slashus2: neat

17:41 hence the name: atom

17:41 Makes perfect sense now.

17:41 Chouser_: great!

17:42 slashus2: Chouser_: Can you think of an example of where using ensure is mandatory? I have played around with refs, but I haven't ever used ensure before.

17:46 I didn't see an example of using ensure in Programming Clojure.

17:50 Would you use it like (ref-set ref (ensure ref))

17:55 dreish: slashus2: When you read a ref within a transaction, you get its value at the instant your transaction started, but there's no guarantee it'll have the same value at the instant the transaction commits. ensure guarantees that. (Apologies if someone has already explained that.)

17:56 slashus2: Otherwise the transaction will retry.

17:57 dreish: Right.

17:57 slashus2: ensure keeps the transaction from having to retry?

17:57 dreish: No, it causes the transaction to retry if someone else has changed the value you read.

17:57 slashus2: I was under the impression that it did that automatically when that happens anyway.

17:57 dreish: No, not if you just read with deref.

17:58 deref is a fetch-and-don't-care-what-happens-afterward.

17:58 slashus2: In that case, when does a transaction retry?

17:58 without using ensure

17:58 dreish: alter

17:59 slashus2: So I only need to use ensure outside of alter?

17:59 dreish: You only need to use ensure if the end state of your transaction would be invalid if the ref in question changed after you read it.

18:00 The canonical example for why you wouldn't care if things change is a sales report as of an instant in time, where you just want to read things but it is understood that their values will keep changing after that instant.

18:01 A less business-y example would be writing a backup to disk.

18:01 slashus2: You just want to see a snapshot.

18:01 Don't care what happens.

18:01 dreish: I can't think of any easy-to-describe use cases where you actually _would_ care about the value; they're usually tied up in the logic of a more complex system.

18:02 care about the value not changing, that is

18:02 slashus2: dreish: Yeah, I can't think of one either, that was the root of my confusion.

18:02 dreish: Yes, I agree it is all confusing. :) It has taken me a few months to really get comfortable thinking in terms of transactions on variables.

18:03 slashus2: It is sort of a black box at first.

18:03 dreish: But I could see right away that it was useful.

18:03 The biggest problem I had was that I couldn't believe it was actually as magical as it really is.

18:04 slashus2: Using ensure would lead to more contention?

18:04 dreish: The idea that the moment you enter a dosync, all refs are instantly frozen from your point of view, even if you have tens of thousands of them -- it seemed like it couldn't possibly be right.

18:04 slashus2: More retries, but in my experience still not that many.

18:04 slashus2: dreish: You have used ensure before in an application?

18:05 dreish: I have a SQL persistence layer that represents a table as a lazy-loaded hash of refs, and I wrote a test function that creates N threads and has them all hammer the same row, doing an atomic get-and-increment.

18:05 With 100 threads, I only see maybe 1 retry out of around 200 transactions.

18:07 slashus2: This is what ensure does to a ref: public void public void touch(){ LockingTransaction.getEx().doTouch(this); }


18:08 It does lock(ref)

18:08 So ensure does lock it

18:09 Puts a write lock in it.

18:09 dreish: Looks that way.

18:09 slashus2: I am looking at LockingTransaction.java

18:09 very interesting

18:10 dreish: It is, but as rhickey always says, don't count on any implementation details as guarantees of a specific behavior.

18:10 Mec: what has a faster lookup, vector or hashmap?

18:10 slashus2: dreish: As they are subject to change?

18:11 dreish: STM is still a research topic, so I think he wants to reserve the right to throw out the entire current design and replace it with something else, preserving only the documented behavior.

18:11 slashus2: dreish: I would only look at the code in curiosity, minding the abstractions.

18:11 dreish: slashus2: No harm there.

18:12 Mec: I think they're nearly the same if you use keywords or integers as keys, but you could always try to benchmark them.

18:13 slashus2: Mec: I seem to remember that it was log32 for vectors

18:13 Mec: then its identicle

18:24 slashus2: So constant time for all practice purposes.

18:26 durka42: that's the idea

18:52 hiredman: ooo

19:07 ieure: Anyone have pointers to docs or examples for using zip-filter.xml?

19:55 slashus2: dreish: From the ant colony example, in the behave function, would ensure be useful instead of just dereferencing ahead when checking if an ant is ahead.

19:55 dreish: slashus2: I have to admit I've never read the ant colony code.

19:56 slashus2: I don't think it will be needed because on commit, it will check if an ant is ahead.

19:57 When you use @reference without ensure inside of a conditional statement, you are saying, if this is the case on commit.

19:57 dreish: This is to check before moving? If it uses alter(s) to actually do the move, ensure isn't needed.

19:57 slashus2: (and (pos? (:food @ahead)) (not (:home @ahead)) (not (:ant @ahead)))

19:58 dreish: No, you're saying "if this was the case at the beginning of the transaction."

19:58 slashus2: alter isn't used inside of the agent function.

20:00 but this check does happen inside of a transaction

20:28 Is that not a valid use of ensure?

21:08 Mec: anyone have a nice fast prime sieve?

21:11 gnuvince_: The one in clojure.contrib?

21:11 Mec: blaspheme

21:12 ieure: So, anyone have pointers on how to use zip-filter.xml?

21:12 Mec: where's it at in contrib? i dont see it

21:15 sohail: anyone here able to request me getting unbanned from ##java please :-)

21:17 gnuvince_: Mec: lazy_seq

21:39 Excuse me, is a macro completely expanded at read-time?

21:40 dnolen: all macros are expanded before read as far as I can tell.

21:41 actually it's seems weirder than that gnuvince

21:42 for example ^ and #' reader macros are evaluated before macro expansion

21:42 gnuvince_: So even if they have code like map or filter in them, they'll be executed and expanded completely at read time?

21:43 dnolen: you can have pretty much anything you want in the expansion.

21:43 gnuvince_: So control is thrown back and forth between the reader and the evaluator?

21:44 dnolen: you could have map and filter in the logic of the macro which creates the expansion, and in the expansion have macros, these will get expanded as well.

21:44 Raynes: gnuvince_: Macros are completely expanded in "Macro expansion" time according to Programming Clojure.

21:45 hiredman: which is after read and before "evaluation"

21:45 cmvkk: hmm that's weird. wouldn't it be during read? it's not the reader that's expanding macros?

21:45 (i don't actually know)

21:45 dnolen: i note that [] and {} #{} are not part of the reader

21:45 hiredman: ,(:macro (meta 'or))

21:45 clojurebot: nil

21:46 hiredman: ,(macro (meta or))

21:46 clojurebot: java.lang.Exception: Unable to resolve symbol: macro in this context

21:46 dnolen: that is they don't become (vector ...) or (hash-map ...)

21:46 hiredman: ,(:macro (meta or))

21:46 clojurebot: java.lang.Exception: Can't take value of a macro: #'clojure.core/or

21:46 hiredman: user=> (read-string "(or a b)")

21:46 (or a b)

21:48 user=> (macroexpand '(or a b))

21:48 (let* [or__3240__auto__ a] (clojure.core/if or__3240__auto__ or__3240__auto__ (clojure.core/or b)))

21:48 so obviously it is not expanded at read time

21:48 cmvkk: oh right. it's expanded at 'compile time' though.

21:48 ...right?

21:49 hiredman: that apears to make sense

21:52 Raynes: The Clojure google group has 1677 members!

21:53 There was only like a few hundred when I first looked at the group o.o

21:54 gnuvince_: What happens if I have side effects in my macro?

21:54 Better to avoid those?

21:55 cmvkk: they will occur at compile time

21:55 Raynes: gnuvince_: Depending on the side effects, you could kill your kitten, eat your babies, or implode the univurse :)

21:55 cmvkk: demons might fly out of your nose

21:55 gnuvince_: Yeah

21:55 That'll never work

21:56 Fuck I'm tired of hunting this performance problem

21:58 Raynes: For some reason, the Clojure plugin seems to interact with, and cause the Scala Netbeans plugin to throw an exception, but still work when a project is created.

21:58 Does anyone else here have both of these plugins installed and can confirm this for me?

22:19 duderdo: Anyone here running debian 5.0 with clojure?

22:28 Mec: how come it's every? but some

22:31 hiredman: ,(every? identity [nil 1 nil])

22:31 clojurebot: nil

22:32 hiredman: ,(some identity [nil 1 nil])

22:32 clojurebot: 1

22:32 Mec: i mean instead of some?

22:32 hiredman: ,(every? identity [1 1 1])

22:32 clojurebot: true

22:32 hiredman: some returns the result of the predicate, not true/nil

22:33 danlarkin: ? goes on the end of functions when they return a boolean

22:33 hiredman: the first non-nil(non false?) result of the predicate

22:33 Mec: why doesnt every just return the last value if all the previous are true?

22:36 meh not really important i guess

22:37 mattrepl: Mec: have an example? I think you're missing that every? returns either a single true or false after testing the predicate function on every element of the collection

22:38 slashus2: Does anyone have any input on my previous observation?

22:39 Mec: i was just wondering what the benefit is of having some return (pred x) instead of just true/nil

22:40 if it returned x the first time (pred x) was true, then i could see it working has a (first (filter))

22:41 gnuvince_: I'm sure this is asked often, but is there a way to force a macro to evaluate a symbol and not just take it as is?

22:41 hiredman: that is what unquote is for

22:42 '~"

22:42 '~'

22:42 gnuvince_: I meant at the call site

22:42 (my-macro my-var)

22:42 slashus2: Whether or not to use ensure in the case of the ant colony simulation where you are checking if an ant is in the position you are moving to. Currently, in the behave function, it is just a deref inside of a transaction.

22:42 gnuvince_: and that my-var be expanded to whatever it is that's in it

22:43 hiredman: gnuvince_: so actually you want a function

22:43 but, yeah, that is what unquote is for

22:43 gnuvince_: hiredman: I wanted a function, but this performance nightmare is forcing me to try every possible avenue

22:43 mattrepl: gnuvince_: or eval

22:43 gnuvince_: (and the next one, is to just abandon the entire venture and switch to Haskell)

22:43 cmvkk: gnuvince_: the problem is that at compile-time, you don't necessarily know what the argument evaluates to.

22:44 gnuvince_: cmvkk: ah, right

22:44 damn

22:45 cmvkk: is definline designed to solve that?

22:45 hiredman: have you tried definline?

22:45 gnuvince_: I haven't

22:47 Raynes: Shoot. I keep typing a parenthesis before method calls in Scala.

22:47 gnuvince_: Does definline work?

22:47 Raynes: -_-

22:48 hiredman: I've not tried it

22:48 gnuvince_: Can't get it to compile

22:51 hiredman: as in AOT compile?

22:51 gnuvince_: Ah

22:51 It must return a list

22:51 hiredman: how so?

22:51 (definline f [x] x) works fine here if I call (f 1)

22:52 cconstantine: given two lists, is there an idiomatic way of combining them such that each element of the new list is every element of one list functioned to every element of the other list?

22:52 gnuvince_: (defninline foo [xs] `(something and such))

22:53 durka42: definline, not defninline

22:53 hiredman: (map #(% %2) list1 list2)

22:53 gnuvince_: durka42: whatever

22:53 hiredman: cconstantine: s/functioned/applied/

22:54 cconstantine: hiredman: oh.. thats what map does when given multiple lists? I thinking there is an x-y grid and I want to hit every spot

22:54 hiredman: gnuvince_: definline doesn't handle quoting like a macro, it is more link a function

22:55 durka42: cconstantine: map doesn't do that. given two lists it applies the function to the i-th element of both.

22:55 hiredman: it just copies it's body inline whereever the function call happens

22:56 cconstantine: durka42: is there a way to do what I want (without making my own function for it)?

22:56 durka42: ,(for [x (range 3) y (range 3)] [x y])

22:56 clojurebot: ([0 0] [0 1] [0 2] [1 0] [1 1] [1 2] [2 0] [2 1] [2 2])

22:56 durka42: is that what you want?

22:56 hiredman: pffft

22:56 cconstantine: durka42: I think then I can just... map my function to the resulting list?

22:57 durka42: well yeah, or put the function in there

22:57 hiredman: ,(map vector (range 3) (range 3))

22:57 clojurebot: ([0 0] [1 1] [2 2])

22:57 durka42: ,(for [x (range 3) y (range 3)] (+ x y))

22:57 clojurebot: (0 1 2 1 2 3 2 3 4)

22:57 * cconstantine needs to learn more about 'for'.

22:57 hiredman: ~for

22:57 clojurebot: for is not a loop

22:57 hiredman: ~for

22:57 clojurebot: for is a loop...in Java

22:57 hiredman: ugh

22:57 cconstantine: hehe

22:57 hiredman: who did that?

22:57 ~for

22:57 clojurebot: for is a loop...in Java

22:57 durka42: well, neither is map

22:57 hiredman: bah

22:58 slashus2: :-(

22:58 durka42: there is doseq, which is like for but really a loop

22:59 gnuvince_: definline isn't working

23:01 cconstantine: ,(for [x (range 10 10) y (range 10 100)] (* x y))

23:01 clojurebot: ()

23:01 cconstantine: is that a bug?

23:01 oh asdfasdfas nevermind

23:02 :)

23:02 slashus2: It behaves like nested loops.

23:02 durka42: ,(range 10 10)

23:02 clojurebot: ()

23:05 slashus2: durka42: Any idea about my ensure conundrum?

23:05 * durka42 missed it

23:05 durka42: has it hit the logs yet?

23:05 cmvkk: is your problem just that you think it should be used in ants when it isn't?

23:06 durka42: oh wait, it is in my backscroll

23:06 slashus2: cmvkk: I don't know.

23:07 maybe

23:07 cmvkk: not having read the ants program, isn't it that if you're checking to see if it's okay to move into a square, that you're then moving into it if it is okay?

23:07 slashus2: The dereference happens inside of a transaction.

23:07 yes

23:07 cmvkk: right, but then don't you alter it in the same transaction?

23:07 slashus2: no

23:07 cmvkk: by actually moving into it?

23:07 slashus2: Wait.

23:07 cmvkk: so you just check to see if it's empty, then that's it?

23:08 slashus2: Let me confirm that.

23:08 I think so.

23:08 So in that case it is okay. As long as it is within the same transaction.

23:09 cmvkk: if you're altering a ref within a transaction, then you're basically ensuring it for that transaction.

23:09 durka42: so if you read and then later write, and it has changed in between, you retry?

23:09 cmvkk: that ought to be the case.

23:09 when you enter a dosync, you're grabbing a snapshot in time of all the refs you touch.

23:10 (i think)

23:10 slashus2: Move is called inside of the transaction, which does alter.

23:10 For some reason I didn't see that.

23:11 I understand. I am still getting a grip on the transactions on variables thing.

23:48 hiredman: ,(into {} [:a :b])

23:48 clojurebot: java.lang.IllegalArgumentException: Don't know how to create ISeq from: Keyword

23:49 hiredman: ,(into {} [[:a :b]])

23:49 clojurebot: {:a :b}

23:49 hiredman: excellent

23:49 cmvkk: you know it would be better if commas, instead of spaces, were just nothing.

23:49 that way you could use them in numbers.

23:49 like 3,000,000 which doesn't work

23:50 Mec: is there a better way to do this: (every? identity (map somef coll1 coll2))

23:51 durka42: is that the same as (every? somef coll1 coll2)

23:51 Mec: i dont think every takes more than one coll

23:51 cmvkk: no, it's doing the map then checking to see if there's any nils

23:51 Mec: ideally i'd like to do what durka suggested

23:52 cmvkk: ahh, i see now

23:52 Mec: tho i guess since map is lazy it will still only take 1 pass not 2

23:53 durka42: correct

23:53 (i think)

23:54 Mec: yup so other then being verbose there's no problem

23:55 durka42: (every? (partial apply somef) (map vector coll1 coll2))

23:55 that's worse

23:56 Mec: i dont think that would work

23:56 durka42: ,((partial apply +) [1 2])

23:56 clojurebot: 3

23:57 Mec: oh i see

Logging service provided by n01se.net