#clojure logs

2008-07-31

00:20dkfdid the syntax change so that (defn *thing* (ref [])) no longer works?
00:20dkfcause I'm getting an Don't know how to create ISeq from: Symbol exception
00:35dkfhmm, I guess that should have been a def
01:07dkfI have a vector, [1 0 1 0], in *myRef .. (seq @*myRef*) and (vec @*myRef*) always return the vector within another set of brackets.. how do I get rid of those brackets, so that conjing another vector (or mutation thereof) is seen as just one list of vectors (and no more levels deep)
05:01meredyddChouser: Thanks for that - loadResourceScript is something I was entirely unaware of!
07:03meredyddHmm, another compiler bug
07:04meredyddUnfortunately, I'm not quite sure how to reproduce this...seems to be an interaction of a couple of macros
07:21meredyddrhickey: *prod*
07:22meredyddrhickey: I've managed to reduce it to one line, to the point where removing any of the forms causes it to start working again
07:22meredydd(def k) (. k dosomething (do (try :something (catch java.lang.Exception e :something-else )) nil))
08:42Chousermeredydd: I can confirm that error
08:43Chouserdkf: (conj @*myRef* 2) ==> [1 0 1 0 2]
10:15rhickeymeredydd: looking at your verify error now
10:15meredyddta
10:16cemericklooks like clojure-contrib/import-static hasn't been updated to the new namespace scheme (there's references like set/intersection, rather than clojure.set/intersection) -- is this right, or am I missing something?
10:20Chousercemerick: I think you're right. Tossing in a (alias 'set 'clojure.set) seems to fix it right up.
10:20cemerickChouser: yeah; although, it should also be in an import_static dir, yes?
10:22Chouseroh, sure enough. looks like most of contrib hasn't been moved yet.
10:23Chouserbut a bunch of stuff has been copied!? hm.
10:23Chouserlooks like a bit of a mess at the moment.
10:24cemerickChouser: yeah, I saw that; I was thinking that perhaps the top-level files are there to continue support for those who are following contrib but not clojure head (and therefore aren't using the new namespaces, etc)
10:25Chouseryeah, you must be right. I guess I should update my contribs.
10:25dkfchouser: I was looking for turning [1 0 1 0 1] into [1 0 1 0 1][1 0 1 0 2] so, basically, i'm derefing an element, mutating it, then conjing it on. My problem was that (seq @*myRef*) returns ([1 0 1 0 1]) and not [1 0 1 0 1]
10:26dkfbut I ended up using (last @*myRef*)
10:26Chouserwhat is [1 0 1 0 1][1 0 1 0 2] ? If it's two things they must be in some kind of container?
10:26dkfa vector
10:27dkf*myRef* is []
10:27dkfso it's [[1 0 1 0 1][1 0 1 0 1]]
10:27Chouserah, ok.
10:27cemerickChouser: although, the top-level lib.clj has a (alias 'set 'clojure.set) in it, which wouldn't work prior to the new namespace stuff (I think -- don't remember which order alias and new namespaces went in)
10:28dkffun little project.. I'm gonna need some more help here in a bit. I'm making a 2d cellular automaton, ala wolfram
10:30dkfright now, though, because I'm such a novice functional programmer (or even programmer, for that matter), I'm accomplishing it through what I like to call "brute force programming".. where there's no recursion.. it almost looks like assembly :)
10:30dkfSo my next step is to condense it down to recursive structures.
10:32Chouserdkf: sounds like a good approach. I'm always in favor of making it work at least a little before making it right or pretty.
10:32rhickeydfk: as a tip, keep the ref logic out of the main logic - don't use refs/@ in the functions that calculate new state
10:34dkfright.. I spent half a day thinking about how I was going to clojure-ify this problem.. then said screw it, I'm building each instruction
10:34rhickey(alter ca-ref ca-step)
10:35lisppaste8dkf pasted "automaton" at http://paste.lisp.org/display/64480
10:35dkfthere it is
10:36dkfI'm not sure if that's how I'll actually use it. I might just have one vector and through away the trailing subvectors
10:37rhickeydkf: first thing to try is vector equality, getting rid of the nths: (= v [0 0 0])
10:38dkfah.. of course!
10:40rhickeydkf: could probably turn tri-iterate into a one-liner with rem and no cond
10:40dkfwait a minute. which function are you talking about?
10:41rhickeydkf: rule45
10:41cemerickChouser: are you making any changes in clojure-contrib to bring it up to speed? If not, I'll post a msg on the group to see where people see things going there.
10:41Chousercemerick: go ahead and post. I haven't been paying close enough attention to be sure what needs to be changed.
10:42dkfah, i see
10:42cemerickNeither have I really (short of those pieces that I use already).
10:42dkfrhickey: how would you use rem in tri-iterate?
10:44rhickeydkf: the logic in each branch of the cond is the same relative to n
10:46dkfright, but remainder.. how does dividing return 3 elements from a given portion of the vector?
10:47Chouseryou can use remainder to calculate the index.
10:47rhickeyrem is used when you have wrap-around logic
10:47dkfmy math isn't so good.
10:47Chouser(rem (+ n 5) 6) to decrement n wrapping around at 6
10:50dkfthe repl says you're right
10:50dkfoh, i see
10:51Chouserright, so you can use the same kind of pattern to increment wrapping around as well
10:52dkfah, but wait.. (rem (+ 6 5) 6) --> 5 .. (rem (+ 0 5) 6) --> 5
10:53Chouseroh, you're right. you found a bug in my code. :-)
10:53dkfneed to get that sixth element
10:53dkfbut I see what you're saying
10:53Chousersince you actually have 7 values (including 0 and 6) you want the remainder when dividing by 7 (not 6 like I said)
10:53dkfah, ok
10:55dkfso it's (rem (+ n 6) 7)
10:55dkfI've never seen that use of remainder before
10:58dkfgreat. So with this, I will be able to make automatons of any size
10:59rhickeydkf: right!
10:59dkfThat was next on my todo list :)
11:05rhickeydkf: there's also a nice way to do it with partition, cycle and range, when you are ready for the next level
11:12cemerickapropos of nothing -- while reorganizing a project here to be in step with the new namespace system, I'm finding this one-directory-per-namespace standard very tiresome. It seems like supporting one file-per-namespace as well as the directory-per-namespace (for namespaces that required multiple source files) would be far friendlier. I don't know what that would require in lib or what the ramifications would be elsewhere, of course.
11:13dkfHow do I find the length of a vector?
11:13Chouserdkf: count
11:13Chouserheh. I don't mean you should count it.
11:13Chouser(count v)
11:13dkfthanks :)
11:14Chousercemerick: in what specific way is it tiresome? can we provide tools to ease the pain?
11:14dkfis that a lisp thing? why wouldn't there be a (length [0 0 0]) function?
11:16Chouserdkf: it's just called count instead of length. In the wide world of APIs, I've seen count, length, and size used almost interchangably.
11:16Chousernobody ever seems to call it width or height, though.
11:17cemerickChouser: it's just a matter of contrast with other environments. When virtually every directory has just a single file in it, moving around that project structure requires perceptibly more work than it would be otherwise.
11:17rhickeylength is not a good fit for non-sequental collections
11:17rhickeycemerick: why so many namespaces?
11:18dkfah
11:18cemerickrhickey: they mirror existing java packages, or packages/classnames we want to expose to java consumers
11:19rhickeycemerick: turning classnames into packages is going to cause that explosion
11:20Chouseryou can put multiple classes in one directory, right?
11:20cemerickrhickey: you mean 'namespaces into packages', yes?
11:20rhickeycemerick: now it is the same as Java, yes
11:20rhickeycemerick: yes
11:20cemerickChouser: Sure.
11:20rhickeycemerick: no package + class into namespace
11:22cemerickrhickey: well, same as Java + 1 -- if Java were to require a directory for the class com.foo.Bar, with a Bar.java file in it
11:22cemerickI realize Java's pretty confused w.r.t. classes functioning as namespaces, but that's the practical effect.
11:22rhickeycemerick: that's what I'm advocating against - why isnt the namespace com.foo ?
11:23cemerickrhickey: because gen-class is going to search for a com.foo.Bar namespace at init -- or am I one step behind recent gen-class changes?
11:23rhickeywhen implementing a Java class using gen-class, it's exactly the same dir/file granularity
11:24rhickeycemerick: yes, you are behind
11:24rhickeycom.foo.Bar is Bar-ths Bar-that in namespace com.foo, file Bar.clj
11:25rhickeydir com/foo/
11:25cemerickright, fooey
11:26Chousercemerick: sorry. now you get to undo all those mkdirs :-/
11:26cemerickwell, that certainly helps
11:26rhickeyok, well at least it seems not to be a gripe with where we are going?
11:26cemerickrhickey: well, I still have a gripe about one dir per namespace -- gen-class' recent changes just make things a little easier otherwise.
11:29rhickeycemerick: too many benefits to playing along with Java packages, but I agree people will have to consider it when organizing their Clojure libs
11:30rhickeybigger than a class but probably finer than your ordinary java package
11:30cemerickrhickey: well, consider clojure/src/clj for a moment -- isn't there a way to indicate that tools should look for clojure.set in clojure/set.clj rather than clojure/set/set.clj?
11:32cemerick(BTW, I keep niggling at this because while it bothers me just a little (and I'll get over it), I know that many programmers will be bothered by it a *lot*, especially those coming from python or ruby environments where one-file-per-module is standard)
11:32rhickeydropping a segment means dropping a distinction at some point
11:32rhickeyPython and Ruby are still class oriented, no?
11:33cemerickI'm far less acquainted with Ruby, but you can do a lot in Python without touching classes.
11:33cemerickJust functions in modules, one module per file.
11:33rhickeywhat if clojure.set had a manifest resource, what's to keep that file from conflicting with the clojure.foo manifest resource?
11:34rhickeyor any other related items
11:34cemerickyou mean manifest, as in /META-INF manifests?
11:34ChouserYou can def functions at a package (module) level in python, but I think you'd usually do all those in a single file in the module's directory -- just like clojure is now.
11:34drewrRuby's and Python's module systems are very different.
11:34rhickeycemerick: any resource really, blah.ico
11:36albinoin python there isn't any point in creating a package (fs directory) when you can do it in one file with a .py extension
11:37cemerickChouser: It's been a little while (a year, maybe since I touched python much), but packages work just like modules, except their name is defined by their directory name, and their definitions are placed in the __init__.py file in that dir
11:37Chouserah, so you can migrate from foo.py to foo/__init__.py if you need to include other files for whatever reason.
11:38cemerickChouser: yup
11:38drewrcemerick: __init__.py is only required to tell the interpreter that the directory contains modules.
11:38ChouserI bet it would be pretty hard to talk Java tools into following that kind of layout.
11:38cemerickdrewr: right, but if you want definitions associated with that package's name, you can put them in __init__
11:39cemerickrhickey: what I'm suggesting is that, if you have a namespace that has multiple resources (whether they're multiple clj files, images files, whatever), then make a directory for the namespace, and pile everything in there. Otherwise, just have a single .clj file for that namespace.
11:39drewrcemerick: True.
11:39cemerickThat requires lib to attempt a couple different loading strategies on each require/use call, but makes life a lot simpler for the simple cases. I think the wildcard is tooling.
11:40rhickeyI think it is a mistake to ignore what classpath/jars/remote-resource loading brings to the table - I can't make Java aware of some home-made scheme
11:42cemerickI guess I'm not following how any namespace conventions that are set forth aren't a home-made scheme -- it's not like a classloader knows that clojure.set maps onto /clojure/set/set.clj natively -- lib has to figure that out, or one has to explicitly load that file.
11:43rhickeyit knows that clojure.set's resources are under clojure/set/, just from the class package
11:44cemerickrhickey: Oh, sure -- but in the simple case where there are no resources, it absolutely doesn't hurt to have clojure.set loaded from /clojure/set.clj
11:46rhickeyWhat are the classes called?
11:47cemerickI don't follow.
11:47rhickeyeach function becomes a Java class that must have a valid package
11:47Chouserclojure functions generate java classes
11:49cemerickI would presume that they'd be called whatever they're called now, based on the namespace. I presume at this point we run into the tooling question.
11:50cemerick(right now, clojure.set/intersection is the class clojure.set.intersection__2037 in my repl, which seems fine)
11:50rhickeyright, before they didn't line up, thwarting tooling (although JSR 45 lets one remap, support varies), now they line up
11:51rhickeyI don't want to go down a road that's going to have to change once people want resources, JNLP, ahead-of-time compilation etc
11:52cemerickI guess where you lose me here is: where, other than enclojure or some other environment where there is clojure awareness built-in, are we looking to support tooling.
11:52rhickeyJNLP
11:52rhickeyresources, everything that uses classpath
11:52cemerickagain, if there are no resources, then I don't see what the downside is
11:53wlrGiven a clojure seq I'd like to print it readably to and re-read it from an external file. Could some kind soul offer up the dual print/read incantations involving *out* and filename?
11:53cemerickif there *are* resources, then they get piled into a directory matching the namespace/package, and all's right with the world
11:53Chouserwlr: i've got an example sitting around. hang on.
11:54lisppaste8dkf annotated #64480 with "automaton" at http://paste.lisp.org/display/64480#1
11:54dkfWell, I've gotten rid of the cond
11:54dkfso it's a little prettier
11:57dkfcould probably get rid of the nth's in tri-take somehow, but I'm going to move on to rule45
11:57lisppaste8Chouser pasted "print/read" at http://paste.lisp.org/display/64489
11:57Chouserwlr: that's what I do, but I should use "read" instead of "load-file"
11:58Chouserdkf: looks good! + can take more than 2 args: (+ n 1 l)
11:58wlrChouser: Thank you very much.
11:59rhickeycemerick: all those are homemade rules every tool is going to have to be aware of, and no Java tools ever will - what if the ns is defined in more than one clj?, if there are resources does the clj move down? etc
11:59dkfChouser: thanks
12:02cemerickrhickey: if there are more than one .clj in a ns, or if there are resources, then everything in that ns goes into a directory. It's seems like a straightforward thing to me (perhaps only because of my ignorance of impl details). Regarding tools -- I'd wonder what tool other than something that is already clojure-aware would need to pull up that single file that defines a namespace (/clojure/set.clj, for example).
12:04Chousercemerick: debuggers, for one
12:04rhickeyprofilers
12:07cemerickPerhaps I'm assuming too much about which tools people are using for those things. i.e. if I'm using clojure, I'd want to be in enclojure or some enclojure-aware emacs environment, etc.
12:07rhickeyAs I said, there is an JSR that let's one specify different paths and file names, and Clojure emits JSR 45 info, but support varies. Putting things in a path that matches the package/ns, and having that be a general rule, is much more straightforward in all contexts
12:09rhickeycemerick: you mention Clojure aware, but in the case of enclojure for instance, what they are doing is trying to get existing Java tooling to work with minimal change
12:09cemerickI guess my opinion would be to rely on tools to catch up with JSR 45. JRuby and Jython have this exact same problem, so it seems like a decent bandwagon to be on, in terms of community demand.
12:10cemerickrhickey: Right, but even without JSR 45, it's no big trick to push the NB debugger or profiler to bring up the contents of this-file-over-here when it needs to show clojure.set.
12:12cemerickI guess I find myself in the unusual position of advocating for the new user. Perhaps my concerns in that regard are unfounded.
12:12rhickeycemerick: I don't you've sold the benefits of your approach at all, just downplaying the benefits of following classpath. What's so difficult about creating a dir for a namespace?
12:14rhickeyI guess a lot has to do with the granularity of a namespace
12:15cemerickIt's not about difficulty, it's about simplicity, cognitive overhead, and things working like people would expect them to work. We're trying to fit into a Java ecosystem, but I'll bet serious money that a Java programmer would be very confused about the ns com.foo.bar needing to reside in /com/foo/bar/bar.clj.
12:17rhickeywhy wouldn't he presume everything related to the package com.foo.bar is in com/foo/bar/ and just be surprised and pleased you don't have to have umpteen .java files to define a package?
12:18rhickeywould you prefer /com/foo/bar/init.clj?
12:18erochesterI don't really have a dog in this fight (and my better judgment is warning me to stay out of this, but when has that ever stopped me?), but cognitively, Clojure already breaks the fairly simple directory=package, file=class schema that a Java programmer might have.
12:18erochesterWell, I'm not an experienced Java programmer, and that's the schema I have about them, anyway.
12:18erochesterSomeone who know Java better may think of it differently.
12:19erochesterAnd I may be misreading Clojure too :)
12:19rhickeyerochester: yes, but these changes unify dir/package/namespace
12:19rhickeynot having classes, things diverge there
12:20cemerickrhickey: I'm pretty sure that most (if not all) java programmers don't think about "defining a package" -- they define classes that happen to live in a package. They'll want to define functions and happen to live in a namespace.
12:20erochesterrhickey: Right, and I can see how they would make tool integration much easier.
12:20rhickeybut technically, there are classes, and they are defined in the source files contained in the dir matching the package/namspace, just like Java
12:21rhickeythose source files end in .clj and there are fewer of them, and their names don't correspond to classnames
12:23rhickeycemerick: would you prefer /com/foo/bar/init.clj? - that's a serious question, is the /bar/bar part the problem?
12:23cemerickrhickey: No, the name of the "top level" clj file in a namespace dir isn't a problem either way
12:26ChouserIt'll be interesting to see how the gen stuff shakes out, but for now I'm experimenting with putting one gen.clj file in each namespace dir: net/n01se/n01se-gen.clj
12:26ChouserThen the various class .clj's next to it (one per class so the generated startup code can find it)
12:26rhickeycemerick: when they "define classes that live in a package" they put the code in source files that live in a dir corresponding to the package - I don't see how this is different
12:27Chouserin that context, it might be interesting to use "gen.clj" for build-time stuff and "run.clj" or "init.clj" for runtime stuff.
12:27cemerickrhickey: agreed, but packages aren't viewed as entities unto themselves in Java
12:27cemerickI guess I'll sit down now, though. :-) I don't have any data or anything to support my claims of new user expectations, so all I've to go on is extrapolating from my personal reactions.
12:29erochesterThis might just be a matter of making this explicit in the introductory docs and in tutorials. The expectations of new Clojure-users (is there a name for this yet?) just need to be managed somewhat.
12:30erochesterI can see how using keeping changing clojure/set/set.clj to clojure/set.clj would be confusing also, since file != module. How do you tell the difference between clojure/boot.clj and clojure/genclass.clj, which are all in clojure, and clojure/set.clj, which is in clojure.set?
12:31rhickeycemerick: it is important. If dirs are truly bothersome we could end up with users avoiding namespaces and lots of fns named blah-foo, where blah should have been a namespace
12:31erochester"using keeping changing" => "changing"
12:31lisppaste8dkf annotated #64480 with "automaton" at http://paste.lisp.org/display/64480#2
12:31dkfso I cleaned up rule45 too, but now I have problems with mutate
12:32dkfI don't see why it's returning a list instead of a vector
12:33rhickeydkf: isn't it returning a vector with a list in it?
12:33dkfyes actually
12:33ChouserYou might want "vec" instead of "vector", to convert the list generated by map into a vector
12:33dkfmap returns a list then
12:34rhickeyyou either want to apply vector, or better, use vec
12:34dkfah, ok
12:34dkfoh yea!
12:35dkfchickachickaaah
12:35dkfoooh, beast.. unlimited size automaton now
12:35Chouserisn't it great when less code gets you more features?
12:35dkfabsolutely
12:36cemerickrhickey: I don't think it'd come to that -- I think of it more of a question of matching expectations and generally making for a gentle learning curve.
12:36cemerick(again, whether or not my impression of expectations is right or not remains to be seen)
12:38cemerickI'd again point out that JRuby and Jython have exactly this problem (mapping Java names to arbitrary resources), so whatever standards enable tooling for them should help clojure as well.
12:39cemericks/arbitrary/"arbitrary"
12:43dkfok, unfortunately, that apparently isn't actually rule 45 :) but some twiddling of the bits should fix that
12:46dkfok, there it is
12:46dkfit's fast too
12:49dkfrule45, 90 cells wide, 1000 iterations: "Elapsed time: 991.024605 msecs"
12:50rhickeycemerick: the only other way I'd think about it is namespace == class, i.e. no adding a set dir later stuff, all but the last segment is a real Java package and you have resources per package, i.e. potentially shared between namespaces. But there are sticky bits, like the generated fn classes - I'm not sure I can fabricate true nested classes there...
12:51rhickeythe other problem is org.myns ends up in Java package org, i.e. you lose a distinguishing level
12:52rhickeyno more namespace clojure
12:54dkfrule45, 90 cells wide, 1000 iterations: "Elapsed time: 761.859189 msecs" (changed one line slightly :)
12:55dkfIs holding the automaton state in a ref the best or most efficient way to do this?
12:56Chouserif you only need to observe the final state of the whole thing, you could build it iteratively (recursively) and return the result -- no need to mutate a ref.
12:57rhickey(take 1000 (iterate mutate [1 0 1 0 1]))
12:57dkfand print to screen each iteration, for the pretty final picture
12:58rhickeydkf: could you call it something other than mutate :)
12:58dkfhahah, yea, why?
12:58rhickeycause you aren't changing anything
12:59dkfoh yea
12:59dkfheheh
12:59rhickeystep/evolve
12:59dkfbifurcate?
12:59dkfstep is too general
13:00Chouserstep-automata
13:01dkfindeed
13:02dkfholy... "Elapsed time: 3.164833 msecs"
13:03dkfthose swaps to the ref taking up the vast majority of time
13:03dkfrule45, 90 cells wide, 1000 iterations: "Elapsed time: 3.164833 msecs"
13:03dkfwe have a winner
13:05dkfwait a minute
13:06dkfI typo'd. dropped the iterate.. but now that I've added the word iterate in there, "Elapsed time: 0.32325 msecs" .. which can't be right
13:07rhickeythe result is lazy
13:08dkfSo it's only measuring the last step?
13:11dkfhow can I print out the results? in the step-automata?
13:12rhickeydkf: best to avoid side-effects in you main code, just walk through the result, doseq would work
13:16dkfok
13:26dkf(doseq prn (take 1000 (iterate (step-automata [0 0 1 0 0])))) ? what am I missing?
13:28dkfI'm still learning to read the docs
13:28dkf(doseq item list & body) not sure what item is here
13:29rhickeydoseq takes a name, a seq, and a body of code which uses the name to refer to the current element in the sequence
13:29rhickey(doseq x aseq (prn x))
13:30dkfaaah
13:31dkfas a newcomer, that wasn't intuitive because everywhere else I see binding done in lets. I don't usually see the binding name outside of some kind of enclosing brackets
13:33dkfbut now it says wrong number of args passed to iterate. whereas, without the doseq iterate functioned fine
13:33dkf(doseq x (take 1000 (iterate (step-automata [0 0 0 1 0 0 0]))) (prn x))
13:34dkfok, so the binding is trying to take place in iterate
13:34rhickeythe entire call to (take 1000 ...) goes where aseq is above
13:36dkfIt looks like it is to me. You mean put the (prn x) inside the body that returns the aseq?
13:39dkfto me, it looks like a replace the aseq above with the call to (take 1000 ...)
13:39rhickeylooks like you aren't using a working call to iterate - it takes a fn as its first arg (iterate step ...) not (iterate (step ...
13:39dkfbam, that fixed it
13:40dkfhmm, iterate worked like that prior to the doseq
13:40rhickey I doubt it
13:40dkfsorry about that.. lets see.. "Elapsed time: 731.130256 msecs"
13:44dkfmost of that time probably spent printing though
13:48dkfok, this is more reasonable (println (last (take 1000 (iterate step-automata [ (90 cells) ])))) "Elapsed time: 611.030474 msecs" and it did indeed print out a changed condition
13:49dkfthat's pretty interesting we did all that without maintaining any state
13:49rhickeythere you go!
13:52dkf1,000,000 iterations: "Elapsed time: 52809.541073 msecs"
13:54dkfheh, I wonder if this kind of problem could be multi-threaded.. I suppose you could concatenate two cell spaces together
13:56Chouseryou're using map in mutate? you could try out pmap
13:56dkfsame syntax?
13:56Chousernot quite
13:56Chouserand you need some 3rdparty .jar -- I've not actually tried it yet.
13:57dkfah
13:59dkfWhat about splitting rule45 into rule45First4Bits and rule45Second4Bits and make rule45 cut the vector in half and call to two different threads?
14:00dkferm, not cut the vector in half
14:00Chouserah, run your tests in parallel, instead of sequence?
14:01dkfI guess just send the vector to each one and one will return a value of 0 or 1.. yea
14:01ChouserI bet you'd get some speedup if you used a hash instead of a cond for rul45
14:01dkfa hash?
14:02Chouser{[0 0 0] 0, [0 0 1] 0, [0 1 0] 1, ...}
14:03Chouserput that in rule45hash, then just: (rule45hash v) to get your new bit
14:03dkfhmm
14:04Chousera hash is a lookup table.
14:04Chousera.k.a. "map", but not to be confused with the map function you're already using.
14:05dkfright.. the repl likes it.. so.. instead of a defn, just (def rule45hash {etc})
14:05Chouseryep
14:06Chouseractually, the hash will act exactly as your fn does now, so just (def rule45 {...})
14:08dkfwoops.. did the million iterations again
14:08dkfit has to best 52 seconds
14:09dkfinteresting.. top says cpu 124% java
14:10dkfuhoh
14:10dkffan on... getting hot
14:10Chouserhm.
14:10dkfstill not done
14:10dkfmight have to kill it
14:11dkfkilled it.. chouser, I think you just software overclocked my computer
14:11Chouserheh
14:11Chouseryou must have dual cores?
14:11dkfyea
14:11Chouserthe only change was rule45?
14:12dkfso maybe hash has some parallelization ?
14:12dkfyea
14:12lisppaste8dkf annotated #64480 with "automaton" at http://paste.lisp.org/display/64480#3
14:12dkfcommented out the last one
14:13dkfare commas necessary?
14:13dkfoh, that was a hundred thousand, not a million
14:14Chousercommas are unecessary
14:14dkfok, here we go
14:14dkf1000 iterations, as before
14:14rhickeymap will be faster
14:14dkf"Elapsed time: 2305.308249 msecs"
14:14dkfyup
14:15dkfhmm
14:15rhickeynot 52:2
14:15dkfwell, that was 1000
14:15dkf52 was 100000 iterations
14:15Chouserrhickey: map faster than pmap?
14:15dkffaster than hash
14:16dkf52 seconds for 100,000 iterations with map
14:16dkfmuch longer for hash, but it seamed to be using both cpus
14:17Chouserdkf: you've got pmap in what you pasted
14:17dkfwhatthe
14:18rhickeyI get a 12:17 ration map/cond for rule45
14:18rhickeyratio
14:18dkffind-doc "pmap" just returns just zipmap for me
14:19dkfrhickey: map verses cond?
14:19dkf(yet, pmap still compiles here
14:19dkf)
14:20rhickeymap data structure vs cond for rule45, isn't that what you are testing?
14:20dkfoh, well, hash-map verses cond
14:20dkfjust hash
14:21dkfand I just switched pmap back to map and....
14:21dkfnew record for 1000 iterations "Elapsed time: 543.289027 msecs"
14:21dkfwonder why pmap worked at all.. its it in the lib and just not documented?
14:22rhickeyright, don't use pmap
14:22dkfheh, ok
14:23dkfrhickey: for map/cond .. were you refering to using a map or using the map function, in rule45?
14:23dkfor hash-map
14:24rhickeyI've gotta run, here's a version, with parallelization (which doesn't help here)
14:24lisppaste8rhickey pasted "ca" at http://paste.lisp.org/display/64496
14:24dkfoh beast.. sweet.. I'll mull this over.. thanks.
14:33dkfhmm. exception in jsr166y.forkjoin.ParallelArray
14:33dkfclass loader issue of some sort or something
14:34dkfanyway, I gotta go to.. thanks chouser, thanks rhickey
15:14dkfyou know what the super food of super programmers is?
15:15dkffricken oatmeal!
15:27lisppaste8rhickey annotated #64496 with "cleaned up a bit" at http://paste.lisp.org/display/64496#1
15:30dkfThis could make a sick example for the wiki
15:32dkfby the way, I had the order of rule 45 wrong.. it's 10110100, backwards
15:32dkffunctions the same way, just a different output
15:33dkfrhickey: has the parallel improved performance?
15:35rhickeyparallel will improve performance as the vector gets wider, no faster at 80
15:37dkfThis is a good example because cellular automatons are usually thought of as stateful (state-machines?) and here's one that's stateless, right?
15:39dkfwait a minute.. I remember you saying in a video that you worked on mathematica... have you read NKS?
23:26CptPicardhi guys... what's wrong with my named fns here?
23:26CptPicardhttp://pastebin.com/m2e09c17b
23:26CptPicard"Var beer-internal is unbound"
23:28CptPicarddoes one need to defn inner functions too?