I've just recently begun to work with Clojure and I am finding it quite gratifying. I am a long-time Lisper (several dialects) but my Java experience is limited and largely in the sheltered environment of Processing (processing.org).
Anyway, my first Clojure exercise has been a version of my PushGP genetic programming system, without a GUI, adapted most directly from a recent Scheme version. Since I've seen such wonderful code critiques on this list I thought I would post it and solicit any comments that any of you have. I'd be interested in comments on any aspect of the code, but I'm particularly eager to hear what people think of the approach to concurrency, which I describe briefly in the next paragraph. I have posted the code at http://hampshire.edu/lspector/clojush PushGP is a "generational" genetic programming system which means that it processes generations of programs -- Push programs, in this case -- sequentially, but that the fitness tests (error computations) of all of the programs within each generation are independent, as are all of the of the breeding operations to produce the next generation (aside from the possibility that multiple breeding operations will access the same parents, for reading only). So what I've done is to make the population a vector of agents (called pop-agents) each of which has as its content a struct-map that contains a program and error values. I use send to ask each agent to compute its error values and I use await to wait until all of these have finished. I use a second vector of agents, child-agents, for breeding: I ask all of the child-agents to construct their new programs based on the programs in pop-agents, I await their completion, and then I copy all of the children back into pop-agents and proceed with the next generation. I realize that I could get better processor utilization without the synchronization, and I plan to experiment with other (e.g. non-generational) approaches to GP parallelism -- in fact, I edit a journal that just published a special issue on parallel evolutionary algorithms, so I know of a lot of options there! -- but for now I just want the basic generational algorithm to be expressed as naturally as possible in Clojure. There seem to be many other options for how to do this using Clojure's concurrency concepts... Does what I've done seem to be the natural Clojure approach? On the development environment front: Is anyone contemplating creating a Mac OS X "Clojure in a Box"? I would be an enthusiastic user. If it could have roughly the feature set of the old Macintosh Common Lisp IDE then I would be ecstatic. Despite a fair amount of tinkering I don't currently have a functional SLIME setup, and despite the nice screencasts for Eclipse/Counterclockwise (and very nice features it seems to have -- e.g. the namespace browser and integrated documentation... is there any environment that has a debugging environment approximating a Lisp break loop?) that's not really working for me yet either. (A few specifics: In emacs, using a variety of configuration instructions and hints from the web, I get syntax coloring and indentation but not a functional inferior Lisp mode. Eclipse is a bit confusing to me overall, I can't seem to figure out how to get Clojure indenting, and it seems to be re-evaluating my buffers without me asking it to :-(. And saving an awful lot of files to its workspace directory.) I'm not only interested in getting one of these environments working on my own machine -- although that would be nice -- but also in having a simple, repeatable sequence of instructions for getting the environment running on fresh machines. This is because I teach and I may want to use this on classroom machines, student machines, etc., with students who have various levels of expertise. Our students use all sorts of platforms but our teaching environment is Mac OS X (with a linux cluster for compute-intensive stuff). Finally, two small specific questions: - When I run clj (from the most recent ClojureX) on the command line with -i and a source file it runs the file but then hangs. If I also specify -r then I get a REPL after the file runs, which is nice, but I was hoping that without -r it would terminate and return to a shell prompt without requiring an interrupt. I don't see any options to clj or to Clojure's main that force termination, or any quit or exit functions that I could call myself at the end of my code... Am I missing something here? - I can get subdirectories to work in load, as in (load "foo/bar"), but references to parent directories fail, as in (load "../bar"). Is there a way to get around this? Thanks to everyone here for developing what seems to be a great new language! -Lee -- Lee Spector, Professor of Computer Science School of Cognitive Science, Hampshire College 893 West Street, Amherst, MA 01002-3359 lspec...@hampshire.edu, http://hampshire.edu/lspector/ Phone: 413-559-5352, Fax: 413-559-5438 Check out Genetic Programming and Evolvable Machines: http://www.springer.com/10710 - http://gpemjournal.blogspot.com/ -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en