#clojure logs

2009-02-11

00:13fynnHello.
00:13fynnhey, no need to quit so fat
00:13fynnI'm just looking for some estimates of clojure's performance
00:14hiredmannetsplit
00:14hiredmanI have no hard numbers
00:14hiredmanI here it is fast enough
00:14hiredmanI think Chouser said it was too fast ofr him
00:14hiredmanhear
00:15technomancyfynn: Clojure can run the Kessel Run in under twelve parsecs.
00:15ayrnieufynn - some estimates: http://groups.google.com/group/comp.lang.lisp/msg/75cd9bd772f1ed39
00:15technomancythat's fast~
00:15technomancy!
00:15fynnah here you are
00:16technomancyfynn: but I'm coming from Ruby and Elisp... so I'm probably not the best person to talk about performance.
00:16hiredmanayrnieu: late on in that thread someone says faster then sbcl
00:16albinoas is usually stated, the normal problem is it's startup time
00:16fynntechnomancy: yeah, I'm coming from Ruby myself
00:16fynnI mean, I did a lot of it.
00:17technomancyfynn: as long as your work is parallelizable then the advantages of clojure vs java should pay off
00:17hiredmanyeah, the start up time, which is why you leave open repls around
00:17fynn"Overall, the speed ain't bad, it's about 10x faster than perl, python,
00:17fynnruby, but x10-x20 slower than most of the Common Lisp Compilers (SBCL,
00:17fynnCMUCL, LispWorks, ACL)."
00:17technomancybut compared to Ruby it's blazing
00:17fynn(that's not saying much :P)
00:18albinofynn: what are you going to write with it that you need such speed?
00:18fynntechnomancy: how does the parallelization thing factoring in?
00:18fynnalbino: manipulations of very large data structures.
00:19technomancyfynn: well clojure apps are trivial to throw more cores at, and that's not true of most languages
00:19hiredmanhttp://groups.google.com/group/comp.lang.lisp/msg/88c5fb880d2b1148
00:19hiredman"In general one can suggest to give type hints to speed up things.
00:19hiredmanFor a little test function that Rainer Joswig gave here in c.l.l some
00:19hiredmanweeks ago I got from x15 more runtime than sbcl to half the runtime of
00:19hiredmansbcl with a few type hints. "
00:19fynntechnomancy: why? I didn't think it was purely functional.
00:20fynntechnomancy: I know what you said is true of Haskell for instance, but not sure why it holds for Clojure.
00:20technomancyfynn: there are side-effects allowed, but they're easy to separate out from the rest of your code
00:21hiredmanand you don't need to worry about locking
00:21ayrnieudrakeson - no, clojure still uses CamelCase. And any dashful syntax would suffer from the built-in syntax that java interop enjoys.
00:21fynnOK, so basically it sounds that wrt parallelization, Clojure should have the same advantages of the purely functional.
00:22technomancyfynn: right. it's *possible* to intermix side-effects into regular code, but that would be Doing It Wrong.
00:22Drakesonayrnieu: parenscript somehow works around javascripts camelCases.
00:22technomancyit's pretty easy to keep them where they belong
00:23blbrown,(doc +)
00:23clojurebot"([] [x] [x y] [x y & more]); Returns the sum of nums. (+) returns 0."
00:23Drakesonwhat would go wrong if clojure did the same?
00:23blbrown,(doc gen-and-save-class)
00:23clojurebotjava.lang.Exception: Unable to resolve var: gen-and-save-class in this context
00:23blbrowndoes that function exist anymore
00:23hiredmannope
00:23fynntechnomancy: interesting. and through all that, it's dynamic.
00:23hiredmanAOT compilation got rid of it
00:23fynnbeing able to use type hinting is pretty powerful.
00:24hiredmanDrakeson: among many things it would make javadoc's less useful, sense everyting would have a different name
00:24ayrnieualthough a predictable name.
00:25hiredmanthe very tight java <-> clojure interop is a huge win
00:25technomancyDrakeson: I think it's an issue of motivation rather than technical challenges
00:25hiredmanthe amount of stuff that ships in the jre is nuts
00:26technomancy...though half of it is deprecated.
00:26hiredman:P
00:26blbrowntoo bad that a lot of the examples in the clojure book don't work
00:26hiredmanblbrown: the wikibook?
00:26blbrownhiredman, programming clojure book, it seems to out of date. A lot of the functions dont exist anymore
00:27ayrnieublbrown - it's only content-complete.
00:27hiredmanuh
00:27technomancyblbrown: check the project on github
00:27hiredman*shrug*
00:27technomancyblbrown: that's being kept more up-to-date; it's got tests and everything
00:27Drakesontechnomancy: I know, there is no technical challenge in that. refer :rename could accept a form instead of a map.
00:28hiredmanDrakeson: well, if it is something you want bad, write a macro for it
00:28hiredmanI think it is silly
00:29hiredmanbut, whatev floats your boat
00:29hiredman,(let [boat 1](class (float boat)))
00:29clojurebotjava.lang.Float
00:30technomancynice
00:30Drakeson:)
00:30fynnwhat's the best resource to learn Clojure?
00:31hiredmanwriting clojure
00:31ayrnieufynn - good resources include: the wiki, the book, this channel, clojure projects.
00:31Drakesonfynn: have you watched the tutorials on blip.tv?
00:31hiredmanI started with project euler
00:32fynnDrakeson: bah, I'm a Real Programmer, I don't watch tutorials ;P
00:32ayrnieuso call it a 'screencast'. Those are pretty cool.
00:32fynnthis book? http://www.pragprog.com/titles/shcloj/programming-clojure
00:32ayrnieuYes.
00:32fynnoh, a screencast, most certain I will watch.
00:33technomancyoh wow, there's a lot more stuff on blip.tv now
00:33fynnanyways, trying to figure out what's special about Clojure
00:33hiredmantechnomancy: url me please, I am lazy
00:33Drakesonfynn: then definitely watch those screencasts.
00:33technomancyhiredman: well I haven't looked at this since november, so take "new" with a grain of salt: http://clojure.blip.tv/posts?view=archive&amp;nsfw=dc
00:34blbrowntechnomancy, can I just change 'gen-and-save' to 'gen-class' here. http://github.com/stuarthalloway/programming-clojure/blob/a3c829f5726c0ab1e565aff86a2e68eca8539a47/examples/junit.clj
00:34hiredmanI doubt it
00:34hiredmanpost AOT gen-class is rather different
00:34fynnI see only 8 tutorials there...
00:35hiredmanthey are not really tutorials
00:35Drakesonwhat the ones by rich hikey :)
00:35hiredmanlast I checked
00:35Drakesonbah. s/what/watch
00:35hiredmanthey where rhickey explaining why he created clojure
00:35hiredmanand what is cool about it
00:35mrsolo_those screencasts aren't tutorial, agree
00:36hiredmanclojurebot: mock object?
00:36clojurebotYour mock object is a joke; that object is mocking you. For needing it. -- rhickey
00:37blbrownhiredman, yea, it is pretty different...great
00:39hiredmangen-class is :(
00:39blbrownmeans I have to read stuff, darn
00:40hiredmanbut yeah, proxy won't work for JUnit
00:40hiredmanclojurebot: gen-class?
00:40clojurebotNo, hiredman, you want gen-interface + proxy
00:40Chouserblbrown: http://clojure.org/compilation
00:41ChouserThe code will be *very* similar, using gen-class instead of gen-and-save...
00:41Chouserhow you call it will be different: you'll have to get your classpath right and call 'compile'
00:43fynnwhat would happen to the JVM if Sun is in too deep of a trouble?
00:43ayrnieuRome will be unbuilt in a day, is what will happen.
00:44hiredmandunno, ibm has their own jvm
00:44hiredmanthe apache foundation has theirs
00:44hiredmanthere is the openjdk
00:44Drakesonfynn: JVM is already released as open source, and there are other people working on that. Like, project "Iced Tea" (backed by redhat, I guess)
00:44fynnisn't the IBM JVM actually faster than the Sun JVM
00:45albinoHarmony
00:45fynnDrakeson: well, if it's fully opensourced than I guess people could always maintain the codebase.
00:45albinooh and JRocket
00:45hiredmanIBM is full of dudes with beards, I bet their jvm makes bacon and eggs too
00:46hiredmanopenjdk is not completely open
00:46hiredmanicedtea is a project to address that
00:46Drakesonhiredman: yet icedTea is.
00:46hiredmanharmony is completely open
00:46fynnif Sun goes under, we'll all have to grow a beard :(
00:46hiredmanand under the apache license
00:47hiredmaninstead of sun's modified gpl
00:47Drakesonhiredman: http://en.wikipedia.org/wiki/IcedTea
00:47hiredmanDrakeson: thank you for a wiki page I have read al ready
00:47albinoHarmony is the basis for android IIRC
00:47hiredmanno
00:48albinooh?
00:48albinowhich one then?
00:48hiredmanthe harmony class libraries are used on android
00:48albinoright, sorry not as specific, but what I was getting at
00:48hiredmanandroid uses some other vm
00:49albinoso basically java won't die with sun
00:49ayrnieualso: Rome is still around.
00:49albinoif ever :)
00:49hiredmanlast time the vm would not build do to a bunch of linuxisms
00:50hiredmandue
00:50ozy`I wonder if google would buy sun when it's finally about to croak
00:50hiredmanugh, this is not the night for my typing
00:50albinosomeone would surely try and buy up solaris, maybe ibm
00:51albinowould be interesting to see Microsoft try and buy up some of the assets
00:51Drakesonhiredman: which one was under apache license?
00:52albinoDrakeson: http://harmony.apache.org/
00:52hiredman^-
00:52Drakesonwhat about openjdk?
00:52hiredmanmodified gpl
00:54albinoIs Harmony written in C?
00:54albinoThe VM I mean
00:54RaynesMust not be vary harmonial.
00:54hiredmanhttp://freejdk.org/faqs/openjdk_license.html
00:54hiredmanI thought c++
00:55Drakesonhiredman: thanks
00:57hiredmanI did nothing, but you are welcome
00:57blbrownChouser, do you see the compiliation issue there, anything I am missing. http://paste.lisp.org/display/75247
00:58hiredmanugh, I forgot the harmony build does some dependency fetching stuff
00:59blbrownSun's JVM is c++
00:59hiredmanthe last time I tried building harmony I think I was try to use ikvm too
00:59Raynesblbrown: Most of it is written in C if I remember right.
01:00hiredmanblbrown: the directory structure needs to match the class name
01:00hiredmanI would use :genclass in the ns macro instead of seperately
01:01blbrownRaynes, no it isn't, hotspot is C++. The class libraries might be written with C. E.g. Java's FFI (the name escapes me right now)
01:03RaynesNo I'm pretty sure a lot of it is written in C. :\
01:03blbrownI am looking at it, openjdk nov 2008
01:04RaynesThen, a lot of people are wrong.
01:04blbrownhttp://en.wikipedia.org/wiki/HotSpot
01:04Raynesblbrown: I believe you.
01:04ozy`a lot of people don't know or don't care about the difference between C and C++
01:05RaynesI'm just saying, a lot of people are wrong.
01:09blbrownhiredman, what would I change in my example, I am following the compilation docs, and getting the same error.. I have a directory: test/. and then test/OctaneTestGen.clj
01:10hiredmanblbrown: what is your classpath?
01:11blbrowngood point
01:12blbrownhiredman, .... .:./test:src:/ and then the clojure libraries
01:13hiredmanis junit in your classpath?
01:13blbrownyep
01:13hiredmanalso, ./classes/ needs to be in your classpath
01:13blbrownwhat is ./classes
01:14ayrnieu,*compile-path*
01:14clojurebotnil
01:14blbrownahhh, interesting
01:14blbrownhiredman, yea, it was classes in the classpath
01:14hiredmanclasses is where the compiled classes get put
01:14hiredmanyou can set *compile-path* to change that
01:15blbrownI missed that in the docs
01:15ayrnieu*compile-path* is, rather. It isn't emphasized enough that this must A) exist, to put things into, and B) be in your classpath, even if you won't use what you've just put it in there.
01:15blbrowngracias
02:06jessehi, I'm new to clojure. Porting some python code. Can anyone tell me the proper way to do something like this in clojure:
02:06jessewest, north, east, south = 0,1,2,3
02:06jessean enum type thing
02:07ayrnieujust use symbols.
02:07ayrnieu,'(west north east south)
02:07clojurebot(west north east south)
02:07jdzor keywords
02:07hiredmankeywords might be the clojure choice
02:07jdz(def directions [:west :north :east :south])
02:08hiredmanyou have something more complicated then that example a hash
02:08hiredman(def directions {:west 0 :north 1 :east 2 :sourth 3})
02:08hiredmanor whatever
02:09jdznaah, my example is better
02:09hiredmanjdz: your example doesn't map from keyword to number
02:09ayrnieuyes it does, hiredman.
02:09hiredman,( [:west :north :east :south] 0)
02:09clojurebot:west
02:09hiredmanworks
02:10hiredmanbut most liekly you want to go the other way
02:10jdzwell, it's the other way around: it maps from number to keyword
02:10ayrnieuyou can also go the other way with that.
02:10hiredmanyou can
02:10jdzbut that is what i think more useful mapping
02:10hiredmansure
02:10hiredmanbut is it as natural as
02:10hiredman,({"west 1} :west)
02:10clojurebotEval-in-box threw an exception:EOF while reading string
02:10hiredman,({"west 1}" :west)
02:10clojurebotEval-in-box threw an exception:Unmatched delimiter: )
02:10hiredmanwhatever
02:11hiredmanyou get my meaning
02:11jdzin reality one would probably want to have both: the map that maps from names to numbers, and the array that maps numbers to names (for calculations)
02:14jdzbut returning to the python example, i guess it's just 4 variables
02:14jdzand you define variables with def in clojure
02:15jdz(for some meanings of variables)
02:15jesseok, how do I use a symbol after defining it?
02:15hiredmanuh
02:15ayrnieujesse - you just name it.
02:15hiredman,'w
02:15clojurebotw
02:15hiredman,'west
02:15clojurebotwest
02:15ayrnieu,['a :a] ;; <-- no special work.
02:16clojurebot[a :a]
02:16jesse(west) --> Unable to resolve symbol: west in this context
02:16hiredmanuh
02:16ayrnieujesse - there's no 'define' step with symbols; jdz only bound a list of symbols to a name.
02:16hiredmanthe is a function call
02:17hiredmanwest is not a function
02:17hiredmanit is a symbol
02:17hiredmansymbols may or may not name functions
02:17jdzi think a tutorial on lisp would be handy at this point
02:17hiredmanYes.
02:17jesseheh, i guess
02:18hiredmanclojurebot: lisp?
02:18clojurebotlisp is the red pill
02:18hiredmanclojurebot: sicp?
02:18clojurebotsicp is http://web.mit.edu/alexmv/6.001/sicp.pdf
02:20jesseok, let me try again...
02:20jesse(def west 0)
02:20jesse(def north 1)
02:20jesse(def east 2)
02:20jesse(def south 3)
02:20jesse(def my_dir west)
02:20jesse(prn my_dir)
02:21hiredmanwoa
02:21jessehow do i make that shorter?
02:21hiredmanpaste bin
02:21jessedidn't go through? woops :)
02:21hiredmanit did
02:21jesselooks good on my end...
02:21ayrnieuIT WENT THROUGH, IT WAS JUST VERY ANNOYING.
02:21hiredmanthat is a lot more declaration then I care to see
02:21jessewhy? just six lines?
02:21hiredmanmore then three
02:22jdzjesse: so why do you want to make it any shorter if it's just six lines?
02:22jesseThere's more that follows the same pattern
02:22jesseThis is in Directions.py
02:22hiredmanjesse: def is used for things that do not change
02:22jesseI use it all over the place
02:22jdz,(let [[west north east south] [0 1 2 3] my-dir west] (prn my-dir))
02:22clojurebot0
02:22hiredmanso (def my_dir west) is silly
02:22lisppaste8ayrnieu pasted "functions as readable maps" at http://paste.lisp.org/display/75250
02:23hiredmansince I guess you will be changing direction?
02:23jesseIn python I would call Directions.west instead of remembering values
02:23jesseas in my_dir = Directions.west
02:23hiredmanok
02:23hiredmanmake a hash
02:24hiredman(def directions {:west 1 :etc 2})
02:24hiredmanthen you do
02:24hiredman(:west directions)
02:24hiredman-> 1
02:25jessecool, looks good
02:25hiredmanand for god's sake, http://web.mit.edu/alexmv/6.001/sicp.pdf
02:26jdzjesse: you can't write code in one programming language by directly mapping constructs from other programming language (unless they are both imperative algol-like)
02:26jdzjesse: as ayrnieu showed, you don't need any numbers at all for directions
03:11alinpopagood morning to all
05:02timothypratleyin core.clj I see (create keys) but I can't find where 'create' is defined
05:11timothypratleyah stupid me sorry ignore that question
06:17AWizzArdHow can I alias a namespace inside its setup (ns xyz ...)?
06:18AWizzArd,(doc alias)
06:18clojurebot"([alias namespace-sym]); Add an alias in the current namespace to another namespace. Arguments are two symbols: the alias to be used, and the symbolic name of the target namespace. Use :as in the ns macro in preference to calling this directly."
06:19AWizzArdSo, this suggests to use :as, and I also tried (ns foo (:as bar))
06:19AWizzArd,(ns foo (:as bar))
06:19clojurebotjava.lang.Exception: No such var: clojure.core/as
06:19jdzAWizzArd: why do you want to do that?
06:19AWizzArdbecause my namespace is (ns de.longcompanyname.gui.tools.LoggingTool)
06:19jdzand?
06:20AWizzArdand I don't always want to type this long beast
06:20jdzthat's when you use alias
06:20AWizzArd(alias 'log 'de.longcompanyname.gui.tools.LoggingTool) works, but I thought this can be done directly inside the (ns ..)
06:21jdzaliasing is the tool for users of the namespaces, not the authors
06:21jdzso to speak
06:21jdzyou don't know what the users of said namespace want to name them in short
06:21jdzand you should not impose your nicknames on others
06:21Chousukeyou don't need to refer to the full namespace in the file that defines it anyway
06:21Chousukeonly when you :use or :require it in another namespace, and you have :as in those cases :)
06:22AWizzArdyes ok, makes sense
06:22AWizzArdMoin Achim
06:23AWizzArdfor testing purposes I will then use (alias ..) during development
06:23achim_phi!
06:23jdzAWizzArd: i use in-ns during development personally
06:23ChousukeAWizzArd: why do you need alias inside the namespace itself though? :/
06:24Chousukeafter the (ns foo ...) form is evaluated, foo becomes the default namespace, and does not need to be explicitly qualified
06:24Chousukeso making an alias for it would be useless.
06:24AWizzArdI want this alias to be available in user
06:25Chousukeah, well, I think you can just (require '[yournewnamespacewithalongname :as nn]) in the user namespace
06:25ChousukeI never remember the syntax right though.
06:59AWizzArdatoms make sense for Singletons that should be changeable during runtime, yes?
07:04Chousukewhy not refs?
07:04Chousukeor well, I guess it depends on what you need.
07:08Chousukea global atom might make sense for some function or value that is generally constant, but might need to be changed sometimes
07:21timothypratleyuser=> (isa? *e java.lang.Throwable)
07:21timothypratleyfalse
07:21timothypratleywhat am I doing wrong?
07:24timothypratleyuser=> (class *e)
07:24timothypratleyclojure.lang.Compiler$CompilerException
07:25timothypratleyoh.....
07:25timothypratleyuser=> (isa? (class *e) java.lang.Throwable)
07:25timothypratleytrue
07:25timothypratleyopps!
07:27durka42try instance?
07:28timothypratleyeven better! thanks
07:34AWizzArdWhen I write small scripts in Clojure which I want to run from the command line, how can I do this then? Can I also pass command line args?
07:39AWizzArdFor example, if I have a file foo.clj that just contains a (print "Hallo"), how do I run it then from the shell?
07:50HolcxjoAWizzArd: java -cp .../some/path/clojure.jar clojure.main helloworld.clj
07:51HolcxjoAWizzArd: see java -cp .../some/path/clojure.jar clojure.main -h
08:01leafwis there any reason why doing an (import '(java.io File)) inside a binding block that also includes usage of that File class, fails? the File class is not found.
08:01AWizzArdHolcxjo: thx
08:46leafwa user is reporting to me that (load-file "D:\path\to\file") fails ... with D\ unknow char or something. Does anybody here use windows? I can't test such thing.
08:46leafwoooh never mind. I saw the problem.
08:47forest\\ ?
08:47AWizzArdyup
08:47jdz_doesn't / also work on winblows nowadays?
08:56leafwjdz_: yes, it does. But I forgot here to .replace('\\','/') ...
08:56leafwand when +'ing strings, the backslashes broke hell.
08:58leafwalso:is there any way to set the number of threads for the thread pool of a pmap command? Would be nice to be able to set it. As I see it, it's hardcoded to (+ 2 (.. Runtime getRuntime availableProcessors).
09:11AWizzArdleafw: it's indeed hardcoded... however, in principle this value makes sense.
09:12let_f_dioesnt set have union, difference etc?
09:13leafwAWizzArd: it doesn't when one doesn't want to bring a machine to its knees. I.e. I may want to leave the GUI reponsive, with one or two cores for it.
09:13jdz_AWizzArd: yeah, but it would be cool to let pmap use only, say, 6 of 8 cores
09:13leafwI think it's possible to add an extra initial arg to pmap, but that would break exisiting code.
09:14leafwi don't know how to add 'key' extra args.
09:14jdz_another solution is for pmap to use a var which could be bound
09:14leafwjdz_: indeed.
09:14leafwthat sounds nicer.
09:15leafwlike *max-cores* or so.
09:15cooldude127let_f_: yes, they are in clojure.set
09:16cooldude127(doc clojure.set/union)
09:16cooldude127clojurebot: (doc clojure.set/union)
09:16clojurebotclojure is a very attractive hammer with a nice heft to it
09:16cooldude127ok then
09:16cooldude127,(doc clojure.set/union)
09:16clojurebot"([xset yset]); Returns a set that is the union of the two sets."
09:22let_f_i find it annoying i cant find functions that operate on a specific type easily, like dir(set) in python.
09:22let_f_i see i didnt know there were such namespaces in the core
09:23let_f_can i lsit all fucntions ina namespace?
09:23cooldude127let_f_: probably, but i'm not immediately sure how
09:23cooldude127and the reason you can do that in python is because all those are methods that are attached to a class
09:24cooldude127this is not object-oriented programming, nor is there static typing, so there is no obvious way to figure something like that out
09:25let_f_but there is if for some functions if they are in a namespace
09:25let_f_i could obv make a function that operatos on a object in python and it wouldnt be listed with dir(object)
09:25cooldude127let_f_: yes, if it was a standalone function
09:25let_f_cant i map over a set and keep it a set?
09:26Chouserhttp://clojure.org/namespaces
09:26let_f_user=> (map inc #{1 2 3})
09:26let_f_(2 3 4)
09:26cooldude127let_f_: map i think returns a seq, so if you still need a set, just call set on the result
09:26Chouser,(into #{} (map inc #{1 2 3}))
09:26let_f_(set (map f set-))
09:26clojurebot#{2 3 4}
09:26cooldude127,(set (map inc #{1 2 3}))
09:26clojurebot#{2 3 4}
09:26let_f_yes but it clutters
09:26cooldude127let_f_: that's how you do it
09:27cooldude127map is lazy, so it returns a seq
09:27let_f_ok
09:27Chouser,(keys (ns-publics 'clojure.set))
09:27clojurebot(rename-keys union select project join intersection map-invert difference rename index)
09:28cooldude127Chouser: damnit, i was just looking that up
09:28jdz,(map first (ns-publics 'clojure.set))
09:28clojurebot(rename-keys union select project join intersection map-invert difference rename index)
09:28cooldude127i had found ns-publics, came back to do it, and i see it's already there
09:28jdzyeah, what chouser said :)
09:34let_f_why is inverting a map in set?
09:34let_f_user=> (clojure.set/map-invert {1 2 3 4})
09:34let_f_{2 1, 4 3}
09:36Chouserclojure.sets is actually about doing "relational" stuff
09:37Chousersets/index, for example, takes a set of maps and returns a map of maps indexed however you specify.
10:14clojurebotsvn rev 1272; Revert: improved Maven integration, patch from hlship [issue 70], broke destination directories
10:14clojurebotsvn rev 1273; added class name to No matching ctor message
10:26Chouserthe new Counted interface makes the clojure classes chart unreadable. :-P
10:32gnuvinceChouser: link?
10:33Chouserummm...
10:34Chouserhttp://chouser.n01se.net/misc/tmp.png
10:34Chouserthe arrows from column 3 to 4 are dense, but can be followed with the eye
10:35Chouserfrom column 4 to 5, though, I can't tell where they're going
10:37danlarkinespecially from, say, AFn -> Obj
10:39Chouserright, or IPersistentSet down to ... ???
10:39danlarkinouch, yeah
10:40waltersChouser: can you just widen it?
10:41waltersit only takes up about half of my 1920x1200 monitor =)
10:41Chouserwalters: maybe. how well do you know dot? :-)
10:41jdzwalters: your 1920x1200 does not compare to my 2560x1600 monitor :)
10:42waltersChouser: last played with it years ago unfortunately
10:42waltersjdz: heh
10:42jdzand generating .pdf or some other vector format would be great
10:43Chouserthe most recent released version is at http://tinyurl.com/clojure-classes -- there's an SVG format there
10:45rsynnottooh, pretty
10:46rsynnottChouser: what'd you use to generate it?
10:48jdzrsynnott: see the URL
10:51Chouserclojure -> dot -> inkscape -> gimp
10:51Chouser:-/
10:51AWizzArdI have a coll of objects and want to add them to a hashmap with a specific key. Is there something more idiomatic than:
10:51AWizzArd,(apply merge (map #(assoc {} %1 %2) [:a :b :c] (range 3)))
10:51clojurebot{:c 2, :b 1, :a 0}
10:51Chouser,(zipmap [:a :b :c] (range 3))
10:51clojurebot{:c 2, :b 1, :a 0}
10:52AWizzArdgoood :)
10:52Chouser:-) used it for the first time a couple days ago.
10:54rsynnottah, impressively concise!
10:57ozy`,(doc zipmap)
10:57clojurebot"([keys vals]); Returns a map with the keys mapped to the corresponding vals."
10:58AWizzArdChouser: great that you remembered it. I really want/need it now.
11:03AWizzArdIs there a reader mac.. syntax for hashtables in Java? Such as { e1, e2, e3 } for Arrays?
11:04leafwAWizzArd: nope.
11:04waltersno...but if you really need it you can fake it by using an anonymous inner subclass of HashMap
11:04leafwAWizzArd: or, at leas,t never came across it in years.
11:05waltersnew HashMap<String,Object>() { { put("foo", 10); put("bar", new Object()); }}
11:05drdoHow can i create a type?
11:10let_f_is it possible to define a method Show like in haskell so everytime a thing is returned its proper representation isnt showed but a prettyprinte one?
11:11Chouserif you use the repl in contrib, I believe you can override the function used by default to print
11:18HolcxjoChouser: Next question: how do you use the repl in contrib? :-) Especially from slime?
11:18let_f_good question :)
11:18let_f_it is good for dsls
11:19Chousersorry, I've not used the repl from contrib, and I've not used slime.
11:21HolcxjoPlus of course: Why are there two repls?
11:23Chousukesomeone thought the default one wasn't good enough? :)
11:23rsynnottHolcxjo: slime provides its own repl, so might be tricky
11:23rsynnottwhat extra stuff does the contrib one do?
11:23Chouser(use '[clojure.contrib.repl-ln :only (repl)]) (repl :print #(println "Custom:" (pr-str %)))
11:24Chouserthat works at a plain shell prompt (and probably in inferior lisp mode or whatever its called)
11:24rsynnottwith slime you're not using inferior lisp mode, though
11:25AWizzArdWasn't there a complete implementation of CLs FORMAT?
11:25let_f_i want all permutations of 3 nested ranges, how?
11:26ChousukeAWizzArd: yeah
11:26Chousuke~format
11:26clojurebotIt's greek to me.
11:26Chousukehmm
11:26AWizzArdthere is this format from Java, which should be sufficient for most things
11:27Chousukeclojurebot: format is http://github.com/tomfaulhaber/cl-format/tree/master
11:27clojurebotc'est bon!
11:27AWizzArdBut iirc someone said a few days ago that, ah yes
11:27rsynnottnext step, a complete implementation of the CL extended loop :)
11:28Chousukehmm, nice
11:28Chousuke"cl-format is 100% compatible with the Common Lisp standard as specified in CLtLv2 with the exception of the support directives for the pretty printer."
11:28Chouserlet_f_: (clojure.contrib.combinatorics/cartesian-product [1 2 3] [4 5 6] [7 8 9])
11:29Chouseror (for [a [1 2 3], b [4 5 6], c [7 8 9]] [a b c])
11:29Chouseror doseq
11:31Chousukeooh, he's working on a pretty printer too :/
11:31let_f_can someone link to the simplest possible implementation of a lisp-interpreter?
11:33AWizzArdlet_f_: that would be Scheme. Try wikipedia.
11:33AWizzArdThe standart of Scheme is just a few pages
11:33Chousukehm
11:34HolcxjoIt used to be smaller than the index of CLtL2 but has become more complex with R5RS and R6RS I believe
11:34ChousukeI saw a ~two-hundred line lisp interpreter written in C once :/
11:34Chousukebut I can't remember wehre
11:35Chousukeit didn't even have garbage collection :)
11:36AWizzArdwhat I find funny is the Lisp version of 99 bottles in CL: http://99-bottles-of-beer.net/language-common-lisp-114.html
11:37Chouser"almost a language of its own" is clearly an understatement.
11:38rsynnottthe loop (rather than format) version would be clearer, still a language of its own, but less impressive/intimidating-looking
11:39Chouserloop is also pretty much its own language
11:39Chouserin CL, not Clojure of course
11:45AWizzArdAlso in Clojure, but it's dramatically much simpler.
11:46Chouserwhat? maybe 'for' and 'doseq' have their own (very simple) language, but loop only has the same (also very simple) destruturing as let, fn, etc.
11:47Chouserso is this better or worse? http://chouser.n01se.net/misc/tmp2.png
11:47AWizzArdvs?
11:47danlarkinoh jeez
11:47Chouservs. http://chouser.n01se.net/misc/tmp.png
11:47danlarkinworse I think
11:48AWizzArdI vote for tmp.png
11:48Chousertmp.png isn't sufficient, though. it's absolutely unusable for several edges.
11:50knoboHas anyone made a clojure application for mobile telephones?
11:51ChouserThere's a hello-world for android. Not sure about JME.
11:51knoboI have a small app, that I would like to install on my sony ericsson, but I don't know how to du it.
11:52AWizzArdknobo: if you find out how to do it, then please write a how-to in the google group
11:52knoboAWizzArd: I'll do that.
11:53AWizzArdknobo: the first thing I would try to do is to download the right sdk. If your handy can run a full jre it would be the jdk. If it supports the JME then download that, or for google handys Android.
11:53AWizzArdAnd you should compile your code into a .jar file, which you can then bluetooth to your phone.
11:54AWizzArdI also have a SE handy, and that one would need the JME. Thats what I guess.
11:54AWizzArdthe sdk for the ME comes with a simulator I think
11:54AWizzArdbut this could fail, as the ME has ridiculous size limitations of your programs
11:55AWizzArdas if phones won't have gigs of memory today
11:57AWizzArdHow can I partition [x1 x2 x3 x4 x5 x6] into ([x1 x3 x5] [x2 x4 x6])?
11:58rsynnottChouser: clojure's destructuring still beats cl's, though
11:58Chouser,(split-at 3 (range 6))
11:58clojurebot[(0 1 2) (3 4 5)]
11:58gnuvinceChouser: wrong ordering
11:59Chouseroh!
11:59Chousersorry
12:00ayrnieuAWizzArd - call it 'deinterleave'
12:00AWizzArdyes ;)
12:00AWizzArdwell, one can do some magic with iterate, to have the indexes and can then mod or something like that
12:01Chouser((fn [s] [(take-nth 2 s) (take-nth 2 (rest s))]) (range 6)), but that's not very satisfying.
12:01knoboAWizzArd: thanx for the hints.
12:01ayrnieujust write a recursive function for it.
12:02drdoHow can i create a new type?
12:02Chouserdrdo: why do you think you need a new type?
12:03drdoChouser: Let's not get started on that
12:03Chouserdrdo: generally algorithms in Clojure make use of combinations of vectors, lists, maps, etc.
12:04Chouseryou can tag any of those with metadata if you want to differentiate one kind from another
12:04Chouser,((fn [s] (map #(take-nth 2 %) [s (rest s)])) (range 6))
12:04clojurebotEval-in-box threw an exception:java.lang.reflect.InvocationTargetException
12:04Chouserclojurebot's having issues. that should work.
12:05drdoSo i cannot create a type indistinguishable from a built-in type?
12:05Chouserdrdo: sure you can, but it's fairly uncommon, which is why I asked "why" :-)
12:06Chouseruse can use 'proxy'
12:06drdoOk, so how can i?
12:10lisppaste8AWizzArd pasted "short example of proxy for drdo" at http://paste.lisp.org/display/75268
12:12lisppaste8ayrnieu annotated #75268 with "more comprehensive example" at http://paste.lisp.org/display/75268#1
12:15HolcxjoAWizzArd: (for [idx (range 2)] (map #(nth % idx) (partition 2 [1 2 3 4 5 6])))
12:15HolcxjoBut that's also quite verbose
12:21AWizzArdBtw, ayrnieu, were futures added to Clojure?
12:21ayrnieusrc/clj/clojure/core.clj:future-call
12:22AWizzArdmy clojure.jar is from Feb 5 and I don't have it ;)
12:24ayrnieuhe pushed it two days ago, I think.
12:41let_f_anyone use yahoo boss api?
12:41let_f_i dont get how to ownload the api
12:45cemerickrhickey: is there any reason to think that AOT compilation will produce smaller classfiles at some point in the future?
12:48danlarkin,(with-meta :foo {:bar true})
12:48clojurebotjava.lang.ClassCastException: clojure.lang.Keyword cannot be cast to clojure.lang.IObj
12:54danlarkinshouldn't that be okay?
13:10Chouserdanlarkin: no, keywords don't support metadata.
13:11Chouserthey're interned, so there's really only one copy
13:11danlarkinhrmph
13:11Chouser,(identical? :foo :foo)
13:11clojurebottrue
13:11Chousersymbols, on the other hand, are not interned and so you can have many copies.
13:11Chouser,(identical? 'foo 'foo)
13:11clojurebotfalse
13:11ayrnieu,(identical? :foo ::foo)
13:11clojurebotfalse
13:12Chouserayrnieu: yeah, but that's something else entirely. :-)
13:12danlarkinI guess I'll use symbols then :) Thanks almighty chouser
13:12danlarkinor all knowing, rather
13:12Chouseryikes. "helpful" would be fine, thanks. ;-)
13:13kotarak,(identical? :user/foo ::foo)
13:13clojurebotfalse
13:13ayrnieu,*ns*
13:13clojurebot#<Namespace sandbox>
13:13ayrnieu,::foo
13:13clojurebot:sandbox/foo
13:17rsynnottstop torturing the poor machine :)
13:17Chouser,(identical? ::foo :sandbox/foo)
13:17clojurebottrue
13:18Chouser,(when 'ok? (println "I'm ok"))
13:18clojurebotI'm ok
13:19rsynnottit's a very friendly one
13:20rsynnott'minion' in #lisp gets annoyed when people talk to it too muc
13:23erohtardanlarkin: u here?
13:23danlarkinerohtar: ya
13:24erohtardanlarkin: sorry to bug u all the time
13:24erohtardanlarkin: having trouble using clojure-json with the latest clojure - specifically it breaks on rev 1263
13:24erohtardanlarkin: i get this error just trying to require it -
13:25erohtardanlarkin: (require '(org.danlarkin [json :as json]))
13:25erohtardanlarkin: java.lang.NoSuchMethodError: clojure.lang.MultiFn.<init>(Lclojure/lang/IFn;Ljava/lang/Object;)V
13:25erohtar at org.danlarkin.json.encoder__init.load(Unknown Source)
13:25erohtar at org.danlarkin.json.encoder__init.<clinit>(Unknown Source)
13:25erohtar at java.lang.Class.forName0(Native Method)
13:26erohtarand MultiFn.java has changed between 1262 and 1263 - looking at it now
13:27danlarkinerohtar: try to use a paste bin for pasting more than a line or two, please. I'm on r1273 of clojure and (require '(org.danlarkin [json :as json])) works fine for me...
13:28erohtardanlarkin: what about contrib, do u use anything there?
13:28danlarkinonly in test.clj
13:30erohtardanlarkin: i cant understand it.... all im doing is a require on the repl, literally... and it works wiht rev 1261 and not with 1262 onwards
13:31danlarkinerohtar: if you comment out the add-encoder macro in json.clj will it work?
13:31erohtarhmm
13:31erohtardanlarkin: i am using the jar
13:31erohtardanlarkin: let me try with code
13:32danlarkinerohtar: have you rebuilt the jar since upgrading clojure?
13:32durka42fwiw, seems to work for me with latest
13:33erohtardanlarking: duh - i have not
13:34danlarkinerohtar: I think you may need to :)
13:34erohtardanlarkin: lemme do that now
13:34erohtardanlarkin: im not this stupid usually :) long time no java
13:36danlarkinerohtar: and are you passing -Dclojure.jar=/path/to/clojure.jar to ant? that will AOT compile the clojure code
13:37erohtardanlarkin: recompiling it now
13:38erohtardanlarkin: that worked, thanks!
13:39erohtardanlarkin: shall i stay with the jar, or go with a git submodule that uses ur clojure code?
13:39danlarkinumm that's up to you
13:40danlarkintoo many factors would influence that decision for me to make it for you
13:42Lau_of_DKGood evening all
13:43kotarakHi Lau
13:55erohtardanlarkin: from a performance stand point, do jars (since theyre compiled) work faster than clj?
13:56danlarkinerohtar: jars created with AOT compiled clojure code will load faster, but not perform faster
13:56Chousercompilation and packaging to jars are two independent things
13:56rsynnottcompiled on load anyway, no?
13:56erohtarand i guess the compiled on load stuff gets cached somewhere
13:56erohtar?
13:57Chouserrsynnott: yes
13:59rsynnottprobably a good move
14:00rsynnottsbcl took the same approach (no interpreter used, though as of a year or so ago there is one if you REALLY want it)
14:00rsynnottand the result is JIT-able JVM bytecode, yep?
14:01durka42hmm, if one could write a compiler that was faster than the zip decompression algorithm, that would be pretty incredible
14:01rhickeyanyone with JDK 6 and not OS X who could try something for me in the lazy branch?
14:03Lau_of_DKsure, if its not more complicated than I can figure out :)
14:04rhickeyLau_of_DK: build the latest lazy and try this a few times in a row at the repl:
14:04rhickey(time (reduce + 0 (filter even? (map inc (range 1000000)))))
14:04Lau_of_DKk, which command can I use to checkout that branch ?
14:04clojurebotsvn rev 1274; [lazy] use seq rather than relying on implicit seq of first/more in core sequence fns
14:05Lau_of_DKsvn checkout http://clojure.googlecode.com/svn/trunk/ clojure-read-only -b something?
14:05ayrnieusvn co http://clojure.googlecode.com/svn/branches/lazy
14:07brianhrhickey: "Elapsed time: 521.42046 msecs"
14:07brianh250000500000
14:07Lau_of_DKuser=> (time (reduce + 0 (filter even? (map inc (range 1000000)))))
14:07Lau_of_DK"Elapsed time: 590.581693 msecs"
14:07Lau_of_DK250000500000
14:08brianhon 64bit
14:08Lau_of_DKon 32bit Ubuntu 8.10
14:08rhickey(System/getProperty "java.version") ?
14:08brianh"1.6.0_12"
14:09Lau_of_DKuser> (System/getProperty "java.version")
14:09Lau_of_DK"1.6.0_10"
14:09rhickeybrianh: you ran it a few times?
14:09rhickeyHere's what I'm getting on OS X:
14:09rhickeyClojure
14:09rhickeyuser=> "Elapsed time: 602.594 msecs"
14:09rhickey250000500000
14:09rhickeyuser=> "Elapsed time: 89.123 msecs"
14:09rhickey317819756
14:09brianhno just once
14:09rhickeyuser=> "Elapsed time: 0.063 msecs"
14:09rhickey0
14:10Lau_of_DKI get 703, 210, 0.2765
14:10Lau_of_DKDunno why the first increased compared to before
14:10rhickeyLau_of_DK: I don't care about the times, but the results are trach?
14:11rhickeytrash?
14:11Lau_of_DK250000500000
14:11Lau_of_DKuser=> (time (reduce + 0 (filter even? (map inc (range
14:11Lau_of_DK 1000000)))))
14:11Lau_of_DK"Elapsed time: 210.677824 msecs"
14:11Lau_of_DK1123959150
14:11Lau_of_DKuser=> (time (reduce + 0 (filter even? (map inc (range
14:11Lau_of_DK 1000000)))))
14:11Lau_of_DK"Elapsed time: 0.276501 msecs"
14:11Lau_of_DK2
14:11Lau_of_DK
14:11rhickeyright, same problem - thanks!
14:11Lau_of_DKnp
14:12rhickeybrianh: you too?
14:12brianhone sec
14:15rsynnottit's actually giving different results?
14:15Lau_of_DKIt sure is :)
14:15rhickeyrsynnott: yeah, it looks like hotspot is choking on closed-over clearing - aargh
14:16rhickeyIt's a bytecode sequence javac would never generate
14:16Lau_of_DKDoes that mean its a bug in hotspot?
14:16rsynnottbut a legal sequence in JVM bytecode?
14:17rhickeyrsynnott: yes, legal
14:17rhickeyJDK 5 has no problem with it
14:18rhickeybut JDK 6 has more optimization
14:18brianhrhickey: sorry, forgot that i had switched back to the trunk jar
14:18brianhso disregard earlier
14:19Chouseroh, nope. screwed it up.
14:25brianhrhickey: switched back to lazy
14:25brianhafter 5 consecutive runs
14:26brianhseeing: "Elapsed time: 408.459176 msecs"
14:26brianh250000500000
14:27rhickeybrianh: interesting, works on 1.6.0_12
14:28brianhi have a 1.6.0_06 i can test it on if u want
14:28brianh32 bit
14:28hiredmanouch
14:29hiredmanthat took a very long time on openjdk7
14:30hiredman"Elapsed time: 1063.158457 msecs" for the first run
14:31wwmorganIt looks like () now evaluates to nil when before it evaluated to (). Why was this changed?
14:34rhickeywwmorgan: separate problem - I'll look into it
14:34rhickeyLau_of_DK: I think I fixed it, could you please try the latest lazy?
14:34clojurebotsvn rev 1275; [lazy] declare closed-over fields non-final for once-only fns
14:35mofmogwhen's 1.0 comin?
14:36rhickeymofmog: when I get it right :)
14:36mofmogheh
14:36WizardofWestmarcrhickey: aside from lazy, what's still left that you want in 1.0?
14:36mofmogi guess a better question is how much longer until someone can write a tutorial that doesn't require the proviso "Do not use the latest Clojure build"
14:37ayrnieututorials are fine, the problem is libraries.
14:38rhickeymofmog: unless you are doing a tutorial on some bleeding edge feature, that's been possible all along. This latest very disruptive stuff is happening in branches
14:38mofmogoh i see
14:38mofmogprogramming clojure beta has a provision in the introduction like that
14:41kotarakI thinks that more, that things may change, not that they are broken. Eg. the defmulti syntax changed. So the examples from the book might not work anymore.
14:41technomancyis 1.0 just waiting for the streams and lazy branches, or is there more?
14:41rhickeymofmog: the writing of the book covered a transition period where breaking changes were introduce subsequent to a release, so people that grabbed the release and the latest had different worlds. Now it should be less needed, but a good idea on his part to point people to a particular version - that will be true when they have names like 1.0 and 1.1 too
14:41Lau_of_DKrhickey: 2 secs
14:42brianhrhickey: i'm still not seeing a problem
14:42brianhuser=> (time (reduce + 0 (filter even? (map inc (range 1000000)))))
14:42brianh"Elapsed time: 948.399866 msecs"
14:42brianh250000500000
14:42brianhuser=> (System/getProperty "java.version")
14:42tomswto what extent are clojure forms memoised? For example, if I have a loop that does 100 things with the value of (/ width cols), need I put it in a let to avoid multiple evaluation?
14:42brianh"1.6.0_06"
14:42brianhuser=>
14:42brianhafter ~5 times
14:42Lau_of_DKrhickey: Its fixed here, runs 3 times, same result
14:42rhickeyLau_of_DK: great, thanks all!
14:43hiredmanugh
14:43hiredmanmy second run is still running
14:45hiredmanmaybe my c2d is showing it's age
14:46hiredmanor not
14:47hiredmanjava is using 0.0% of cpu time
14:47hiredmanhmmm
14:47kotarakhiredman: your clojure is too lazy. ;)
14:47danlarkinhiredman: missing a closing paren? :)
14:47hiredmanit has been running for around 16 minutes
14:47rhickeythe problem was closed-overs were declared final, but clearing them is a mutation. HotSpot was leveraging the final declaration to reorder things (which it's free to do). So, my bad - HotSpot is fine (whew!)
14:48hiredmanmaybe the machine is clocking itself down
14:48kotarakhiredman: is it a laptop? Turn off energy saving.
14:48hiredman*shrug*
14:49technomancyrhickey: have you found any actual new bugs in hotspot yet?
14:49hiredmanthis is my desktop at home (I am at work right now) so I am not even in front of the machine, but firefox is taking 20% of cpu time
14:49Lau_of_DKrhickey: Are you having any thoughts on combining the lazy branch with the master?
14:49hiredman*sigh*
14:49hiredmancomputers
14:51rhickeyLau_of_DK: well, I certainly feel better about it now than I did 20 minutes ago :)
14:53Lau_of_DKhehe
14:54Lau_of_DKIve heard critics say that it will make code less elegant, with numerous calls to (next!) and such, do you have an oppinion about that rhickey ?
14:54ericthorsenshould not (with-in-str "(" (read *in* false -1)) return -1
14:55kotarakericthorsen: no, it throws...
14:55kotarakericthorsen: (with-in-str "" (read *in* false -1)) => -1
14:55kotarakericthorsen: (with-in-str "" (read *in* true -1)) => throws
14:55ericthorsenkotarak: I guess I thought I could tell the reader eof is not an error and return the value i passed?
14:57ericthorsenkotarak: They are both eof exceptions yes?
14:57rhickeyLau_of_DK: I don't think so - have a look at core.clj in lazy and decide for yourself
14:57kotarakericthorsen: oeh, sorry don't know by heart.
14:58ericthorsenkotarak: with-in-str "" (read *in* true -1)) throws EOF
14:59Lau_of_DKrhickey: ok
14:59rhickeyLau_of_DK: where are these critics of which you speak?
15:00ericthorsenkotarak: let me double check my version of clojure........
15:00Lau_of_DKrhickey: They'll present themselves if they're willing to stand by their words, I was referring a private conversation so I cant really implicate them without their consent :)
15:02ChouserI believe Lau_of_DK is referring to things I said about the streams branch (not the lazy branch).
15:02kotarak! sounds like stream...
15:02Lau_of_DKOh thats right - my bad! :)
15:03rhickeyChouser: that makes sense - I'm a critic of streams code myself :)
15:04Lau_of_DKrhickey: I thought that streams was what allowed you to be fully lazy, so I must have gotten the two mixed up
15:04ChouserI'm looking forward to the scope stuff, and I'll be quite content with fully-lazy.
15:04rhickeyWhat you are seeing in lazy and streams is the kind of work I used to be able to do in private the couple of years before I released Clojure. Patience is the rule
15:05ChouserI'd be willing to go along with streams if our BDFL goes that direction, but I definitely have misgivings.
15:05Lau_of_DK(doc BDFL)
15:05Chouser~BDFL
15:05clojurebotIt's greek to me.
15:06Lau_of_DKrhickey: Im very patient, and also very interested- Watching a language take shape like this is most exciting... man I sound like a geek :)
15:06Chouserclojurebot: BDFL is Benevolent Dictator For Life (a.k.a. Rich Hickey)
15:06clojurebotc'est bon!
15:06rhickeyIt ends up that for best perf with fully-lazy, you need to grab the seq and not rely on first/more calling seq - the double indirection is a big hit
15:06rhickeyso, a fair amount of when-lets in core code, more casual code can ignore the difference
15:07rhickeyso, map like this:
15:07rhickey ([f coll]
15:07rhickey (lazy-seq
15:07rhickey (when-let [s (seq coll)]
15:07rhickey (cons (f (first s)) (map f (more s))))))
15:08Lau_of_DKThis may be a really dumb question, but if I always need to work with seq, then doesnt that make the call itself redundant?
15:09Chouserah, call seq once, not multiple times on the same call.
15:09rhickeyLau_of_DK: coll is not necessarily a seq, nor is the result of more
15:09rhickeyChouser: right
15:09Lau_of_DKAh ok
15:09rhickeyChouser: hotSpot can't optimize through the chained call
15:09Lau_of_DKAnd 'more' instead of 'rest' because first is constantly changing right? I like...
15:10rhickeyLau_of_DK: (rest x) == (seq (more x))
15:10rhickeyi.e. eager
15:11Lau_of_DKsure - but (s (seq [1 2 3])) isnt (= 1 (first s)) and (= 2 (first s)) both true when run in sequence?
15:12rhickeyLau_of_DK: you are confusing this with streams, (first s) always returns the same thing, same as ever
15:12Lau_of_DKk
15:12Lau_of_DKYes youre right, I am - only cause I like the streams approach
15:12Lau_of_DK:)
15:16rhickeyI encourage everyone to try the lazy branch and give feedback, been little so far
15:17Lau_of_DKrhickey: Got something like .org/streams regarding lazy, so I know what Im looking for when trying it out?
15:17kotarakrhickey: will there be a lot of changes for existing code?
15:17rhickeyLau_of_DK: http://clojure.org/lazier
15:19rhickeykotarak: http://clojure.org/lazier
15:19rhickeylet me know if that *doesn't* answer any questions
15:19Lau_of_DKrhickey: I like the intro to that article :)
15:20Lau_of_DKJust to be clear, when you say something is fundamentally eager, what is meant by that?
15:23rhickeyLau_of_DK: in order to satisfy its interface, it needs to see if there is another item
15:24hiredmanrest never returns an empty seq
15:24rhickeyhiredman: there's still no such thing as an empty seq in Clojure
15:24rhickeyseq or nil
15:24Lau_of_DKrhickey: So in that way he's right actually :)
15:25hiredman...
15:27rhickeyLau_of_DK: rest never returns a unicorn either
15:27hiredmanclojurebot: rest?
15:27clojurebotcertainly brianh
15:27hiredmanuh
15:28hiredmanclojurebot: rest is <reply>rest never returns a unicorn
15:28clojurebotIk begrijp
15:28Lau_of_DKhaha, a unicorn ? :)
15:28technomancythe question is what function *does* return a unicorn... you probably need contrib for that, right?
15:28Lau_of_DKrhickey: Going from that article, the lazy stuff looks downright awesome, cant wait to dig in
15:29jbondesontechnomancy: clojure.contrib.mythical.clj
15:29hiredmanI imagine you could just use the jre unicorn creation framework
15:29hiredmanbut I am not sure
15:29hiredmanit makes pretty heavy use of annotations
15:30danlarkinUnicornFactoryFactory
15:30Youhourhickey: were you intending to do more work on the zipper implementation, or do you consider it pretty much what should be there in core?
15:32rhickeyYouhou: I'd rather see someone contrib a nice implementation of finger trees
15:32Youhourhickey: finger trees? I glossed over them as I was going through papers. Hmm.
15:33rhickeyhttp://www.soi.city.ac.uk/~ross/papers/FingerTree.html
15:33Youhourhickey: I'm trying to use the zipper, but in the current state I find it is very hard to use in real applications (looks nice in tiny demos though)
15:33rhickeyYouhou: I know Chouser and cgrand have used it profitably in some contrib code
15:34Youhourhickey: ah, interesting -- they actually define folding operations. That was my biggest problem with zippers.
15:34Youhourhickey: I also found that the zipper is essentially a hidden comonad -- and without supporting infrastructure it quickly gets tedious if you want to do things to it (passing seeds around quickly gets cumbersome)
15:34hiredman"However, one could argue
15:34hiredmanthat this support sometimes leads programmers to use lists when a more general
15:34hiredmansequence type would be more appropriate
15:34hiredman"
15:35hiredmana general sequence type huh?
15:35Lau_of_DKrhickey: The implications of the last filter-example in your article, are they that everything is now automatically memoized and that I would hit those Heap explosions as often? :)
15:36rhickeyLau_of_DK: everything has always been memoized with lazy-cons, this just solves the close-over issue
15:37Lau_of_DKok, even better
15:38hiredmanof course the paper is full of haskell
15:38hiredman*sigh*
15:38Youhourhickey: ok, now I remember. I read this paper, or at least skimmed through it. I didn't find the structure to be of interest. All I need are n-ary trees which I modify and fold (traverse). I don't actually need any of the properties of finger trees.
15:41gnuvinceStupid question here: how does one implement things like finger trees in Clojure? In Haskell you'd use data, in an object oriented language you'd use a class. What's the prefered way to do this in Clojure, use the basic data types with a few select functions?
15:42Lau_of_DKHows that a stupid question?
15:42gnuvinceLau_of_DK: I figure I'm missing something painfully obvious
15:42rhickeyYouhou: ok. I'd still like finger trees and treaps: http://www.cs.cmu.edu/afs/cs.cmu.edu/project/scandal/public/papers/treaps-spaa98.pdf
15:42ayrnieugnuvince, http://gist.github.com/55662
15:44Youhourhickey: what I'll try to implement (and contribute) is traversal (foldts, to be exact, as in http://okmij.org/ftp/papers/XML-parsing.ps.gz) for zipper trees.
15:45YouhouProblem is, it needs to be monadic (comonadic) to be exact, to avoid ugliness in passing the seed around. I still don't know how to implement that properly in Clojure.
15:47rhickeyYouhou: have you looked at: http://code.google.com/p/clojure-contrib/source/browse/trunk/src/clojure/contrib/zip_filter.clj
15:47ayrnieugnuvince - so deftype, there, just updates a central repo of type information to facilitate pattern-matching over types. The constructors are left to the user.
15:48Youhourhickey: I looked at chouser's code in clojure-contrib -- yes, zip_filter, and the XML specialization. But what he does is only useful for static trees. If you want to "modify" the tree during traversal, you can't just map a function over a seq of children, you have to use the zipper functions to move around.
15:49Youhourhickey: so the zip_filter stuff is a simplification -- useful if your tree doesn't change. Which isn't my case.
15:49ChouserYouhou: that's a little detail I hadn't considered until the last week or two.
15:50ChouserAll of my early use cases were for extracting data, but of course it's reasonable to want to make adjustments and get back a new tree.
15:50YouhouChouser: I actually completely missed it until recently. And then I noticed that zf/children looks cool, but actually gives me a number of different trees, not children in the same tree.
15:50Chouserright
15:51Chouserwell, of course they're different trees because they're all immutable
15:51gnuvinceJan Rychter
15:51gnuvinceoops, sorry
15:51Chouserbut I can see that it'd be useful to for a step in the filter to modify the tree in some way other than traversal, and have that new tree passed to the next step.
15:51YouhouChouser: well, I implemented Kiselyov's foldts for zippers -- and it works fine -- but it isn't pretty and isn't general. I'm afraid generalizing it will require some sort of a monadic approach.
15:52ayrnieugnuvince - you can think of type declarations in Haskell (Mercury, O'Caml, Lisp after you do a little bit of work) as just establishing constructors and destructors. The constructors you use like a normal function, the 'destructors' extend the pattern-matcher. The magic is only in making this efficient, safe.
15:52YouhouChouser: I'm working on a web framework, which is component-based and operates on a tree of widgets (think DOM). I do need to modify that tree.
15:54ChouserYouhou: you could use any one result from a zip-filter expression as the basis for a modification, but then you'd have to start the zip-filter process over again on that one new tree.
15:54gnuvinceayrnieu: and underneath, it's vectors and whatnot?
15:55jbondesonrhickey: i take it you're looking for a persistent treap?
15:55ChouserI haven't thought through yet how new trees would be passed through the chain of filter expressions, what options would be useful and such.
15:55rhickeyjbondeson: yes
15:55YouhouChouser: it hit me when I wanted to recursively descend down my tree -- I wanted to map a function on children. But you need to get the result from one map step and feed it to another, collecting real output on the side as you go. Monadic computation, I'd say.
15:56ayrnieugnuvince - sure.
15:57gnuvinceayrnieu: at this point, is it the responsability of the library to ensure that a user doesn't use seq operations to modify the data strucuture in a possibly incoherent manner?
15:58ChouserYouhou: you wanted to map on the final nodes returned by the whole filter expression, right, not on intermediate stages of the filter?
16:00ayrnieugnuvince - safety and representation really are separate issues. You can write a library that deals with a type and say "if you only operate on this type with this library's functions, you'll be coding in a state of grace". You can do this in C.
16:00YouhouChouser: what do you call a "filter expression"? I don't actually use the xml stuff, I just have zipper trees with structs in them. And I tried using some functions from zip_filter (children and descendants, from what I recall). As for the trees, I need to walk through them making changes along the way, there is no specific stage when that happens.
16:01YouhouAnyway -- I'll report back with a working foldts once I solve this.
16:02Chouserhm.. apparently I need to grok monads more deeply before I pursue this. :-)
16:02gnuvinceayrnieu: so the contract with the user is "use my functions and you'll be fine, if you try to fiddle with the internals, you're on your own"?
16:05ayrnieugnuvince - this is always the case :-) You can try to make your type more opaque by only offering keys to the user (think of file descriptors in unix -- they're just numbers, they obviously don't contain the i/o information in themselves), or by storing the data in an unprintable java object. You can try to reveal errors earlier by type-checking. Maybe Clojure can help you out with this, linguistically.
16:14YouhouChouser: that is exactly what I'm trying to do right now. It doesn't help that people mostly write about monads using mathematical concepts (unnecessary) and they all use Haskell notation (which I find confusing and unclear). I have feeling that the underlying concept is simple, it's just presented in a complicated manner.
16:14ChouserYouhou: there are a couple monad implementations for Clojure, which might be helpful on the notation front.
16:15ayrnieuhttp://paste.lisp.org/display/43723 is how I delt with state in Hedgehog Lisp, in which (def x y) means that x is y forever and no fooling with 'refs', 'STM', etc.
16:19ayrnieubasically a (-> state ...) macro, extended with control flow and with an (_ "don't mangle this expression" (println "current state:" state) )
16:25let_f_how many gigabites are all the images on the internet?
16:27durka42quite a few
16:27danlarkintwo problems: 1) gigabits or gigabytes? 2) unanswerable
16:28durka42or gibibytes
16:49let_f_petabytes
16:50HolcxjoMore like exabytes or even more
16:52Chousuketoo many :(
16:55zargon_Hi! Thought experiment: Writing a game without destructive updates, where we have 100+ "objects" in screen at a frame-rate of 50fps. In pure functional programming each "object" state change would result in a new object instead of modifying the original one. When implementing such a game in clojure what would the effects be? Wouldn't there be a massive amount of object creation and associated garb
16:55zargon_age collection?
16:57technomancyzargon_: yes, this will result in huge amounts of garbage creation
16:57technomancybut it doesn't matter
16:57technomancyGC for ephemeral objects is obscenely cheap
16:57zargon_"ephemeral"?
16:58kotarakWhat was the amount of the ant simulation on the Azul box?
16:58technomancyzargon_: short-lived
16:58technomancykotarak: I want to say 20 GB/second?
16:58kotarakSomething like that, yes...
16:58technomancy7% CPU usage over ~600 cores
16:59zargon_technomancy: I do a lot server side programming in Java an there are times where GC stops execution for many seconds, that wouldn't be the case for our hypothetical game, you say?
16:59wwmorganzargon_: it seems like something that would be easy enough to test/measure
16:59technomancyzargon_: also: these objects will share internal structure, so the new objects only need to create basically a diff with the old one it's based on
17:00technomancyzargon_: there are multiple GC strategies in the JVM. some of them pause, some don't IIRC
17:00technomancyI'm sure you could avoid pauses like that
17:00zargon_hmm
17:01zargon_i'll have to look into the various snake implementations seen on the mailing list ...
17:01technomancyconsidering I've never written any Java. =)
17:03technomancyis the lazy branch built off the streams branch, or are they independent?
17:03Chouserindependent
17:06danlarkinI finally saw an explanation of what it means to be "basically free"
17:06danlarkinit averages out to less than one cpu instruction per ephemeral object
17:07danlarkinso they round down :)
17:07technomancyheh
17:07hiredman...
17:14lisppaste8ayrnieu pasted "need A) a macroexpand-all so that the errors in this can be considered, or B) reduce submacros to one tree-walker" at http://paste.lisp.org/display/75306
17:15c|phello all
17:16ayrnieuif the errors are in fact in that code and not in clojure.
17:17ayrnieu"java.lang.IllegalArgumentException: Wrong number of args passed to: user$if--GT-" on (defn-> match [char] (if-> (look= char) (get-char) (thru ...)))
17:40ayrnieu(OK, it isn't an error in clojure, it's just macro hell. So you should have a 'flat' DSL like in that hedgehog example. But dynamic variables are probably a better way to do this.)
17:47scottjI'm reading p211 of b6 of Programming Clojure and it says that you can't write defstruct as a function because def can't be called at runtime.
17:47scottj(defn defstruct2 [name & keys] (eval `(def ~name (create-struct ~@keys))))
17:48ayrnieuscottj - it assumed that you would not use eval.
17:48kotarakeval is baaaad
17:48kotarakeval is almost always not one wants.
17:48kotarakwhat one wants
17:49scottjso when I need to use eval in a function, that's an indicator I should use a macro?
17:49hiredmangenerally
17:49kotarakscottj: Whenever you have to control the evaluation of the arguments, you need a macro.
17:49ayrnieuyou cannot replace every use of eval with a macro.
17:53scottjin this case, are there any big differences between using eval with a function and a quoted symbol, and using a macro with a symbol?
17:53kotarakscottj: yes. The eval depends on runtime information. The macro cannot depend on runtime information.
17:54kotarakscottj: (apply defstruct2 (some-user-input-here))
17:56scottjok, thanks all.
18:01c|pi agree
18:01c|pratios are much ccoler
18:01cooldude127i get stuck with floats when i start having to square root stuff
18:02cooldude127and that is the magic that results in a number that should be 0 becoming 0.43 !!!
18:02cooldude127or others
18:04cooldude127OMG THIS IS SO STUPID! 0.0 != 7.771561172376096E-16
18:05cooldude127but for all intents and purposes, they are the same
18:05cooldude127until you try to divide 1 by each of them
18:05cooldude127and then i start to cry
18:05technomancyyes, floats are inherently flawed
18:05cooldude127someone help me fix this. i'm begging you!
18:05technomancysome believe the only upside to them is that the word "mantissa" is fun to say.
18:05cooldude127lol
18:06cooldude127i will sell my left kidney to the first person to offer a good solution to this ;)
18:06technomancycooldude127: "fix"? the fix is not to use floats when accuracy is required.
18:06cooldude127technomancy: the problem is i don't have a choice really
18:06lisppaste8replaca pasted "eval in macro" at http://paste.lisp.org/display/75310
18:06cooldude127unless you have a square root function i can use that keeps things in ratios
18:07replacaThis eval discussion brings up a question I've had for a while. What happens when I want to use a var at compile time when evaluating a macro? I found myself using eval, but was thinking there was a more idiomatic way.
18:07replacaas shown in the paste right there
18:10hiredmanclojurebot: google how to write a square root function
18:10clojurebotFirst, out of 256000 results is:
18:10clojurebotThe Niklas Lindblad Organisation � Blog Archive � Write Your Own ...
18:10clojurebothttp://nlindblad.org/2007/04/04/write-your-own-square-root-function/
18:10Chouser,@(resolve 'map)
18:10clojurebot#<core$map__3634 clojure.core$map__3634@128d900>
18:11Chouserreplaca: ^^
18:11Chouserobviously only works for Vars, though, not locals
18:12cooldude127that square root function might work actually. looks like what i remember from sicp
18:12cooldude127except i can use ratios
18:12cooldude127which i think would actually work in scheme
18:13replacaChouser: ahh, so here I'd use "(resolve 'symbol-map)" instead of "(eval symbol-map)"?
18:13Chouseroh
18:13Chouserum
18:13replacaChouser: (since I'm doing the quoting further out)
18:13ChouserI didn't look at your example very closely
18:13replacaChouser: :-)
18:13Chouserwhy not just ~symbol-map ?
18:14Chouserum
18:14Chouserstill not closely enough, sorry.
18:14replacaChouser: because that evals at run time and I'm using the symbol-map at compile time to build the structure
18:14replacaChouser: basically I'm building a struture that binds dome variable depending on a table
18:15replaca*dome -> some
18:17hiredmanactually
18:18hiredmanwikipedia has a page devoted to methods for finding square roots
18:18Chouserok, symbol-map will be a symbol that names a var?
18:18Chouserif so, then you could say @(resolve symbol-map)
18:18replacaChouser: yeah, in practice it will be "write-option-table"
18:19replacaas defined above
18:19Chouserbut if somebody passes in a literal map, the eval would work by resolve will blow up
18:19replacaChouser: hmmm, interesting
18:19replacaso eval may actually be best here?
18:20replacait's only a compile time cost
18:20replacaanyway
18:21cooldude127ok clojure's driving me crazy with the fact that it doesn't have it's own math functions
18:22cooldude127i'm getting sick of Math/everything-i-need!
18:22cooldude127lol
18:22kotarakreplaca: the eval won't work with locals.
18:22Chouserneither will resolve :-)
18:23Chouserreplaca: actually, you might be better off looking at the definition of 'binding' and doing something similar
18:23kotarakMaybe this is a sign, that is Not a Good Idea?
18:23Chouseras kotarak has demonstrated, I believe
18:23Chouserdinnertime. bbl.
18:24kotarakHuh? I have demonstrated something?
18:24replacaby locals you mean "local to the function that contains the instance of the macro to be expanded"?
18:25kotarak1:5 user=> (defmacro foo [x] `(do ~@(map (fn [y] `(println ~y)) (eval x))))
18:25kotarak#'user/foo
18:25kotarak1:6 user=> (let [x [1 2 3]] (foo x))
18:25kotarakjava.lang.UnsupportedOperationException: Can't eval locals (repl-1:6)
18:25replaca(in this case, I need to modify it to work like the defn of binding anyway, but I still will need the table I think)
18:25kotarakeval has its uses. But they are rare.
18:25replacaahh, that makes sense, cause the local doesn't exist at compile time anyway!
18:26kotarakBingo.
18:26replacaso it wouldn't match this case
18:26kotarakWhy is it so important to have the binding at compile time?
18:26kotarak(Just asking stupid questions, without knowing the background...)
18:27replacain this case cause I'm using the table to build the structure of the resulting macro expansion
18:27replacathink: table driven code generation
18:27replacathough there are other ways I could solve this example
18:28replacabut the problem got me thinking
18:29replaca(in fact in this case, I could just hard-code it, cause it doesn't really need to be table driven - that's just spurious elegance)
18:32kotarak(my-opinion "I almost never need eval. In fact I have eval only at one point in all of my code. And that's a Repl, so one of the few legitimate uses of eval.") Of course: YMMV, but I'm deeply suspicious of code using eval. In my cases, this was always a sign, that I did something wrong or wanted to be too clever....
18:33replacathat's why I brought it up :-)
18:34replacagenerally, however, this notion of "table driven code generation" seems interesting and potentially useful
18:36cooldude127is there a way to check if something is an integer? do i need to do (instance? Integer)
18:36cooldude127?
18:42Chouser,(integer? 2.5)
18:43Chouseroh, he's gone. anyway, 'integer?', cooldude127
18:43replacaChouser: you eat fast!
18:43Chouserreplaca: this place is a zoo. leaving again in 2 minutes.
18:44replaca:-)
18:44Chouserreplaca: but since you're trying to build binding, you might just use clojure.lang.Var/pushThreadBindings, just like the 'binding' macro itself does.
18:45Chouserthen you could pass in literals, locals, or whatever.
18:45Chouserbbl! :-)
18:45replacayeah, that's my eventual theory
18:45hiredman,(loop [] (recur))
18:45cooldude127Chouser: thank you, that's much cleaner
18:45replacacul8r!
18:45clojurebotExecution Timed Out
18:46hiredmanclojurebot: really?
18:46clojurebotexcusez-moi
18:47hiredmanbecause to me it looks like java is still running that loop
18:47replacahiredman: you need to host clojurebot on a faster machine!
18:48hiredman.cancel on a future doesn't do what I want
18:48hiredmanso clojure's future doesn't seem like it will be used just yet with clojurebot
19:02cooldude127yay i have a sqrt that uses ratios!
19:02cooldude127fuck you floats!
19:03sohailsqrt says: "I can do more sqrts/sec than you"
19:04technomancycooldude127: you're four days late: http://achewood.com/index.php
19:05lisppaste8cooldude127 pasted "sucky sqrt" at http://paste.lisp.org/display/75315
19:05cooldude127although i'm not gonna lie, this is disappointing
19:06cooldude127^
19:07Chouseryeah, I'm not sure that's strictly accurate.
19:07hiredmanwell
19:07cooldude127Chouser: it's an approximation. an ugly approximation
19:19cooldude127square roots are disgusting
19:19sohailcooldude127, how are you approximating
19:19sohailiterative?
19:19cooldude127sohail: whatever newtons method is
19:20sohailiterative
19:20cooldude127i'm trying to figure out a way that can give me clean integer results for perfect squares, and at the same time use ratios for non perfect squares
19:20sohailgood luck
19:21cooldude127yeah kill me
20:22clojurebotsvn rev 1276; added multi-arg clojure.set/union/difference/intersection, patch from jawolfe
20:27p_lHas anyone tried running clojure applications on Android?
20:32hiredmanthere are reports that it works in the emulator
20:34p_lhmmm... nothing specific yet? I guess I'll have to play with it a little - there's some market for Android and I'd prefer to avoid writing in "normal" Java :)
20:35hiredmanthere are some patches on the mailing list to reduce start up time on android
20:37p_lhmm.. I'll have to go through it, as soon as I get the SDK working
20:37ChouserI believe clojure still requires a small patch to work with android
20:38Chouserbut with that patch it has been shown to work on an actual device.
20:40p_lthanks for info
20:42durka42~logs
20:42clojurebotlogs is http://clojure-log.n01se.net/
20:44hiredman,(loop [] (recur))
20:44clojurebotExecution Timed Out
23:20danlarkinman, I *really* love destructuring bind
23:21thearthurhow to i call java.lang.system.exit
23:22danlarkinthearthur: (System/exit 0)
23:22thearthur:)
23:22thearthurthanks