Re: Enhanced Primitive Support
On Sat, Jun 19, 2010 at 11:22 PM, Mike Meyer wrote: > > "Rob Lachlan" wrote: > >>Actually, Mike, your two functions work just fine. (Equal branch). >>Mind you I checked that out over two hours ago, so this information >>might be out of date. >> >>Rob >> >>On Jun 19, 6:59 pm, Mike Meyer > Ok, why does this work but the fact fail? Or does the fact example still fail > on that build? > > The fact that this requires explanation is a pretty good argument the fact > behavior. > >> (defn fact [n] >> (loop [n n r 1] >> (if (zero? n) >> r >> (recur (dec n) (* r n) (The quoting in this thread is getting out-of-hand, everyone please reply on the bottom) The difference between your examples and the fact examples is that (inc prim) -> prim while (* prim boxed) -> boxed In the fact example, the type of n as an initializer in the loop statement is unknown at compile time and thus must be boxed. The fact that you need to know that, is very much what some people are arguing against. The choices are to do either: (loop [n n r (num 1)] or (loop [n (long n) r 1] Either option will make (* r n) return a primitive or boxed value of the appropriate type. Both versions will overflow and throw an exception at (fact 21). To have a fact that works for large numbers you need: (defn fact [n] (loop [n n r (num 1)] (if-not (pos? n) r (recur (dec n) (*' r n) Most of the versions posted so far were broken for negative n by the way. -- 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: Enhanced Primitive Support
"Rob Lachlan" wrote: >Because the compiler is upset that it doesn't know what n is. r is a >long, but n is ???. The following works: > >(defn ^:static fact [^long n] > (loop [n n r 1] >(if (zero? n) > r > (recur (dec n) (* r n) > >Or see Dnolen's version above. But yeah, I wish that it still worked, >because it used to work just fine. Is there reason the compiler can't box r instead of throwing an exception? -- Sent from my Android phone with K-9 Mail. Please excuse my brevity. -- 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: Enhanced Primitive Support
Because the compiler is upset that it doesn't know what n is. r is a long, but n is ???. The following works: (defn ^:static fact [^long n] (loop [n n r 1] (if (zero? n) r (recur (dec n) (* r n) Or see Dnolen's version above. But yeah, I wish that it still worked, because it used to work just fine. Rob On Jun 19, 8:22 pm, Mike Meyer wrote: > "Rob Lachlan" wrote: > >Actually, Mike, your two functions work just fine. (Equal branch). > >Mind you I checked that out over two hours ago, so this information > >might be out of date. > > >Rob > > >On Jun 19, 6:59 pm, Mike Meyer > Ok, why does this work but the fact fail? Or does the fact example still fail > on that build? > > The fact that this requires explanation is a pretty good argument the fact > behavior. > > >> (defn count-in [value col] > >> (loop [value value col col res 0] > >> (if (empty? col) > >> res > >> (recur value (rest col) (if (= (first col) value) (inc res) > >> res) > > >> (defn ones-n-zeros [vectors] > >> (loop [vectors vectors m-zeros 0 m-ones 0] > >> (if (empty? vectors) > >> [m-zeros m-ones] > >> (let [data (first vectors) > >> zeros (count-in 0 data) > >> ones (count-in 1 data)] > >> (recur (rest vectors) (if (> zeros ones) (inc m-zeros) m-zeros) > >> (if (> ones zeros) (inc m-ones) > >> m-ones)) > > -- > Sent from my Android phone with K-9 Mail. Please excuse my brevity. -- 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: Enhanced Primitive Support
"Rob Lachlan" wrote: >Actually, Mike, your two functions work just fine. (Equal branch). >Mind you I checked that out over two hours ago, so this information >might be out of date. > >Rob > >On Jun 19, 6:59 pm, Mike Meyer > (defn count-in [value col] >> (loop [value value col col res 0] >> (if (empty? col) >> res >> (recur value (rest col) (if (= (first col) value) (inc res) >> res) >> >> (defn ones-n-zeros [vectors] >> (loop [vectors vectors m-zeros 0 m-ones 0] >> (if (empty? vectors) >> [m-zeros m-ones] >> (let [data (first vectors) >> zeros (count-in 0 data) >> ones (count-in 1 data)] >> (recur (rest vectors) (if (> zeros ones) (inc m-zeros) m-zeros) >> (if (> ones zeros) (inc m-ones) >> m-ones)) -- Sent from my Android phone with K-9 Mail. Please excuse my brevity. -- 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 to use Clojure with Robocode
This answer is couple months too late but I was messing with robocode this weekend, had the same problem OP had. The solution is to unzip clojure.jar into the folder where your compiled class files are. That makes the error go away but it will also increase robocode's boot time by 20-30 secs. Hope this helps... -- Nurullah Akkaya http://nakkaya.com On Mar 19, 10:56 am, ubolonton wrote: > Hi, > > Has anyone been able to use Clojure with Robocode? > I've followed thishttp://www.fatvat.co.uk/2009/05/clojure-and-robocode.html > but got the error > > Round 1 initializing.. > Let the games begin! > java.lang.ExceptionInInitializerError > at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native > Method) > at > sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAcce > ssorImpl.java: > 39) > at > sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstru > ctorAccessorImpl.java: > 27) > at java.lang.reflect.Constructor.newInstance(Constructor.java:513) > at java.lang.Class.newInstance0(Class.java:355) > at java.lang.Class.newInstance(Class.java:308) > at > net.sf.robocode.host.security.RobotClassLoader.createRobotInstance(RobotCla > ssLoader.java: > 272) > at > net.sf.robocode.host.proxies.HostingRobotProxy.loadRobotRound(HostingRobotP > roxy.java: > 201) > at > net.sf.robocode.host.proxies.HostingRobotProxy.run(HostingRobotProxy.java: > 242) > at java.lang.Thread.run(Thread.java:637) > Caused by: java.lang.NullPointerException > at clojure.lang.Var.setMeta(Var.java:179) > at clojure.lang.Var.internPrivate(Var.java:96) > at ubolonton.MyRobot.(Unknown Source) > ... 10 more > > 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
Re: Enhanced Primitive Support
I don't think my computer has enough memory to test that. But, you're right, I might have spoken hastily. Rob On Jun 19, 7:26 pm, Aaron Cohen wrote: > I actually believe it will throw an overflow exception if col contains > more than Integer.MAX_VALUE elements. Hard to confirm without getting > bored though. > > -- Aaron > > > > On Sat, Jun 19, 2010 at 10:19 PM, Rob Lachlan wrote: > > Actually, Mike, your two functions work just fine. (Equal branch). > > Mind you I checked that out over two hours ago, so this information > > might be out of date. > > > Rob > > > On Jun 19, 6:59 pm, Mike Meyer > 620...@mired.org> wrote: > >> On Sat, 19 Jun 2010 20:40:13 -0400 > > >> David Nolen wrote: > >> > Mark and Mike you fail to address my deeper question. > > >> Maybe because you've failed to ask in your hurry to claim code is > >> non-idiomatic or calling our example rhetoric. > > >> > I've been using > >> > many different Clojure libraries all day long with the latest equals > >> > branch. Guess > >> > what? > > >> > No loop/recur bugs. > > >> I wouldn't expect anything else, for two reasons: > > >> 1) Most clojure code doesn't deal with integers - it deals with > >> symbols, strings, and sequences. Hence it won't run into this problem. > >> 2) The libraries are generally written by experienced users who will > >> have tweaked them for performance - meaning they've typed hinted > >> them, and thus avoided this problem. > > >> > When you guys start postIng your broken code that has this problem > >> > then people can start believing it is an issue for working code. > > >> I guess a perfectly natural expression of a reasonable algorithm that > >> works under 1.1 and doesn't on the equal branch isn't "broken" because > >> it's the same function we've been using all along. So here's some new > >> examples, pulled in sequence from some of my combinatorics code: > > >> (defn count-in [value col] > >> (loop [value value col col res 0] > >> (if (empty? col) > >> res > >> (recur value (rest col) (if (= (first col) value) (inc res) > >> res) > > >> (defn ones-n-zeros [vectors] > >> (loop [vectors vectors m-zeros 0 m-ones 0] > >> (if (empty? vectors) > >> [m-zeros m-ones] > >> (let [data (first vectors) > >> zeros (count-in 0 data) > >> ones (count-in 1 data)] > >> (recur (rest vectors) (if (> zeros ones) (inc m-zeros) m-zeros) > >> (if (> ones zeros) (inc m-ones) > >> m-ones)) > > >> No, I haven't verified it fails - I've given up trying to check out > >> the branch, as hg convert failed, and git (after reinstalling over a > >> broken version) keeps complaining about "warning: remote HEAD refers > >> to nonexistent ref, unable to checkout." However, my reading of the > >> proposal is that the inc's here will cause the same problems as the > >> *'s in the perfectly reasonable factorial example. > > >> Now go ahead and claim that that's not very good code, because an > >> expert would have type hinted it or written it with map & apply or > >> some such, or that there's a contrib library somewhere with a faster > >> implementation of count-in in it. That, after all, is your rhetoric. > > >> But that's my point. I want the *obvious* code to work. I'll worry > >> about making it fast after I've made it right. If you want a read-only > >> language that requires an expert to get working code in a reasonable > >> amount of time, you can always write in Perl or C. > > >> >> -- > >> Mike Meyer http://www.mired.org/consulting.html > >> Independent Network/Unix/Perforce consultant, email for more information. > > >> O< ascii ribbon campaign - stop html mail -www.asciiribbon.org > > > -- > > 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: Enhanced Primitive Support
I actually believe it will throw an overflow exception if col contains more than Integer.MAX_VALUE elements. Hard to confirm without getting bored though. -- Aaron On Sat, Jun 19, 2010 at 10:19 PM, Rob Lachlan wrote: > Actually, Mike, your two functions work just fine. (Equal branch). > Mind you I checked that out over two hours ago, so this information > might be out of date. > > Rob > > On Jun 19, 6:59 pm, Mike Meyer 620...@mired.org> wrote: >> On Sat, 19 Jun 2010 20:40:13 -0400 >> >> David Nolen wrote: >> > Mark and Mike you fail to address my deeper question. >> >> Maybe because you've failed to ask in your hurry to claim code is >> non-idiomatic or calling our example rhetoric. >> >> > I've been using >> > many different Clojure libraries all day long with the latest equals >> > branch. Guess >> > what? >> >> > No loop/recur bugs. >> >> I wouldn't expect anything else, for two reasons: >> >> 1) Most clojure code doesn't deal with integers - it deals with >> symbols, strings, and sequences. Hence it won't run into this problem. >> 2) The libraries are generally written by experienced users who will >> have tweaked them for performance - meaning they've typed hinted >> them, and thus avoided this problem. >> >> > When you guys start postIng your broken code that has this problem >> > then people can start believing it is an issue for working code. >> >> I guess a perfectly natural expression of a reasonable algorithm that >> works under 1.1 and doesn't on the equal branch isn't "broken" because >> it's the same function we've been using all along. So here's some new >> examples, pulled in sequence from some of my combinatorics code: >> >> (defn count-in [value col] >> (loop [value value col col res 0] >> (if (empty? col) >> res >> (recur value (rest col) (if (= (first col) value) (inc res) >> res) >> >> (defn ones-n-zeros [vectors] >> (loop [vectors vectors m-zeros 0 m-ones 0] >> (if (empty? vectors) >> [m-zeros m-ones] >> (let [data (first vectors) >> zeros (count-in 0 data) >> ones (count-in 1 data)] >> (recur (rest vectors) (if (> zeros ones) (inc m-zeros) m-zeros) >> (if (> ones zeros) (inc m-ones) >> m-ones)) >> >> No, I haven't verified it fails - I've given up trying to check out >> the branch, as hg convert failed, and git (after reinstalling over a >> broken version) keeps complaining about "warning: remote HEAD refers >> to nonexistent ref, unable to checkout." However, my reading of the >> proposal is that the inc's here will cause the same problems as the >> *'s in the perfectly reasonable factorial example. >> >> Now go ahead and claim that that's not very good code, because an >> expert would have type hinted it or written it with map & apply or >> some such, or that there's a contrib library somewhere with a faster >> implementation of count-in in it. That, after all, is your rhetoric. >> >> But that's my point. I want the *obvious* code to work. I'll worry >> about making it fast after I've made it right. If you want a read-only >> language that requires an expert to get working code in a reasonable >> amount of time, you can always write in Perl or C. >> >> > -- >> Mike Meyer http://www.mired.org/consulting.html >> Independent Network/Unix/Perforce consultant, email for more information. >> >> O< ascii ribbon campaign - stop html mail -www.asciiribbon.org > > -- > 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: Enhanced Primitive Support
On 20 June 2010 03:59, Mike Meyer wrote: > So here's some new > examples, pulled in sequence from some of my combinatorics code: This works fine as far as arithmetic ops are concerned, though I suppose it might suffer from issues of = vs. == now (which is a separate matter). Sincerely, Michał -- 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: Enhanced Primitive Support
Actually, Mike, your two functions work just fine. (Equal branch). Mind you I checked that out over two hours ago, so this information might be out of date. Rob On Jun 19, 6:59 pm, Mike Meyer wrote: > On Sat, 19 Jun 2010 20:40:13 -0400 > > David Nolen wrote: > > Mark and Mike you fail to address my deeper question. > > Maybe because you've failed to ask in your hurry to claim code is > non-idiomatic or calling our example rhetoric. > > > I've been using > > many different Clojure libraries all day long with the latest equals > > branch. Guess > > what? > > > No loop/recur bugs. > > I wouldn't expect anything else, for two reasons: > > 1) Most clojure code doesn't deal with integers - it deals with > symbols, strings, and sequences. Hence it won't run into this problem. > 2) The libraries are generally written by experienced users who will > have tweaked them for performance - meaning they've typed hinted > them, and thus avoided this problem. > > > When you guys start postIng your broken code that has this problem > > then people can start believing it is an issue for working code. > > I guess a perfectly natural expression of a reasonable algorithm that > works under 1.1 and doesn't on the equal branch isn't "broken" because > it's the same function we've been using all along. So here's some new > examples, pulled in sequence from some of my combinatorics code: > > (defn count-in [value col] > (loop [value value col col res 0] > (if (empty? col) > res > (recur value (rest col) (if (= (first col) value) (inc res) res) > > (defn ones-n-zeros [vectors] > (loop [vectors vectors m-zeros 0 m-ones 0] > (if (empty? vectors) > [m-zeros m-ones] > (let [data (first vectors) > zeros (count-in 0 data) > ones (count-in 1 data)] > (recur (rest vectors) (if (> zeros ones) (inc m-zeros) m-zeros) > (if (> ones zeros) (inc m-ones) m-ones)) > > No, I haven't verified it fails - I've given up trying to check out > the branch, as hg convert failed, and git (after reinstalling over a > broken version) keeps complaining about "warning: remote HEAD refers > to nonexistent ref, unable to checkout." However, my reading of the > proposal is that the inc's here will cause the same problems as the > *'s in the perfectly reasonable factorial example. > > Now go ahead and claim that that's not very good code, because an > expert would have type hinted it or written it with map & apply or > some such, or that there's a contrib library somewhere with a faster > implementation of count-in in it. That, after all, is your rhetoric. > > But that's my point. I want the *obvious* code to work. I'll worry > about making it fast after I've made it right. If you want a read-only > language that requires an expert to get working code in a reasonable > amount of time, you can always write in Perl or C. > > -- > Mike Meyer http://www.mired.org/consulting.html > Independent Network/Unix/Perforce consultant, email for more information. > > O< ascii ribbon campaign - stop html mail -www.asciiribbon.org -- 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: Enhanced Primitive Support
On 20 June 2010 02:13, David Nolen wrote: > On Sat, Jun 19, 2010 at 4:10 PM, Michał Marczyk > wrote: >> (defn fact [n] >> (loop [n n r 1] >> (if (zero? n) >> r >> (recur (dec n) (* r n) > Huh? That doesn't look like it's going to work at all. > 1) 1 is primitive, we know that, accept it > 2) we don't know the type of n, what will (* r n) be? > 3) BOOM! Yes, I know what's going on, after reading through this rather lengthy thread and participating in / listening in on a number of exchanges on #clojure. I still find the notion that this code "doesn't look like it's going to work at all" to be fairly surprising. (Also, I'd rather not refactor a private loop so that it becomes exposed to the outside world (presumably to be instructed to ignore the binary overload), but that is beside the point. The (num ...) hint is a simple enough solution, which incidentally I'd be able to live with if things were not to go the way I prefer.) I wanted to address the pre-BOOM points above, though: 1) With the other approach being proposed, this would read something like "1 is primitive in primitive contexts, but will get boxed if used as an initialiser for an unhinted local". That's rather a significant improvement over the stylistically matching description of the 1.2-master (& 1.1) state of affairs (which I'll omit from here while noting that apparently acceptance was pretty low on that). I'm very happy to see Clojure moving forward w.r.t. the way in which top numeric performance can be achieved; that leaves plenty of room for doubting whether it should be the outright default. So, how about we address this point...? 2) That is in fact precisely the reason why I find it odd to presume that we know the desired type of r based on the literal alone. The question I wanted to pose when posting that factorial example was this: Should basic arithmetic work with no explicit hints / casts / primed ops / whatever -- or not necessarily? This seems like a valid question to me. If the answer is "not necessarily", I'll probably be able to get used to the idea; if it is "yes", or at least "hopefully", then perhaps there's something left to tweak / change etc. Note that if there was a way to have primitive-by-default arithmetic, yet also have naive arithmetic code work without hinting, this would be orthogonal to the issue of the choice of default. (In fact, it could affect my personal preference, or at least the degree to which I care about it.) Sincerely, Michał -- 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: Enhanced Primitive Support
On Sat, 19 Jun 2010 20:40:13 -0400 David Nolen wrote: > Mark and Mike you fail to address my deeper question. Maybe because you've failed to ask in your hurry to claim code is non-idiomatic or calling our example rhetoric. > I've been using > many different Clojure libraries all day long with the latest equals > branch. Guess > what? > > No loop/recur bugs. I wouldn't expect anything else, for two reasons: 1) Most clojure code doesn't deal with integers - it deals with symbols, strings, and sequences. Hence it won't run into this problem. 2) The libraries are generally written by experienced users who will have tweaked them for performance - meaning they've typed hinted them, and thus avoided this problem. > When you guys start postIng your broken code that has this problem > then people can start believing it is an issue for working code. I guess a perfectly natural expression of a reasonable algorithm that works under 1.1 and doesn't on the equal branch isn't "broken" because it's the same function we've been using all along. So here's some new examples, pulled in sequence from some of my combinatorics code: (defn count-in [value col] (loop [value value col col res 0] (if (empty? col) res (recur value (rest col) (if (= (first col) value) (inc res) res) (defn ones-n-zeros [vectors] (loop [vectors vectors m-zeros 0 m-ones 0] (if (empty? vectors) [m-zeros m-ones] (let [data (first vectors) zeros (count-in 0 data) ones (count-in 1 data)] (recur (rest vectors) (if (> zeros ones) (inc m-zeros) m-zeros) (if (> ones zeros) (inc m-ones) m-ones)) No, I haven't verified it fails - I've given up trying to check out the branch, as hg convert failed, and git (after reinstalling over a broken version) keeps complaining about "warning: remote HEAD refers to nonexistent ref, unable to checkout." However, my reading of the proposal is that the inc's here will cause the same problems as the *'s in the perfectly reasonable factorial example. Now go ahead and claim that that's not very good code, because an expert would have type hinted it or written it with map & apply or some such, or that there's a contrib library somewhere with a faster implementation of count-in in it. That, after all, is your rhetoric. But that's my point. I want the *obvious* code to work. I'll worry about making it fast after I've made it right. If you want a read-only language that requires an expert to get working code in a reasonable amount of time, you can always write in Perl or C. http://www.mired.org/consulting.html Independent Network/Unix/Perforce consultant, email for more information. O< ascii ribbon campaign - stop html mail - www.asciiribbon.org -- 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: need help understanding two issues
On 19 June 2010 18:59, Albert Cardona wrote: > 1. How come APersistentMap$KeySet doesn't implement IPersistentSet? Beyond what Rob has already written above, keys works with APersistentMap$KeySeq (note the "q" at the end), not APersistentMap$KeySet. To get at the latter, use (.keySet {:a 1 :b 2}); you'll get back a java.util.Set of two entries, :a and :b. This is mainly an interop feature, I believe (meant to make it easier for non-Clojure code on the JVM to read Clojure data structures directly). clojure.set/intersection knows how to handle java.util.Set instances, though in this case, using (comp set keys) -- that is, normally, (set (keys ...)) -- is the more usual and overall more sensible way to go. > 2. I can't get clojure.set/project to work. clojure.set/project is meant to implement the projection operator of [Relational algebra](http://en.wikipedia.org/wiki/Relational_algebra). The representation of relations assumed here is a "collection of tuples", which makes sense: the mathematical definition of a relation -- the one used in relational algebra -- is "a set of tuples". The tuples are here represented as maps. Of course in a mathematical relation all tuples have the same "format"; in Clojure, if some of the maps happen to be missing some of the keys present in some of the other maps, the overall semantics are very much (if not exactly) as if they had those keys bound to nil (as the usual Clojure semantics for maps would imply). Now the projection operator takes a relation and throws out some of its attributes (or some of the columns if you visualise it as a table; or if you think of a set of tuples, it removes some axes from all the tuples). The result is still a relation, i.e. a set, meaning in particular that there are no duplicates: (clojure.set/project #{{:foo 1 :bar 2} {:foo 1 :bar 3}} [:foo]) returns #{{:foo 1}}, because once we throw out the :bars, the two tuples from the input relation become indistinguishable on the basis of the remaining :foo attribute and "blend together" into just one tuple in the output relation. An example where the projection is larger: (clojure.set/project #{{:foo 1 :bar 2} {:foo 2 :quux 3}} [:foo]) ; => #{{:foo 1} {:foo 2}} So, that's how it's supposed to work. Your final example should perhaps fail more gracefully -- the first argument to clojure.set/project cannot be a map (which is by definition a collection of map entries and not of maps, as required here). As things stand, it gives a weird result due to clojure.set/project using select-keys, which in turn uses clojure.lang.RT/find, which happens to return nils when it's called with an argument which makes no sense (in addition to returning nil when the argument does make sense -- i.e. is a map -- but the given key is not found). Sincerely, Michał -- 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: Enhanced Primitive Support
Mark and Mike you fail to address my deeper question. I've been using many different Clojure libraries all day long with the latest equals branch. Guess what? No loop/recur bugs. When you guys start postIng your broken code that has this problem then people can start believing it is an issue for working code. Until then this is just theoretical rhetoric. On Saturday, June 19, 2010, Mark Engelberg wrote: > On Sat, Jun 19, 2010 at 5:13 PM, David Nolen wrote: >> Huh? That doesn't look like it's going to work at all. >> 1) 1 is primitive, we know that, accept it >> 2) we don't know the type of n, what will (* r n) be? >> 3) BOOM! > > Yes David, if you have a deep understanding of how loop/recur > interacts with primitives, and you understand that n, as an input is > boxed and that literals are primitives, it is of course possible to do > the analysis and see why it doesn't work. > > But it does look like it *should* work -- in current Clojure it works, > and the same kind of code in just about any dynamically typed language > I can think of would work. It might not work in a statically typed > language, but the types would be right there in your face, so it would > be totally obvious what was going on. The problem is that the > behavior is dependent on something that is invisible from the code, > and requires considerable reasoning even for this simple example. > >> My suggestion is to stop it with the contrived examples. Start showing some >> real code, real problems in your real programs. Using loop/recur is already >> the beginning of code smell for anything that is not performance sensitive. > > I think the notion that loop/recur is a code smell for anything that > isn't performance sensitive is absurd. It's basically the only > looping mechanism that Clojure offers - it's in all types of code. > >> (defn fact >> ([n] (fact n 1)) >> ([n r] (if (zero? n) >> r >> (recur (dec n) (* r n) >> Sleep soundly. > > The fact that this refactoring of the fact function fixes the problem > further bolsters our argument that the newly proposed semantics are > significantly more inscrutable than they should be. Without a fair > amount of thought, it's completely unobvious why this refactoring > should fix the problem. (Yes, I know it's because it boxes the 1 when > it passes it to the two-arg version, but stuff like this really > shouldn't make such a significant difference in behavior). > > -- > 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: Enhanced Primitive Support
The main example for recur on the special forms page (http:// clojure.org/special_forms#Special%20Forms--(recur%20exprs*)) is: (def factorial (fn [n] (loop [cnt n acc 1] (if (zero? cnt) acc (recur (dec cnt) (* acc cnt)) I may not be be clojure jedi, but I've been learning the language for a while. I've never come across the notion that this is a code smell. I thought that the loop recur form was perfectly orthodox. Also, the fact that the form above doesn't compile in the equal branch does make me a little uneasy. Rob On Jun 19, 5:13 pm, David Nolen wrote: > On Sat, Jun 19, 2010 at 4:10 PM, Michał Marczyk > > wrote: > > (defn fact [n] > > (loop [n n r 1] > > (if (zero? n) > > r > > (recur (dec n) (* r n) > > Huh? That doesn't look like it's going to work at all. > > 1) 1 is primitive, we know that, accept it > 2) we don't know the type of n, what will (* r n) be? > 3) BOOM! > > My suggestion is to stop it with the contrived examples. Start showing some > real code, real problems in your real programs. Using loop/recur is already > the beginning of code smell for anything that is not performance sensitive. > > (defn fact > ([n] (fact n 1)) > ([n r] (if (zero? n) > r > (recur (dec n) (* r n) > > Sleep soundly. -- 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: Enhanced Primitive Support
On Sat, 19 Jun 2010 20:13:07 -0400 David Nolen wrote: > On Sat, Jun 19, 2010 at 4:10 PM, Michał Marczyk > wrote: > > (defn fact [n] > > (loop [n n r 1] > >(if (zero? n) > > r > > (recur (dec n) (* r n) > > Huh? That doesn't look like it's going to work at all. > > 1) 1 is primitive, we know that, accept it > 2) we don't know the type of n, what will (* r n) be? > 3) BOOM! > > My suggestion is to stop it with the contrived examples. Start showing some > real code, real problems in your real programs. Using loop/recur is already > the beginning of code smell for anything that is not performance sensitive. Oh, come on. I didn't write that example, but it's a perfect reasonable implementation of the factorial loop algorithm. I'd say that you're calling "using loop/recur" a code smell is itself a smell, indicating that loop/recur is broken. http://www.mired.org/consulting.html Independent Network/Unix/Perforce consultant, email for more information. O< ascii ribbon campaign - stop html mail - www.asciiribbon.org -- 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: Enhanced Primitive Support
On Sat, Jun 19, 2010 at 5:13 PM, David Nolen wrote: > Huh? That doesn't look like it's going to work at all. > 1) 1 is primitive, we know that, accept it > 2) we don't know the type of n, what will (* r n) be? > 3) BOOM! Yes David, if you have a deep understanding of how loop/recur interacts with primitives, and you understand that n, as an input is boxed and that literals are primitives, it is of course possible to do the analysis and see why it doesn't work. But it does look like it *should* work -- in current Clojure it works, and the same kind of code in just about any dynamically typed language I can think of would work. It might not work in a statically typed language, but the types would be right there in your face, so it would be totally obvious what was going on. The problem is that the behavior is dependent on something that is invisible from the code, and requires considerable reasoning even for this simple example. > My suggestion is to stop it with the contrived examples. Start showing some > real code, real problems in your real programs. Using loop/recur is already > the beginning of code smell for anything that is not performance sensitive. I think the notion that loop/recur is a code smell for anything that isn't performance sensitive is absurd. It's basically the only looping mechanism that Clojure offers - it's in all types of code. > (defn fact > ([n] (fact n 1)) > ([n r] (if (zero? n) > r > (recur (dec n) (* r n) > Sleep soundly. The fact that this refactoring of the fact function fixes the problem further bolsters our argument that the newly proposed semantics are significantly more inscrutable than they should be. Without a fair amount of thought, it's completely unobvious why this refactoring should fix the problem. (Yes, I know it's because it boxes the 1 when it passes it to the two-arg version, but stuff like this really shouldn't make such a significant difference in behavior). -- 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: Enhanced Primitive Support
> Where can I get jar files of the various branches so I can test for > myself without having to deploy whatever infrastructure is needed to > build clojure these days? Or am I likely to be able to build them with > tools found in the BSD ports tree? It still seems to build with 'ant' like it always has for me? Install devel/apache-ant and simply run 'ant' in the clojure checkout. If you want to get the maven artifact installed in your local repository for use with leiningen/maven projects, you first want to install devel/maven2. The complication is that clojure is not built by maven (normally you would just 'mvn install'), but instead is built with Ant with it's maven tasks. So, you need to drop in: http://www.apache.org/dyn/closer.cgi/maven/binaries/maven-ant-tasks-2.1.0.jar Into ~/.ant/lib so that ant can pick that up. Afterwards, you should be able to run: ant ci-build And that should install (although it does so very silently) clojure into your (user) local maven repository: ls -ltr ~/.m2/repository/org/clojure/clojure/1.2.0-master-SNAPSHOT -- / 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
Re: Enhanced Primitive Support
On Sat, Jun 19, 2010 at 4:10 PM, Michał Marczyk wrote: > (defn fact [n] > (loop [n n r 1] >(if (zero? n) > r > (recur (dec n) (* r n) Huh? That doesn't look like it's going to work at all. 1) 1 is primitive, we know that, accept it 2) we don't know the type of n, what will (* r n) be? 3) BOOM! My suggestion is to stop it with the contrived examples. Start showing some real code, real problems in your real programs. Using loop/recur is already the beginning of code smell for anything that is not performance sensitive. (defn fact ([n] (fact n 1)) ([n r] (if (zero? n) r (recur (dec n) (* r n) Sleep soundly. -- 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: Enhanced Primitive Support
On Sat, Jun 19, 2010 at 4:10 PM, Michał Marczyk wrote: > (defn fact [n] > (loop [n n r 1] > (if (zero? n) > r > (recur (dec n) (* r n) Thanks for posting this surprisingly simple example of something that looks like it should work, but wouldn't under the current proposal. Really demonstrates how even for straightforward programs you would have to do a certain amount of "type flow" analysis to verify that it will compile. -- 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: Enhanced Primitive Support
On 19 June 2010 23:51, Mike Meyer wrote: > In any case, I don't think 10% is enough gain to justify narrowing the > range for which naive programs are correct. An order of magnitude > would be. A factor of two is a maybe. QFT! Have a look at this: (defn fact [n] (loop [n n r 1] (if (zero? n) r (recur (dec n) (* r n) This doesn't compile. To make it compile, the initial value of r has to be given as (num 1) *or* the initial binding of the "inner" n has to be given as (long n). Changing the ops to *' and dec' rules out the latter option, but the (num ...) hint on r is still required. Not surprisingly having r start off with (Long. 1) solves makes this compile too. The summary is that I'm finding it impossible to write a standard tail-recursive factorial function without type hints on my literals. I suppose I can guess what the reason is by now, but I find it unreasonably confusing. Not sure to which degree this can be ironed out if boxing were to remain an opt-in rather than -out...? Oh, just in case votes on this are of interest, I like the idea of loop' for fast-by-default looping. Sincerely, Michał -- 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: Enhanced Primitive Support
On 19 June 2010 16:43, David Nolen wrote: > "Most real world programs". You mean like Clojure itself? > Please look over the implementation of gvec before making statements like > this: Surely Clojure's internals are a *very* special case though... I wouldn't find it particularly worrying if they turned out to require some hinting. I suppose even Ruby 1.8 must have its fair share of full-speed C math under the hood (disclaimer: I'm not a Rubyist though, so I never cared to check), which has nothing to do with the performance of math in user programmes, which is what I interpreted Mike's statement to be referring to. Sincerely, Michał -- 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: Enhanced Primitive Support
On Sat, 19 Jun 2010 22:27:05 +0100 Nicolas Oury wrote: > On Sat, Jun 19, 2010 at 10:15 PM, Mike Meyer wrote: > > Pretty much any time I really need integer speed, I also deal with > > numbers that can get much larger than 10^19th, because I tend to be > > doing combinatorics or cryptography. > But you would agree that for this kind of domain, it wouldn't be too bad to > be explicit about > wanting bigint. If you write a program that work with XML, you don't ask > clojure data to be > encoded in XML. Yes, I would agree. The real issue is that when I say "gimme bigints", it happens pretty much everywhere, so I don't have to worry about overlooking some quantity that might overflow. I suppose this cuts both ways - when you want primitives, you want them everywhere, so you don't have to worry about overlooking some heavily used quantity somewhere. The difference is, I'm worried about getting the correct answer, but you're worried about performance. You can profile your code to identify where the time is going (in fact, you should have already done that before adding the first annotation) to make sure you don't overlook anything. The only automated tool I've got for finding overflows is - well, to run into them. Having to fix them and repeat the run pretty thoroughly negates any win I might have gotten out of using primitive arithmetic where I could. > > True, this represents a small fraction of all programs. The question > > I'd really like answered is how much difference does this make for > > non-numeric clojure code, where only a few percent of the calls to > > core functions are calls to integer ops. > I tried on some code with 1/2 ops per functions and already quite a dew > annotations. 10% speed-up in a program that spend 80% in Object.hashCode > (which does not get accelerated at all). Not quite what I wanted, for at least one reason (preexisting annotations) and possibly because you should be comparing the two variants of the appropriate branch, instead of comparing that branch with either 1.1 or the current master. In any case, I don't think 10% is enough gain to justify narrowing the range for which naive programs are correct. An order of magnitude would be. A factor of two is a maybe. > I think that's due to the 1/2 ops + the ops hidden in clojure library code. > I'd like to see more results like that and bugs in real programs. > It was a matter of minutes to try. > - pull the branch with git > - compile with ant > - replace your clojure.jar > - recompile. Except you have to do it twice, and get correct timings. It would really help if someone could provide precompiled jars with an appropriate README. http://www.mired.org/consulting.html Independent Network/Unix/Perforce consultant, email for more information. O< ascii ribbon campaign - stop html mail - www.asciiribbon.org -- 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: Enhanced Primitive Support
On Sat, Jun 19, 2010 at 10:15 PM, Mike Meyer wrote: > > > Pretty much any time I really need integer speed, I also deal with > numbers that can get much larger than 10^19th, because I tend to be > doing combinatorics or cryptography. > > But you would agree that for this kind of domain, it wouldn't be too bad to be explicit about wanting bigint. If you write a program that work with XML, you don't ask clojure data to be encoded in XML. > True, this represents a small fraction of all programs. The question > I'd really like answered is how much difference does this make for > non-numeric clojure code, where only a few percent of the calls to > core functions are calls to integer ops. > > I tried on some code with 1/2 ops per functions and already quite a dew annotations. 10% speed-up in a program that spend 80% in Object.hashCode (which does not get accelerated at all). I think that's due to the 1/2 ops + the ops hidden in clojure library code. I'd like to see more results like that and bugs in real programs. It was a matter of minutes to try. - pull the branch with git - compile with ant - replace your clojure.jar - recompile. -- 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: Enhanced Primitive Support
On Sat, 19 Jun 2010 20:20:48 +0100 Nicolas Oury wrote: > Not "ordinary" code. 10^19 is big. No, Aleph-2 is big. Any non-infinite number you can name in your lifetime is small ;-). Pretty much any time I really need integer speed, I also deal with numbers that can get much larger than 10^19th, because I tend to be doing combinatorics or cryptography. True, this represents a small fraction of all programs. The question I'd really like answered is how much difference does this make for non-numeric clojure code, where only a few percent of the calls to core functions are calls to integer ops. http://www.mired.org/consulting.html Independent Network/Unix/Perforce consultant, email for more information. O< ascii ribbon campaign - stop html mail - www.asciiribbon.org -- 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: Enhanced Primitive Support
While I generally favor correct over fast (worrying about fast before you're correct is a good sign that you're engaged in premature optimization), I'm still trying to figure out the tradeoffs here. Especially since most LISPs & other dynamic languages don't seem to run into this issue - or at least the debate that we're seeing here. IIUC, the problem is that we've got three "kinds" (not types; which normally refers to bit lengths) of integer: primitive, which is what the JVM does it's math with. boxed, which is the primitive wrapped in a Java object, and what Java normally uses. bigint, which is a clojure-specific kind of integer. Other numeric types don't have issues because they don't have all three kinds (is that right? Or could this entire thread be rewritten in terms of primitive vs. boxed floats?). And the bottom line is that for some reason we can't get from primitives (which are required for speed) to bigints (which are required to maximize the domain for which we get correct answers) automatically. Assuming that that's right, the first question that occurs to me is: Does clojure really need java's boxed types? Other than for java interop, of course. Again, other languages seem to get by with the platform primitives (module tweaks to get type information) going to bigints, and to get reasonable performance by throwing away the dynamic nature of the language for the hot spots. Could clojure do something similar, or is this something technical issue with the JVM, similar to the reason we don't get TCE? http://www.mired.org/consulting.html Independent Network/Unix/Perforce consultant, email for more information. O< ascii ribbon campaign - stop html mail - www.asciiribbon.org -- 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: Enhanced Primitive Support
On Sat, 19 Jun 2010 10:43:36 -0400 David Nolen wrote: > On Sat, Jun 19, 2010 at 5:13 AM, Mike Meyer < > mwm-keyword-googlegroups.620...@mired.org> wrote: > > > > > > Were those real world programs, or arithmetic benchmarks? Most real world > > programs I see spend so little of their time doing arithmetic that making > > the math an order of magnitude slower wouldn't make a noticeable difference > > in overall runtime. > > > > "Most real world programs". You mean like Clojure itself? > > Please look over the implementation of gvec before making statements like > this: This is actually the what I'm trying to figure out. While *my* code may have no explicit arithmetic in it, it's not clear without diving into the guts of clojure how much arithmetic gets done in it's name by things like gvec. http://www.mired.org/consulting.html Independent Network/Unix/Perforce consultant, email for more information. O< ascii ribbon campaign - stop html mail - www.asciiribbon.org -- 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: Enhanced Primitive Support
On Sat, 19 Jun 2010 11:00:39 +0100 Nicolas Oury wrote: > There is a bit of arithmetic involved everywhere, and around 2-3 double > operations per function in the part choosing the instance of rule to apply. That still sounds arithmetic-heavy to me. In looking through my code, I find three different classes of algorithm: 1) Things that are hard-core number-crunching, which for me is usually either combinatorics or crypto, where bigint is either a necessity or a major convenience. 2) Searches of various kinds, where most of the code manipulates trees/graphs to be searched with no (explicit) arithmetic, and one function evaluates a node with maybe a half-dozen arithmetic ops, meaning an average of <1 arithmetic op per function. 3) Everything else (web hacks, database stuff, string processing, etc.) where there's basically *no* arithmetic. I guess the real question I should be asking is: Where can I get jar files of the various branches so I can test for myself without having to deploy whatever infrastructure is needed to build clojure these days? Or am I likely to be able to build them with tools found in the BSD ports tree? http://www.mired.org/consulting.html Independent Network/Unix/Perforce consultant, email for more information. O< ascii ribbon campaign - stop html mail - www.asciiribbon.org -- 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: Enhanced Primitive Support
On Jun 19, 2:24 pm, Mark Engelberg wrote: > On Sat, Jun 19, 2010 at 12:20 PM, Nicolas Oury wrote: > > Not "ordinary" code. 10^19 is big. > > Nicolas, I think you misunderstand my point. I'm talking about > loop/recur behavior. If you initialize a loop with the literal 1, and > then recur with a number 2 that's pulled from a collection (and thus > boxed), it will break. That's ordinary code. What if loop had its current functionality, but if one tries to recur with a different type, the affected loop variable becomes automatically boxed (and if *warn-on-reflection* or a similar variable is set, the compiler emits an note)? What would be the downside of this approach? All of the code that currently works correctly with the current state of the equal branch remains fast, and all of these examples of bad behaviour should just work, and the programmer should be able to ask to know about them. -- 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: Enhanced Primitive Support
Do any of the proposals on the table affect floating point math? Currently, it seems mildly inconsistent to me that Clojure's numeric operations are auto-promoting and arbitrary-precision for integers but not for floats unless you specifically request it with the M suffix. This probably matters only to people doing scientific computing, but it's something to think about. To illustrate with a question: If we were to make "fast" the default and "correct" something you opt into with the primed operators and (num ), then does the question arise whether BigDecimals (as opposed to doubles) are returned from (num ) and (*' )? -- 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: Enhanced Primitive Support
On Sat, Jun 19, 2010 at 12:20 PM, Nicolas Oury wrote: > Not "ordinary" code. 10^19 is big. Nicolas, I think you misunderstand my point. I'm talking about loop/recur behavior. If you initialize a loop with the literal 1, and then recur with a number 2 that's pulled from a collection (and thus boxed), it will break. That's ordinary code. -- 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: Enhanced Primitive Support
On Jun 19, 3:53 pm, Rich Hickey wrote: > On Jun 19, 2010, at 6:39 AM, Jules wrote: > > > > > > > I know nothing about the JVM, but I do know that on x86 you can handle > > fixnum -> bignum promotion fairly cheaply. You compile two versions of > > the code: one for bignums and one for fixnums. After an arithmetic > > instruction in the fixnum code you check if it overflowed, and if it > > did you switch to the bignum code. > > > while(n < 10) { > > n = n + 1; > > } > > > => > > > while(n #< 10) { > > a = n #+ 1; > > if(overflow){ n = ToBignum(n); goto foo; } > > n = a; > > } > > > while(n.lessthan(10)) { > > foo: > > n = n.add(1); > > } > > > where #< and #+ are the fixnum versions of < and +, and lessthan and > > add are the bignum versions. Yeah it's slower than ignoring the > > overflow, but faster than tagged 31-bit fixnums and a whole lot faster > > than bignums. Can you convince the JVM to produce similar code? > > You can do things like that in a closed world of a few operators and > types (although it gets unwieldy as the number of variables goes up). > And of course, inside the math ops Clojure already does things like > that. > > But that is not what we are dealing with here. This is an open system, > where representational issues of functions, arguments and returns come > into play. The 'operators' +, - etc are actually function calls - they > are not special to the compiler. And your loop may also contain other > function calls: > > while(n < 10) { > foo(n) > n = n + 1; > > } > > how do I know foo can handle the bigint once I've upgraded? > > How about this? > > while(n < 10) { > n = foo(n) > > } > > Unless you have a tagged architecture you can't have boxed/unboxed arg/ > return uniformity (and even then you lose some bits of range). > > Rich There are two possibilities: either foo gets inlined and the same optimization is applied to the inlined code. Or foo is not inlined and then you pass the general boxed representation to foo (but inside foo the same optimization will be applied). Suppose that we have a boxed representation like this: class Num { ... } class Small { int val; Num add(int n){ // argument specialized to int for simplicity of this example int sum = val + n; if(overflow) return val.toBig().add(n); else return new Small(sum); } ... } class Big { BigNum val; Num add(int n){ ... } } Now the while loop. I use functional notation because the control flow is hairy and with while loops this leads to a lot of reorganization. With functional notation it's easier to see that every step is simple and mechanical. Here's our while loop and the library function to add two numbers: loop(n) = if p(n) then n else loop(add(n,1)) add(Small a, int b) = let sum = a.val+b in if overflow then add(Big(a.val),b) else Small(sum) add(Big a, int b) = bigAdd(a,b) Inline add into the loop: loop(Small n) = if p(n) then n else let sum = n.val+1 in if overflow then loop(add(Big(n.val),1)) else loop(Small(sum)) loop(Big n) = if p(n) then n else loop(bigAdd(n,1)) Introduce a new name: loop_small(n) = if p(n) then n else let sum = n.val+1 in if overflow then loop(add(Big(n.val),1)) else loop(Small(sum)) loop(Small n) = loop_small(n) loop(Big n) = if p(n) then n else loop(bigAdd(n,1)) Inline loop into loop_small and eliminate dead code, turning loop(Small(sum)) into loop_small(Small(sum)): loop_small(n) = if p(n) then n else let sum = n.val+1 in if overflow then loop(add(Big(n.val),1)) else loop_small(Small(sum)) loop(Small n) = loop_small(n) loop(Big n) = if p(n) then n else loop(bigAdd(n,1)) Note that we have eliminated the checks (in this case pattern matching) from the loop_small loop! Inlining + dead code elimination did the trick. Sure, we are still using a boxed representation in loop_small, but it's not polymorphic anymore and standard algorithms can turn the heap allocated Small instances into stack allocated local int variables (essentially "inlining" the Small class' instance variables into the local variables, in this case only val). It's not trivial to build a compiler that does this, but it's not impossible either. Perhaps the JVM already does some of this. You can get best of both worlds: speed *and* correctness. The situation is not "pick one: speed, correctness", it is "pick two: speed, correctness, simple compiler". Jules -- 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: Enhanced Primitive Support
Not "ordinary" code. 10^19 is big. On Sat, Jun 19, 2010 at 8:08 PM, Mark Engelberg wrote: > > Agreed, but with a default of boxing, it is possible to write all code > without ever using an annotation -- it will just be a bit slower than > it could be. With a default of primitives, there is ordinary code > that won't work properly unless you dig deeper into Clojure and learn > all about explicit boxing and figure out when and where to use it. I > prefer the default where I 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
Re: Enhanced Primitive Support
On Sat, Jun 19, 2010 at 6:32 AM, Rich Hickey wrote: > Really? It seems tedious to me. Don't you get tired of saying int i = 42 in > Java, when you know full well the compiler knows 42 is an int? I do, and > Clojure is competing with languages that infer the right types without the > redundancy. In this case, the question isn't so much whether Clojure can figure out that 42 is a primitive or boxed integer. The question is whether the programmer wants to insist that, upon recurrence, the primitiveness must match the initial binding. Right now, Clojure makes the determination about what the recurrence needs to be based on the initial binding, so it becomes paramount for the programmer to understand the type of that initial binding. But conceivably there are other ways that Clojure could make a determination about what kind of loop/recur behavior you want other than the type of the initial binding. So an alternative way to think about this is to relax the restriction that a recur must match the primitiveness of the loop binding, but allow the programmer to somehow control whether they want this primitive-matching behavior or not. Ideally, the behavior of recur should be readily apparent from inspection of the code. Unfortunately, the type of the initial binding is not always clear, which suggests to me that another scheme would be preferable. Sadly, I don't have any idea right now on how to cleanly specify the desired loop/recur behavior other than something that looks a lot like type annotations. But thinking of it in this way opens up the possibility of other solutions (such as a loop' construct), so maybe brainstorming along these lines will be useful. I agree with another poster that the holy grail would be if loop/recur automagically gave performance benefits when recurring with a primitive that matched the initial binding, but if you recur with something else, it just gracefully rolls over to a boxed version of the whole loop. Given that Java has no way of expressing that something can be a primitive or an Object, this seems unlikely to be possible, but perhaps with that ideal in mind, some approximation can be found. > Again, it is a matter of defaults, the non-default is going to have to be > explicit, and you can just as easily be explicit that you want the loop > argument to be an Object, either with (loop [^Object i 42] ...), (loop [i > (num 42)] ...) or your (loop' [i 42] ...) idea. Agreed, but with a default of boxing, it is possible to write all code without ever using an annotation -- it will just be a bit slower than it could be. With a default of primitives, there is ordinary code that won't work properly unless you dig deeper into Clojure and learn all about explicit boxing and figure out when and where to use it. I prefer the default where I can ignore tedious type annotations and my code "just works". -- 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 script in the classpath
On 19 June 2010 17:22, Chas Emerick wrote: > If you're just looking to run a script that happens to be on the classpath, > you can do so by prepending an '@' character to the classpath-relative path > to the script. > > So, if a directory foo is on your classpath, and a clojure file you'd like > to run is at foo/bar/script.clj, then you can run it with: > > java -cp clojure.main @/bar/script.clj > > FWIW, this is noted in the documentation for clojure here: > > http://clojure.org/repl_and_main Nice! Thanks. Paul. -- 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 script in the classpath
On 19 June 2010 07:24, rzeze...@gmail.com wrote: > On Jun 18, 6:15 pm, Paul Moore wrote: >> I've just seen a couple of postings which, if I'm not mistaken, imply >> that it's possible to have a Clojure script in my classspath. Is that >> right? > > Yes, you can have .clj files on your classpath. In fact, you can > pretty much have anything on your classpath. Checkout > java.lang.ClassLoader > http://java.sun.com/j2se/1.5.0/docs/api/java/lang/ClassLoader.html#getResource(java.lang.String) > . This is what Clojure uses under the covers. Thanks! (And thanks for the rest of your comments). I'll look into this a bit more. I think that my experiments were failing because I had the namespaces wrong - thanks for the pointer. Paul. -- 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: Basic toolset for non-Java programmer
Thanks to Ryan, Rob and Alex for the suggestions. I'll have a deeper look into all of them. Paul -- 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: Enhanced Primitive Support
On Jun 19, 11:45 am, Rich Hickey wrote: > On Jun 19, 2010, at 4:25 AM, Daniel wrote: > > > > > Checked out the new prim branch to repeat some tests. > > > user=> (defn ^:static fib ^long [^long n] > > (if (<= n 1) > >1 > >(+ (fib (dec n)) (fib (- n 2) > > #'user/fib > > user=> (time (fib 38)) > > "Elapsed time: 4383.127343 msecs" > > 63245986 > > > That's certainly not what I expected > > > user=> (defn fact [n] (loop [n n r 1] (if (zero? n) 1 (recur (dec' n) > > (*' r n) > > #'user/fact > > user=> (fact 40) > > java.lang.ClassCastException: clojure.lang.Symbol cannot be cast to > > java.lang.Number (NO_SOURCE_FILE:7) > > > Neither is this. According to the docs "long-and-smaller integers > > promote in all cases, even when given integer primitives" with the > > prime ops. > > > Something I did wrong? > > Yes, you are in the wrong branch. Get the 'equal' branch. > > Rich Cool. This works correctly now. Super nice, too :) user=> (defn ^:static fib ^long [^long n] (if (<= n 1) 1 (+ (fib (dec n)) (fib (- n 2) #'user/fib user=> (time (fib 38)) "Elapsed time: 601.563589 msecs" 63245986 And this returns the error you specified: user=> (defn fac [n] (loop [n n r 1] (if (zero? n) 1 (recur (dec' n) (*' r n) java.lang.RuntimeException: java.lang.IllegalArgumentException: recur arg for primitive local: r is not matching primitive, had: java.lang.Number, needed: long (NO_SOURCE_FILE:13) Which is really poor behavior. Having numeric literals default to primitive types is great but this behavior does not match the documentation. To quote: "long-and-smaller integers promote in all cases, even when given integer primitives" with the prime ops. Any behavior other than that is confusing and essentially means the programmer cannot have dependable bindings (to be fair, boxing at the start of the loop fixes it but whatever). I fully acknowledge that the reason I don't understand 'primitive-by-default locals' may be because I'm so new at Clojure (and functional programming), so take this suggestion with a grain of salt: locals should default to the type specified in code (which means the prime ops should cause the rebind to auto-box/upgrade like the documentation dictates) or have sensible defaults (like literals default to primitives (which is awesome!)). At least that makes sense to me in a dynamic context. > Really? It seems tedious to me. Don't you get tired of saying int i = > 42 in Java, when you know full well the compiler knows 42 is an int? I > do, and Clojure is competing with languages that infer the right types > without the redundancy. Agree 100%, which is partly why this silly loop/recur behavior needs to be fixed. -- 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: Enhanced Primitive Support
On Jun 19, 2010, at 1:05 PM, Tim Daly wrote: (proclaim (speed 3) (safety 0)) is verbose? Telling the compiler in one place that you care about boxing speed, such as (declare (x unboxed)) seems to me to be a very direct way to tell the compiler to choose +' vs + everywhere that 'x' occurs. This means that "it just works" code does not need additional unboxing overhead. It also means that "make it fast" code is marked in a single place. And the form can be dynamically computed so you can adapt to the platform. It has the additional factor that common lispers will "get it". I understand that it does not fit with your current model of using inline typing. For a pervasive change like fast numerics the inline typing or library-based typing is, to my mind, a bit more cumbersome than 'proclaim' and 'declare' but that's probably because of my common lisp background. Type hinting feels to me like using symbol-property machinery in common lisp. I don't want to get into it here, but the CL model in this area is quite cumbersome and opaque, IMO. What precisely will (proclaim (speed 3) (safety 0)) do? And of course, that is never enough, this from the CL spec: (defun often-used-subroutine (x y) (declare (optimize (safety 2))) (error-check x y) (hairy-setup x) (do ((i 0 (+ i 1)) (z x (cdr z))) ((null z)) ;; This inner loop really needs to burn. (declare (optimize speed)) (declare (fixnum i)) )) The (declare (fixnum i)) above being pertinent to this discussion vis- a-vis verbosity. Not to mention the wonderful 'the' (this also from the CL spec): (let ((i 100)) (declare (fixnum i)) (the fixnum (1+ i))) => 101 N.B. that the declaration of the type of i does not cover the result of 1+, which needs its own declaration. Never mind that trading runtime safety for speed is completely not on the table for Clojure. It is one of the great lies of CL that it is both safe and very fast. It is safe *or* very fast. Clojure code will remain verifiable and safe. The CL model is not something I want to emulate in Clojure. Point taken about the type hinting. OTOH, metadata type hints flow through macros, whereas the decoupled i and its declaration of the CL above are extremely difficult to transform together. Metadata flowing is really an enormous win, IMO. Rich -- 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: need help understanding two issues
I'll take a whack at it. > 1. How come APersistentMap$KeySet doesn't implement IPersistentSet? Because keys and vals are designed to return (lazy) sequences. More important, these two functions return those two sequences in the same order. The laziness avoids having to incur the overhead of creating the set structure, though if you want that you can just call (set (keys map)) as in your example. > > 2. I can't get clojure.set/project to work. All of the following throw > an exception: > > (clojure.set/project (keys {2 "two" 4 "four"}) #{2 3}) > (clojure.set/project (set (keys {2 "two" 4 "four"})) #{2 3}) > Yeah, I found the doc confusing as well. Here's an example: user> (ns user (:use clojure.set)) nil user> (project [{1 2, 2 4, 3 6}, {1 3, 2 6}] [1]) #{{1 3} {1 2}} So project seems to take a collection of maps, and "projects", or restricts them all on to the values specified in the second argument. Cheers 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
Re: Enhanced Primitive Support
(proclaim (speed 3) (safety 0)) is verbose? Telling the compiler in one place that you care about boxing speed, such as (declare (x unboxed)) seems to me to be a very direct way to tell the compiler to choose +' vs + everywhere that 'x' occurs. This means that "it just works" code does not need additional unboxing overhead. It also means that "make it fast" code is marked in a single place. And the form can be dynamically computed so you can adapt to the platform. It has the additional factor that common lispers will "get it". I understand that it does not fit with your current model of using inline typing. For a pervasive change like fast numerics the inline typing or library-based typing is, to my mind, a bit more cumbersome than 'proclaim' and 'declare' but that's probably because of my common lisp background. Type hinting feels to me like using symbol-property machinery in common lisp. In any case, keep up the good work. I'm impressed with Clojure. Tim Daly Rich Hickey wrote: On Jun 19, 2010, at 2:50 AM, Tim Daly wrote: Is it possible to follow the Common Lisp convention of proclaim/declaim/declare in order to specify types? It would be possible of course, but undesirable. We're trying to avoid that kind of verbosity. Rich -- 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
need help understanding two issues
Hi all, I have run into the following two issues over the last few days. I would appreciate insight/help/advice: 1. How come APersistentMap$KeySet doesn't implement IPersistentSet? (clojure.set/intersection (keys {2 "two" 4 "four"}) #{2 3}) java.lang.ClassCastException: clojure.lang.APersistentMap$KeySeq cannot be cast to clojure.lang.IPersistentSet So one must: (clojure.set/intersection (set (keys {2 "two" 4 "four"})) #{2 3}) ... which is redundant. Is there a better way? 2. I can't get clojure.set/project to work. All of the following throw an exception: (clojure.set/project (keys {2 "two" 4 "four"}) #{2 3}) (clojure.set/project (set (keys {2 "two" 4 "four"})) #{2 3}) Caused by: java.lang.ClassCastException: java.lang.Integer cannot be cast to java.util.Map ... and this one returns a result that I don't understand: (clojure.set/project {2 "two" 4 "four"} #{2 3}) #{{}} So perhaps I have misread what "xrel" is supposed to be, in the docs for clojure.set/project: clojure.set/project ([xrel ks]) Returns a rel of the elements of xrel with only the keys in ks I understand that one should use select-keys to get the submap for a given set of keys. But how come the map's key set is not set that plays well with the rest of clojure sets? Help very appreciated. Albert -- http://albert.rierol.net -- 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: Enhanced Primitive Support
On Jun 19, 2010, at 4:25 AM, Daniel wrote: Checked out the new prim branch to repeat some tests. user=> (defn ^:static fib ^long [^long n] (if (<= n 1) 1 (+ (fib (dec n)) (fib (- n 2) #'user/fib user=> (time (fib 38)) "Elapsed time: 4383.127343 msecs" 63245986 That's certainly not what I expected user=> (defn fact [n] (loop [n n r 1] (if (zero? n) 1 (recur (dec' n) (*' r n) #'user/fact user=> (fact 40) java.lang.ClassCastException: clojure.lang.Symbol cannot be cast to java.lang.Number (NO_SOURCE_FILE:7) Neither is this. According to the docs "long-and-smaller integers promote in all cases, even when given integer primitives" with the prime ops. Something I did wrong? Yes, you are in the wrong branch. Get the 'equal' branch. Rich -- 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: labrepl isn't a project in netbeans 6.8 - (Ubuntu 10.04)
Find the Maven plugin in the NB's plugin section and install if you don't have it. It *might* help. At least that's what fixed it for my NB installation. -- 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: classpath and require
Yes, exactly it was, also at some point I was trying examples/introduction (ruby's require like statement) instead of examples.introduction which all together made me lost. Thanks everybody for your help. Thanks, Mohammad On Sat, Jun 19, 2010 at 11:59 AM, Michael Wood wrote: > On 19 June 2010 17:46, Rob Lachlan wrote: > > I was wondering whether putting a dot in a directory on the classpath > > makes a difference. On OS X, the answer is no. Unfortunately, I > > don't have a windows machine, so I can't check for certain what the > > situation is there. > > No, rzezeski found the problem. > > Mohammad's CLASSPATH environment variable was correct, but he was > overriding that by using: > java -cp clojure-contrib.jar;clojure.jar clojure.main > > -- > Michael Wood > > -- > 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
Records forget they are records
Hello, I am working with Clojure for a university project and hit this problem http://paste.pocoo.org/show/227239/ I am trying to defines symbols from a map with keywords as keys and X as value (where X is usually a lambda or a Record), the first example does that ... (binder data) Creates the definitions but the record loose the Record type information. Using a macro works but I can not operated on the whole collection, have tried multiple options including doseq but all hit different issues. >From the chat it seems that a record evals to map and is the reason why the function approach fails (thx AWizzArd). Is this intended or did I just hit an under construction sign? Any suggestions? best regards, Oscar -- 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: Enhanced Primitive Support
Checked out the new prim branch to repeat some tests. user=> (defn ^:static fib ^long [^long n] (if (<= n 1) 1 (+ (fib (dec n)) (fib (- n 2) #'user/fib user=> (time (fib 38)) "Elapsed time: 4383.127343 msecs" 63245986 That's certainly not what I expected user=> (defn fact [n] (loop [n n r 1] (if (zero? n) 1 (recur (dec' n) (*' r n) #'user/fact user=> (fact 40) java.lang.ClassCastException: clojure.lang.Symbol cannot be cast to java.lang.Number (NO_SOURCE_FILE:7) Neither is this. According to the docs "long-and-smaller integers promote in all cases, even when given integer primitives" with the prime ops. Something I did wrong? -- 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: classpath and require
Correction, it worked.. On Fri, Jun 18, 2010 at 6:19 PM, Mohammad Khan wrote: > No, it didn't work.. what else I could be missing.. > > > On Fri, Jun 18, 2010 at 5:56 PM, Rob Lachlan wrote: > >> Whoops, that should read: >> >> java -cp c:\clojure-contrib\clojure-contrib.jar;c:\clojure >> \clojure.jar;c: >> \projects.clj clojure.main >> >> On Jun 18, 2:51 pm, Rob Lachlan wrote: >> > have you tried starting with: >> > >> > c:\clojure-contrib\clojure-contrib.jar;c:\clojure\clojure.jar;c: >> > \projects.clj clojure.main >> > >> > On Jun 18, 2:00 pm, Mohammad Khan wrote: >> > >> > >> > >> > > C:\Projects.clj>java -cp >> > > c:\clojure-contrib\clojure-contrib.jar;c:\clojure\clojure.jar >> clojure.main >> > > Clojure 1.1.0-alpha-SNAPSHOT >> > > user=> (require 'examples.introduction) >> > > java.io.FileNotFoundException: Could not locate >> > > examples/introduction__init.class or examples/introduction.clj on >> > > classpath: (NO_SOURCE_FILE:0) >> > > user=> >> > >> > > C:\Projects.clj>echo %CLASSPATH% >> > > C:\Projects.clj;C:\clojure;C:\clojure-contrib >> > > C:\Projects.clj>dir examples\introduction.clj >> > > Volume in drive C is xxx >> > > Volume Serial Number is - >> > > Directory of C:\Projects.clj\examples >> > >> > > 06/18/2010 04:52 PM40 introduction.clj >> > >1 File(s) 40 bytes >> > >0 Dir(s) xx,xxx,xxx bytes free >> > >> > > C:\Projects.clj> >> >> -- >> 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: Clojure script in the classpath
If you're just looking to run a script that happens to be on the classpath, you can do so by prepending an '@' character to the classpath-relative path to the script. So, if a directory foo is on your classpath, and a clojure file you'd like to run is at foo/bar/script.clj, then you can run it with: java -cp clojure.main @/bar/script.clj FWIW, this is noted in the documentation for clojure here: http://clojure.org/repl_and_main Cheers, - Chas On Jun 18, 2010, at 6:15 PM, Paul Moore wrote: I've just seen a couple of postings which, if I'm not mistaken, imply that it's possible to have a Clojure script in my classspath. Is that right? I come from a Python background (little or no Java experience) and the idea that anything other than .class or .jar files (or directories) could be on the classpath never occurred to me. Can anyone give me a complete example of how this works? (I probably need to get the file names and namespaces right, something I'm still struggling with - again the Java/JVM requirements for filenames that match classnames is a new concept for me). Could I have found anything about this on the web? The Java documentation (http://java.sun.com/javase/6/docs/technotes/tools/windows/classpath.html ) didn't mention anything other than classes/jars/zips/directories, and my Google skills didn't turn up anything clojure-specific. Thanks, Paul. -- 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: classpath and require
On 19 June 2010 17:46, Rob Lachlan wrote: > I was wondering whether putting a dot in a directory on the classpath > makes a difference. On OS X, the answer is no. Unfortunately, I > don't have a windows machine, so I can't check for certain what the > situation is there. No, rzezeski found the problem. Mohammad's CLASSPATH environment variable was correct, but he was overriding that by using: java -cp clojure-contrib.jar;clojure.jar clojure.main -- Michael Wood -- 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: Enhanced Primitive Support
The hard error has been restored: http://github.com/richhickey/clojure/commit/25165a9ccd1001fa7c4725a8219c4108803ae834 Rich On Jun 19, 2010, at 2:03 AM, Mark Engelberg wrote: I'm confused. In the latest scheme, what is the eventual plan for handling a recur to a loop element that was initialized with a primitive? Are boxed numbers automatically coerced to the primitive? Would a long be coerced to a double, or double to long? Under what scenarios will you get a warning, and when will you get an error? I think what troubles me the most about this loop/recur issue is that the semantics of recur depend completely on whether a variable is assigned a primitive or boxed numeric type. To know what the recur will do, you must know the type of the assigned value. This has always been the case, but in the current version of Clojure, provided you aren't using Java interop, it's relatively straightforward to know. Unless the variable or literal is explicitly cast to a primitive, it's not a primitive. But now, with the advent of static functions which can return primitives, it becomes more likely to not easily be able to determine this fact. If I say (loop [x (foo 2)]...) I have no way of knowing what's going to happen when I recur. Yes, I realize that you can run the function and use warnings/errors to find out. But I find it unsettling to have a commonly used code form with semantics I can't predict just by looking at it. It's attractive that the current proposal gives speed benefits to common cases with no additional annotation. But I personally place a higher value on being able to understand the semantics of my code when reading through it. I would prefer a version where loop requires some sort of explicit annotation on a variable if you want it to require a primitive upon recur. (Ideally, I'd probably want the annotation on the variable using a syntax that mirrors static functions, rather than the old technique of typecasting the initializer, since the whole typecasting system makes less sense now that literals and certain return values are already primitives. Unifying the syntax and semantics of using primitives in loops with the syntax and semantics of using primitives as inputs to static functions makes a lot of sense to me.) -- 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: classpath and require
I was wondering whether putting a dot in a directory on the classpath makes a difference. On OS X, the answer is no. Unfortunately, I don't have a windows machine, so I can't check for certain what the situation is there. Another issue: I ignored case-sensitivity in my answer above. Are windows paths ever case-sensitive? (silly question, I know, but I haven't worked with windows in a while.) Another question: If you run: java -cp "c:\clojure-contrib\clojure-contrib.jar;c:\clojure \clojure.jar;c:\projects.clj\examples" clojure.main can you then just do (require 'introduction) And do try it with quotes around the classpath. The dot in projects.clj might be like a space in that it could lead to a parsing error without quotes. Good luck Rob On Jun 19, 1:58 am, Rasmus Svensson wrote: > 2010/6/18 Mohammad Khan > > > > > > > C:\Projects.clj>java -cp > > c:\clojure-contrib\clojure-contrib.jar;c:\clojure\clojure.jar clojure.main > > Clojure 1.1.0-alpha-SNAPSHOT > > user=> (require 'examples.introduction) > > java.io.FileNotFoundException: Could not locate > > examples/introduction__init.class or examples/introduction.clj on > > classpath: (NO_SOURCE_FILE:0) > > user=> > > > C:\Projects.clj>echo %CLASSPATH% > > C:\Projects.clj;C:\clojure;C:\clojure-contrib > > C:\Projects.clj>dir examples\introduction.clj > > Volume in drive C is xxx > > Volume Serial Number is - > > Directory of C:\Projects.clj\examples > > > 06/18/2010 04:52 PM 40 introduction.clj > > 1 File(s) 40 bytes > > 0 Dir(s) xx,xxx,xxx bytes free > > > C:\Projects.clj> > > Hello! > > To me it looks like you have gotten the most things right. As I see you > understand, you must have clojure, clojure-contrib and the source on the > class path. However, how these are specified can be a bit tricky. There are > basically two cases: directories and jar files. > > When using jar files, the jar file itself must be in the class path, not the > directory which contains it. In our case, the entries would be > c:\clojure\clojure.jar and c:\clojure-contrib\clojure-contrib.jar, just as > you wrote. > > When using folders with clojure source files or ahead-of-time compiled > classes, the directory that contains the folder that represents the topmost > component of the namespace. For example, in your case the namespace > examples.introduction is stored in the file > C:\Projects.clj\examples\introduction.clj so the directory C:\Projects.clj\ > should be inlcuded in the class path. > > When Clojure loads the namespace examples.introduction, it will try to find > examples\introduction.clj in every directory (or jar file) in the class > path. The error you got is an indication that no matching file could be > found. > > On windows, the paths are delimited with semicolons, but on most other > platforms colons are used. That's why most examples will use colons. If the > paths in the class path contains spaces or other special characters, you > should enclose the thing in spaces, like this: > > java -cp "C:\path one\;C:\path two\" clojure.main > > From what I can tell, Rob's example should work. I'm not sure if a trailing > backslash is required for directories, but you could try with and without it > to see if it makes any difference. If that doesn't work, try renaming > projects.clj to something without a dot in it. Also, look carefully for > typos... > > I hope this helps... > > // raek -- 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
what replaces clojure.parallel?
Hi all, The http://clojure.org/other_libraries web page states that: "Parallel Processing" "The parallel library (namespace parallel, in parallel.clj) wraps the ForkJoin library. This lib is now deprecated." If the clojure.parallel is deprecated, what replaces it? Is it pcalls and pvalues in clojure.core? What other parallel computation constructs exist in clojure 1.2 beyond pmap, pcalls and pvalues? Pointers very appreciated. Albert -- http://albert.rierol.net -- 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: Enhanced Primitive Support
I definitely would like to see more people trying their code with primitive by default and talk about unexpected bugs and performance improvements. On Sat, Jun 19, 2010 at 3:43 PM, David Nolen wrote: > > "Most real world programs". You mean like Clojure itself? > -- 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: labrepl isn't a project in netbeans 6.8 - (Ubuntu 10.04)
Jared, There was another post about issues with netbeans. I am looking into why this is happening. On another note, labrepl uses clojure 1.2, but that is all handled via leiningen. Cheers, Aaron On Thu, Jun 17, 2010 at 11:10 PM, Jared wrote: > I was following the instructions to get labrepl up and running and hit > a snag. Netbeans does not recognize Samples/Clojure/Relevance > LabReplProject as a project. After creating it it does not appear in > the Projects window. So I go to File -> Open Project and click on > RelevanceLabRepl and hit Open Project. Instead of opening the project > it displays the subfolders. Also, when RelevanceLabRepl is selected it > does not display a name for Project Name:, and the box Open as Main > Project is grayed out. > > I do have a normal clojure project that I can open. I am using clojure > 1.0 if that matters. > > -- > 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: Enhanced Primitive Support
On Sat, Jun 19, 2010 at 5:13 AM, Mike Meyer < mwm-keyword-googlegroups.620...@mired.org> wrote: > > > Were those real world programs, or arithmetic benchmarks? Most real world > programs I see spend so little of their time doing arithmetic that making > the math an order of magnitude slower wouldn't make a noticeable difference > in overall runtime. > "Most real world programs". You mean like Clojure itself? Please look over the implementation of gvec before making statements like this: clojure.lang.IPersistentCollection (cons [this val] (if (< (- cnt (.tailoff this)) (int 32)) (let [new-tail (.array am (inc (.alength am tail)))] (System/arraycopy tail 0 new-tail 0 (.alength am tail)) (.aset am new-tail (.alength am tail) val) (new Vec am (inc cnt) shift root new-tail (meta this))) (let [tail-node (VecNode. (.edit root) tail)] (if (> (bit-shift-right cnt (int 5)) (bit-shift-left (int 1) shift)) ;overflow root? (let [new-root (VecNode. (.edit root) (object-array 32))] (doto ^objects (.arr new-root) (aset 0 root) (aset 1 (.newPath this (.edit root) shift tail-node))) (new Vec am (inc cnt) (+ shift (int 5)) new-root (let [tl (.array am 1)] (.aset am tl 0 val) tl) (meta this))) (new Vec am (inc cnt) shift (.pushTail this shift root tail-node) (let [tl (.array am 1)] (.aset am tl 0 val) tl) (meta this)) 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: Enhanced Primitive Support
Maybe it's only because I'm coming from Ruby, in which number promotion is automatic and everything is slow, but if I have to choose between correctness and performance as a *default*, I'll choose correctness every time. I think there's a good reason that GCC, for instance, makes you push the compiler harder with compiler flags if you want to squeeze extra performance out of a program and accept the corresponding brittleness that it often brings. I also always thought that the transparent promotion of arithmetic was one of the strongest selling points of Common Lisp. My impression has always been that performance of numerics is rarely the bottleneck in typical code (web stuff, text processing, network code etc), but that unexpected exceptions in such code are the source of a lot of programmer heartache. On the other hand, I think 99% of the cases in which I've had a number exceed a 64 bit value were also examples of errors that might as well have been exceptions because they indicated a flaw in the code. -- 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: Enhanced Primitive Support
On Jun 19, 2010, at 6:41 AM, Heinz N. Gies wrote: On Jun 19, 2010, at 4:12 , Rich Hickey wrote: I have to say I'm in the 'pay for what you use' camp - you need a box, you ask for one. If I don't (and neither do any of those loops), why should I have to do extra work to avoid it? - 42 I totally and wholeheartedly disagree, as long as there is a chance something goes wrong, and here is a lot of it, the default can not be we force people to know more - for example that they explicitly need to box things. And it is not even about longs and BigInts, doubles and Floats or what the java version means also come into play, how often do you mixed calculations because initializing 1 is shorter and more used for you then 1.0? This will now break your loop, make it crumble into dust and give you odd, unexpected and wrong results. Lets get away from the argument already cast and bring a new one. It is an impossible situation that the literal 1 in one place has a different meaning and behavior then in another place. This is in fact a show stopper, I'm serious, this would be worst then java. (* 1 0.2) -> works fine but (loop [n 1 r 1](if (zero? n) r (recur (dec n) (* r 0.2 does not because the 1 there is not the 1 in the upper example, that is so utterly wrong and horrible please think about it and think about how you'd sell someone he has to know where a literal means what, I can guarantee you this will keep many people from this wonderful language :(. As I told Mark, this was, and will again be, a hard error. I am telling you though, if you continue with these "show stopper", "will keep people from using Clojure" sky-is-falling histrionics, I will stop reading your messages. Rich -- 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: Enhanced Primitive Support
On Jun 19, 2010, at 6:39 AM, Jules wrote: I know nothing about the JVM, but I do know that on x86 you can handle fixnum -> bignum promotion fairly cheaply. You compile two versions of the code: one for bignums and one for fixnums. After an arithmetic instruction in the fixnum code you check if it overflowed, and if it did you switch to the bignum code. while(n < 10) { n = n + 1; } => while(n #< 10) { a = n #+ 1; if(overflow){ n = ToBignum(n); goto foo; } n = a; } while(n.lessthan(10)) { foo: n = n.add(1); } where #< and #+ are the fixnum versions of < and +, and lessthan and add are the bignum versions. Yeah it's slower than ignoring the overflow, but faster than tagged 31-bit fixnums and a whole lot faster than bignums. Can you convince the JVM to produce similar code? You can do things like that in a closed world of a few operators and types (although it gets unwieldy as the number of variables goes up). And of course, inside the math ops Clojure already does things like that. But that is not what we are dealing with here. This is an open system, where representational issues of functions, arguments and returns come into play. The 'operators' +, - etc are actually function calls - they are not special to the compiler. And your loop may also contain other function calls: while(n < 10) { foo(n) n = n + 1; } how do I know foo can handle the bigint once I've upgraded? How about this? while(n < 10) { n = foo(n) } Unless you have a tagged architecture you can't have boxed/unboxed arg/ return uniformity (and even then you lose some bits of range). Rich -- 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: Enhanced Primitive Support
On Jun 19, 2010, at 2:50 AM, Tim Daly wrote: Is it possible to follow the Common Lisp convention of proclaim/declaim/declare in order to specify types? It would be possible of course, but undesirable. We're trying to avoid that kind of verbosity. Rich -- 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: Enhanced Primitive Support
On Jun 19, 2010, at 2:03 AM, Mark Engelberg wrote: I'm confused. In the latest scheme, what is the eventual plan for handling a recur to a loop element that was initialized with a primitive? Are boxed numbers automatically coerced to the primitive? Would a long be coerced to a double, or double to long? Under what scenarios will you get a warning, and when will you get an error? I think what troubles me the most about this loop/recur issue is that the semantics of recur depend completely on whether a variable is assigned a primitive or boxed numeric type. To know what the recur will do, you must know the type of the assigned value. This has always been the case, but in the current version of Clojure, provided you aren't using Java interop, it's relatively straightforward to know. Unless the variable or literal is explicitly cast to a primitive, it's not a primitive. But now, with the advent of static functions which can return primitives, it becomes more likely to not easily be able to determine this fact. If I say (loop [x (foo 2)]...) I have no way of knowing what's going to happen when I recur. Yes, I realize that you can run the function and use warnings/errors to find out. But I find it unsettling to have a commonly used code form with semantics I can't predict just by looking at it. Sorry for the confusion. This is a part of the design subject to change. I had temporarily eased the error here in an effort to see the usage patterns. The current warning tells you what is going on, since the compiler always knows when it is using a primitive local. Restoring the error on recur mismatch will cover all of these cases, without requiring any sophisticated analysis. If you get it wrong, it won't compile, and will tell you quite explicitly why. The default (auto-primitives or always Objects) will follow the default for +, - etc. It's attractive that the current proposal gives speed benefits to common cases with no additional annotation. But I personally place a higher value on being able to understand the semantics of my code when reading through it. I would prefer a version where loop requires some sort of explicit annotation on a variable if you want it to require a primitive upon recur. (Ideally, I'd probably want the annotation on the variable using a syntax that mirrors static functions, rather than the old technique of typecasting the initializer, since the whole typecasting system makes less sense now that literals and certain return values are already primitives. Unifying the syntax and semantics of using primitives in loops with the syntax and semantics of using primitives as inputs to static functions makes a lot of sense to me.) Really? It seems tedious to me. Don't you get tired of saying int i = 42 in Java, when you know full well the compiler knows 42 is an int? I do, and Clojure is competing with languages that infer the right types without the redundancy. Loops are unlike static function arguments, in many ways. There is no context when defining the signature of a static function, and you are explicitly creating an interface for callers. By contrast, a loop is not an interface for anyone, and all possible context is present. Again, it is a matter of defaults, the non-default is going to have to be explicit, and you can just as easily be explicit that you want the loop argument to be an Object, either with (loop [^Object i 42] ...), (loop [i (num 42)] ...) or your (loop' [i 42] ...) idea. Everyone who is advocating for what the other side ought to do should be aware that if the default doesn't go their way, the other side will be them. Rich -- 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: Enhanced Primitive Support
On Jun 19, 2010, at 14:55 , Rich Hickey wrote: > > Yes, that's a bit Java-ish. All we care about here is returning the canonic > boxed representation of the number. It was suggested before that it is simple to allow automatic promotion, by compiling multiple versions. how about doing this? One version with primitives and one version with everything object boxed. This would (of cause mean) even if only one argument has to get boxed all others will to but it would give use speed and correctness. Would that be possible? -- 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: Enhanced Primitive Support
On Jun 18, 2010, at 11:47 PM, dmiller wrote: Yes, it's easy to imagine a world where people who want efficient code have to jump through hoops to get it. OTOH, you can just say (num some- expr) to force it to be boxed, if you want assurance of an Object initializer. Which will be the more common need? From the wiki page "Enhanced Primitive Support": * Note: this means that locals initialized with literals will have primitive type, e.g. (let [x 42] …), and especially: (loop [x 42] …). If you intend to recur with a non-primitive, init like this, (loop [x (num 42)] …) I'd like to ask for some consideration on any use of (num x). On the CLR side, it is unimplementable as documented, there being no equivalent in the CLR to Number. If a proposed use of num can be satisfied by this definition of num: (defn num {tag :object} [x] x) I can manage. I imagine this to be the case, but haven't had time to read all the new code. If you really mean to use a type that is a base type for all the primitive numeric types -- not going to happen on the CLR. Yes, that's a bit Java-ish. All we care about here is returning the canonic boxed representation of the number. Rich -- 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: Enhanced Primitive Support
> I think if we had them, promoting ops > should be the primed ones, and they would mostly be used in library Oops, I had meant the non-primed ops should support promotion. But tbh, I have mixed feelings about promotion. I haven't required bitint promotion myself, but having statically typed numeric vars, where the type of the vars is chosen by Clojure and it isn't obvious what that type is, seems potentially confusing. It is the issue of loop initialisers fixing the types of the loop variable slot that I'm more bothered about though. -- Dave -- 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: Enhanced Primitive Support
On Jun 19, 2010, at 14:18 , David Powell wrote: > > (loop [^int n 1 r 1](if (zero? n) r (recur (dec n) (* r 0.2 > > > Numeric literals would still produce primitives where possible, but > would get auto-boxed in loop initialisers. > > I think this option wouldn't have any nasty surprises. > +41 (would be 42 if it were ^long since it is the clojure type I think) This gives the option of make it fast if you know-what-you-are-doing(TM) which is great, and I certainly would use that myself :P but it still keeps the things simple and working for the default case. Regards, Heinz -- 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: Enhanced Primitive Support
Personally, I have no real interest in bigints, but I'm glad that they are there, and that arithmetic code supports them polymorphically. I'm not sure what I think regarding non-promoting numeric operators. They are ok, but they seem to add complexity to the language, and they don't look very newbie friendly. I think if we had them, promoting ops should be the primed ones, and they would mostly be used in library functions where performance is important. > but > (loop [n 1 r 1](if (zero? n) r (recur (dec n) (* r 0.2 > does not [work] This seems to be particularly nasty. Clojure is statically typing r on the assumption that just because the init value of r fits a primitive int, that it can never be anything else. Promoting operators do no good, because the variable slot for the loop var has already been assumed to be a primitive, so it isn't possible to promote it. Is there any possibility that loop variables could be assumed to be boxed numerics, unless type hinted to something else? So: (loop [^int n 1 r 1](if (zero? n) r (recur (dec n) (* r 0.2 Numeric literals would still produce primitives where possible, but would get auto-boxed in loop initialisers. I think this option wouldn't have any nasty surprises. -- Dave -- 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: Problems with URL params and http-agent
On 18 June 2010 23:54, Timothy Washington wrote: > That works, thanks. It's a bit weird because I did try just http encoding > the parameters before. But I obviously encoded the wrong characters, or > maybe used the wrong character encoding. Hmmm. > > Thanks :) No problem :) -- Michael Wood -- 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: Enhanced Primitive Support
On 19 June 2010 03:33, Rich Hickey wrote: > Turnabout is fair play, so I've produced a version that swaps the > defaults, still in the 'equal' branch: The issue of which behaviour should be the default aside, I think that I'd expect the *, + etc. ops to go with unannotated literals and the primed variants to go with explicit hinting, whereas now this seems not to be the case: (defn fact [n] (loop [n (num n) r (num 1)] (if (zero? n) r (recur (dec n) (* r n) This works for (fact 40), whereas the version with dec' and *' (and the (num ...) still in place) doesn't; I'd expect this to be reversed. In general, I'd expect the primed ops to be there for those who know what they're doing; same goes for explicit hinting. On 19 June 2010 04:12, Rich Hickey wrote: > I have to say I'm in the 'pay for what you use' camp - you need a box, you > ask for one. If I don't (and neither do any of those loops), why should I > have to do extra work to avoid it? The question is which desirable commodity Clojure programmers can expect to get for free and which is to be obtainable through voluntary banter: the sturdy boxes or the Potion of Speed +5. I'm used to paying for the PoS, but a sudden rise in the price of boxes seems unwarranted to me, especially if it only serves to lower the price of the PoS from a (prim ...) hint where the local is introduced to zero. I mean, this is no longer about "the free lunch", it's more about "the free dessert" which the power number crunchers surely do not need. I have a hunch that if (num ...) stays in and primitive is the default, people (I mean just about *everybody*) will only box things in the face of the first crash or *maybe* after developing a great intuitive feel for when that might be required. Of course there's going to be a period of frantic learning about numeric representations on the JVM etc. in between the crash and the boxing. And, um, whatever for...? Interestingly, the introductory materials on Clojure I've read so far tout the "don't worry about it" quality of Clojure's numerics as a benefit of the language. (The "don't worry about it" phrasing comes from "Programming Clojure".) I just mention this because I tend to think it reasonable to present that as a benefit. The idea of making a U-turn on this is surprising to me... Which is partly to say that I'm still evaluating it, though so far my intuition stays pretty firmly on the "don't worry about it"-is-good side. TLDR summary: I'm very excited about the latest equal; I'd definitely want the primed arithmetic ops to go with the hinted locals, whereas non-primed (basic) variants would do the right thing for the simplest, unhinted code (so which ops should get the primes in my eyes depends on whether boxing of locals is the default); my heart is still on the side of free sturdy boxes while I'm expecting to pay for the Potion of Speed. Sincerely, Michał -- 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: scala
For such a young language it has a big momentum. Did Scala have that after 2 years? On 18 Jun., 23:56, cageface wrote: > Quick disclaimer - there are a lot of things I like in Scala and I > think Odersky & crew have done some very impressive work bringing > functional language concepts to the VM and giving Java developers a > path forward. I also don't think Clojure vs x language battles are > very productive and don't want to encourage one. > > Anyway, I imagine my trajectory as a developer over the last 10 years > is pretty typical. I started out doing Java stuff but fell in love > with Ruby and Rails in 2004 and have been working almost entirely in > Ruby since. The idea that all that heavy, cumbersome Java cruft could > in many cases be dispensed with was a revelation and the discovery > that I could build software in a language that offered *no* compile > time error checking that was still robust was a very pleasant > surprise. > > Like a lot of Ruby hackers though, I also saw some warts in the > language and also remained curious about other approaches. Also like a > lot of Ruby hackers, the recent rise of new JVM languages has piqued > my interest, particularly Scala and Clojure. Scala seemed like a more > natural step from Ruby and my first experiences with it were > encouraging. It seemed to offer a lot of the expressiveness of Ruby > but with potentially much better performance and more robust runtime > and, intriguingly, static type checking. However, after writing a > handful of small but non-trivial programs in it the complexity lurking > under the surface started peeking through and the intricacies of the > type system and the significant complexity of the language itself > became more apparent. It started to feel like a step back to the > rigors of Java and heavyweight syntax and fights with the compiler. > The predominant Scala web platform, Lift, also seemed to have a very > heavy, enterprisey sort of "correctness" about it that felt > overengineered. > > So I bounced over to Clojure and its clean, elegant core and minimal, > flexible syntax seemed very refreshing. It felt much more in the > liberal, malleable spirit of Ruby. The functional stuff was a bit of a > stretch but it also seemed built on a simpler set of core concepts > than the featureful but complex Scala collections. > > Unfortunately there seems to be a lot more commercial momentum for > Scala though. It's still a blip compared to the mainstream languages > but I'm seeing more and more job posts mentioning it, and hardly any > for Clojure. I don't think Scala is a bad language overall, but I'm > not sure I'd dump Ruby for it. On the other hand, I can imagine > migrating most of my dev work over to Clojure with the right project. > Has anybody else wrestled with this choice? Any thoughts? -- 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: Enhanced Primitive Support
On Jun 19, 2010, at 4:12 , Rich Hickey wrote: > I have to say I'm in the 'pay for what you use' camp - you need a box, you > ask for one. If I don't (and neither do any of those loops), why should I > have to do extra work to avoid it? - 42 I totally and wholeheartedly disagree, as long as there is a chance something goes wrong, and here is a lot of it, the default can not be we force people to know more - for example that they explicitly need to box things. And it is not even about longs and BigInts, doubles and Floats or what the java version means also come into play, how often do you mixed calculations because initializing 1 is shorter and more used for you then 1.0? This will now break your loop, make it crumble into dust and give you odd, unexpected and wrong results. Lets get away from the argument already cast and bring a new one. It is an impossible situation that the literal 1 in one place has a different meaning and behavior then in another place. This is in fact a show stopper, I'm serious, this would be worst then java. (* 1 0.2) -> works fine but (loop [n 1 r 1](if (zero? n) r (recur (dec n) (* r 0.2 does not because the 1 there is not the 1 in the upper example, that is so utterly wrong and horrible please think about it and think about how you'd sell someone he has to know where a literal means what, I can guarantee you this will keep many people from this wonderful language :(. The default case for a language has to be the most intuitive version otherwise you end up with a mess of complex rules and special cases. It was said before, this is premature optimization in it's worst since it is forced on the user if they want or not. The priority has to be 'it works' later if it matters we can worry about 'it is fast' but this isn't working any more. Regards, Heinz -- 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: Enhanced Primitive Support
I know nothing about the JVM, but I do know that on x86 you can handle fixnum -> bignum promotion fairly cheaply. You compile two versions of the code: one for bignums and one for fixnums. After an arithmetic instruction in the fixnum code you check if it overflowed, and if it did you switch to the bignum code. while(n < 10) { n = n + 1; } => while(n #< 10) { a = n #+ 1; if(overflow){ n = ToBignum(n); goto foo; } n = a; } while(n.lessthan(10)) { foo: n = n.add(1); } where #< and #+ are the fixnum versions of < and +, and lessthan and add are the bignum versions. Yeah it's slower than ignoring the overflow, but faster than tagged 31-bit fixnums and a whole lot faster than bignums. Can you convince the JVM to produce similar code? Jules On Jun 19, 4:22 am, Rich Hickey wrote: > On Jun 18, 2010, at 10:18 PM, Mark Fredrickson wrote: > > > So far most of the action has concerned arithmetic ops (+, -, *, /). > > Will these new semantics include the bit-shift operators? I vote yes. > > My use cases for bit ops would benefit from primitive ops. > > > On a related note, my use cases call for silent overflow of bit shifts > > (pseudo random number generators). Will there be a way to disable > > overflow exceptions (either via a binding or through unchecked-* > > functions)? > > Yes, bit-ops will be made to align with whatever is done here. > > Rich > > > > > > > On Jun 18, 8:33 pm, Rich Hickey wrote: > >> Turnabout is fair play, so I've produced a version that swaps the > >> defaults, still in the 'equal' branch: > > >> Docs: > > >>https://www.assembla.com/wiki/show/b4-TTcvBSr3RAZeJe5aVNr/ > >> Enhanced_Pr... > > >> Code: > > >>http://github.com/richhickey/clojure/commit/ > >> 310534b8e7e7f28c75bb122b4... > > >> You can get the older arbitrary-precision default with this commit: > > >>http://github.com/richhickey/clojure/commit/ > >> 7652f7e935684d3c7851fbcad... > > >> I've also temporarily enabled a diagnostic (in both) that tells you > >> when you have a mismatch between a loop initializer and its recur > >> form. It goes off over a hundred times in Clojure itself, when using > >> the arbitrary precision default. In each case, the recur value is > >> needlessly being boxed, every iteration of a loop, for loops that > >> will > >> never be bigints; indexes, counters etc. I expect this will be very > >> typical of most code. But removing that useless overhead would be a > >> lot of tedious work. > > >> With the defaults swapped, only 2 warnings. > > >> Pay for what you use ... > > >> Rich > > >> On Jun 18, 4:52 pm, Rich Hickey wrote: > > >>> I've revised and enhanced the strategy, based upon the feedback > >>> here. > >>> I think it is a nice compromise. > > >>> Docs (see update section at the top) > > >>>https://www.assembla.com/wiki/show/b4-TTcvBSr3RAZeJe5aVNr/Enhanced_Pr > >>> ... > > >>> Code: > > >>>http://github.com/richhickey/clojure/commit/c79d28775e06b196ae1426f6c > >>> ... > > >>> Thanks to all for the feedback, keep it coming! > > >>> Rich > > >>> On Jun 17, 2010, at 4:13 PM, Rich Hickey wrote: > > I've been doing some work to enhance the performance, and unify the > semantics, of primitives, in three branches. I've started to > document > this work here: > > https://www.assembla.com/wiki/show/clojure/Enhanced_Primitive_Support > > Feedback welcome, > > Rich > > > -- > > 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: Enhanced Primitive Support
yes, when it will be released :-b. I can describe it though: it applied a stochastically a set of rewriting rules on trees (represented by records of records). To speed up, the activity of the rules in each subtree is cached in a Java weak hash table from one step to another. There is a bit of arithmetic involved everywhere, and around 2-3 double operations per function in the part choosing the instance of rule to apply. On Sat, Jun 19, 2010 at 10:28 AM, Mike Meyer < mwm-keyword-googlegroups.620...@mired.org> wrote: > > "Nicolas Oury" wrote: > > >I tried it on my program. Very few arithmetic, most of it with annotation. > >10% > > Can we see the source? > -- > Sent from my Android phone with K-9 Mail. Please excuse my brevity. > > -- > 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: Enhanced Primitive Support
"Nicolas Oury" wrote: >I tried it on my program. Very few arithmetic, most of it with annotation. >10% Can we see the source? -- Sent from my Android phone with K-9 Mail. Please excuse my brevity. -- 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: Enhanced Primitive Support
I tried it on my program. Very few arithmetic, most of it with annotation. 10%. On an arithmetic benchmark, it would be in te *10/*20 range. This 10% is orthogonal to what profiling shows. It just makes a lot of little improvements spread everywhere. That's why it couldn't be solved with annotation. On Sat, Jun 19, 2010 at 10:13 AM, Mike Meyer < mwm-keyword-googlegroups.620...@mired.org> wrote: > > "Nicolas Oury" wrote: > > >On the other hand, having boxed by default is a very significant slowdown > >(10% on the strange program I tried, that had already a lot of > annotations, > >probably 20% or more on most programs), that can never be addressed : you > >can't write annotations on every single line of your program. > > Were those real world programs, or arithmetic benchmarks? Most real world > programs I see spend so little of their time doing arithmetic that making > the math an order of magnitude slower wouldn't make a noticeable difference > in overall runtime. > > Which puts making numbers primitives by default squarely in the realm of > premature optimization. > -- > Sent from my Android phone with K-9 Mail. Please excuse my brevity. > > -- > 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: Enhanced Primitive Support
"Nicolas Oury" wrote: >On the other hand, having boxed by default is a very significant slowdown >(10% on the strange program I tried, that had already a lot of annotations, >probably 20% or more on most programs), that can never be addressed : you >can't write annotations on every single line of your program. Were those real world programs, or arithmetic benchmarks? Most real world programs I see spend so little of their time doing arithmetic that making the math an order of magnitude slower wouldn't make a noticeable difference in overall runtime. Which puts making numbers primitives by default squarely in the realm of premature optimization. -- Sent from my Android phone with K-9 Mail. Please excuse my brevity. -- 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: classpath and require
2010/6/18 Mohammad Khan > C:\Projects.clj>java -cp > c:\clojure-contrib\clojure-contrib.jar;c:\clojure\clojure.jar clojure.main > Clojure 1.1.0-alpha-SNAPSHOT > user=> (require 'examples.introduction) > java.io.FileNotFoundException: Could not locate > examples/introduction__init.class or examples/introduction.clj on > classpath: (NO_SOURCE_FILE:0) > user=> > > C:\Projects.clj>echo %CLASSPATH% > C:\Projects.clj;C:\clojure;C:\clojure-contrib > C:\Projects.clj>dir examples\introduction.clj > Volume in drive C is xxx > Volume Serial Number is - > Directory of C:\Projects.clj\examples > > 06/18/2010 04:52 PM40 introduction.clj >1 File(s) 40 bytes >0 Dir(s) xx,xxx,xxx bytes free > > C:\Projects.clj> > Hello! To me it looks like you have gotten the most things right. As I see you understand, you must have clojure, clojure-contrib and the source on the class path. However, how these are specified can be a bit tricky. There are basically two cases: directories and jar files. When using jar files, the jar file itself must be in the class path, not the directory which contains it. In our case, the entries would be c:\clojure\clojure.jar and c:\clojure-contrib\clojure-contrib.jar, just as you wrote. When using folders with clojure source files or ahead-of-time compiled classes, the directory that contains the folder that represents the topmost component of the namespace. For example, in your case the namespace examples.introduction is stored in the file C:\Projects.clj\examples\introduction.clj so the directory C:\Projects.clj\ should be inlcuded in the class path. When Clojure loads the namespace examples.introduction, it will try to find examples\introduction.clj in every directory (or jar file) in the class path. The error you got is an indication that no matching file could be found. On windows, the paths are delimited with semicolons, but on most other platforms colons are used. That's why most examples will use colons. If the paths in the class path contains spaces or other special characters, you should enclose the thing in spaces, like this: java -cp "C:\path one\;C:\path two\" clojure.main >From what I can tell, Rob's example should work. I'm not sure if a trailing backslash is required for directories, but you could try with and without it to see if it makes any difference. If that doesn't work, try renaming projects.clj to something without a dot in it. Also, look carefully for typos... I hope this helps... // raek -- 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: compiling the instructions of a simple vm into a function
There is two way to make a domain-specific language with a clojure back-end : - if you want the language to be an extension of Clojure, still to be used in a REPL or by clojure source -> you write macros. That's what I call embedded. There is a lot of litterature on Embedded Domain Specific Language in functional languages. (A *lot* in Haskell, for example) In this situation, eval is most of the time evil. - you want to read instructions that are very far from Clojure in a file and execute them. (Your case, not by choice but because of the ICFP specs). Then, eval is necessary. But you have to call it only once per compiled function, ideally, and never while executing the code (for performance). In your situation, I would write (defn compile-instruction [instructions] ...) Then, when reading the instructions (let [compiled-function (eval (compile-instruction (read-file...)))] ... Then, eval is called once, just after reading and compiling. And compiled-function is a real Clojure function. Have fun, Nicolas. On Sat, Jun 19, 2010 at 3:39 AM, Eugen Dück wrote: > Thanks Nicolas, > > your first variant resembles the generated code much closer than my > initial approach, which is great. I need the eval though, to be able > to pass in non literals. In my real program I'm reading the > instructions from a binary file. So if I want to be able to do > something like this: > > (def three-instructions '([+ 2 3] [- 0 1] [+ 1 0])) > (def compiled (compile-instructions three-instructions)) > > The macro would have to look like this: > > (defmacro compile-instructions > [instructions] > (let [memory (gensym "memory-")] > `(fn [~memory] > ~@(map (fn [[op m1 m2]] > `(aset ~memory ~m1 (~op (aget ~memory ~m1) (aget > ~memory ~m2 >(eval instructions) > > But I like your suggestion to turn it into a function even better: > > (defn compile-instructions > [instructions] > (let [memory (gensym "memory-")] >(eval > `(fn [~memory] > ~@(map (fn [[op m1 m2]] >`(aset ~memory ~m1 (~op (aget ~memory ~m1) (aget ~memory > ~m2 > instructions) > > And > > (def compiled (compile-instructions three-instructions))) > > just works as before. So I guess macros don't add any value here. > > > eval is evil, but eval is not evil is a compiler (you have to evaluate > the > > code you read). > > However eval is evil again in an "embedded compiler", when you use macro > to > > extend Clojure. > > What do you mean by "embedded compiler"? > > Eugen > > -- > 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: Basic toolset for non-Java programmer
Hello Paul Moore at "Sat, 19 Jun 2010 00:08:54 +0100" wrote: PM> - Build tools: There seem to be things like ant, maven, leiningen. How PM> do they relate to each other? Is there an "obvious" best answer or PM> should I be expecting to check them all out depending on my needs? In PM> that case, are there any good comparisons around? I use mvn or lein to build clojure code PM> - Profilers: Same sort of question - do IDEs offer this, are there PM> standalone tools? I use VisualVM to profile code PM> - Testing: I've not really got to the documentation on Clojure's own PM> testing tools, so maybe that's all I need, but are there testing PM> frameworks I should look at, that sort of thing? clojure.test provides enough features to test code PM> - Deployment: For simple standalone utilities, am I looking at bat PM> file wrappers (I'm on Windows mainly) to set classpath and the like? PM> Given that there are some annoying limitations with bat files (nasty PM> nesting behaviour, ugly console windows for GUI applications), are PM> there any commonly used better solutions? For web applications, I PM> gather that a servlet container (all that fancy J2EE stuff :-)) and PM> something like compojure is a good place to start. For non-web PM> long-running services, is it still reasonable to use an application PM> server, or should I be looking at something to wrap a Clojure app up PM> as a Windows service (something like "Java Service Wrapper" PM> (http://wrapper.tanukisoftware.org/doc/english/download.jsp) came up PM> for me on a Google search)? I use procrun from apache commons daemon project to run clojure app on windows as service. All works fine, except case when you need to load resources manually. See ticket #379 in Clojure's Assembly for more details To build installers I use izpack from maven -- With best wishes, Alex Ott, MBA http://alexott.blogspot.com/http://alexott.net/ http://alexott-ru.blogspot.com/ Skype: alex.ott -- 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: Enhanced Primitive Support
On Sat, Jun 19, 2010 at 3:12 AM, Rich Hickey wrote: > > I have to say I'm in the 'pay for what you use' camp - you need a box, you > ask for one. If I don't (and neither do any of those loops), why should I > have to do extra work to avoid it? > > Rich > > > +1. It is often very easy to spot integers that can grow above 10^18. Again, > 95% of number variables that someone will write in his life never will attain that because they are somehow referring to a ressource, either in the computer (counter, indices) or in the real world. So, except for scientific programming, fact, fib and ackerman, that's not a problem. (For scientific programming, I argue people should know what to do with numbers). I still would like to have a real world example were it is hard to predict and to solve. On the other hand, having boxed by default is a very significant slowdown (10% on the strange program I tried, that had already a lot of annotations, probably 20% or more on most programs), that can never be addressed : you can't write annotations on every single line of your program. So, we take a 10/30% speed hit, that won't be solved, mainly because we want people writing their first Fib or fact function not to have an exception thrown. I think people can handle this level of complexity. If boxed is the default, I advocate at least a flag allowing to change that (and possibly allowing int as a default for embedded stuff). Most problem with semantic changing flag disappear if the flags have an order. It is close to choosing the size of your heap on the command -line, which is a semantic-changing run-time flag... -- 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: Enhanced Primitive Support
On 18.06.2010, at 15:31, Nicolas Oury wrote: > In this situation, I would rather have some kind of toggle > *use-bigints-by-default* (defaulted to false) used by the compiler. > Then, if someone needs big integers, he can switch the toggle and recompile > everything. > You wouldn't have to change the libraries ns. I don't think it's a good idea to have a compiler switch change the semantics of number handling. > As for being predictable, if you have numbers that can be bigger than 10^19, > you would probably know it in advance. > (indices, counters and the like don't grow that big) True, but that's on a variable-by-variable basis. Konrad. -- 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 / Common Lisp Question
Clojure is an amazing piece of work. I'm interested in Clojure for the concurrency. I'm also interested in the immutable data structure work. Someone needs to write a paper about the performance characteristics of immutable structures when the whole structure changes. That is, what are the performance comparisons of mutable/immutable for various sorts? I'm using Clojure as a "console front end" to our huge Java project. Rather than writing Java programs to generate test or output I write Clojure. Rich Hickey's insightful videos have caused me to stop writing loops whenever possible. For me this is the same level of "thinking-change" that happened when I moved to using "Structured Programming" rather than GOTO (in Fortran). Rich needs to write a paper called "Loops considered harmful" Common lisp, however, gives me precise machine-level to massive function semantics, e.g. (car ...) is a machine pointer and (integrate ...) is a huge function but I can freely mix them in (integrate (car ...)). I don't feel the same "one-ness" in Clojure/Java. In general, I'm a common lisp bigot :-) Tim Daly rob levy wrote: As an informal survey of people who use both Clojure and Common Lisp for different projects, what do you see as the main determining factors behind your choice to use either Clojure or Common Lisp for a project, given the present state of Clojure. Let's only assume we are talking about projects you completely own and have complete freedom to do what you want with. Common lisp: Compiled on the processor, fast. Reader macros. Quality, not quantity of libraries. Multi-paradigm programming with no nudging -- programmer has freedom to be insane/bizarre in ways Clojure makes hard (see Let Over Lambda for examples) Downsides: Hard to deploy. -- but not a problem as server side of web app Can't run on on GAE. -- need to run a server or rent/maintain virtual server. Limited to native librares, though they tend to be awesome. Clojure: Neat concurrency stuff. Better deployment. Can run on Google App Engine. (maybe ABCL can too, but I wouldn't want to use that personally). Lots of Java libraries, many more than for CL. Increasing a large number of awesome native libraries. Downsides: As server side of web app in apache, less straigtforward requires Tomcat, Java crud. Java interop is great-- but Java itself sucks! There is an impedance mismatch of language semantics. The nudging of paradigm/idiom makes many things easier in Common Lisp. Lots of cool benefits of Clojure (such as any/all GUI stuff for example) depend on crufty Java nonsense you must contend with. So, for me at this point, if I don't need interesting concurrent stuff, and I do my own hosting, Common Lisp in Hunchentoot or mod lisp still seems like a superior web development approach. On the other hand if I am doing desktop apps, applets, want to use GAE, etc, Clojure seems better. I feel like as time goes on we will be more abstracted away from the pain of Java. Any thoughts on how you make your decision for specific projects? Thanks, 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 -- 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: Enhanced Primitive Support
On 18.06.2010, at 15:20, Rich Hickey wrote: > Which then begs the questions: > > - how will someone 'protect' themselves from libraries written using fastmath? Using fastmath or not would be part of the library specification. Or, in general, of the documentation for each individual function. It may not matter at all for the user of some functions, but be very important for others. > - similar looking code will change semantics when the ns switch is made - > seems dangerous as it might violate the presumptions of the original authors. That is true, but it is true for any strategy to introduce new maths semantics into Clojure. As soon as there are two, there is a risk for confusion. And even if there is only one but different from the one in the past, there is a risk for confusion as well. Konrad. -- 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