#clojure logs

2009-10-24

00:21hiredman,(macroexpand '(lett [x 1 y 2] (+ x y)))
00:21clojurebot((clojure.core/fn [x] (sandbox/lett [y 2] (+ x y))) 1)
00:26qedhow do you use clojure.contrib.combinatorics
00:27qedor any library
00:36hiredman(use 'clojure.contrib.combinatorics) will make everything available in the current ns
00:37hiredman(require 'clojure.contrib.combinatorics) will load the library, but you will need to prefix calls to fns from the library with the libraries namespace
00:37hiredmanthere are various variations on the two
00:38qedhiredman: should it return nil
00:41hiredmanyep
00:42hiredman,(require '[clojure.zipper :as zip])
00:42clojurebotjava.io.FileNotFoundException: Could not locate clojure/zipper__init.class or clojure/zipper.clj on classpath:
00:42hiredman,(require '[clojure.zippers :as zip])
00:42clojurebotjava.io.FileNotFoundException: Could not locate clojure/zippers__init.class or clojure/zippers.clj on classpath:
00:42hiredmanbah
00:42hiredman,(require '[clojure.zip :as zip])
00:42clojurebotnil
00:43hiredman,(-> '(a (b c (d e) f) g) zip/seq-zip)
00:43clojurebot[(a (b c (d e) f) g) nil]
00:43hiredman,(-> '(a (b c (d e) f) g) zip/seq-zip zip/next zip/next (zip/replace 'X))
00:43clojurebot[X {:changed? true, :l [a], :pnodes [(a (b c (d e) f) g)], :ppath nil, :r (g)}]
00:43hiredman,(-> '(a (b c (d e) f) g) zip/seq-zip zip/next zip/next (zip/replace 'X) zip/root)
00:43clojurebot(a X g)
00:51qed(phmmm
00:51qedi have (def nums (range 1 100))
00:52qedim trying to use (reduce fn (nums))
00:52hiredmannums is not a function
00:52qedoh duh
00:52qedhiredman: basically im trying to add the squares of 1 to 99
00:52qed1^2 + 2^2, etc
00:53qedwhats a good way to do that
00:53qedcould i be fancier in how i use (range 1 100)
00:55hiredman,(-> 1 (range 100) ((partial map (comp (partial apply *) (partial repeat 2)))) ((partial apply +)))
00:55clojurebot328350
00:56hiredman:P
00:56qedhaha
00:56qedi dont understand your partial stuff
00:56qedbut thanks for the code
00:56hiredman,(doc range)
00:56clojurebot"([end] [start end] [start end step]); Returns a lazy seq of nums from start (inclusive) to end (exclusive), by step, where start defaults to 0 and step to 1."
00:56qedill study it
00:56hiredmanpartial is partial application
00:56hiredman,(partial + 1)
00:56clojurebot#<core$partial__4965$fn__4967 clojure.core$partial__4965$fn__4967@19a12cb>
00:56hiredman,((partial + 1) 1)
00:56clojurebot2
00:57qedah ha
00:57qedthanks for your help man
00:57qedand congrats on solving the 3rd easiest problem on project euler in one line on irc in 5 minutes
00:57hiredmanoh, well, I've eulered before
00:57hiredmanbut was before my -> addiction
00:58qedwhat is ->
00:58hiredmanit's the thrush combinator
00:58qedwow that is awesome
00:59hiredman,(-> 1 inc inc)
00:59clojurebot3
00:59hiredman,(inc (inc 1))
00:59clojurebot3
00:59qedvery cool
00:59qedthanks for the info
00:59qedback to euler :)
01:03tomojdammit
01:03tomojI can't start sbcl slime anymore because it automatically tries to require clojure.test
03:32hiredmanugh, syntaxquotereader is so gnarly looking
05:34tomojambient: are you the one doing sound stuff with clojure?
05:44G0SUBI think there is some problem with c.c.http-agent.
05:44G0SUB(http-agent "http://yahoo.com/&quot; :handler (fn [a] (string a)))
05:45G0SUBwhy is this returning an agent error?
05:45G0SUB#<Exception java.lang.Exception: Can't await in agent action>
05:45G0SUBany ideas?
05:54arsatikig0sub: don't use string (or bytes or stream) in the handler, since they all call result in the end
05:55arsatikiwhich calls await. and that raises the error
05:56arsatikino wait
05:56arsatikiI was wrong
05:57G0SUBarsatiki: how does this work? http://freegeek.in/blog/2009/10/downloading-a-bunch-of-files-in-parallel-using-clojure-agents/
06:00ttmrichterIt's too anxious for the agent to act? (Seriously: no idea. Just like the error message.)
06:05arsatikiit seems stream is fine, bytes and strings less so.
06:05snowwhite07Doesn't lazy-cons exists?
06:11hoeck1snowwhite07: lazy-cons was superseded by lazy-seq in the 1.0 release
06:11snowwhite07hoeck1, oh, thanks
07:19adityohow will i convert a stream to a string?
07:53adityogot it
09:09tomojis it true that structmaps don't know what kind they are?
09:09tomojor, that they can't tell me, I mean?
09:11notallamapretty sure it's just a hashmap, but with optimizations.
09:12tomojlooking at the source, it appears they know, but the field is not public and there's no accessor
09:12tomojguess I should use :type metadata
09:16tomojeh, clojure-json won't call the multimethod on structmaps anyway
09:19notallamaclojure.lang.Script doesn't seem to print anything. (i have just a print statement in the script). any idea what's up with that/how to change it?
09:32tomojnotallama: try clojure.main
09:32notallamaok, found the problem. print doesn't automatically flush
09:33tomojweird
09:34tomojwhen running with clojure.main, it does, but not with clojure.lang.Script
09:44tomojheh, I stared at "(= codepoint 0x7D) object ; }" for a minute confused by the unmatched "}" and wondering if ";" was some weird reader construct I hadn't seen before
09:44tomojI need sleep :)
09:46notallamai was confused by it as well. :V that just made me realize how little i use comments.
09:47notallamai guess with docstrings, i don't need them much
09:47tomojI think the spacing makes it more confusing too
09:48tomojif it were "(= codepoint 0x7D) object ; }" I would've understood it immediately I bet
09:48notallamawhat changed?
09:49tomojmore space before the comment
09:49tomojso that ; and } aren't spaced like forms usually are
09:50notallamaah. irc ate the extra space, i guess
09:50tomojtest (this is in the middle of lots of spaces) test
09:51notallamaall single spaces there.
09:51tomojweird
09:58notallamapointfree style is pretty fun. so i just made a bunch of functions to support it (i stole >>>, &&&, ***, ||| and +++ from haskell, basically). perhaps this is a project for github/contrib if people like it.
09:59rhickeynotallama: got some sample code using it?
10:02rhickeyhmmm... could support dynamic defclass where class visibility was limited to the same file
11:02hvesalaijust coded my first line of clojure
11:02durka42welcome!
11:02hvesalaiis (Integer/parseInt s) an idiomatic way to turn string into number?
11:03durka42probably
11:03hvesalaior is there something in clojure API for the same task?
11:03chouserhvesalai: yep
11:03chousernope
11:03hvesalaiok
11:04hvesalaiis it so that I have to code clojure "bottom up" i.e. define functions before I can use them in the definitions of an other function
11:04hvesalaii.e. i cannot say (defn b [x] (a x)) (defn a [y] (+ y 1))
11:05rhickeyhvesalai: you can use declare to make names available before definition
11:05durka42yes, except for declare and letfn
11:05hvesalaiok
11:05rhickeychouser: did you see: rhickey: hmmm... could support dynamic defclass where class visibility was limited to the same file
11:06chouserrhickey: no! reading logs now...
11:06rhickeyi wonder about the utility, in the new branch I just made it so all code loaded in same file shares a classloader
11:07rhickeyso a defclass could install the class in the dynamic classloader loading the file, where it could be found by subsequent calls to new and .field etc
11:07chouserinstead of one classloader per ... what, top-level form? per "load" call?
11:07rhickeyhowever, partial recompilation (select block, eval) as is common in interactive dev, wouldn't work well
11:07rhickeyper load call
11:08rhickeynot important to expose now, I needed it for deftype
11:09chouserREPL classloader would be unable to see the defclass's dynamically loaded via a 'load' or 'require'?
11:09rhickeychouser: right
11:10chouserthat sounds ... well, really confusing. :-)
11:10chouserworse than rootloader
11:11rhickeyyeah, probably no need given fully dynamic deftype
11:11rhickeyI'm pulling apart reify now...
11:11rhickeydeftype will be defined in terms of defclass
11:12chouserlet us know when you're ready for help with hashcode, equals, etc.
11:12rhickeychouser: will do, thanks
11:13rhickeyone more issue was the fact that when using deftype, you;ll need a factory function that can set all of the fields, including meta and extmap, else you can;t really write functions that construct new instances
11:13chouserI'm hopeful it will be done (enough) in time to cover it in the book.
11:14rhickeyI hope to get through the bulk of it today, with the same limits currently for reify (type of this, covariant return bridges not emitted)
11:15chouserare bridge methods too hairy for others to help out? proxy does them already, doesn't it?
11:16rhickeyso, the type factory fn might look like this: (fn ([the fields you supplied] ...) ([the fields you supplied meta extmap] ...))
11:16rhickeychouser: unfortunately I copied gen-class and not proxy when I did reify :(
11:16rhickeybut yes, the logic is in proxy
11:17rhickeyright now I just want to simplify as much as possible, getting rid of complexity relating to concrete supers
11:17rhickey(which is not much, as I didn't support ctors with args/protected/supercalls yet anyway)
11:19rhickeyalso I want to make it so the bulk of the generated impls (hashCode, equals, meta, type, etc) are done not by direct ASM emit, but by Java code emitting forms subject to normal compilation
11:22rhickeyso I'm concerned about the second form of the factory fn above
11:23chouserit doesn't look very scary to me -- so obviously I don't understand sufficiently. :-)
11:24rhickeysomething like that is needed so you can write fns that create complete values, but I wonder if people will constantly have to wrap it in order to get what they have with struct-map
11:25rhickeyare people often creating structs with struct-map, i.e. with extra/partial field sets?
11:26chouserauto imeta impl will mean with-meta will Just Work, right?
11:26chouserand similar for assoc/dissoc?
11:26rhickeyith-meta is IObj
11:26rhickeywith-meta
11:27rhickeyIMeta is just meta
11:27rhickeyILookup gives you get
11:27chouserok. you weren't planning on providing easy support for with-meta?
11:28hvesalaiso can I convert strings into keywords (for adding keyword,value pairs into a map)
11:28rhickeyand Associative assoc
11:28rhickeychouser: yes, with-meta via IObj
11:28chouserhvesalai: you can use strings as keys in maps, but you can use the fn 'keyword' if you want to convert.
11:28chouser,(keyword "foo")
11:29hvesalaithanks
11:29chouserrhickey: so the extra ctor has to be there to support Associative and IObj methods. What wrapping would users feel they need beyond those?
11:30rhickeychouser: well, and protocol that was like that, i.e. that required you to create a new 'modified' value, would require you to copy all fields
11:30rhickeyany protocol
11:30hvesalaiis anybody using the counterclockwise eclipse plugin to generate java classes?
11:31hvesalaiI didn't find any way to make the classes appear in the classes directory other than running (compile 'mynamespace) in REPL
11:31hvesalaiis there a way to make ecplise do that for me automatically?
11:34rhickeychouser: think of using deftype to define PersistentMap where IPersistentMap was a protocol, you wouldn't have the auto-generated Associative, but you'd need to define fns that created new instances from old, propagating all stuff. In Clojure impl that stuff was usually just meta
11:35rhickeyand meta went first
11:35rhickey[meta the fields you supplied]
11:37rhickeyexpando complicates things, but without being built in it would mean every impl having to do the lookup work
11:42chouserthat does complicate things when they are trying to implement IPersistentMap themselves.
11:42chouserwithout closures you can't really share utility methods, can you.
11:43rhickeychouser: if the implement IPersistentMap/Assoc/ILookup they don't get expando or impls of those
11:44rhickeychouser: the thing is the lookup will be custom compiled per class, thus really fast, so not generic code that can be reused
11:44rhickeyI want lookup to be much faster than structs right now
11:45rhickeyright now - lookup index in map of key->index, then lookup field val in array at index
11:45rhickeytypes/classes: generate a switch statement based on key hashes
11:46rhickeyinline code returns .field
11:47rhickeyfind perfect hash and pack for tableswitch
11:47rhickeyin any case, custom code per type/class
11:53mgarrissWrite a function foo that takes a number n and returns a function that takes a number i, and returns n incremented by i. (i.e. an accumulator generator)
11:54mgarrissin javascript: function foo (n) { return function (i) { return n += i } }
11:54mgarrisstrying to figure out how to do it in clojure
11:55mgarrissin ruby: def foo (n) lambda {|i| n += i } end
11:55chouserright, custom code, but possibly via macro instead of asm (assuming tableswitch can be exposed sanely I suppose?)
11:56rhickeychouser: not a macro until cinc
11:57chousermgarriss: both your examples mutate a local -- clojure locals are immutable
11:58rhickeyalmost of of the versions here: http://www.paulgraham.com/accgen.html are broken in the face of concurrency
11:58chousermgarriss: so instead you'll want to choose a Clojure reference type, probably an atom
11:58rhickeyand the whole premise in unsoundly stated - " returns n incremented by i"
11:59rhickeybut as chouser says, you can make a threadsafe version in Clojure with atom
12:00rhickeyif n is a number it can't be incremented as distinct from plus. One can't increment 42 in the sense he states, so there's a presumption of holes in environments etc
12:01rhickeyLike the Erlang/Haskell/Mozart examples there, Clojure correctly requires you put the state in an explicit container
12:03rhickeysince holes in environments are usually bereft of concurrency semantics
12:03tomoj(defn accumulator [n] (let [acc (atom n)] (fn [i] (swap! acc + i)))) ?
12:04rhickeytomoj: right
12:04mgarrisstomoj: that works
12:04rhickeyand of the concurrency correct versions, the shortest and simplest
12:06tomojclojure makes me happy
12:06solussd,(str "[" (apply str (interpose "] [" (range 10)) "]"))
12:07mgarrissi've never used atom or swap! before
12:08mgarrissrhickey and chouser: i'm still having problems thinking in a immutable way, thanks for the pointers
12:08tomojmaybe you mean (str "[" (apply str (interpose "] [" (range 10))) "]") ?
12:10rhickeyand in a golf match for brevity with the other versions there: (defn foo [n] (let [a (atom n)] #(swap! a + %)))
12:10mgarrissok, an algorithm problem: can i write a function that returns the intersection of two collections that is better than O(n^2) ?
12:11tomojcertainly
12:12tomojmaybe I'm just hallucinating from sleep-deprivation, but I can't even imagine an O(n^2) algorithm
12:13tomojthe naive solution, I think, is O(n)
12:13mgarrisswhat would that be?
12:14mgarrissin pseudo-code is fine
12:14tomojoh, I see what you mean I think
12:14solussdi cant think of one that is O(n). :)
12:14tomojif it takes O(n) to see if something's inside, then it's O(n^2) I guess
12:15tomojyou could get best-case O(n log n) by sorting first I suppose
12:15mgarrissi'm thinking about creating a hash with the second coll and using that to compare against, not that's better
12:15mgarriss*not sure that's
12:16tomojprobably a set would be better
12:16tomojah yes, you can make a set out of one of them, which has (I think?) constant time lookup, then run down the other for O(n)
12:16spuzmgarriss: Clojure already has such a function: http://clojure.org/api#toc659
12:16mgarrisssorting is not an option, the collection it heterogeneous
12:17tomojyou can certainly make a set, though
12:18mgarrissspuz: this is a question i got passed on in an interview, i want to know the algorithm used
12:18mgarriss-got
12:19spuzheh ok
12:19tomojhmm
12:20spuzI imagine if the set lookup is O(1), then intersection is O(n)...
12:20tomojclojure.set/intersection seems worse than linear
12:23solussdthe naive implementation is an order of magnitude faster than clojure.set/intersection: (defn intersection [a b] (filter #(contains? a %) b))
12:23tomojwhy is clojure.set/intersection slow?
12:27tomojoh, I think I might see why
12:28solussd?
12:29tomojwell, I'm not really sure, but it looks like what it's doing is looping through the longer set and for each item, checking whether it is in the second, and if not, disj'ing it from the accumulator
12:29tomojmaybe disj is worse than constant time?
12:31mgarrissthe hash idea in ruby: def intersection(a, b) h = a.inject({}){|m,e| m[e] = true; m}; b.delete_if{|e| !h[e]} end
12:31mgarrissthat's better then n^2 i htink
12:31tomojthat's pretty much what set/intersection does
12:31tomojif I understand it right
12:32mgarrissmake a hash like hash[key] = true for the one coll, then use that to compare against the second
12:33mgarrissi can't figure out the big O level of it however, it's been too long since i was in school
12:33mgarrissis it 2n ?
12:33mgarrisscreating the hash is n
12:34chouserclojure.set/intersection returns a set -- solussd's naive implementation returns a seq
12:34Chousukewhy would you need a separate hash? /:
12:35mgarrissChousuke: i don't know how else to do it
12:35Chousukethe fastest interjection would be (into #{} (filter shorter-seq larger-seq))
12:36Chousukeet
12:36Chousukeshorter-set of course
12:36solussdyep.. returning a set definitely would make the time difference. :)
12:37Chousukethough I suppose that would fail if there are nils or falses in the set :)
12:37tomojbut making a set should only be roughly O(n), yes?
12:38solussdyes
12:39Chousukeyeah. intersection should be O(n)*lookup
12:40tomojI'm trying to graph my results of set/intersection to see better if it's really more than O(n)
12:40Chousuke~def intersection
12:40Chousukeoh shoot
12:44tomojI think it is actually linear
12:49spuzis it possible to use 'loop' to make an infinite sequence?
12:52ambientthis interests me too
12:53ambient(defn foo[] (lazy-seq (loop [n 0] (recur (inc n))))) don't seem to work
12:55tomoj(loop [] (iterate inc 0)) :P
12:55ambientwhich does not use loop/recur :/
12:55tomojI can't imagine how or why you'd use loop for an infinite seq
12:56tomojexcept if calculating the values requires looping
12:56spuzhmm
12:57tomojoh, I see
12:57tomojwell
12:57tomoj(defn foo [] (loop [n 0] (lazy-seq (cons n (recur (inc n))))))
12:57tomojbut you can't do that
12:57tomojbecause you can only recur from tail position
12:58tomojlazy-seqs make loop unneeded
12:58tomojyou can just call the function and the stack won't blow
13:00lisppaste8spuz pasted "Inifnite mandelbrot set" at http://paste.lisp.org/display/89213
13:01tomoj(defn foo [] ((fn rec [i] (lazy-seq (cons i (rec (inc i))))) 0))
13:01spuzWell, I'm trying to optimize that function, while keeping it lazy
13:02spuzif say I call (nth (mandelset -0.123 -0.234) 100000) I believe the multiple function calls and maps are slowing it down
13:02chouserlazy seqs can't be made of primitives, nor can you avoid allocating memory as the seq is walked.
13:03chouseryou can however use chunked seqs which reduces the number of allocations per item.
13:04tomojiterate doesn't chunk?
13:05lisppaste8rhickey pasted "reify/deftype syntax unification" at http://paste.lisp.org/display/89214
13:06rhickeythe macro-izable versions are pretty verbose
13:06rhickeyplus I really like implicit this
13:07rhickeydefclass same as deftype
13:10lisppaste8rhickey annotated #89214 "another reify possibility" at http://paste.lisp.org/display/89214#1
13:13rhickeyI guess it's a wash for simplest things:
13:13rhickey(proxy [ActionListener] [] (actionPerformed [evt] ...))
13:13rhickey(reify [ActionListener (actionPerformed [evt] ...)])
13:14chouserhm, so listing the interfaces separately from the methods complicates providing macros that do both for you
13:14rhickeychouser: I think so, also methods in blocks vs a la carte
13:15rhickeyelse you'd need to, e.g., unroll do in macroexpansions that emit multiple methods
13:16rhickeythe whole macros for methods is a bit speculative right now
13:16rhickeyit's certainly more declarative to have the interfaces listed together
13:17div`when doing methods in an interface block, isn't it more confusing when 2 or more interfaces have a common method
13:17rhickeydiv`: yes, that's a potential issue
13:18rhickeycan't really do validation per block due to potential overlap
13:18div`my gut feel is to prefer interfaces grouped together
13:18div`but that may be because of the java background too :)
13:18rhickeybut if you wanted to use macro to generate overlapping method sets you simply couldn't, not a big limitation IMO
13:19div`not a limitation, but may be confusing to a reader
13:20rhickeyanother possibility is to go proxy-style and use some sort of escape (~ ?) to trigger macroexpansion
13:21div`wooosh :<
13:22lisppaste8rhickey annotated #89214 "reify proxy-ish with macro escape" at http://paste.lisp.org/display/89214#2
13:22lisppaste8spuz annotated #89213 "Implementation using loops but no infinite sequences" at http://paste.lisp.org/display/89213#1
13:23spuztomoj: that implementation is about 5 times faster but it will only ever calculate values up to *max-iters*
13:23tomojwell, that's what you're probably doing for mandelbrot anyway, huh? :)
13:23spuzso, ideally, I'd want the best of both but I have no idea how to turn this looping version into an infinite version
13:24spuztomoj: yes exactly, but just from a functional point of view I'm wondering what the best way to do it is
13:26div`rhickey: that looks nice. Would be very handy to abstract away a generic implementation in a macro like that
13:26div`without having to sacrifice an extends
13:41toupsWhat is the idiomatic way to represent a homogeneous vector in clojure such that the compiler can optimize it?
13:41toupsI can see that you can type annotate arguments to functions
13:41toupsBut what if the argument is a vector of doubles?
13:41toupsShould I just use a java array?
13:42rhickeytoups: there aren't specializations of, e.g. vectors, for primitives yet
13:44toupsSo would it be reasonable to expect a java array to provide better performance?
13:46rhickeyfor many things yes, but you can't add to the end of an array, and they are not threadsafe under mutation
13:47toupsThat isn't an issue for this problem.
13:47toupsSo I should be ok
13:47toupsReally, I am prematurely optimizing.
13:47toupsPerformance is really not crucial at this point.
13:48toupsBut I am just considering future possibilities.
13:53ambienti tried using both infinite lazy-seqs and atoms in my program, but array beat them both by a factor of 100
13:55toupsHow do I type hint, for instance, an array of doubles?
13:55ambient#^doubles
13:56toupsMy
13:56toupsThat is nice
13:56toupsThanks
13:57ambientyou might find this useful: http://bitbucket.org/amb/clojure-snippets/src/tip/src/amb/synth.clj
14:00ambientit's currently unfortunately unreadable :(
14:00ambienti don't know how to make array code more immediately apparent
14:00ambientc-like structures might be useful
14:01ambientperhaps there is a way to build light-weight java classes. but that seems very un-clojur-ish to me
14:03ambientthe whole mutable arrays concept, accessing values by index, almost looks like anathema, but it's way faster than anything else as far as I can tell, because every variable in my program needs to be modifiable in runtime, anytime, anywhere, anyhow
14:07rlbIs there a clever idomatic clojure way to create a map with optional elements, i.e. elements that should only be in the map if some test is true?
14:08rlb(per-element)
14:13kunleyHi folks.
14:15chouserrlb: the best I've seen so far is (-> {} (conj (when foo [:k1 v1])) (conj (when foo2 [:k2 v2])))
14:15rlbchouser: OK, thanks -- I was just playing with (-> (hash-map required-bits) ...)
14:16chouserambient: light-weight java classes is a reasonable way to describe what rhickey is desiging as we speak.
14:17ambientcool :)
14:17toupsI find myself "map" ing and then immediately forcing the result into a vector.
14:18qedWhy doesn't clojure-mode auto-indent?
14:18toupsIs there a built-in function that allocates the output of map right into a vector?
14:18ambientqed you tried pressing tab?
14:18ambientthere was a way to make it auto-auto-indent but can't recall :(
14:20qedambient: im sure tab works
14:20qedbut yeah i wanted it to do fancy auto-auto
14:20qedit used to do it
14:20qednot sure why it doesnt now :\
14:21chouserhuh. 'vec' uses neither chunks nor transients?
14:22toupschouser: I am not sure I understand your question.
14:22toupsCorrect me if I am wrong, but map returns a seq
14:22toups?
14:23toupsIs there a map-alike that returns a vec without the laziness or conversion steps that (vec (map ...)) would have?
14:23toupsDoesn't matter, really
14:23toupsI am writing it now
14:23chouseryes, map returns either a chunked or regular seq
14:25chouseroh, it does use transients.
14:26toupschouser: does the use of transients effect the present situation?
14:26chouserso, if you map over a chunked seq and use 'vec' to put the results into a vector, that will almost certainly run faster than doing a non-chunked map into a non-transient vector.
14:26toupschouser: still seems like it would be less efficient than just writing a special version would put the output directly into a vector, no laziness.
14:27toupschouser: that seems counter-intuitive
14:27chousertoups: feel free to try it and let us know how it goes.
14:27toupsIs there someplace I can read about transients and mapping to get a sense for their performance profiles?
14:28ambientefficiency and dynamicity are often at odds with each other
14:28qedam i the only one in here who can't quit telling their CS friends to learn clojure because it makes all other languages look like worthless sh*t
14:28qedor is that common?
14:28toupsI think Haskell and Clojure are pretty neck and neck.
14:29toupsVery arguably, Haskell is more elegant, even if it is harder to wrap one's head around.
14:29Chousukemaybe it's counterintuitive because map and vec optimise things behind the scenes
14:29chouserwhat is Haskell's library story?
14:29ambienti wouldn't recommend clojure for anybody just yet, only for the hardcore enthusiast.
14:30qedHaskell is great and all
14:30qedbut the whole monad thing sort of sucks
14:30qedif I wanna do I/O in clojure, I can, without all of the extra garbage that goes on in Haskell
14:31qedthere are some weird edge cases where monads become a huge headache IIRC
14:31Chousukemonads are a neat construct though.
14:31chousertoups: if you write a fn that takes only Indexed collections and produces a vector via transients, you might be able to beat the speed of (vec (map ...)) by a bit.
14:31Chousukebeing *forced* to use them isn't so cool :/
14:31qedyeah, neat construct, but pretty constrictive
14:31qedexactly Chousuke
14:32qedim the programmer -- i dont need a forcing me to do my job in a certain way
14:32qedlanguage forcing*
14:32chouserambient: what would clojure need for you to start recommending it?
14:32Chousukeone thing I don't like about haskell is the large number of almost identical functions
14:32qedyeah that is a little annoying, i agree
14:33qedi havent sspent a ton of time on haskell, so i cant really speak with much authority on that
14:33Chousukeyou have foldl, foldl', zip, zip2, zip3, mapM, mapM_... icky :/
14:33toupsYeah
14:33qedyikes
14:33toupsStrong typing I guess.
14:33ambientchouser robustness, documentation, trial by fire etc... i just don't trust _any_ new technology by default for production use
14:34qedambient: i know people like you
14:34qed:)
14:34solussdambient: do you trust java?
14:34qedim the opposite (depending on what kind of stuff you're doing in "production", though)
14:34qedi say use what works
14:34qednew or old
14:35chouserambient: ok, thanks.
14:35ambientchouser anyway, it's a hard question. mainly just FUD
14:35ambientclojure hasn't done enough to assure me
14:35qedwhat if chouser holds your hand? :)
14:38chouserambient: that's fine -- just curious what Clojure needed to close the deal with you. Sounds like docs and time. Both are being worked on. :-)
14:45AWizzArdhttp://www.roberthalftechnology.com/SearchJobs?5_jobSearch.request_type=ViewJobDetail&amp;5_jobSearch.job_number=41891821&amp;5_jobSearch.single_job=true&amp;specificJob=41891821
14:52ambienti don't disagree that clojure looks like the best thing since sliced bread. it's just very "raw"
14:52qedi think that's how lisp has always been
14:53qedraw is what makes it so flexible
14:53ambientraw as in very limited set of tools
14:53qedsee i just disagree with that because Java kind of renders that argument null
14:54ambientin theory it does. but the java interop is not without its problems
14:54ambienti digress, i should write more code, talk less :)
14:57qedhehe
14:58qedim using it to do the euler project right now
14:58qedit's going pretty well
14:58qedive finished most of the first page with clojure
14:58ChousukeI doubt anyone would disagree that Clojure is still rough around the edges. :P
15:02somniumare there any test-coverage tools for java that can analyze the .class files that clojure outputs?
15:02tomojthat's a good question
15:04somniumafter a week of hacking in the repl I have a usable library but about 6 assertions :( (all the functions worked at repl, I swear)
15:54toupsWhat is up with not being able to use -'s in clojure filenames
15:55toupsI know it is trivial, but it sort of grinds my gears.
15:55ChousukeJVM limitation
15:55qedit's a "c'mon son!" moment
15:55dreishI'm not a fan either, but at least it isn't rhickey's fault.
15:56ChousukeI think it could be worked around but it's more work than it's worth I guess :P
15:56dreishUnderscores are teh s uck.
15:56toupsIs there any convention?
15:56toupsLike do people just avoid using names that have dashes, or do they just use underscores in the filename and dashes in clojure?
15:56toupsOr do we use just underscores everyone in library names?
15:56Chousukeyou need to name your files using underscores instead.
15:56toupsOr is it a big mess.
15:57Chousukeno, all clojure-facing names have normal dashes.
15:57Chousukejust the filenames get underscore treatment
15:57dreish(use 'my-lib) => my_lib.clj
15:57chouserthe filenames use underscores so that they can be valid Java package and classnames.
15:58toupsThanks
16:15qedhow would i turn a large number into a sequence of digits?
16:15ambient,(str (int 101010))
16:15ambienthmm no clojurebot? :(
16:16ambientwell at least for me the class that the aforewritten piece outputs is java.class.String
16:16qedlooks like i doesnt
16:16qedambient: thanks
16:16qedthat's really awesome, i guessed it would be harder
16:17ambientyou can loose the int part
16:17ambientif you already know your type
16:17chouserlose
16:18ambientthank you, language police
16:18chousersorry
16:18qedhmm why doesnt: user> (reduce + (seq (str (factorial 100))))
16:18qedwork?
16:19chouserqed: + is for numbers not Characters
16:19qedah, hmm
16:19ambient(map int your-seq) i'd think
16:20ambientif you want to sum the ascii codes
16:20qedi want to sum the digits of 100!
16:26chouseryou want to do it via strings and characters, or via math (dividing by 10s)?
16:26qedeither way is fine
16:27chouserqed: you know about the project euler clojure wiki?
16:27qedyeah im not trying to cheat just yet
16:27qedif you can give me a hint on a function to use
16:27chousergood. :-)
16:27qedto turn my seq of chars back into ints
16:27qedthat'd be cool
16:27chouserint
16:27qedk thanks :)
16:27chouser(int \0) ==> 48
16:28chouserqed: which problem number is this?
16:28qedit's so early on im going to embaress myself
16:28qedi think it's like #20
16:29qedyeah #20
16:29chouserhm, never did 20 in clojure.
16:29qedi need to get \9 to be 9
16:29qednot 57
16:29qedi was gonna do (reduce + (seq (str (factorial 100))))
16:29chouserI've a gap between 14 and 24 where I only used scala
16:29qedsomething like that
16:30chouser(- 57 48) ==> 9
16:30qedahhhhh, yes
16:31somniumis it worth going through all the problems in clojure? I did the first 10 or so until I started getting comfortable, then I got programming clojure and just started hacking.
16:32chouserI didn't lose interest until around 50, though I've done a few others above that.
16:33chouserthough I didn't switch from scala to clojure until around 30, and went back and did the first few over again in Clojure later.
16:36somniumCan you recommend any good sources for pattern matching in clojure? I watched most SICP, but I don't think I quite got it.
16:37tomojthere's pattern matching?
16:37ambientthis is what i came up: (reduce + (map #(mod % 10) (take-while #(>= % 1) (iterate #(int (/ % 10)) 123456789))))
16:38somniumin SICP they implement pattern matching in scheme, its not built in
16:38tomojah I see
16:43qedhow do i do something like: (map (- 48) sequence-of-ints)
16:43dreish(map #(- % 48) ...)
16:44dreishOr if you want to be flashy, (map (partial + -48) ...)
16:44somniumlol
16:45tomojhmm
16:45tomojwhy + -48 instead of - 48?
16:45somniumim not sure if that qualifies as flashy or something else
16:45dreishWrong argument order.
16:45tomojoh, yeah
16:45dreishsomnium: Tell that to the Haskell people.
16:45tomoj(-48) :(
16:46qedoh right, a little lambda
16:46qedim so used to having lambdas hidden from me
16:46tomojguess it would have to be (- 48) eh
16:46somniumI've been putting off learn Haskell because I'm afraid I won't be able to enjoy monad tutorials anymore
16:46tomojI'm learning haskell because the monad tutorials make no sense to me
16:47qedhaha
16:47ChousukeI need to reread monad tutorials periodically to refresh my enlightenment.
16:48qedthat's a running joke in #haskell
16:48qedhow many monad tutorials do you need to read to understand it
16:48ChousukeI think I kind of get gist of monads but I still wouldn't be able to use them effectively :P
16:48qedyeah same here
16:48dreishHow many monad tutorials does it take to screw in a light bulb?
16:48qedi dont know, how mnay?
16:48qedmany*
16:48dreishI don't know. That was the punchline.
16:49qedoh i thought youd have some slick haskell code
16:49qed:)
16:49Chousukedreish: well, seeing how screwing the light bulb is quite side-effecty, I'd guess at least a dozen
16:49dreishTrying to do some simple state change, like screwing in a light bulb, spending two weekends in a row staring at monad tutorials ...
16:49qedyeah, a light bulb into a socket, sounds like IO to me
16:50ambient(swap! old-bulb new-bulb) :p
16:50dreishI think it would be (swap! bulb change-bulb)
16:51dreishOr (reset! old-bulb new-bulb).
16:52somniumI think new-bulb was a variadic function that spontaneously creates a new light-bulb
16:52dreishI guess that works.
16:53qedwhat does % do in #(- % 48)
16:53ambient(fn [x] (- x 48))
16:53dreishIt's the argument to the lambda.
16:54qedahhhh thanks dreish
16:54qedits a special variable then?
16:55somnium# <- is a reader macro
16:55dreishIt's technically reader syntax.
16:55dreishTry '#(+ % %)
16:55ambientyou can also use %1 %2 %3 etc
16:56ambient(fn [x y z] (+ x y z)) => #(+ %1 %2 %3)
16:56dreishDon't forget %&
16:56ambientwhat does that do?
16:56somniumthen it really starts to look like perl
16:56danlei((fn [%] %) 1) is almost the same as (#(%) 1), but the latter won't work
16:57dreish'#(list %& %) => (fn* [p1__1852 & rest__1851] (list rest__1851 p1__1852))
16:58somnium,(#(%) #(+ 2 3))
16:58somniumhmm, he must be off today...
16:58dreishNow you're thinking with lambdas.
16:59qedahhhh
16:59qedthanks
17:01somniumI have this library, maybe 200 - 300 lines, and this feeling it could be one function, that takes one value and 20 keywords, and does (apply comp .....)
17:02somniumI need to reread SICP
17:03qedSICP is sort of dated IMO
17:03qedi know that's heresy
17:03qed:X
17:04lpetithvesalai: still struggling with counterclockwise to have your classes compiled automatically ?
17:06somniumsome of it, like environment and objects, is almost ridiculous nowadays, but the functional parts are still mind-expanding for me
17:24toupsPS - the best way to get monads is to implement them in your favorite language.
17:24toupshttp://github.com/VincentToups/emacs-utils
17:25toupsThis may be of interest to clojure users
17:25toupsIt is an implementation of clojure style destructuring binds for function definitions and let forms for emacs lisp.
17:25toupsAlso included is a simple implementation of monads ala the clojure-contrib library.
17:26toupsI wrote it because I didn't want to re-implement common-lisp style destructuring just to get lexical functions, and the destructuring syntax in clojure is simpler.
17:27toupsBut it also provides non-lexical versions of defn and let.
17:41KjellskiGood evening..
17:41Kjellski=)
17:43AWizzArdNa Kjell, alles klar?
17:46KjellskiHö? Jow bei mir is alles klar... woher kenne ich Dich?
17:46Kjellski^^
17:51KjellskiSorry for german... but that´s confusing, do I know you?
17:55KjellskiWe´ve got it private, nevermind...
18:00danleiWie klein die Welt doch manchmal ist ;)
18:00KjellskiWieso?
18:01danleiAh, dachte ihr hättet euch grad zufällig getroffen ...
18:02KjellskiKannten uns nicht, aber er hat an meinem ".de" Login erkannt das ich wohl auch aus Deutschland komme und mal Nabernd gesagt ^^
18:03danleiachso .)
18:04Kjellski*lach* den Smiley merk ich mir .)
18:16qedso in clojure a conj adds to the end when appropriate
18:17qedand a cons always adds to the ead
18:17qedhead*
18:17qed?
18:17qedthe way it says conj adds to different "places" as appropriate is a tad confusing
18:17qedif i conj onto a set, it wont go to the end or the beginning, right?
18:17qedwell, it could, but not every time
18:18rhickeyconj adds to a collection. hash sets don't have places
18:21qedrhickey: thanks -- im new to the cons cell, but i can see now after a little trial-by-fire how it works
18:22notallamaexcellent. it works: http://paste.lisp.org/display/89224 (curry function)
18:22rhickeyqed: no cons cells in sets/vectors/maps
18:24qedrhickey: only in lists then?
18:24rhickeyright
18:24Kjellskiin others it just can not make sense right?
18:26KjellskiBut you could think of it when you use sorted-map or sorted-set?
18:27rhickeyKjellski: they are ordered, but not linked lists
18:27qedKjellski: I saw something in Rich's talk with Beckman about how conj works fwiw
18:27qedbtw rhickey -- I really enjoyed that screencast
18:27rhickeygreat
18:28rhickeyjust think of conj as add and remember that all the collections are different data structures, even if they all can be accessed sequentially
18:30KjellskiUups, yes.
18:30KjellskiWhere can I find that cast?
18:30Kjellskiblip?
18:34qedKjellski: let me find you the link
18:34qedKjellski: http://channel9.msdn.com/shows/Going+Deep/Expert-to-Expert-Rich-Hickey-and-Brian-Beckman-Inside-Clojure/
18:35qedKjellski: pay no attention to the "Install Microsoft Silverlight" thing, just click on the Media Downloads link and get the WMV or whatever
18:35Kjellskiqed: thanks!
18:35qedKjellski: no problem, if you find any neat references/videos/etc. let me know :)
18:36Kjellskiqed: Sure =)
18:38Kjellskigone for watching...
18:38qedKjellski: enjoy :)
18:49qedKjellski: FWIW the conj/cons stuff is at about T+25min
18:58Kjellskiqed: thanks... I´m getting there soon
19:04ambientthe thing is, lisp is only like one third of what one has to learn in clojure
19:05ambienti still haven't grokked all the concurrency constructs
19:08defnweird. why doesn't lazy-cons exist for me?
19:08ambientit's lazy-seq now afaik
19:08defnoh, thanks
19:08ambientand it works a bit different
19:25chouserlazy-cons is from pre-1.0 clojure. If you find it documented somewhere, you might write the author so they can update it.
19:39qedim gonna re-write the code with lazy-seq and then post it to my blog and reference the original article
19:39qedhttp://clj-me.cgrand.net/index.php?s=Primes is where i found it
19:40qedim trying to make a lazy sequence of primes using def
19:49Kjellskirhickey: That was a great talk... have you talked on after the recording?
19:49Kjellskirhickey: Sounded pretty fancy what Brian told you about his RTOS at the end...
19:50rhickeyKjellski: yes, Brian's a neat guy
19:50qedHow could you not like a guy with a cowboy hat and sunglasses?
19:51qedThat wasn't a subtle jab, btw-- I think it's great.
19:55qedKjellski: I enjoyed it quite a bit -- I've actually used it as an intro to clojure/lisp for a few of my friends
19:56qedIt sort of gives a brief conversational history of some common things you'd find in lisp, how they work in clojure, etc.
19:56qedI think the main thing I took away from it was some of the language and how you'd express some of the ideas in clojure in a conversational way
19:59fanaticoqed: link?
20:00djorkqed: what do you use as an intro?
20:00Kjellskihttp://channel9.msdn.com/shows/Going+Deep/Expert-to-Expert-Rich-Hickey-and-Brian-Beckman-Inside-Clojure/
20:02djorkis it wrong to make a nondeterministic seq?
20:02KjellskiYes, the introduction is pretty nice... that´s what I say too, just to overwhelm people with argument why I really _needed_ to learn just _another_ language (which normally takes a conversation in a "You´ve definitly have too much time" like thing...) ^^
20:03djorkheh
20:14KjellskiWhat should I do if I want to go through a vec and if the element meet some criteria, I want that one to be changed? Sorry, but I don´t know how to explain what I mean in a immutable way...
20:15Kjellski+s
20:15djorkstart with thinking "how should I build the result"
20:15djorkso you've got three parts, the beginning, the element you want to change, and the rest
20:16KjellskiWait, I´ll post the problem and my textual solution...
20:16djorkSide note: it would be immensely helpful, but also hard to pronounce, to have a "The Little Clojure-er"
20:16djorkor maybe Clojurist
20:18Kjellskihttp://paste.lisp.org/display/89229
20:18KjellskiYap, I would love to have that too... /annotate
20:18Kjellski^^
20:22djorkKjellski: I'd just return a new vector with the new value for each bacteria and any new 5s that spawn... pretty simple I'd think.
20:23Kjellskidjork: just not trying to make that all at one?
20:23Kjellskice
20:25djorkthe resulting population from a given population is pretty simply defined there
20:25djorkyou just have to think in terms of the next population
20:25KjellskiI´m just not in functional thinking you know... that´s my whole problem here
20:26djorkyeah I know what you mean :)
20:26djorkthink of it like this
20:26djorkyour population is [2]
20:27djorkso the next population is [2 5]
20:27djorkerr sorry
20:27djork[1 5]
20:27Kjellskisure
20:28Kjellskibut think of the case you´ve got [3 3]..
20:28Kjellski[2 2 5 5]
20:28Kjellskiand than [1 1 5 5 4 4]
20:31rhickeyIt's alive!! (defclass* begins to breathe)
20:31Kjellskihow to get the new vector with that decreased one bac?
20:31Kjellskirhickey: congrats!
20:32djorkKjellski: the idea is to not add the dead bacteria to the new population vector
20:32djorkremember, you're not mutating the current generation... just creating the next one
20:32Kjellskiokay. *shame* my brain needs to be rewired by funtional thinking...
20:35KjellskiDamned, I think I´ve got it... but how to return 5 and the (dec bac) ?
20:35Kjellski^^
20:50AWizzArdrhickey: thanks for this nice message, I will now sleep well :-)
20:50KjellskiGood night.
20:54chouserrhickey -- writing Java code so we don't have to.
20:56danleiwhat's defclass*? is that related to deftype?
20:57RaynesI don't know what either one of those are. :| I've been out of the loop for a while.
20:57danleiRaynes: http://www.assembla.com/wiki/show/clojure/Datatypes
21:02RaynesOh. Sort of like Haskell's Data-types... Sort of.
21:02RaynesMinus the hyphenation.
21:02RaynesI was feeling dashy. :>
21:03RaynesIt reminds me of Haskell Datatypes, somehow.
21:03KjellskiHow can I "unpack" vectors in vectors?
21:04Kjellskilike [1 [2 3] -> [1 2 3] ?
21:04Kjellskierr [1 [2 3]] -> [1 2 3] ?
21:05danleiKjellski: clojure.contrib.seq-utils/flatten
21:05Kjellskidanlei : thanks
21:07danleiwelcome
21:15djorkwhat's the idiomatic way to express "else" in a cond
21:15djork?
21:15djorkis it to just (def else true) ? :)
21:15danlei:else
21:15djorkah
21:15djorkis that in the docs?
21:15djorkI don't see it in /api
21:16danleiactually, everything true will work
21:16danleibut :else is conventional
21:20djorkjust not documented?
21:20djorkoh, nevermind I see
21:20djork:else is treated as true
21:20djork:anything would be
21:22djorkhmm, so a fn with [x] and [[x & rest]] is the same arity?
21:26durka42djork: looks like it
21:33danlei(defn foo
21:33danlei ([x] 'hello)
21:33danlei ([x & rest] 'goodbye))
21:34danlei(foo 1) → hello, (foo 1 1) → goodbye
21:35danleioh, nevermind :)
22:01Kjellski,(remove nil [1 2 3 nil])
22:01Kjellski???
22:01KjellskiThis causes a NullPointerException
22:02danlei(remove nil? [1 2 3 nil])
22:02The-KennyKjellski: remove taks a predicate, not an element.
22:02KjellskiI seeee ^^ thanks, but why is it not saying that nil is no IFn or so?
22:03danleierror messages are just not the best ones atm
22:04Kjellskinevermind... just wondered because these seemed to me pretty consistent...
22:18Kjellskilet me guess, remove is lazy right?
22:18chouseryep
22:19KjellskiI could just bang my head against a wall ^^
22:21Kjellskijust like flatten?
22:22chouserflatten uses filter and tree-seq, both lazy, so yes.
22:23KjellskiJust couldn´t find it in the doc of flatten.
22:25chouseryeah, it probably ought to say its lazy.
22:27chouserit's
22:32toupsIs there something like with-output-to-file in clojure-contrib or the core that I am missing?
22:51lisppaste8rhickey pasted "defclass* begins" at http://paste.lisp.org/display/89234
23:02qedclojure.lang.LazySeq cannot be cast to clojure.lang.IFn
23:03qed(def pal-range (range 900 1000))
23:03qedwha?? I was doing this earlier with no problems...
23:11qedanyone? this is weird.
23:16chouserqed: you're trying (pal-range) ? Try instead without parens.
23:19chouserrhickey_: is there significance in having it all in one function?
23:37cemaHi all. First time here, not sure about the etiquette. I am learning Clojure and have a quick question - anyone available to give me an answer or a hint?
23:38notallamaperhaps. what's your question?
23:38rhickey_chouser: it's jjust a way for me to call new without AOT since the body of the fn will have the same classloader
23:39chousercema: you're welcome to ask
23:39chouserrhickey_: ah, got it.
23:39cemaReading from console in Emacs/Slime versus terminal clj.
23:39jkoppelWow, looks like I had good timing logging in. I was just about to ask how to use AOT
23:39cemaSpecifically, reading the password (but any readLline).
23:40cemaCan I copy a line of code here?
23:40chousercema: a line or two is fine here, otherwise use paste.lisp.org
23:41chouserlisppaste8: url
23:41lisppaste8To use the lisppaste bot, visit http://paste.lisp.org/new/clojure and enter your paste.
23:41cema(def P (.readPassword (java.lang.System/console)))
23:42cemaWorks fine in terminal, but returns a null error in Emacs/Slime.
23:42cemaSo I guess two questions here.
23:42cemaOne, how to read passwords properly in a console-type application.
23:42chousercema: I've never used System/console -- looks handy.
23:43cemaTwo, whether I should avoid the console (and what to use instead).
23:43cemaThanks!
23:43chousercema: but I imagine swank starts the JVM process without a console attached.
23:44cema*in* is set; is that not sufficient?
23:44cemaOr should I explicitly start... something (what then?)?
23:44chouserprobably not -- a pipe may or may not be associated with a console.
23:45cemaI see. Is there a standard way to attach it?
23:45cema(Or a non-standard way?)
23:46chouserI would guess if you want to do a password prompt via slime/swank, you'd probably have to do something emacs-specific -- somehow communicate to emacs that it shouldn't echo keystrokes.
23:46chouserI don't know nearly enough about emacs to help you there though.
23:46cemaI see. But even .readLine does not work in Emacs.
23:46notallamaso i'm working on a pointfree library. this is what it looks like now: http://paste.lisp.org/display/89236
23:46chouseremacs itself could be running in a graphical mode without any console available I would imagine.
23:47cemaSo I guess I need to see what Emacs (specifically, Swank) does with console?
23:47cemaThen #clojure may not be the best place to ask. Any place you could recommend?
23:48chousercema: maybe some emacs/lisp person could help you. It seems likelye that whatever solution would work for emacs and Common Lisp, for example, could be made to work for Clojure.
23:49jkoppelAlright, I'm trying to AOT compile a project of mine. I just compiled a couple dependencies from contrib just fine, but I'm getting an IOException from File.createNewFile when attempting to compile my own darmani.utils namespace
23:49jkoppelI'm using the line: (binding [*compile-path* "projects/clojure/"] (compile 'darmani.utils))
23:49cemaThat is correct, and I think I will now search for the solution towards that direction. Thanks a lot!
23:55jkoppelSo....can anyone tell me how I should be using AOT compilation?
23:56chouserjkoppel: you're sure your "projects/clojure/" directory exists and is writable?