Re: Getting started with Counterclockwise
On Sun, Jan 23, 2011 at 2:07 AM, Sean Corfield wrote: > On Tue, Jan 18, 2011 at 12:45 PM, Chas Emerick wrote: >> The links to the users' and developers' google groups for ccw are >> prominently linked on the right side of the ccw site: >> >> http://code.google.com/p/counterclockwise/ > > And that URL is the #1 Google result for: clojure eclipse And looks to CCW newbies like it's likely to just lead to a code repository, tracker, and CCW-developer-centric mailing lists. > (and this discussion has occurred before about the discoverability of > IDE documentation with much the same content and result) It has indeed. -- 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
Re: Why no def- ?
wrote:>> Please don't. It has already been discussed and declined. The metadata is uglier because we want doing this to be slightly ugly.. Sorry, didn't get your response in time.. Anyways, I agree with Ken it seems weird to have defn- in core and not def- - or is defn- sort of deprecated in favour of ^:private ? -- 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
An efficient persistent, immutable deque for Clojure with amortized O(1) peek and pop at both ends
I got to thinking how one might implement a persistent, immutable deque that was efficient. At first I considered modifying my queue implementation. Peeking at both ends could easily be done in constant time, and popping from the left. Popping from the right presented a problem: when it ate the whole vector it would have to hit the seq, so you'd have to move the seq to the right, veccing it, and replace the left chunk with nil. This would be O(n) in the current length of the queue. It would also only happen sometimes, but a worst case access pattern where right-pops are done until the vector is gone and then right-pop, left-pop, right-pop, etc. was done would be O(n) overall, as the vector would keep being seqd, nexted, vecced, popped, seqd, nexted, vecced, popped, etc. -- it's easy to see the time taken to do this with n items until all are gone is triangular in n/2, which makes it quadratic in n, which makes the *per-item* cost linear in n. So I thought, at first, "how do we make removing at both ends efficient"? Trees suggested an answer, and I quickly came up with a sorted-map-based implementation (but it is NOT the best I eventually developed): (defprotocol LPop (lpeek [this]) (lpop [this]) (lconj [this object])) (deftype LogNDeque [content lowest highest metadata] clojure.lang.IObj (withMeta [this m] (LogNDeque. content lowest highest m)) (meta [this] metadata) clojure.lang.IPersistentStack (cons [this object] (if content (let [h2 (inc highest)] (LogNDeque. (assoc content h2 object) lowest h2 metadata)) (LogNDeque. (sorted-map 0 object) 0 0 metadata))) (count [this] (if content (inc (- highest lowest)) 0)) (empty [this] (LogNDeque. nil 0 0 metadata)) (equiv [this other] (= (seq this) other)) (seq [this] (if content (seq (vals content (peek [this] (if content (content highest))) (pop [this] (if content (if (= lowest highest) (empty this) (LogNDeque. (dissoc content highest) lowest (dec highest) metadata)) (throw (IllegalStateException. "Can't pop empty deque" LPop (lpeek [this] (if content (content lowest))) (lpop [this] (if content (if (= lowest highest) (empty this) (LogNDeque. (dissoc content lowest) (inc lowest) highest metadata)) (throw (IllegalStateException. "Can't pop empty deque" (lconj [this object] (if content (let [l2 (dec lowest)] (LogNDeque. (assoc content l2 object) l2 highest metadata)) (LogNDeque. (sorted-map 0 object) 0 0 metadata))) java.lang.Object (toString [this] (if content (str (seq this)) "()")) (defn deque [& things] (apply conj (LogNDeque. nil 0 0 {}) things)) Obviously, this has logarithmic performance in general, and for large deques could be up to 32x slower than ideal. Furthermore, there's a problem with it and Clojure 1.3 alpha: if you used it as a queue, so mainly popped at one end and conjed at the other, the numeric indices used internally would crawl towards Long/MAX_VALUE or Long/MIN_VALUE and then it would blow up. On 1.2 and earlier it would simply slow down drastically when it started to use bignum arithmetic. Wondering if there was a way to improve on that I revisited my earlier queue implementation. I found a bug or two and fixed them: (deftype Queue [chunk1 chunk2 size metadata] clojure.lang.IObj (withMeta [this m] (Queue. chunk1 chunk2 size m)) (meta [this] metadata) clojure.lang.IPersistentStack (cons [this object] (Queue. chunk1 (conj chunk2 object) (inc size) metadata)) (count [this] size) (empty [this] (Queue. nil [] 0 metadata)) (equiv [this other] (= (seq this) other)) (seq [this] (seq (lazy-cat chunk1 chunk2))) (peek [this] (if chunk1 (first chunk1) (first chunk2))) (pop [this] (if chunk1 (Queue. (next chunk1) chunk2 (dec size) metadata) (if-let [nc1 (seq chunk2)] (Queue. (next nc1) [] (dec size) metadata) (throw (IllegalStateException. "Can't pop empty queue") java.lang.Object (toString [this] (if (zero? size) "()" (str (seq this) (defn queue [& things] (Queue. (seq things) [] (count things) {})) and thought about whether there was a way to make it pop efficiently from the other end after all. I was thinking of things like how java.util.ArrayList will sometimes have to copy and double the size of an internal array, which is O(n), but also because it doubles the size it has to do so at ever diminishing intervals, so in the worst case of constantly adding on the end without ever removing it does one add, then one add and doubles, then two adds and doubles, four adds and doubles, eight adds and doubles, etc.; the time taken in a simplistic model where it takes 1 to add without doubling and 1 per element to double, is 1 for the first add, 2 for the next, 1 for the next tw
Re: An efficient persistent, immutable deque for Clojure with amortized O(1) peek and pop at both ends
Did you have a look at: http://www.cs.cmu.edu/~rwh/theses/okasaki.pdf After p. 50 there is a description of dequeues. I don't know how they compare to yours. -- 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
Re: An efficient persistent, immutable deque for Clojure with amortized O(1) peek and pop at both ends
On Sun, Jan 23, 2011 at 5:48 AM, nicolas.o...@gmail.com wrote: > Did you have a look at: > > http://www.cs.cmu.edu/~rwh/theses/okasaki.pdf > > After p. 50 there is a description of dequeues. I don't know how they > compare to yours. That's weird. If I click that link in Chromium I get a blank page with an address of about:blank. -- 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
Re: An efficient persistent, immutable deque for Clojure with amortized O(1) peek and pop at both ends
What is this "Chrome" of which you speak? Are you trying to say that you don't use clojure for everything? (clojure.java.io/copy (.openStream (java.net.URL. "http://www.cs.cmu.edu/~rwh/theses/okasaki.pdf"; )) (file-str "~/okasaki.pdf")) --Robert McIntyre On Sun, Jan 23, 2011 at 5:59 AM, Ken Wesson wrote: > On Sun, Jan 23, 2011 at 5:48 AM, nicolas.o...@gmail.com > wrote: >> Did you have a look at: >> >> http://www.cs.cmu.edu/~rwh/theses/okasaki.pdf >> >> After p. 50 there is a description of dequeues. I don't know how they >> compare to yours. > > That's weird. If I click that link in Chromium I get a blank page with > an address of about:blank. > > -- > 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 -- 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
Re: An efficient persistent, immutable deque for Clojure with amortized O(1) peek and pop at both ends
On Sun, Jan 23, 2011 at 6:15 AM, Robert McIntyre wrote: > What is this "Chrome" of which you speak? Are you trying to say that > you don't use clojure for everything? Certainly not up to and including implementing my own whole web browser from scratch. At least, not yet. ;) -- 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
Re: Getting clojure projects into maven central - aot vs sources, -javadoc and -sources artifacts
I'm relying entirely on memory at the moment, but there are two answers to this question. First, Sonatype's validation of -sources.jar and -javadoc.jar aren't as stringent as you might expect. That is, the OSS/central repos' validation routines appear to check for the existence of those artifacts corresponding to a given jar artifact, but they aren't inspected for completeness. So if you're AOT-compiling, just ensuring that you have -sources.jar and -javadoc.jar files in the repository you're promoting will get you past the validation (but of course not be particularly helpful in the case of -javadoc.jar, since it'd be empty). Always producing a complete -sources.jar should never be a problem. The second answer is that it'd be ideal to have autodoc output be emitted for your project, and then packaged into the -javadoc.jar. Tooling would then be able to pick up that jar file from upstream maven repos and display relevant contents as desired, just as Java IDEs do for javadoc. There's a lot of niggling little details here (e.g. how to make javadoc and autodoc output coexist in the same file hierarchy – a must for hybrid projects, settling on either a single autodoc output file layout so tooling can reliably find what they need or implementing a lookup mechanism, etc). IIRC, Tom Faulhaber seemed receptive to whatever additions would be necessary to make this possible, but it needs someone who is willing and capable of coordinating the design so that the result is useful to all known Clojure development environments (a rapidly-growing category these days). Cheers, - Chas On Jan 22, 2011, at 7:12 PM, Peter Schuller wrote: > Hello, > > I'm experimenting with getting my feet wet with proper maven central > releases by trying to get a small library[1] into maven central. > > The sonatype instructions[2] require, among other things: > > (1) If the project packaging is jar, and the jar file contains java > classes, there must be a -javadoc.jar for main artifact. > (2) If the project packaging is jar, and the jar file contains java > classes, there must be a -sources.jar for main artifact. > > It is non-obvious to me what to do about clojure projects. If I have > *only* clojure code, and disable AOT in clojure-maven-plugin, I can > address both (1) and (2) by no longer producing a jar that "contains > java classes". However, that is not sustainable. Some projects may > contain some Java code too, or else maybe AOT:ed clojure code (what is > the idiomatic approach there btw; to AOT or not to AOT?). > > clojure-contrib *seems* to be using the strategy to just include > .clj:s in the main artifact, although the clojure-contrib parent pom > implies in comments that individual modules may over-ride the lack of > AOT. How would such artifacts be accepted into maven central if they > fail (1)/(2)? > > [1] https://github.com/scode/plru > [2] > https://docs.sonatype.org/display/Repository/Sonatype+OSS+Maven+Repository+Usage+Guide > > -- > / Peter Schuller > > -- > 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 -- 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
Map keys
Is it possible to create a map key from an integer or string to be used for retrieving data dynamically from a map? Bill -- 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
Re: Map keys
On Sun, Jan 23, 2011 at 11:59 AM, WoodHacker wrote: > Is it possible to create a map key from an integer or string to be > used for retrieving data dynamically from a map? Yep. user=> (keyword "foo") :foo user=> (keyword (str 42)) :42 user=> -- 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
Re: Map keys
2011/1/23 WoodHacker > Is it possible to create a map key from an integer or string to be > used for retrieving data dynamically from a map? > Yes, but with numbers and Clojure 1.2, be careful to always use the same kind of "wrapper" (java.lang.Integer or java.lang.Long) or you'll be in trouble: user=> (def m { "a b c" "first", (Integer. "2") "second", (Long. "3") "third"}) #'user/m user=> (get m "a b c") "first" user=> (get m (Integer. "2")) "second" user=> (get m (Long. "2")) nil user=> (get m 2) "second" user=> (get m 3) nil HTH, -- Laurent -- 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
Re: Unification
On Jan 22, 8:16 pm, David Nolen wrote: > On Sat, Jan 22, 2011 at 2:09 PM, rb wrote: > > On Jan 21, 11:41 pm, Alex Baranosky > > wrote: > > > Hi, > > > > I've read a bit about clojure.core.unify ( > >http://blog.fogus.me/2010/12/14/unification-versus-pattern-matching-t... > > > ) > > > > I haven't gotten through PAIP yet, but I gather unification libraries > > enable > > > logic programming? Is it true that unification is a superset of pattern > > > matching? > > > > Mostly, I'd like to hear more about what something like > > clojure.core.unify > > > is good for. > > > I've used unification with dataflow variables and data structures > > holding unbound variables (though not in clojure) and found it really > > powerful! > > > I'm not sure dataflow variables are available in clojure though, but > > would be happy to stand corrected (I heard about the contrib dataflow > > module, but from what I read it's more like cells updating based on > > upstream cells it depends on, whereas what I mean by dataflow variable > > is a variable that makes a thread wait until it gets bound if that > > thread uses that variable) > > This exists in Clojure in the form of promise/deliver. > Thanks Ken and David, I'll take a closer look! Raph > > > > Cheers > > > raph > > > > Best, > > > Alex -- 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
Reading back record instances
I've been using records extensively lately and I think they are a really great addition to Clojure. One problem I'm facing tough is to read them back once printed to a file (or anything else). All others Clojure data structures are supported by the reader, but not records. One way to do this would be to write my own printer to output constructor forms for the given records. That should be working as the current implementation returns the keys in order. Am I missing something? Is there a better way? Regards, budu -- 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
Re: ANN: Textmash - another IDE for Clojure
I have added you to committers group, so you can commit your work. Later I will switch to github since SVN with its "central repository" scenario is not very useful in situation where I'm lack of time. On 23 Sty, 00:28, Laurent PETIT wrote: > Hello again Olek, > > 2011/1/18 Olek > > > Hi, > > > Here is a link:http://code.google.com/p/textmash/ > > > Some time ago I have written it in order to help accomplish a task of > > creating some paraller processing system written entirely in Clojure > > (it was the map reduce framework from Google). > > > It was also used with success in other tasks, like editing PHP pages, > > Clojure learning, writing small programs in Clojure and some simple > > text processing. > > > Feel free to contribute in bug fixing and improving or maybe even > > rewriting it in Clojure (there are not too much lines of code). > > I'm using your project as a demonstration on how 'easy' it is to embed > paredit.clj. > > How should I "contribute" ? I mean, it seems that you're using svn, so it's > not clear to me how you would like to get contributions. > > My first idea was to clone your repo via git-svn, and then publish my fork > on e.g. github ? > Or ... ? > > Cheers, > > -- > Laurent > > > > > > > The main idea is to take what is best in Eclipse, NetBeans and > > ergonomy of Mac OS and put into light tool. > > I hope you will enjoy it. > > > Bye! > > > -- > > 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 -- 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
Re: ANN: Textmash - another IDE for Clojure
Pros: 1. Yes, it uses Swing. I have even stared writting it in Clojure, but startup time was too long, not acceptable for lightweight text editor. 2. Yes, it is. I've carefully studied Mac's TextEdit, NetBeans and Eclipse and merged theirs ideas. Cons: 1. Yeah, I haven't implemented highligting yet. The cost (time and work) of implementation would be higher than profits I would get. For me more important were brackets matching and highlighting occurences of selected word. 2. Yes, first it must be configured. 3. I think that low level configuration gives you much more possiblities of running or integrating it in different scenarios (folder layouts, libraries dependiences etc.) I have no more time for improving the editor, that is why it has been open sourced. Thanks for trying it out and feedback! On 19 Sty, 07:28, Shantanu Kumar wrote: > I downloaded the JAR and gave it a try. Here's my first impression: > > Pros: > 1. Feels really fast (does it use Swing?) > 2. Consistent U/I - seemingly nice defaults > > Cons: > 1. Clojure files are not syntax highlighted by default > 2. Clojure->"Open a REPL" doesn't work (at least not out of the box) > 3. Clojure->"Configure" requires me to edit a text file > 4. Doesn't detect that the Clojure JAR is already in classpath > 5. View->"Syntax Highlight" submenu is disabled > > My suggestions: > 1. Make it easy for first timers to use > 2. Detect if the Clojure JAR is already in the classpath and use it > accordingly > 3. Don't make me go through the configuration text file > > Regards, > Shantanu -- 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
Re: ANN: Textmash - another IDE for Clojure
2011/1/23 Olek > I have added you to committers group, so you can commit your work. > Later I will switch to github since SVN with its "central repository" > scenario is not very useful in situation where I'm lack of time. > OK, thanks. What I've achieved is more a "proof of concept" right now. Maybe I should put it in a branch. I'll quickly describe what I'm talking about, so you can choose: * I've "leiningened" the project. Maybe I could "mavenize" it instead. What are your guts here ? * I've "leiningened" it to test the "mavenization", on my side, of paredit.clj. * paredit.clj uses clojure and clojure contrib. So the feature currently shows a delay when it is first invoked. Since the point of my demo was not clojure integration but paredit.clj integration, I've not tried to make this happen in the background, etc. To the contrary, I've tried to compact the "proof of concept" code as much as possible in one place, so it can be easily spotted and reviewed. * Currently, I've just demonstrated the "raise over sexpr" command I described in an earlier post in this same thread. What I've not been able to achieve (but I admit I haven't spent too much time right now on it) is how to make the command appear in the menu. I thought at first that it was derived from the "actions" map in the TextEditor class, but the layout of the menus must live somewhere else ... If you can help me spot the right place ? I also still have to finish proper bundling of paredit.clj in the first place, half done and should not last 'til the end of this week. Cheers, -- Laurent > > On 23 Sty, 00:28, Laurent PETIT wrote: > > Hello again Olek, > > > > 2011/1/18 Olek > > > > > Hi, > > > > > Here is a link:http://code.google.com/p/textmash/ > > > > > Some time ago I have written it in order to help accomplish a task of > > > creating some paraller processing system written entirely in Clojure > > > (it was the map reduce framework from Google). > > > > > It was also used with success in other tasks, like editing PHP pages, > > > Clojure learning, writing small programs in Clojure and some simple > > > text processing. > > > > > Feel free to contribute in bug fixing and improving or maybe even > > > rewriting it in Clojure (there are not too much lines of code). > > > > I'm using your project as a demonstration on how 'easy' it is to embed > > paredit.clj. > > > > How should I "contribute" ? I mean, it seems that you're using svn, so > it's > > not clear to me how you would like to get contributions. > > > > My first idea was to clone your repo via git-svn, and then publish my > fork > > on e.g. github ? > > Or ... ? > > > > Cheers, > > > > -- > > Laurent > > > > > > > > > > > > > The main idea is to take what is best in Eclipse, NetBeans and > > > ergonomy of Mac OS and put into light tool. > > > I hope you will enjoy it. > > > > > Bye! > > > > > -- > > > 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 > > -- > 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 > -- 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
Re: ANN: Textmash - another IDE for Clojure
Yes, make a branch. I seen many people are using "leiningened", so it is a good (main stream) choice, especially that your parts of code are written in Clojure. The layout of menus is made in pl/olek/textmash/menu/ WorkspaceMenu.java. I have also started TextMash2 which is going to be entirely written in Clojure, it is going to be written - 20 minutes a day, mainly in fundamental (proof of concept) parts so It will be easier to other to add/fullfill project with new features. On 23 Sty, 20:49, Laurent PETIT wrote: > 2011/1/23 Olek > > > I have added you to committers group, so you can commit your work. > > Later I will switch to github since SVN with its "central repository" > > scenario is not very useful in situation where I'm lack of time. > > OK, thanks. > > What I've achieved is more a "proof of concept" right now. Maybe I should > put it in a branch. > I'll quickly describe what I'm talking about, so you can choose: > > * I've "leiningened" the project. Maybe I could "mavenize" it instead. > What are your guts here ? > * I've "leiningened" it to test the "mavenization", on my side, of > paredit.clj. > * paredit.clj uses clojure and clojure contrib. So the feature currently > shows a delay when it is first invoked. Since the point of my demo was not > clojure integration but paredit.clj integration, I've not tried to make this > happen in the background, etc. To the contrary, I've tried to compact the > "proof of concept" code as much as possible in one place, so it can be > easily spotted and reviewed. > * Currently, I've just demonstrated the "raise over sexpr" command I > described in an earlier post in this same thread. > > What I've not been able to achieve (but I admit I haven't spent too much > time right now on it) is how to make the command appear in the menu. I > thought at first that it was derived from the "actions" map in the > TextEditor class, but the layout of the menus must live somewhere else ... > If you can help me spot the right place ? > > I also still have to finish proper bundling of paredit.clj in the first > place, half done and should not last 'til the end of this week. > > Cheers, > > -- > Laurent > > > -- 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
Re: Getting started with Counterclockwise
On Sun, Jan 23, 2011 at 12:46 AM, Ken Wesson wrote: >>> http://code.google.com/p/counterclockwise/ >> And that URL is the #1 Google result for: clojure eclipse > And looks to CCW newbies like it's likely to just lead to a code > repository, tracker, and CCW-developer-centric mailing lists. I'll concede that it looks to _you_ like such a site. When I picked up CCW for the first time, I assumed (correctly) it was the project home page and would be where I could find all the end user documentation (as well as developer documentation). >> (and this discussion has occurred before about the discoverability of >> IDE documentation with much the same content and result) > It has indeed. Which tempts me to ask why you decided to bring it up again? :) -- Sean A Corfield -- (904) 302-SEAN Railo Technologies, Inc. -- http://getrailo.com/ An Architect's View -- http://corfield.org/ "If you're not annoying somebody, you're not really alive." -- Margaret Atwood -- 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
Re: Clojure/JVM languages internal presentation
Thank you for sharing this Rob! I've recently gone thru a similar process with a company and we ended up introducing both Scala and Clojure, for different purposes, although we didn't have a large team to convince (so I didn't need to do as much work to get the changes accepted :) I love the comparisons in your slides between Java and all the other languages. I don't work in Java much these days but it reminded me why I'd moved to higher-level languages :) On Mon, Jan 17, 2011 at 3:33 PM, Robert Campbell wrote: > This past summer I gave a presentation on JVM langauges at our > company's worldwide developer summit. I tried to get approval for > Clojure but had to settle for Scala because its syntax didn't frighten > management. I figured I'd share it in case any of the slides can be of > use elsewhere. > > open in browser (no notes): > http://public.iwork.com/document/?d=JVM_Languages.key&a=p1045023190 > > src: https://github.com/rcampbell/jvm-languages > > The talk (w/notes in github .key file) was very important and the > slides don't make much sense without it, but it generally went like: > > -Topic is JVM languages, what they are, why we should care about them > -We (as a mostly Java house) have two big problems: bloat and concurrency > -Show bloat with examples, try to illustrate a trend > -Why are these other languages so concise? > -Go back over the examples pulling out a single language feature from > each (in bold), explain how it leads to more concise code > -Talk a bit about concurrency, No free lunch (R), Ghz wall, cores increasing > -Java's answer to concurrency is difficult to work with > -Make a token effort to select a JVM language based on books, > perceived momentum/maturity/community, etc > -Select Clojure and Scala, end with Scala example since that's the one > that was approved (replace slide here :-) > > Rob -- 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
How does pmap partition its work?
Suppose I have a sequence of tasks I'd like to parallelize using pmap. The amount of CPU time these tasks require varies greatly; in particular, many of them will require virtually no work. Can I rely on pmap to divide the work efficiently even if there is some pattern to the distribution of easy tasks (e.g. clumped at the beginning, or every nth)? Assume it's not possible to identify the easy tasks beforehand. -- 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
Re: How does pmap partition its work?
No, you cannot rely on pmap to do that. pmap is lazy in the sequence it produces, so it tries not to work farther ahead of the consumer of its "output sequence" than the amount of parallelism it uses, which is the number of available processors plus 2. Suppose you have 4 available processors, so pmap tries to keep at most 6 parallel invocations of your map function running. Suppose also for example's sake that the function you are using with pmap on each element is sequential, so it uses at most one processor at a time. Imagine that the numbers below are the times in seconds required to calculate your function on each element of the input sequence to pmap: 100 1 1 1 1 (15 more elements requiring 1 second each) 100 1 1 1 1 (15 more elements requiring 1 second each) When some code tries to retrieve the first element of the lazy seq that is the output of pmap, 6 threads will start calculating. The threads for calculating the function on the 2nd through 6th elements will finish soon (if scheduling is fair), but no threads will be invoked to calculate the function on the 7th element yet, because pmap is trying not to work too far ahead. When the function is done calculating the first element, and some consumer tries to access the 2nd element of the output sequence, then a thread will be started working on the 7th input element, and so on. So if the consumer of the output sequence is trying to retrieve elements as quickly as possible and doing some negligible amount of processing on each one, here will be the rough pattern of CPU busy time: (1) 1.5 seconds of 4 processors working for 1 second each on the first 6 elements. (2) about 99 seconds more time finishing the function on the first element, but only 1 processor busy at a time, the other 3 idle (3) about 14/4 seconds of all 4 processors busy working on the next 14 elements, each taking about 1 sec of CPU time. Then this pattern repeats when the next "heavy element" requiring 100 seconds to calculate the function is reached. Note: Sometimes working at odds with pmap's "Don't work too far ahead" approach is if the input sequence to pmap is chunked. When a chunk is reached, all elements in that chunk have threads start in parallel, so the number of parallel threads can easily exceed (availableProcessors +2) during those times. Amit Rathore's medusa is intended to let you keep processors busy, but with a different method of invoking it than pmap. Andy On Jan 23, 2011, at 5:56 PM, Michael Gardner wrote: Suppose I have a sequence of tasks I'd like to parallelize using pmap. The amount of CPU time these tasks require varies greatly; in particular, many of them will require virtually no work. Can I rely on pmap to divide the work efficiently even if there is some pattern to the distribution of easy tasks (e.g. clumped at the beginning, or every nth)? Assume it's not possible to identify the easy tasks beforehand. -- 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 -- 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
ANN: A simple scheme interpreter in clojure
I have implemented a simple interpreter in clojure,it is just transformed from the interpreter in SICP.Maybe someone interested in it. I have pushed it on github at https://github.com/killme2008/cscheme ,you can clone and run it by yourself. -- 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
Logos v0.4 - Closing in on SWI-Prolog ?
I just pushed the latest version of Logos. The project is now, I believe, sufficiently original. For the amount of time that I've spent on it, I'm surprised that it can solve the classic Zebra problem in nearly the same amount of time as SWI-Prolog - 7ms on my machine. I attribute this to a few things: * miniKanren's purely functional approach is a great design that matches with Clojure's unique strengths * protocols deliver on allowing you to write succinct code that really lets you get to the speed of the host Another big change is a logos.nonrel namespace which contains copy-term, project, cond-a (soft cut), cond-u (Mercury-style committed choice). Next up, logic variable aware pattern matching so that you can write Clojure miniKanren programs that are as succinct as their Prolog cousins. David -- 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
Re: Logos v0.4 - Closing in on SWI-Prolog ?
On Sun, Jan 23, 2011 at 10:01 PM, David Nolen wrote: > I just pushed the latest version of Logos. The project is now, I believe, > sufficiently original. For the amount of time that I've spent on it, I'm > surprised that it can solve the classic Zebra problem in nearly the same > amount of time as SWI-Prolog - 7ms on my machine. I attribute this to a few > things: > > * miniKanren's purely functional approach is a great design that matches > with Clojure's unique strengths > * protocols deliver on allowing you to write succinct code that really lets > you get to the speed of the host > > Another big change is a logos.nonrel namespace which contains copy-term, > project, cond-a (soft cut), cond-u (Mercury-style committed choice). > > Next up, logic variable aware pattern matching so that you can write > Clojure miniKanren programs that are as succinct as their Prolog cousins. > > David > Link: https://github.com/swannodette/logos -- 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
Re: How does pmap partition its work?
On Jan 23, 2011, at 8:34 PM, Andy Fingerhut wrote: > No, you cannot rely on pmap to do that. Thanks for the detailed and informative answer. I'll probably settle for shuffling the list of inputs before passing them to pmap, and just accept that there may be some inefficiency in the distribution of work. -- 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
Re: How does pmap partition its work?
On Sun, Jan 23, 2011 at 8:56 PM, Michael Gardner wrote: > Suppose I have a sequence of tasks I'd like to parallelize using pmap. The > amount of CPU time these tasks require varies greatly; in particular, many of > them will require virtually no work. Can I rely on pmap to divide the work > efficiently even if there is some pattern to the distribution of easy tasks > (e.g. clumped at the beginning, or every nth)? Assume it's not possible to > identify the easy tasks beforehand. Here's a little data: user=> (def printer (agent nil)) #'user/printer user=> (defn xyz [n] (send printer (fn [_] println (Thread/currentThread))) (* n n)) #'user/xyz user=> (xyz 3) # 9 user=> (pmap xyz (range 20)) # # # # # # # # # # # # # # # # # # # # (0 1 4 9 16 25 36 49 64 81 100 121 144 169 196 225 256 289 324 361) user=> The fiddling with an agent is to prevent individual println outputs from getting intermingled; instead the lines are perhaps slightly out of order but at least are not mangled into unreadability. As you can see, there are at least seven threads called somewhat randomly; not a simple alternating pattern of 2 as you might naively expect on a dual-core machine. It seems to prefer thread 22 for some reason. I don't know exactly what is going on under the hood but it looks like it either involves some degree of randomness, or it tries to load-balance (and something else was sometimes preempting threads -- I don't know what, when I ran this nothing on my system was doing anything CPU-intensive with a priority equal to or higher than the REPL process, but NetBeans and the REPL were both being a bit sluggish; some sort of Windows weirdness). Either way it's likely that a mix of easy and hard jobs, even with a pattern, won't screw things up too much. That can be further tested: user=> (defn heavy [f amt] (fn [x] (Thread/sleep amt) (f x))) #'user/heavy user=> (defn s [x] (* x x)) #'user/x user=> (def l (heavy s 1000)) #'user/y user=> (defn run [fseq n] (time (doall (pmap #(%1 %2) fseq (range n nil) #'user/run user=> (run (cycle [s l]) 100) "Elapsed time: 17141.64872 msecs" nil user=> (run (cycle [s s l l]) 100) "Elapsed time: 17020.59136 msecs" nil user=> (run (cycle [s s l s l l]) 100) "Elapsed time: 17007.0366 msecs" nil user=> (defn randomize [s] (let [n (count s)] (repeatedly #(nth s (rand-int n) #'user/randomize user=> (run (randomize [s l]) 100) "Elapsed time: 18015.8562 msecs" nil As you can see, the timings are fairly consistent when a 50/50 mix of short (<1msec) and long (>1000msec) tasks get parallelized using pmap, with several possible patterns and also with no pattern to their distribution. This was again on a dual-core machine; it's interesting that the numbers are around 17-18s instead of 25s (100 jobs, averaging 500ms each, split between two cores). The use of more than two threads in the thread pool is presumably the cause of this; Thread/sleep lets another of the threads make progress. It didn't collapse down to just 1s so it's also not the case that pmap is spawning as many threads as will maximize throughput (fifty running the slow jobs plus two running the fast ones on both cores while the slow ones sleep). Since the jobs would cumulatively take 50s if run serially, the speedup factor from pmap here is just under 3. One more data point: user=> (run (repeat l) 50) "Elapsed time: 10172.37124 msecs" nil That's fifty long jobs without any short ones. The speedup factor here is 5 rather than 3. This shows that it will allow five, but no more, jobs to be running concurrently, and that it doesn't load balance. If it did, adding the short jobs wouldn't slow it down more than a few ms; in fact doing so almost doubles the time, so it seems the jobs are preallocated in some manner and the short jobs take up half the available threads in the pool. (This is odd given that it seemed before to be using at least seven threads, not just five.) Of course, real jobs are likely to be CPU-intensive instead of yielding like Thread/sleep. user=> (def foo (atom nil)) #'user/foo user=> (defn l2 [x] (doseq [a (range 750)] (reset! foo (* a x))) (* x x)) #'user/l2 The number 750 causes l2 to take about 900ms on my machine. user=> (run (cycle [s l2]) 100) "Elapsed time: 37024.37508 msecs" nil Oddly, quite a bit less than 50s. Perhaps reset! spends some time yielding the CPU for some reason? user=> (run (cycle [s s l2 l2]) 100) "Elapsed time: 46963.28936 msecs" nil user=> (run (cycle [s s l2 s l2 l2]) 100) "Elapsed time: 36551.62528 msecs" nil user=> (run (randomize [s l2]) 100) "Elapsed time: 51713.50044 msecs" nil user=> (run (repeat l2) 50) "Elapsed time: 43197.77312 msecs" nil These numbers suggest that the CPU load will generally be divvied up equally among your cores, if the jobs don't yield the CPU (sleep, block on I/O, block on monitors). If they do yield the CPU here and there, it looks like pmap may perform slightly better, rather than slightly worse, if the jobs that do so form
Re: How does pmap partition its work?
On Sun, Jan 23, 2011 at 10:31 PM, Ken Wesson wrote: > On Sun, Jan 23, 2011 at 8:56 PM, Michael Gardner wrote: >> Suppose I have a sequence of tasks I'd like to parallelize using pmap. The >> amount of CPU time these tasks require varies greatly; in particular, many >> of them will require virtually no work. Can I rely on pmap to divide the >> work efficiently even if there is some pattern to the distribution of easy >> tasks (e.g. clumped at the beginning, or every nth)? Assume it's not >> possible to identify the easy tasks beforehand. > > Here's a little data: > user=> (def printer (agent nil)) > #'user/printer > user=> (defn xyz [n] (send printer (fn [_] println > (Thread/currentThread))) (* n n)) Eh, that's weird. That's not the definition I used. I used (defn xyz [n] (let [t (Thread/currentThread)] (send printer (fn [_] (println t (* n n)) of course so it would be the pmap thread, not the agent thread, in the printout. I had been experimenting with investigating the agent thread pools too, so the defn must have come from that part of the REPL session. This data: > # > # > # > # > # > # > # > # > # > # > # > # > # > # > # > # > # > # > # > # was generated using the latter defn (the one that captures Thread/currentThread outside the send). -- 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
Re: Getting started with Counterclockwise
On Sun, Jan 23, 2011 at 7:21 PM, Sean Corfield wrote: > On Sun, Jan 23, 2011 at 12:46 AM, Ken Wesson wrote: >>> (and this discussion has occurred before about the discoverability of >>> IDE documentation with much the same content and result) >> It has indeed. > > Which tempts me to ask why you decided to bring it up again? :) Because the topic arose again. -- 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
Re: How does pmap partition its work?
Other posts to the thread indicate that longer-range patterns in the inputs could cause problems. If you know you'll be consuming the full sequence, try this: (defn eager-pmap [f & colls] (map deref (doall (apply map #(future (f %)) colls This creates all of the futures right away (due to the doall) and leaves it up to the future implementation to distribute work around some thread pool. On my system, it creates 80 or so of them each time it's run on a seq of 10 things, which persist for some time afterward -- so, a bit of a problem there. Another one that seems like it ought to be more efficient: (defn eager-pmap [f & colls] (let [cores (.. Runtime getRuntime availableProcessors) agents (cycle (for [_ (range cores)] (agent nil))) promises (apply map (fn [& _] (promise)) colls)] (doall (apply map (fn [a p & args] (send a (fn [_] (deliver p (apply f args) agents promises colls)) (map deref promises))) This one uses the agent "send" thread pool to divide up the work. Oddly, it's actually 2-3x slower than the previous and only uses 75% CPU on a dual-core machine, though it doesn't leak threads. It looks like agents, or promise/deliver, or both have lots of overhead compared to futures. (Which is odd since the obvious implementation of future is (defmacro future [& body] `(let [p# (promise)] (.start (Thread. (fn [] (deliver p# (do ~@body) p#)). So maybe it's agents that are causing the inefficiency? On the other hand, the result of evaluating (future foo) doesn't appear to be a naked promise, though it could still be a wrapped one, and that implementation would not limit itself to 80-odd threads; maybe future instead uses the agent "send-off" pool?!) I'd recommend just using the first version of eager-pmap in this email if you need an eager-pmap. The extra threads it creates are not too numerous (it doesn't create 100,000 threads for an input seq of 100,000 items) and they *do* seem to disappear again *eventually* (it may take several minutes; it takes much less than 1 hour; it takes more than 30 seconds; can't be more precise with the data I've gathered thus far). -- 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
Re: How does pmap partition its work?
On Sun, Jan 23, 2011 at 11:34 PM, Ken Wesson wrote: > Other posts to the thread indicate that longer-range patterns in the > inputs could cause problems. If you know you'll be consuming the full > sequence, try this: > > (defn eager-pmap [f & colls] > (map deref (doall (apply map #(future (f %)) colls > > This creates all of the futures right away (due to the doall) and > leaves it up to the future implementation to distribute work around > some thread pool. On my system, it creates 80 or so of them each time > it's run on a seq of 10 things, which persist for some time > afterward -- so, a bit of a problem there. Another one that seems like > it ought to be more efficient: > > (defn eager-pmap [f & colls] > (let [cores (.. Runtime getRuntime availableProcessors) > agents (cycle (for [_ (range cores)] (agent nil))) > promises (apply map (fn [& _] (promise)) colls)] > (doall > (apply map (fn [a p & args] > (send a > (fn [_] (deliver p (apply f args) > agents promises colls)) > (map deref promises))) > > This one uses the agent "send" thread pool to divide up the work. > Oddly, it's actually 2-3x slower than the previous and only uses 75% > CPU on a dual-core machine, though it doesn't leak threads. I've managed to make this more efficient, by making each agent send process a larger portion of the job than one single item: (defn eager-pmap [f & colls] (let [cores (.. Runtime getRuntime availableProcessors) agents (cycle (for [_ (range cores)] (agent nil))) ccolls (map (partial partition 16 16 []) colls) promises (apply map (fn [& _] (promise)) ccolls)] (doall (apply map (fn [a p & chunks] (send a (fn [_] (deliver p (apply map f chunks) agents promises ccolls)) (mapcat deref promises))) This is much faster than either of the other eager-pmaps I posted to this thread, and yet it's only using 60% CPU on my dual-core box. That means there's still another x1.6 or so speedup possible(!) but I'm not sure how. Raising the size of the partitions from 16 all the way to 1024 makes no noticeable difference. -- 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
Re: ANN: A simple scheme interpreter in clojure
Line 86 of core.clj is: (list 'cadr caddr) and should be: (list 'caddr caddr) On Jan 23, 9:45 pm, dennis wrote: > I have implemented a simple interpreter in clojure,it is just > transformed from the interpreter in SICP.Maybe someone interested in > it. > > I have pushed it on github athttps://github.com/killme2008/cscheme > ,you can clone and run it by yourself. -- 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
Re: Why no def- ?
Hello. Sorry to cut in, but I agree with Ken, too. If defn- should be in core and def- shouldn't, it seems asymmetric. Showing why there is asymmetric design may leads to positive discussion, I think. Thank you. -- Name: OGINO Masanori (荻野 雅紀) E-mail: masanori.og...@gmail.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
Re: ANN: A simple scheme interpreter in clojure
Hi, You may want to see if there is anything of interest for you there: http://clojure.wikidot.com/scheme-interpreter-in-clojure It has its own reader that attempts to be more compatible with Scheme than the reader used in Clojure. It constructs a fairly elaborate syntactic tree (perhaps it would be better to abstract its nodes a bit - currently it's somewhat convoluted) and preserves a lot of information about the source code in metadata. OTOH, the evaluator is AFAIR fairly buggy and incomplete. The whole thing is unmaintained now so feel free to scavenge any parts of it, if you like. Cheers, Andrzej On Mon, Jan 24, 2011 at 11:45 AM, dennis wrote: > I have implemented a simple interpreter in clojure,it is just > transformed from the interpreter in SICP.Maybe someone interested in > it. > > I have pushed it on github at > https://github.com/killme2008/cscheme > ,you can clone and run it by yourself. -- 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