Re: Clojure Truck Factor
From my outside observation you would need to hit Rich Hickey, Timothy Baldridge, David Nolen, Stuart Halloway + other cognitect staff all at once. This wouldn't exactly kill clojure. But may put it into maintenance only mode for a while. On Saturday, August 8, 2015 at 4:21:40 AM UTC+12, Guilherme Avelino wrote: As part of my PhD research on code authorship, we calculated the Truck Factor (TF) of some popular GitHub repositories. As you probably know, the Truck (or Bus) Factor designates the minimal number of developers that have to be hit by a truck (or quit) before a project is incapacitated. In our work, we consider that a system is in trouble if more than 50% of its files become orphan (i.e., without a main author). More details on our work in this preprint: https://peerj.com/preprints/1233 We calculated the TF for *Clojure* and obtained a value of *2*. The developers responsible for this TF are: Rich Hickey - author of 58% of the files Stuart Halloway - author of 27% of the files To validate our results, we would like to ask *Clojure* developers the following three brief questions: (a) Do you agree that the listed developers are the main developers of *Clojure*? (b) Do you agree that *Clojure* will be in trouble if the listed developers leave the project (e.g., if they win in the lottery, to be less morbid)? (c) Does *Clojure* have some characteristics that would attenuate the loss of the listed developers (e.g., detailed documentation)? Thanks in advance for your collaboration, Guilherme Avelino PhD Student Applied Software Engineering Group (ASERG) UFMG, Brazil http://aserg.labsoft.dcc.ufmg.br/ -- 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: Durable atom
Datomic is basically what you want. when you get a db instance from the connection it is equivalent to dereffing an atom - You get an immutable reference to the data at that point in time. On Monday, August 17, 2015 at 2:59:09 AM UTC+12, Jeremy Vuillermet wrote: Hello, With the rise of Om, Reagent or re-frame for that matter, I'm using more a more the single state atom pattern in my clojurescript app. So much so that for my current application, I've been using atoms server side because my apps are split in really small app that only need to store few data - things like mini multiplayer game or polls. At the very least, it's useful while developing so I don't have to think too much about the storage layer. While looking for ways to keep my atom like interface while persisting my data, I found http://avout.io/ Distributed state for clojure which would be perfect for my use case. I also found things like https://github.com/alandipert/enduro : durable atom in clojure or https://github.com/torsten/zookeeper-atom All of them does not seem active anymore and I wonder why and what's the current status for those kind of thing. Are those solution not ready for production ? Do you eventually end up with a traditional database so nobody need that ? -- 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: Durable atom
Imo datomic really is ahead of other databases. It is worth using the pro starter edition despite being closed source, one day it might become open source, who knows. On Monday, August 17, 2015 at 12:59:24 PM UTC+12, Fluid Dynamics wrote: On Sunday, August 16, 2015 at 7:27:11 PM UTC-4, Andrew Chambers wrote: Datomic is basically what you want. What if he wants open source? -- 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: Functional programming and security
I would say the transaction model of datomic would have saved Mt Gox from its problems dealing with atomic transactions, however that's more due to datomic's design and poor design of the Mt Gox system than a clojure specific thing. On Monday, May 5, 2014 6:21:47 PM UTC+12, Magnus Therning wrote: On Mon, May 5, 2014 at 12:13 AM, Evan Rowley rowle...@gmail.comjavascript: wrote: The question we have to ask is: Would use of a (specific?) functional language prevented these? My opinion: Probably not in the case of Mt. Gox because their problems had more to do with their application design. There is no language that will prevent logical errors, that is true. There's that old saying that a good programmer can write Fortran in any language ;) However, choosing language wisely will allow you to concentrate on solving the 'real' problem at hand, and relieve you from solving unrelated problems (memory management, dealing with pointers, etc). It will also simplify reasoning about your code. I haven't found enough information about the Mt Gox bug to judge whether their demise could have been avoided using a better language. It sure sounds like they were doomed no matter what. As for Apple, I think the 'goto' feature is missing from at least Clojure. Both Haskell and Erlang have 'goto', but it's use isn't encouraged. I'm thinking that because these languages are functional, the goto feature works in a safer manner that wouldn't have allowed Apple's code to work with the failed certificate check. But that's just a guess. I'm pretty sure there is no 'goto' in Haskell, it's not a keyword in the language. There are ways of using continuations to implement goto in monadic code, but I'm pretty sure that would be possible in Scheme/Clojure too then. 'Goto' isn't a keyword in Erlang either! For OpenSSL's Heartbleed, I'm going to say that this wouldn't have been prevented even with functional programming. The problem lies in the design of the heartbeat code. One thing I do have to wonder about is whether or not this heartbeat code would have been designed differently if it were done in a functional programming language. It's worth keeping in mind that the higher level of abstraction most functional programming languages have would have contributed to a different design. I think the base cause of OpenSSL Heartbleed is the presence of pointers in the language used. In fact, I am convinced that if the developer community would move en masse to language that don't have pointers we'd see a huge fall in reported security vulnerabilities. FreeBSD's TCP bug *might* have been prevented if the functional programming language's runtime did effective memory management. I'm going to assume that everyone here agrees that functional programming languages have well-designed memory management. Hear, hear! /M -- Magnus Therning OpenPGP: 0xAB4DFBA4 email: mag...@therning.org javascript: jabber: mag...@therning.orgjavascript: twitter: magthe http://therning.org/magnus -- 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Idiomatic tokenizing and performance
I've been trying to make a tokenizer/lexer for a project of mine and came up with the following code, I've modelled the stream of characters as seq/lazy of chars which is then converted to a lazy-seq of token objects. I'm relatively happy with how idiomatic and functional the code seems, however when benchmarked, the code takes about 30 seconds on clojure (after i increase the heap to 1 gig) to process a 30 meg file, and over 1 minute 30 seconds with clojurescript. This is in contrast to about of 0.1 to 0.5 seconds or less in C. Is there any idiomatic way to process the file without being a factor of 100 times slower than C? Also, is there a tool for clojure similar to gprof for C? Each function takes in a char seq and returns both a token and the seq after its been advanced. (defn match-ident [cs] (let [start (first cs)] (if (ident-first-char? start) (let [ identseq (cons start (take-while ident-tail-char? (rest cs))) ^String ident (apply str identseq)] [(drop (.length ident) cs) [:ident ident]] (defn match-num [cs] (if (digit? (first cs)) (let [ numseq (take-while digit? cs) ^String numstr (apply str numseq) retseq (drop (.length numstr) cs)] (if (= (first retseq) \.) nil [retseq [:number numstr]] (defn match-ws [cs] (if (whitespace-char? (first cs)) (let [ wsseq (take-while whitespace-char? cs) ^String wsstr (apply str wsseq) retseq (drop (.length wsstr) cs)] [retseq [:ws wsstr]]))) ... (defn next-token [cs] (or (match-ident cs) (match-ws cs) (match-punct cs) (match-num cs) (match-eof cs) (match-unknown cs))) ;; Here I build the lazy seq of tokens. (defn token-seq [cs] (let [[newcs tok] (next-token cs)] (lazy-seq (cons tok (token-seq newcs) Cheers, Andrew Chambers -- 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: Idiomatic tokenizing and performance
Thanks, I should have done that tbh. my code is on github https://github.com/andrewchambers/ccc/blob/master/src/ccc/lex.clj . Don't think it compiles or runs on master currently though. If anyone is interested im trying to test the feasibility/size/maintainability of a clojure (or clojurescript) version of this guys tiny C compiler https://github.com/rui314/8cc. Basically to compare functional programming with what i consider excellent C code. Cheers, On Monday, May 5, 2014 4:43:27 PM UTC+12, Atamert Ölçgen wrote: I created a gist of your code for better readability, I hope you don't mind. https://gist.github.com/muhuk/7c4a2b8db63886e2a9cd On Mon, May 5, 2014 at 12:36 PM, Andrew Chambers andrewc...@gmail.comjavascript: wrote: I've been trying to make a tokenizer/lexer for a project of mine and came up with the following code, I've modelled the stream of characters as seq/lazy of chars which is then converted to a lazy-seq of token objects. I'm relatively happy with how idiomatic and functional the code seems, however when benchmarked, the code takes about 30 seconds on clojure (after i increase the heap to 1 gig) to process a 30 meg file, and over 1 minute 30 seconds with clojurescript. This is in contrast to about of 0.1 to 0.5 seconds or less in C. Is there any idiomatic way to process the file without being a factor of 100 times slower than C? Also, is there a tool for clojure similar to gprof for C? Each function takes in a char seq and returns both a token and the seq after its been advanced. (defn match-ident [cs] (let [start (first cs)] (if (ident-first-char? start) (let [ identseq (cons start (take-while ident-tail-char? (rest cs))) ^String ident (apply str identseq)] [(drop (.length ident) cs) [:ident ident]] (defn match-num [cs] (if (digit? (first cs)) (let [ numseq (take-while digit? cs) ^String numstr (apply str numseq) retseq (drop (.length numstr) cs)] (if (= (first retseq) \.) nil [retseq [:number numstr]] (defn match-ws [cs] (if (whitespace-char? (first cs)) (let [ wsseq (take-while whitespace-char? cs) ^String wsstr (apply str wsseq) retseq (drop (.length wsstr) cs)] [retseq [:ws wsstr]]))) ... (defn next-token [cs] (or (match-ident cs) (match-ws cs) (match-punct cs) (match-num cs) (match-eof cs) (match-unknown cs))) ;; Here I build the lazy seq of tokens. (defn token-seq [cs] (let [[newcs tok] (next-token cs)] (lazy-seq (cons tok (token-seq newcs) Cheers, Andrew Chambers -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clo...@googlegroups.comjavascript: Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+u...@googlegroups.com javascript: 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+u...@googlegroups.com javascript:. For more options, visit https://groups.google.com/d/optout. -- Kind Regards, Atamert Ölçgen -+- --+ +++ www.muhuk.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 --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: testing clojure.core/group-by with clojure.test.check
One approach you can use is write the generators in such a way that they generate the final answer group-by should return, then you write code which does the inverse to group by and then you check the group by answer is equal to the originally generated solution. On Wednesday, April 30, 2014 11:38:19 PM UTC+12, henry w wrote: Hi, I wanted to get started with clojure.test.check (formerly simple-check) and I am new to property based testing. I plucked clojure.core/group-by for no particular reason as a function to test. I started by stating some properties i think should hold: ;; 1. applying the grouping key function to each member in a grouping should result in the grouping key ;; 2. flattening the vals of the group-by result should give back the contents of the original collection. ;; 3. no element appears in more than one grouping. so far so good I think. there may be others but this seems ok for now. now, how to generate some data. for group-by we need two params: 1) a grouping function 2) a collection of items to be grouped If I start by naively generating collections of maps (containing keyword keys and int vals, for example), the data is of the right shape to use in group by, but there is no guarantee that: 1) any of the maps share a key that I could use for grouping 2) the values under a common key are shared This is really the crux of my problem ideally I would have the generator *mostly* produce data which is actually doing to result in the sort of collection i might want to call group-by on in real life (ie not have everything grouped under nil on each generation). So should i create a generator that creates keywords (which i will want to use as grouping function) then have another generator that produces what are going to be the values under this grouping key, then a generator that uses both of these to create collections of maps from these. then i would have to find out what the grouping keyword was that was generated this could all work, I have read enough about generators to have a stab at this... but is it the right approach? as far as implementing tests for the properties so far, I have done property 2 above, using a basic generator and yanking out an arbitrary key from it clearly a flawed approach as not much 'realistic' grouping is going to happen here. (def vector-of-maps (gen/such-that not-empty (gen/vector (gen/such-that not-empty (gen/map gen/keyword gen/int) (def all-elements-are-grouped (prop/for-all [group-by-input vector-of-maps] (let [a-map-key (- group-by-input first keys first)] ;; hmm, seems far from ideal (= (set group-by-input) (- (group-by a-map-key group-by-input) vals flatten set) help appreciated... perhaps I need to learn more about the paradigm first, but resources linked from the readme are all a bit more basic than this. so if you know of some more advanced tutorials please let me know. Thanks -- 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: Update
Well, why write it in primitives when there is a perfectly good compiler from java to primitives? I dont quite understand why you think there would be benefit from manually writing everything with java bytecode. The JVM works with classes, thats how its designed, Clojure itself is just a java library. On Tuesday, April 29, 2014 8:25:01 PM UTC+12, Divyansh Prakash wrote: Why are Clojure features defined in terms of Java classes, instead of as bytecode primitives? For eg: Cons is a class containing two objects: first and rest. Is this only to achieve Java interoperability, or is there more to it? -- 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: Update
For the llvm based approach you can look at vmkit. On Wednesday, April 30, 2014 3:39:21 AM UTC+12, Divyansh Prakash wrote: Check out my previous reply. The parrot vm provides gc and everything, But still the author defines lambda primitives in c, and then builds over it. -- 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: cursive plugin question
To do this i created a new run configuration with and in the run config dialog set it to local clojure repl, then you need to go to preferences and create keybindings for send current form to repl (I just used shift + enter). Then it should work no problem. On Tuesday, April 29, 2014 11:04:24 PM UTC+12, Roelof Wobben wrote: Hello, I installed intelij with the cursive plugin. Now I wonder if this can be done in some way. Suppose I have a file with 3 functions. Can I send one to REPL so I can test if it works as I expected. Roelof -- 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: Which linux distro has intelij ?
Don't install intellij from and package manager (it will probably be out of date/not there), just install java then download it from the intellij/cursive website. Its self updating anyway and should work on any distro and on windows that way. On Wednesday, April 23, 2014 5:11:54 AM UTC+12, Roelof Wobben wrote: Hello, Does anyone know a Linux distro which I can use to learn clojure and which has inteljij aviable. I really like to test the cursive plugin Roelof -- 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
ring streaming efficiency
When you set the body of a ring response to a java input stream and return it, is this still a thread per stream? or does it use some sort of java event loop for efficiency? I'm worried that a traffic download/upload server in ring wouldn't handle many concurrent large file uploads and downloads as efficiently as something like google go or nodejs would. I would like to use ring because I want Datomic to manage the access permissions. -- 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: Which linux distro has intelij ?
Just for reference, i use xubuntu (with the apt-get java jdk) and windows with cursive no problem. I love cursive compared to other clojure dev tools I've tried. On Wednesday, April 23, 2014 11:37:12 AM UTC+12, Andrew Chambers wrote: Don't install intellij from and package manager (it will probably be out of date/not there), just install java then download it from the intellij/cursive website. Its self updating anyway and should work on any distro and on windows that way. On Wednesday, April 23, 2014 5:11:54 AM UTC+12, Roelof Wobben wrote: Hello, Does anyone know a Linux distro which I can use to learn clojure and which has inteljij aviable. I really like to test the cursive plugin Roelof -- 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: ring streaming efficiency
I need access control for the static files. The alternative is signed s3 urls which expire. Uploads still require streaming through ring however as i cant generate signed upload urls with the parameters that I need. On Wednesday, April 23, 2014 3:27:09 PM UTC+12, James Reeves wrote: Java input streams are blocking, rather than asynchronous, so yes it would use a thread per stream. In theory an asynchronous solution would be more efficient, and there are adapters, like http-kit, that support this optimisation. However, in practice, Java can handle many threads in a single process, so it's unlikely you'll run into difficulties until you have to support 1000s of concurrent downloads. It's often a good idea to avoid premature optimisations, particularly if you lack concrete benchmarks. It also depends a lot on how you're generating the downloads. If you're generating the files dynamically, you may find that your bottleneck is CPU-bound, rather than I/O-bound; in which case, there would be little benefit to going async. If you're just serving static files, then it might be useful hosting your files on a service like S3, and redirecting your users instead. - James On 23 April 2014 04:03, Andrew Chambers andrewc...@gmail.comjavascript: wrote: When you set the body of a ring response to a java input stream and return it, is this still a thread per stream? or does it use some sort of java event loop for efficiency? I'm worried that a traffic download/upload server in ring wouldn't handle many concurrent large file uploads and downloads as efficiently as something like google go or nodejs would. I would like to use ring because I want Datomic to manage the access permissions. -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clo...@googlegroups.comjavascript: Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+u...@googlegroups.com javascript: 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+u...@googlegroups.com javascript:. For more options, visit https://groups.google.com/d/optout. -- 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: Clojure compiletime vs runtime
Why are the toplevel forms which arent macros executed at compile time? For example Lua can be compiled to bytecode without executing its top level calls. On Tue, Apr 15, 2014 at 9:04 PM, Softaddicts lprefonta...@softaddicts.cawrote: Ahem :) a) The fn x does not exist in the universe until you call foo, hence you cannot expect the compiler to known anything about it if it's not called before making any reference to x. b) If you refer to x at the top level (the universe above :) before defining it, obviously it does not exist. You might use (declare x) before referring to it. This allows you to define it later at your convenience. c) In general, you should avoid using def/defn within a function. Macros may do that but this is a different story. d) Yes code at the top level is executed, how can you expect the REPL to work interactively if forms are not evaluated first ? A defn expands to a function call, a special form in fact but it still behaves like a function. Any function call at top level will get executed after being compiled to byte code. Now about the compilation step... Traditionally, most Lisps allow you to refer to stuff in interpreted mode not defined yet hoping that it will get defined by the time you run the code that refers to these undefined things. It can even be something transient on the stack... oups... You can still compile in other Lisps but this is a special case where you have to make sure that stuff is defined in some way. You need to add directives to tell the compiler that this stuff will exist later and that it can safely refer to it. On the JVM, some underlying byte code has to be generated for any forms typed in the REPL at the top level any reference has to be defined before hand. There's no other way to generate byte code... there cannot be black holes waiting to get filled later. Hence the compilation phase and the restriction that stuff you refer to are to be defined either directly or using declare. Hope it explains the compromise. Luc P. Is there an explanation of how clojure deals with scoping and its static checking. It seems to be a hybrid of a static language and a dynamic language when it comes to compilation. I'll elaborate. The following code wont compile: (defn x [] nil) (defn y[]) ((x)) however this code will compile: (defn foo[] (defn x[] nil)) (defn y[]) ((x)) but calling y before foo fails with a runtime exception. Also, the following code: (println hello) (defn -main [args] (println world)) prints hello at compile time and also hello world at runtime. My conclusions from this is that the static symbol checker is actually fairly stupid and is just there to provide some simple sanity, and that all toplevel code in a namespace is executed at compile time AND at runtime. Is this correct? -- 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout. -- Softaddictslprefonta...@softaddicts.ca sent by ibisMail from my ipad! -- 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 a topic in the Google Groups Clojure group. To unsubscribe from this topic, visit https://groups.google.com/d/topic/clojure/VUWTAwOEHS0/unsubscribe. To unsubscribe from this group and all its topics, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout. -- 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
Re: Clojure compiletime vs runtime
I only noticed it because I was trying to write a macro which expands to multiple def calls. This requires the def's to be inside a do block, which made me question a whole lot about how the AOT compiler works. On Tue, Apr 15, 2014 at 11:05 PM, Phillip Lord phillip.l...@newcastle.ac.uk wrote: You need to distinguish between compiled and aot compiled to byte code. As far as I know, all forms are compiled before they are executed. So, if you type: (+ 1 1) it is first compiled to bytecode, and then run. It's not executed at compile time at all; rather when it is evaluated, it is compiled and then run. If you aot compile, then you are do the same thing, but dump the bytecode to file. So, you still evaluate the entire top level. So, when you say compile, I presume you you mean aot compiled. Macros have to be run, so the question is should they be expanded but not evaluated? And what about macros with side-effects? And if top level forms are NOT evaluated when loaded what would this do: (ns user) (def x 1) (load user_y) === in user_y.clj (def y 1) Now the AOT would only load the first file in the namespace because (load user_y) would not be evaluated. Why are you worried about this? Most of the time compilation in Clojure is an implementation detail, as it is in python. It just happens when it needs to, and away you go. Phil Andrew Chambers andrewchambe...@gmail.com writes: Why are the toplevel forms which arent macros executed at compile time? For example Lua can be compiled to bytecode without executing its top level calls. On Tue, Apr 15, 2014 at 9:04 PM, Softaddicts lprefonta...@softaddicts.cawrote: Ahem :) a) The fn x does not exist in the universe until you call foo, hence you cannot expect the compiler to known anything about it if it's not called before making any reference to x. b) If you refer to x at the top level (the universe above :) before defining it, obviously it does not exist. You might use (declare x) before referring to it. This allows you to define it later at your convenience. c) In general, you should avoid using def/defn within a function. Macros may do that but this is a different story. d) Yes code at the top level is executed, how can you expect the REPL to work interactively if forms are not evaluated first ? A defn expands to a function call, a special form in fact but it still behaves like a function. Any function call at top level will get executed after being compiled to byte code. Now about the compilation step... Traditionally, most Lisps allow you to refer to stuff in interpreted mode not defined yet hoping that it will get defined by the time you run the code that refers to these undefined things. It can even be something transient on the stack... oups... You can still compile in other Lisps but this is a special case where you have to make sure that stuff is defined in some way. You need to add directives to tell the compiler that this stuff will exist later and that it can safely refer to it. On the JVM, some underlying byte code has to be generated for any forms typed in the REPL at the top level any reference has to be defined before hand. There's no other way to generate byte code... there cannot be black holes waiting to get filled later. Hence the compilation phase and the restriction that stuff you refer to are to be defined either directly or using declare. Hope it explains the compromise. Luc P. Is there an explanation of how clojure deals with scoping and its static checking. It seems to be a hybrid of a static language and a dynamic language when it comes to compilation. I'll elaborate. The following code wont compile: (defn x [] nil) (defn y[]) ((x)) however this code will compile: (defn foo[] (defn x[] nil)) (defn y[]) ((x)) but calling y before foo fails with a runtime exception. Also, the following code: (println hello) (defn -main [args] (println world)) prints hello at compile time and also hello world at runtime. My conclusions from this is that the static symbol checker is actually fairly stupid and is just there to provide some simple sanity, and that all toplevel code in a namespace is executed at compile time AND at runtime. Is this correct? -- 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
Re: [ANN] Gorilla REPL 0.2.0 - all new extensible renderer
This is awesome (reminds me of ipython notebooks). I hope to use this to custom render some data structures internal to my compiler project. I'll have to read up on how to render directed graphs. On Thursday, March 20, 2014 9:22:57 AM UTC+13, Jony Hudson wrote: Hi all, I'm happy to announce a new release of Gorilla REPL. The number one comment I got from people on the original release was that it looked good, but they'd like to see it extended to some library or other. Jeff Rose hit the nail on the head with: Being able to render values of different types is important, and I think it deserves a lot of attention in both the design and documentation. So with that in mind, on to the changes: - All new renderer. This is the main change. The new renderer is simple and predictable, _very_ flexible, supports first-class pluggable custom rendering, and really respects the structure of Clojure values. In particular it renders aggregates of values as you might hope, so you can draw lists of tables, tables of plots, associatives of tables of tables of plots etc. I've made a couple of videos walking through its features, and how easy it is to extend. I'm really pleased with how it's come out :-) https://vimeo.com/89529751 https://vimeo.com/89532785 As per the request, there's also documentation on it. Enough to choke a horse! http://gorilla-repl.org/renderer.html - You can open multiple tabs on the same REPL. This works really nicely - they each get they own session, but share the REPL. - Runs a real nREPL server now, so should work together with things like vim-fireplace that make their own connection to the REPL server. (I haven't tested this though!) - As you might have guessed from the above, there's now a website. http://gorilla-repl.org - Numerous small bug-fixes and feature requests. There are some minor breaking changes, hence the version bump: - Old worksheets will need to be re-run to regenerate their output. - Code that dabbled with the internals of gorilla-plot might need to be adjusted. It's on clojars now, with coordinates [gorilla-repl 0.2.0] . The new renderer lays the foundation for adding rendering for other libraries. I'd love to see support for core.matrix and Incanter, so I think this will be the immediate focus of development. If you maintain a library and would like to see it supported, then please do get in touch. As always, all comments and criticism gratefully received. [Proof-reading this email, I realise I sound rather pleased with myself. My apologies for that, but in truth I think I _am_ rather pleased with how this version has came together!] Yours, Jony -- 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: true lightweight threads on clojurescript?
You need to write either an interpreter of some sort of bytecode in javascript/clojurescript and and have the interpreter implement the threading, or use a webworker for each process then something like core.async for sending ui events to the main browser loop. Clojurescript doesnt attempt to emulate full threads. On Wednesday, April 9, 2014 8:51:57 AM UTC+12, t x wrote: Hi, * I am aware of core.async. However, I don't like the fact that (go ... ) is a macro, thus forcing the ! and ! to appear in the body, and I can't do nested things like: (defn foo [chan] (let [x (! chan)] ... )) (go ... (foo ... )) * For the following, I only need it to work in ClojureScript. I don't need it to work in Clojure. Furthermore, we can assume browser = latest Firefox, or browser = latest Chrome. Now, my question: is there a library which provides true lightweight Clojurescript threads? Thanks! -- 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [ANN] Gorilla REPL 0.2.0 - all new extensible renderer
Is there a way to rerun the whole notebook top to bottom with a hotkey? On Wed, Apr 16, 2014 at 3:59 PM, SteveSuehs skelter@gmail.com wrote: I'm running Leiningen 2.1.2 on Java 1.7.0_45 Java HotSpot(TM) 64-Bit Server VM Upgrading now...version 2.3.4 Removed tools.nrepl from project.clj $ lein gorilla Gorilla-REPL. Started nREPL server on port 50235 Running at http://localhost:8990/worksheet.html . Ctrl+C to exit. Looking good! On Tuesday, April 15, 2014 10:03:33 AM UTC-5, Jony Hudson wrote: Thanks for the kind words chaps - glad you like it! @Steve Are you sure your Leiningen is up to date? I've only seen this problem when accidentally trying to run Gorilla with Lein 1.7 (as Debian seems to have that version as its default install). @Andrew Probably not what you're looking for, but there should be a renderer for Loom graphs soon, which shells out to GraphViz to do the heavy lifting. Take a look at this PR: https://github.com/aysylu/loom/pull/20. Even if your data doesn't fit with loom then it might be useful for an idea. -- 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 a topic in the Google Groups Clojure group. To unsubscribe from this topic, visit https://groups.google.com/d/topic/clojure/a1FsteQXhrQ/unsubscribe. To unsubscribe from this group and all its topics, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout. -- 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Extending a data model
Hi everyone, I'm new to clojure and in order to learn I'm working on making some compiler tools which converts a lightweight IR code into assembly. My data model for an IR function is along the lines of (def code { :entry [[:loadaddr :x global_label] [:loadconst 1 :y] [:add :x :y :z] [:jmp :exit]] :exit [[:ret :z]] }) This, when translated to assembly and after register allocation would turn into something like (ignoring calling conventions etc): (def assembly-code { :entry [[:x86.lea :eax global_label] [:x86.loadimm 1, :eax] [:x86.add32 :ebx :eax] [:jmp :exit]] :exit [[:ret]] }) The problem arises when I have to query the IR code for things like accesses-memory? or get-output-vars in an extensible way so that multiple target architectures can be supported. e.g. (get-output-vars [:add :a :b :c]) - :c (get-output-vars [:x86.add :a :b]) - :b ;; the input and output positions are opcode specific (get-output-vars [:x86.add :a :b]) - :b (get-output-vars [:divmod :a :b :c :d]) - :c :d (accesses-memory? :x86.add) - false (accesses-memory? :x86.load) - true (accesses-memory? :loadconst) -false I have to be able to write these functions in a way that knows about the format of the basic IR opcodes, but can also be extended to handle opcodes of architectures that don't exist in my code yet, the extensions would exist within the namespaces of that specific architecture and shouldn't need to modify the code for the built in opcodes. What is the most seamless and efficient way to achieve this sort of function extension in clojure? Also, how would I allow sharing of implementations where instructions have similar layouts. e.g. (get-output-vars [:add :a :b :c]) - :c (get-output-vars [:sub :a :b :c]) - :c -- 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: Potential Intro clojure projects - libraries and ideas with wow factor
Clojure logic programming with core.logic (something akin to a sudoku solver https://gist.github.com/swannodette/3217582 is a good example) or using datomic to have a database with a time machine and datalog for queries might be cool (perhaps visualizing the data in the database at arbitrary times in the past). Both don't really have equivalents in other languages. Other things that are hard to achieve in other languages would involve the immutable data structures, concurrency, and macros. On Monday, April 14, 2014 9:15:31 AM UTC+12, utel wrote: A handful of developers at the organisation I work at, want to encourage interest in Clojure with the aim of using it in production amongst the organisation's wider developer community (hundreds of developers). We ourselves are Clojure hobbyists. We wanted to do this through a basic project (with few moving parts), so I wanted to get feedback on a couple of aspects: 1. Examples of basic project ideas that would be compelling to fellow developers not familiar with Clojure (e.g. something useful that you can do easily with Clojure that's harder to do in more established languages such as Java) 2. Particular libraries that again had a wow factor towards an objective not easily achievable in more established languages (perhaps related to data analysis, visualisation, or taking advantage of the benefit of lazy evaluation in a novel way as examples). I realise these questions are somewhat open-ended, but just wanted to spark off some ideas for us through bouncing these questions off the google group's members. Thanks for any leads! -- 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: Extending a data model
Thanks for the tip, I think multimethods may be what i need in this case (perhaps which checks the current architecture in the dispatch function so i can disable some). I want to avoid having to pass an object around and extract methods (simply because it clutters my code). Dynamically binding methods may be another solution. On Tuesday, April 15, 2014 11:59:17 AM UTC+12, Reid McKenzie wrote: Hey Andrew, I actually built something very much along these lines a few months ago if you care to cheat off of it: http://github.com/arrdem/toothpick is an assembler generator system that works more or less along these lines. Label support is still a problem I haven't completely solved and I never did build a compiler backed targeting Toothpick, but the idea is there. One approach, and the one that I took, is to make everything in your API parametric on some representation of the target architecture. In Toothpick, I build a monolithic map representing the target, and all the utility functions are built in terms of operating on an arbitrary instruction sequence in conjunction with this target description. This is probably the easiest thing to do, as in your (accesses-memory?) you can simply enquire of the target description structure rather than relying on the user to have provided a multimethod implementation or anything else. Hope this helps, Reid On Monday, April 14, 2014 6:52:36 PM UTC-5, Andrew Chambers wrote: Hi everyone, I'm new to clojure and in order to learn I'm working on making some compiler tools which converts a lightweight IR code into assembly. My data model for an IR function is along the lines of (def code { :entry [[:loadaddr :x global_label] [:loadconst 1 :y] [:add :x :y :z] [:jmp :exit]] :exit [[:ret :z]] }) This, when translated to assembly and after register allocation would turn into something like (ignoring calling conventions etc): (def assembly-code { :entry [[:x86.lea :eax global_label] [:x86.loadimm 1, :eax] [:x86.add32 :ebx :eax] [:jmp :exit]] :exit [[:ret]] }) The problem arises when I have to query the IR code for things like accesses-memory? or get-output-vars in an extensible way so that multiple target architectures can be supported. e.g. (get-output-vars [:add :a :b :c]) - :c (get-output-vars [:x86.add :a :b]) - :b ;; the input and output positions are opcode specific (get-output-vars [:x86.add :a :b]) - :b (get-output-vars [:divmod :a :b :c :d]) - :c :d (accesses-memory? :x86.add) - false (accesses-memory? :x86.load) - true (accesses-memory? :loadconst) -false I have to be able to write these functions in a way that knows about the format of the basic IR opcodes, but can also be extended to handle opcodes of architectures that don't exist in my code yet, the extensions would exist within the namespaces of that specific architecture and shouldn't need to modify the code for the built in opcodes. What is the most seamless and efficient way to achieve this sort of function extension in clojure? Also, how would I allow sharing of implementations where instructions have similar layouts. e.g. (get-output-vars [:add :a :b :c]) - :c (get-output-vars [:sub :a :b :c]) - :c -- 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: Extending a data model
An update, I read about protocols and multimethods. I think multimethods are a decent way to go (cant use protocols without a defrecord) provided they work across namespaces. On Tuesday, April 15, 2014 11:52:36 AM UTC+12, Andrew Chambers wrote: Hi everyone, I'm new to clojure and in order to learn I'm working on making some compiler tools which converts a lightweight IR code into assembly. My data model for an IR function is along the lines of (def code { :entry [[:loadaddr :x global_label] [:loadconst 1 :y] [:add :x :y :z] [:jmp :exit]] :exit [[:ret :z]] }) This, when translated to assembly and after register allocation would turn into something like (ignoring calling conventions etc): (def assembly-code { :entry [[:x86.lea :eax global_label] [:x86.loadimm 1, :eax] [:x86.add32 :ebx :eax] [:jmp :exit]] :exit [[:ret]] }) The problem arises when I have to query the IR code for things like accesses-memory? or get-output-vars in an extensible way so that multiple target architectures can be supported. e.g. (get-output-vars [:add :a :b :c]) - :c (get-output-vars [:x86.add :a :b]) - :b ;; the input and output positions are opcode specific (get-output-vars [:x86.add :a :b]) - :b (get-output-vars [:divmod :a :b :c :d]) - :c :d (accesses-memory? :x86.add) - false (accesses-memory? :x86.load) - true (accesses-memory? :loadconst) -false I have to be able to write these functions in a way that knows about the format of the basic IR opcodes, but can also be extended to handle opcodes of architectures that don't exist in my code yet, the extensions would exist within the namespaces of that specific architecture and shouldn't need to modify the code for the built in opcodes. What is the most seamless and efficient way to achieve this sort of function extension in clojure? Also, how would I allow sharing of implementations where instructions have similar layouts. e.g. (get-output-vars [:add :a :b :c]) - :c (get-output-vars [:sub :a :b :c]) - :c -- 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Clojure compiletime vs runtime
Is there an explanation of how clojure deals with scoping and its static checking. It seems to be a hybrid of a static language and a dynamic language when it comes to compilation. I'll elaborate. The following code wont compile: (defn x [] nil) (defn y[]) ((x)) however this code will compile: (defn foo[] (defn x[] nil)) (defn y[]) ((x)) but calling y before foo fails with a runtime exception. Also, the following code: (println hello) (defn -main [args] (println world)) prints hello at compile time and also hello world at runtime. My conclusions from this is that the static symbol checker is actually fairly stupid and is just there to provide some simple sanity, and that all toplevel code in a namespace is executed at compile time AND at runtime. Is this correct? -- 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: Clojure compiletime vs runtime
Forgive me, the first example was meant to be The following code wont compile: (defn y[]) ((x)) (defn x [] nil) On Tuesday, April 15, 2014 4:39:59 PM UTC+12, Andrew Chambers wrote: Is there an explanation of how clojure deals with scoping and its static checking. It seems to be a hybrid of a static language and a dynamic language when it comes to compilation. I'll elaborate. The following code wont compile: (defn x [] nil) (defn y[]) ((x)) however this code will compile: (defn foo[] (defn x[] nil)) (defn y[]) ((x)) but calling y before foo fails with a runtime exception. Also, the following code: (println hello) (defn -main [args] (println world)) prints hello at compile time and also hello world at runtime. My conclusions from this is that the static symbol checker is actually fairly stupid and is just there to provide some simple sanity, and that all toplevel code in a namespace is executed at compile time AND at runtime. Is this correct? -- 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.