Re: Speeding up equals using the cached hash code?
That's might be an interesting trade-of to try. It is really good when big data structures are nearly equal. The comparison is linear but the comparaison once you know the hash is O(1) with a high probability. It is bad on very different structure, if you force a hash. Ideally, the equals method could hash as it goes. When 2 structures are equal, their hashes would be known. If not, by comparing the numbero fo elments hashed to the count, the implementation could decide whether or not to continue hashing... On Wed, Aug 4, 2010 at 10:40 PM, sune.simonsen sune.simon...@gmail.com wrote: I was looking around the Clojure source code and noticed that the persistent immutable collections caches their hash codes. The java doc says the following about the equals method: (http:// download.oracle.com/javase/1.4.2/docs/api/java/lang/Object.html) If two objects are equal according to the equals(Object) method, then calling the hashCode method on each of the two objects must produce the same integer result. So I was thinking, wouldn't it be possible to use the cached hash code to rule out cases of equals where equals returns false? public boolean equals(Object obj){ ... if (_hash != -1 hashCode() != obj.hashCode()) { return false; } ... } This might of cause result in an extra call to hashCode(), so I don't know if it is worth it. Maybe some internal functionality could be added, to ask the collections if their hash code has been cached. What are your thoughts? Kind regards Sune Simonsen -- 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: existing idiom for delaying a future ?
Hi Laurent, On Aug 5, 9:41 am, Laurent PETIT laurent.pe...@gmail.com wrote: Here is what I've come up in my head : * create a datastructure with 2 fields, one holding a future, one holding a delay. the future will wait for n millisecs, and then force the delay. * The datastructure will accept the future API and delegate all calls to the future,*except* for the deref call which will bypass the future and deref the delay instead What do you think ? How about this: (def *parser* (agent nil)) (defn schedule-parse [] (send *parser* (constantly (delay (parse-stuff) (defn trigger-parse ([] (trigger-parse 0) ([delay-in-millis] (future (when (pos? delay-in-millis) (Thread/sleep delay-in-millis)) (let [result (promise)] (send *parser* #(do (deliver result @%) %))) @result) In the instantaneous case it creates an unnecessary future, but this is the same with your approach as I understand it. One could save that if one drops the requirement to implement the future API on the return value. Or one wraps up the return value in a proxy implementing the future API with no-ops + deref. The agent coordinates scheduled parser runs. Changing the buffer schedules a new parse run. In between any trigger-parse uses the cached one. Does that make sense? Sincerely Meikel -- 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: existing idiom for delaying a future ?
2010/8/5 Meikel Brandmeyer m...@kotka.de Hi Laurent, On Aug 5, 9:41 am, Laurent PETIT laurent.pe...@gmail.com wrote: Here is what I've come up in my head : * create a datastructure with 2 fields, one holding a future, one holding a delay. the future will wait for n millisecs, and then force the delay. * The datastructure will accept the future API and delegate all calls to the future,*except* for the deref call which will bypass the future and deref the delay instead What do you think ? How about this: (def *parser* (agent nil)) (defn schedule-parse [] (send *parser* (constantly (delay (parse-stuff) (defn trigger-parse ([] (trigger-parse 0) ([delay-in-millis] (future (when (pos? delay-in-millis) (Thread/sleep delay-in-millis)) (let [result (promise)] (send *parser* #(do (deliver result @%) %))) @result) In the instantaneous case it creates an unnecessary future, but this is the same with your approach as I understand it. One could save that if one drops the requirement to implement the future API on the return value. Or one wraps up the return value in a proxy implementing the future API with no-ops + deref. The agent coordinates scheduled parser runs. Changing the buffer schedules a new parse run. In between any trigger-parse uses the cached one. Does that make sense? Looks complex. One think I forgot to mention is that by making the datastructure implement the future API, I *desire* the ability to cancel the future while it's still sleeping : so that when the user types fast, intemediate values are not computed at all. -- 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: existing idiom for delaying a future ?
ok. Now one more question please: your solution looks also slightly more complex from the user's perspective: he has to deal with the *parser* object and the future object (returned by schedule-parse). So the question is: what does your solution provide that the sketch of my solution does not ? Do you see my solution harder to implement ? Do you see your solution more generic ? Smth else ? 2010/8/5 Meikel Brandmeyer m...@kotka.de Hi Laurent, On Aug 5, 11:07 am, Laurent PETIT laurent.pe...@gmail.com wrote: Looks complex. Hmm.. Maybe we can save the agent and use an atom? (For some reason, I thought, it wouldn't work with an atom...) (def *parser* (atom nil)) (defn schedule-parse [] (reset! *parser* (delay (parse-stuff (defn trigger-parse ([] (trigger-parse 0)) ([delay-in-millis] (future (when (pos? delay-in-millis) (Thread/sleep delay-in-millis)) @@*parser*))) One think I forgot to mention is that by making the datastructure implement the future API, I *desire* the ability to cancel the future while it's still sleeping : so that when the user types fast, intemediate values are not computed at all. Well. You can. If you cancel the trigger-parse future while it's sleeping, the parse run will not be triggered. You can even put more logic into schedule-parse and only update the delay in the atom if really necessary. Sincerely Meikel -- 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.comclojure%2bunsubscr...@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: processing sequence/collection of functions
Functions are fist-class-objects in Clojure. You can pass them around just like every other object. You can even create anonymous functions and pass them to a function. (The function for anonymous functions is called fn) On Thu, Aug 5, 2010 at 7:10 AM, foop1 bsmd...@gmail.com wrote: Hmm interesting , Thank you for your answer. On Aug 5, 12:36 am, Miki miki.teb...@gmail.com wrote: Hello, Does anyone of you can say as to how to pass in a collection/sequence of functions as input? for ex pass in a vector /sequence [ function1 function2 function3] at the other end it would read in the vector and execute those functions user= (defn f1 [] 1) #'user/f1 user= (defn f2[] 2) #'user/f2 user= (defn f3[] 3) #'user/f3 user= (def v [f1 f2 f3]) #'user/v user= (map #(%) v) (1 2 3) HTH, -- Miki -- 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 -- Moritz Ulrich Programmer, Student, Almost normal Guy http://www.google.com/profiles/ulrich.moritz -- 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: existing idiom for delaying a future ?
Hi, On Aug 5, 11:34 am, Laurent PETIT laurent.pe...@gmail.com wrote: Now one more question please: your solution looks also slightly more complex from the user's perspective: he has to deal with the *parser* object and the future object (returned by schedule-parse). So the question is: what does your solution provide that the sketch of my solution does not ? Do you see my solution harder to implement ? Do you see your solution more generic ? Smth else ? I'm hesitant to extend existing types in a way, so that they behave slightly different. This ties your program to the API of the type at hand. If that changes, your program is broken until you update your code. So I prefer using existing things first. If it doesn't work out, one can still do a custom thing. That said: man! What was I thinking? (def *parsed-code* (atom nil)) ; First concern: ; When characters are typed we have to re-parse things. ; But delay it! (defn char-typed-hook [] (reset! *parsed-code* (delay (parse-code ; Second concern: ; Use the parsed information. ; This will trigger the delayed parsing. (defn mark-errors [] (let [parsed-code (force @*parsed-code*)] ...)) ; Third concern: ; Parse things AOT in a calm second to provide better user experience. ; THIS IS A SIDE-EFFECT! You might want to store the future somewhere ; to be able to cancel it, etc. (defn cursor-hold-hook [] (future (Thread/sleep trigger-delay) (force @*parsed-code*))) Consumers trigger the delay if necessary. In such a case the future becomes a no-op. The future itself can still be canceled if necessary. The consumers don't have to care about the future at all. Does this make more sense? Sincerely Meikel -- 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: Speeding up equals using the cached hash code?
If two objects are equal, they must have same hash code. But it does not imply the other way too. Two objects having the same hash code may be not equal (see, hash collision). So this approach may give false positives. - Abhinav On Thu, Aug 5, 2010 at 1:45 PM, Nicolas Oury nicolas.o...@gmail.com wrote: That's might be an interesting trade-of to try. It is really good when big data structures are nearly equal. The comparison is linear but the comparaison once you know the hash is O(1) with a high probability. It is bad on very different structure, if you force a hash. Ideally, the equals method could hash as it goes. When 2 structures are equal, their hashes would be known. If not, by comparing the numbero fo elments hashed to the count, the implementation could decide whether or not to continue hashing... On Wed, Aug 4, 2010 at 10:40 PM, sune.simonsen sune.simon...@gmail.com wrote: I was looking around the Clojure source code and noticed that the persistent immutable collections caches their hash codes. The java doc says the following about the equals method: (http:// download.oracle.com/javase/1.4.2/docs/api/java/lang/Object.html) If two objects are equal according to the equals(Object) method, then calling the hashCode method on each of the two objects must produce the same integer result. So I was thinking, wouldn't it be possible to use the cached hash code to rule out cases of equals where equals returns false? public boolean equals(Object obj){ ... if (_hash != -1 hashCode() != obj.hashCode()) { return false; } ... } This might of cause result in an extra call to hashCode(), so I don't know if it is worth it. Maybe some internal functionality could be added, to ask the collections if their hash code has been cached. What are your thoughts? Kind regards Sune Simonsen -- 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.comclojure%2bunsubscr...@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.comclojure%2bunsubscr...@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: 2 links for beginners
http://steve-yegge.blogspot.com/2006/04/lisp-is-not-acceptable-lisp.html a prophetic writing ... great ! thank you mike. -- 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: existing idiom for delaying a future ?
2010/8/5 Laurent PETIT laurent.pe...@gmail.com Hello, My problem: the user types in the ccw's editor. Each time she types, there's an opportunity to reparse the editor's content. But the reparse is not always necessary, especially when the types a symbol. So I could use a delay to only force the repase on-demand. On the other end, when the user stops typing for a while (say 500 ms), it could be interesting to automatically trigger a reparse, so that the next editor command implying a fresh parsetree seems to be instantaneous. So I could use a delayed future. A future which would do nothing the first n milliseconds (eg n = 500 ms), and then do its job. But I can't use a classic future, 'cause I want the deref of this delayed future to bypass the pause. Is there an classical idiom for this ? Here is what I've come up in my head : * create a datastructure with 2 fields, one holding a future, one holding a delay. the future will wait for n millisecs, and then force the delay. * The datastructure will accept the future API and delegate all calls to the future,*except* for the deref call which will bypass the future and deref the delay instead I had a first working version which implemented both clojure.lang.IDeref and java.util.concurrent.Future, but as Meikel said, the less I'll depend on several external interfaces, the better. And I also had the problem of not knowing what to implement for certain methods of java.util.concurrent.Future. e.g. what should the behaviour of (get [_ timeout _]) be ? timeout on what. This was silly. So I wrote this final version which only implements IDeref (which I want to), and also adds a cancel/isCancelled property a-la java.util.concurrent.Future but not tied to the Future interface : (ns delay.util) (defprotocol Cancellable (isCancelled [this]) (cancel [this])) (defn timed-delay [pause fun] (let [d (delay (fun)) f (future (Thread/sleep pause) @d)] (reify clojure.lang.IDeref (deref [_] @d) delay.util.Cancellable (isCancelled [_] (future-cancelled? f)) (cancel [_] (future-cancel f) What about this ? -- 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: existing idiom for delaying a future ?
2010/8/5 Meikel Brandmeyer m...@kotka.de Hi, On Aug 5, 11:34 am, Laurent PETIT laurent.pe...@gmail.com wrote: Now one more question please: your solution looks also slightly more complex from the user's perspective: he has to deal with the *parser* object and the future object (returned by schedule-parse). So the question is: what does your solution provide that the sketch of my solution does not ? Do you see my solution harder to implement ? Do you see your solution more generic ? Smth else ? I'm hesitant to extend existing types in a way, so that they behave slightly different. not types, but interfaces. But you're right, and there were some java.util.concurrent.Future methods which did not make sense in my first design, so I implemented my own Cancellable protocol, resulting in cleaner semantics. This ties your program to the API of the type at hand. If that changes, your program is broken until you update your code. So I prefer using existing things first. If it doesn't work out, one can still do a custom thing. That said: man! What was I thinking? (def *parsed-code* (atom nil)) ; First concern: ; When characters are typed we have to re-parse things. ; But delay it! (defn char-typed-hook [] (reset! *parsed-code* (delay (parse-code ok ; Second concern: ; Use the parsed information. ; This will trigger the delayed parsing. (defn mark-errors [] (let [parsed-code (force @*parsed-code*)] ...)) ; Third concern: ; Parse things AOT in a calm second to provide better user experience. ; THIS IS A SIDE-EFFECT! You might want to store the future somewhere ; to be able to cancel it, etc. (defn cursor-hold-hook [] (future (Thread/sleep trigger-delay) (force @*parsed-code*))) ok. What I don't like with your approach is that the behaviour isn't embedded in a reusable fashion, but must be applied throughout the user codebase, with these (force @) calls. But you proved your point. Consumers trigger the delay if necessary. In such a case the future becomes a no-op. The future itself can still be canceled if necessary. The consumers don't have to care about the future at all. Does this make more sense? yes, our solutions are quite similar, mine being a bit more encapsulated, but adds this Cancellable protocol. Hmm, in the end, what do you prefer ? -- 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: Speeding up equals using the cached hash code?
2010/8/5 abhinav sarkar abhinav.sar...@gmail.com If two objects are equal, they must have same hash code. But it does not imply the other way too. Two objects having the same hash code may be not equal (see, hash collision). So this approach may give false positives. No, you didn't read the thread carefully enough. The OP is suggesting a fail-fast approach based on the comparison of the hash-code, not a success-fast (which as you said, is not possible from hash codes) - Abhinav On Thu, Aug 5, 2010 at 1:45 PM, Nicolas Oury nicolas.o...@gmail.comwrote: That's might be an interesting trade-of to try. It is really good when big data structures are nearly equal. The comparison is linear but the comparaison once you know the hash is O(1) with a high probability. It is bad on very different structure, if you force a hash. Ideally, the equals method could hash as it goes. When 2 structures are equal, their hashes would be known. If not, by comparing the numbero fo elments hashed to the count, the implementation could decide whether or not to continue hashing... On Wed, Aug 4, 2010 at 10:40 PM, sune.simonsen sune.simon...@gmail.com wrote: I was looking around the Clojure source code and noticed that the persistent immutable collections caches their hash codes. The java doc says the following about the equals method: (http:// download.oracle.com/javase/1.4.2/docs/api/java/lang/Object.html) If two objects are equal according to the equals(Object) method, then calling the hashCode method on each of the two objects must produce the same integer result. So I was thinking, wouldn't it be possible to use the cached hash code to rule out cases of equals where equals returns false? public boolean equals(Object obj){ ... if (_hash != -1 hashCode() != obj.hashCode()) { return false; } ... } This might of cause result in an extra call to hashCode(), so I don't know if it is worth it. Maybe some internal functionality could be added, to ask the collections if their hash code has been cached. What are your thoughts? Kind regards Sune Simonsen -- 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.comclojure%2bunsubscr...@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.comclojure%2bunsubscr...@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.comclojure%2bunsubscr...@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: existing idiom for delaying a future ?
Hi, On Aug 5, 2:14 pm, Laurent PETIT laurent.pe...@gmail.com wrote: (ns delay.util) (defprotocol Cancellable (isCancelled [this]) (cancel [this])) (defn timed-delay [pause fun] (let [d (delay (fun)) f (future (Thread/sleep pause) @d)] (reify clojure.lang.IDeref (deref [_] @d) delay.util.Cancellable (isCancelled [_] (future-cancelled? f)) (cancel [_] (future-cancel f) What about this ? This looks ok, I think. At least better than hijacking the future. However, I'm still the opinion, that you mix up concerns here. Cancellable somehow implies that it stops whatever the thing is doing. But it has no influence on the deref. To me this would be surprising. For me the whole future thing is a side-effect which is not relevant to the consumer of the parsed code. It is a convenience which can be tracked separately from the actual delay. Sincerely Meikel -- 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: Speeding up equals using the cached hash code?
Just a quick follow-up. This is a big plus when you know (from meta reasons) that most successful equality tests will come from the identical? part of the test. Then you have most of the fail in O(1) by hashing and most of the successes in O(1) with identical?. While still being correct and complete. What I have in mind is one of my recurring rant about Hash Consing. http://en.wikipedia.org/wiki/Hash_consing With a clever caching of hash value and comparing the hash, you can have an equality for records that is O(1) with high expectation on any hash-consed values, while still being correct for non hash-consed value. Best, Nicolas. -- 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: existing idiom for delaying a future ?
2010/8/5 Meikel Brandmeyer m...@kotka.de Hi, On Aug 5, 2:14 pm, Laurent PETIT laurent.pe...@gmail.com wrote: (ns delay.util) (defprotocol Cancellable (isCancelled [this]) (cancel [this])) (defn timed-delay [pause fun] (let [d (delay (fun)) f (future (Thread/sleep pause) @d)] (reify clojure.lang.IDeref (deref [_] @d) delay.util.Cancellable (isCancelled [_] (future-cancelled? f)) (cancel [_] (future-cancel f) What about this ? This looks ok, I think. At least better than hijacking the future. However, I'm still the opinion, that you mix up concerns here. Cancellable somehow implies that it stops whatever the thing is doing. But it has no influence on the deref. To me this would be surprising. For me the whole future thing is a side-effect which is not relevant to the consumer of the parsed code. It is a convenience which can be tracked separately from the actual delay. Yes, maybe I'm putting too much ... will need to think about it again But I don't understand your usage of the expression side-effect. e.g. the instance given will play well in any situation. Even if you call cancel on it, this will not prevent following calls to deref to succeed. So holders of a reference to it can use it without knowing at all that the instance also implements the Cancellable interface. Maybe it's the names that must be adjusted. After all I was wrong, it's not a delayed delay I've written. How to rename things ? timed-delay - ? delay.util.Cancellable - ? isCancelled - ? cancel - ? -- 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: 2 links for beginners
Here's a nice commentary by fogus on Yegge's piece: http://blog.fogus.me/2009/02/06/yegge-clojure-arc-and-lolita-or-days-of-future-past/ For all intents and purposes, Clojure’s creator Rich Hickey is Arc’s Torvalds quipped on by Mr. Yegge. On Aug 5, 8:08 am, faenvie fanny.aen...@gmx.de wrote: http://steve-yegge.blogspot.com/2006/04/lisp-is-not-acceptable-lisp.html a prophetic writing ... great ! thank you mike. -- 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: existing idiom for delaying a future ?
2010/8/5 Laurent PETIT laurent.pe...@gmail.com 2010/8/5 Meikel Brandmeyer m...@kotka.de Hi, On Aug 5, 2:14 pm, Laurent PETIT laurent.pe...@gmail.com wrote: (ns delay.util) (defprotocol Cancellable (isCancelled [this]) (cancel [this])) (defn timed-delay [pause fun] (let [d (delay (fun)) f (future (Thread/sleep pause) @d)] (reify clojure.lang.IDeref (deref [_] @d) delay.util.Cancellable (isCancelled [_] (future-cancelled? f)) (cancel [_] (future-cancel f) What about this ? This looks ok, I think. At least better than hijacking the future. However, I'm still the opinion, that you mix up concerns here. Cancellable somehow implies that it stops whatever the thing is doing. But it has no influence on the deref. To me this would be surprising. For me the whole future thing is a side-effect which is not relevant to the consumer of the parsed code. It is a convenience which can be tracked separately from the actual delay. Yes, maybe I'm putting too much ... will need to think about it again But I don't understand your usage of the expression side-effect. e.g. the instance given will play well in any situation. Even if you call cancel on it, this will not prevent following calls to deref to succeed. So holders of a reference to it can use it without knowing at all that the instance also implements the Cancellable interface. Maybe it's the names that must be adjusted. After all I was wrong, it's not a delayed delay I've written. Or is it ? I'm getting self-confused this afternoon :-) -- 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: 2 links for beginners
That is the most unsubstantiated, moronic piece of writing I've ever read in my life. I can't really tell what he's attacking, he's just swinging some dick-shaped sword around trying to hit stuff. i do not agree ... its clear that the article is a rant, does not go deep and misses important facts (does not mention any of the great features that clojure implements). but he unerringly focuses on the most critical point of clojure: its dependency on a host-runtime and a host-language. to abstract away from esp. java-language seems an crucial thing ... and moves like clojure in clojure address this. jvm7's dynamic-language-support will also mitigate that point. one thing i would like to know is: what are the advantages of common-lisp running on a lisp-machine compared to clojure running on the jvm ? have a successful time -- 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: existing idiom for delaying a future ?
Hi, On Aug 5, 2:47 pm, Laurent PETIT laurent.pe...@gmail.com wrote: Yes, maybe I'm putting too much ... will need to think about it again I don't want to talk you into something. I just have a different view. But I don't understand your usage of the expression side-effect. Ok. Why do I think that the future stuff is a side-effect. The main concern is to parse the code for augmented user experience while editing (error markers, etc.). So, when a character is typed the we parse the code and update eg. an atom. Convenience functions can now easily access the parsed code. This is step 1. However parsing things after every entered key does a lot of unnecessary work. Hence we delay the parsing until it is really required. This makes general editing faster, but the convenience functions might become slower due to the parsing which has now to be done. This is step 2. Now as a complete nice-to-have convenience thing, we decide to pre- parse the code in a calm second when the user pauses from typing. Then the parsing would be done by the time a convenience functionality is called and the editor doesn't feel sluggish because of too much (unnecessary) work. On the other hand the pre-parser has to be stopped if the user continues typing. It is completely independent from the consumer of the parsed code. (It's just in so far dependent, that it should parse the code again, when this was already triggered by a consumer. But this we get for free with the delay). This is step 3. This is the scenario as I understand it. How would I implement step 3? I start with the cursor-hold-hook, which is triggered when the user stops typing. There the future with the sleep gets fired off and stored in a suitable place. (def *parsed-code* (atom nil)) (def *pre-parser* (atom nil)) (defn cursor-hold-hook [] (reset! *pre-parser* (future (Thread/sleep pre-parse-delay) (reset! *pre-parser* nil) (force @*parsed-code* Then three things might happen during the sleep: - Nothing. - The user enters more text. - A convenience functionality is invoked. In the first case, the future does its thing. The code gets pre- parsed. Everything is fine. In the second case, the force will become a no-op. So we can just as well leave the future alone. In the third case, we might want to save the parsing because the user typed more text. So we modify the char-entered-hook. (defn char-entered-hook [] (when @*pre-parser (swap! *pre-parser* #(do (when % (future-cancel %)) nil))) (reset! *parsed-code* (delay (parse-code The real situation in the eclipse editor might be different. So this might not be applicable. Or it might be a bad idea in the first place. Anyway: that's how I would do it. It is a pretty straight-forward translation of how I understand the situation. After all I was wrong, it's not a delayed delay I've written. How to rename things ? timed-delay - ? delay.util.Cancellable - ? isCancelled - ? cancel - ? timed-delay - ok Cancellable - Timed isCancelled - countdown-stopped? cancel - stop-countdown Maybe like this? I dunno. I'm bad at names. :] Sincerely Meikel -- 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: Records can't be treated as functions anymore
If records implemented IFn, you could treat them as collections, which they are not. There is an asymmetry here: Maps can be used as (impoverished but easy) records, but the reverse is not true: (:foo x); x is logically a record (though might be a map for simplicity). (x :foo); x is a collection (not a record, entity, etc.) Records not implementing IFn forces you to do what you should do anyway -- access records with the keyword first. Stu Hi BG, It is a common mistake to think that callability, corresponding to the clojure.lang.IFn interface, is part of the persistent map contract (I've done it myself, as did many others a Conj labs :). It is not. It is actually just a feature of clojure.lang.PersistentHashMap (and the other clojure map implementations). While I get that part, I wonder why records do not implement IFn, it'd be convenient if they did. -- 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: existing idiom for delaying a future ?
Woops. It's just in so far dependent, that it should parse the code again, when this was already triggered by a consumer. I mean't: it should *not* parse the code again ... -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Records can't be treated as functions anymore
2010/8/5 Stuart Halloway stuart.hallo...@gmail.com If records implemented IFn, you could treat them as collections, which they are not. Isn't the fact of making records associative for easing the use of treating them as collections ? user= (assoc (user.R. 1) :b 2) #:user.R{:a 1, :b 2} user= (seq (user.R. 1)) ([:a 1]) user= There is an asymmetry here: Maps can be used as (impoverished but easy) records, but the reverse is not true: (:foo x) ; x is logically a record (though might be a map for simplicity). (x :foo) ; x is a collection (not a record, entity, etc.) Records not implementing IFn forces you to do what you should do anyway -- access records with the keyword first. Stu Hi BG, It is a common mistake to think that callability, corresponding to the clojure.lang.IFn interface, is part of the persistent map contract (I've done it myself, as did many others a Conj labs :). It is not. It is actually just a feature of clojure.lang.PersistentHashMap (and the other clojure map implementations). While I get that part, I wonder why records do not implement IFn, it'd be convenient if they did. -- 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.comclojure%2bunsubscr...@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: existing idiom for delaying a future ?
2010/8/5 Meikel Brandmeyer m...@kotka.de Hi, On Aug 5, 2:47 pm, Laurent PETIT laurent.pe...@gmail.com wrote: Yes, maybe I'm putting too much ... will need to think about it again I don't want to talk you into something. I just have a different view. But I don't understand your usage of the expression side-effect. Ok. Why do I think that the future stuff is a side-effect. The main concern is to parse the code for augmented user experience while editing (error markers, etc.). So, when a character is typed the we parse the code and update eg. an atom. Convenience functions can now easily access the parsed code. This is step 1. However parsing things after every entered key does a lot of unnecessary work. Hence we delay the parsing until it is really required. This makes general editing faster, but the convenience functions might become slower due to the parsing which has now to be done. This is step 2. Now as a complete nice-to-have convenience thing, we decide to pre- parse the code in a calm second when the user pauses from typing. Then the parsing would be done by the time a convenience functionality is called and the editor doesn't feel sluggish because of too much (unnecessary) work. On the other hand the pre-parser has to be stopped if the user continues typing. It is completely independent from the consumer of the parsed code. (It's just in so far dependent, that it should parse the code again, when this was already triggered by a consumer. But this we get for free with the delay). This is step 3. This is the scenario as I understand it. How would I implement step 3? This is exactly the scenario, yes. I start with the cursor-hold-hook, which is triggered when the user stops typing. There the future with the sleep gets fired off and stored in a suitable place. (def *parsed-code* (atom nil)) (def *pre-parser* (atom nil)) (defn cursor-hold-hook [] (reset! *pre-parser* (future (Thread/sleep pre-parse-delay) (reset! *pre-parser* nil) (force @*parsed-code* Then three things might happen during the sleep: - Nothing. - The user enters more text. - A convenience functionality is invoked. In the first case, the future does its thing. The code gets pre- parsed. Everything is fine. In the second case, the force will become a no-op. So we can just as well leave the future alone. In the third case, we might want to save the parsing because the user typed more text. So we modify the char-entered-hook. (defn char-entered-hook [] (when @*pre-parser (swap! *pre-parser* #(do (when % (future-cancel %)) nil))) (reset! *parsed-code* (delay (parse-code Yes, np, I took a careful look at your code, and it indeed seems to work. My point was that by providing different interfaces/protocols to different users, it's more an implementation detail than anything else if they have the same object or not. I don't expect my users to program on types, but on protocols/interfaces. (ok, in this case, i'm my own user, so I have indeed some expectations on me ;) ) The real situation in the eclipse editor might be different. So this might not be applicable. Or it might be a bad idea in the first place. Anyway: that's how I would do it. It is a pretty straight-forward translation of how I understand the situation. Yes. Maybe I was generalizing too much the situation. Maybe not :) After all I was wrong, it's not a delayed delay I've written. How to rename things ? timed-delay - ? delay.util.Cancellable - ? isCancelled - ? cancel - ? timed-delay - ok Cancellable - Timed isCancelled - countdown-stopped? cancel - stop-countdown Maybe like this? I dunno. I'm bad at names. :] Hm, well .. let's say not worse than 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
Programming Clojure: Snake: update-positions: What does the do do here?
ORIGINAL (defn update-positions [snake apple] (dosync (if (eats? @snake @apple) (do (ref-set apple (create-apple)) (alter snake move :grow)) (alter snake move))) nil) WITHOUT do (defn update-positions [snake apple] (dosync (if (eats? @snake @apple) ((ref-set apple (create-apple))-- Removed do from here (alter snake move :grow)) (alter snake move))) nil) Both versions work, so why does the do on line 4 contribute? -- 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: Records can't be treated as functions anymore
Maybe Im just getting stuck on semantics, but I'm confused. If maps are collections, and records function as maps, aren't records also collections? Steve On Thu, Aug 5, 2010 at 8:52 AM, Stuart Halloway stuart.hallo...@gmail.comwrote: If records implemented IFn, you could treat them as collections, which they are not. There is an asymmetry here: Maps can be used as (impoverished but easy) records, but the reverse is not true: (:foo x) ; x is logically a record (though might be a map for simplicity). (x :foo) ; x is a collection (not a record, entity, etc.) Records not implementing IFn forces you to do what you should do anyway -- access records with the keyword first. Stu Hi BG, It is a common mistake to think that callability, corresponding to the clojure.lang.IFn interface, is part of the persistent map contract (I've done it myself, as did many others a Conj labs :). It is not. It is actually just a feature of clojure.lang.PersistentHashMap (and the other clojure map implementations). While I get that part, I wonder why records do not implement IFn, it'd be convenient if they did. -- 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.comclojure%2bunsubscr...@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: Programming Clojure: Snake: update-positions: What does the do do here?
Hi, On Aug 5, 4:18 pm, michele michelemen...@gmail.com wrote: ORIGINAL (defn update-positions [snake apple] (dosync (if (eats? @snake @apple) (do (ref-set apple (create-apple)) (alter snake move :grow)) (alter snake move))) nil) WITHOUT do (defn update-positions [snake apple] (dosync (if (eats? @snake @apple) ((ref-set apple (create-apple)) -- Removed do from here (alter snake move :grow)) (alter snake move))) nil) Both versions work, so why does the do on line 4 contribute? It is an accident that the second version works. Probably create-apple returns a map. Replacing (create-apple) with - say - 5, should trigger an exception. The do is required, because you can have only one expression for the then-branch or the else-branch in an if. If you want to have several expressions in a branch you need a do, which executes each expression in a row and returns the value of the last one. So this is mostly useful for side effects. In the example the side effects are the calls to ref-set and alter. Hope this helps. Sincerely Meikel -- 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: Programming Clojure: Snake: update-positions: What does the do do here?
ORIGINAL (defn update-positions [snake apple] (dosync (if (eats? @snake @apple) (do (ref-set apple (create-apple)) (alter snake move :grow)) (alter snake move))) nil) WITHOUT do (defn update-positions [snake apple] (dosync (if (eats? @snake @apple) ((ref-set apple (create-apple)) -- Removed do from here (alter snake move :grow)) (alter snake move))) nil) Both versions work, so why does the do on line 4 contribute? The do is there because if takes the form (if pred then else), and in this case the then is supposed to be two statements executed for side-effects. Removing the do form would actually result in something different than above; what you've done is replaced a (do form1 form2) with a ((form1) form2). In other words, you're calling (ref-set apple (create-apple)), and then *calling the return value of that* with the parameter (alter snake move :grow). Why this seems to work I don't know without looking at the snake example, but presumably (create-apple) creates an apple, and presumably an apple is something which is callable (probably a map, so that when called with the return-value of (alter snake move) it simply returns nil or some value associated with that key). -- / 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: Speeding up equals using the cached hash code?
I believe the code already does what you are asking about. Are you talking about something like this? http://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/APersistentMap.java#L57 this? http://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/APersistentSet.java#L58 and this? http://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/APersistentVector.java#L45 Or am I misunderstanding the OP? Paul http://paul.stadig.name/ (blog) 703-634-9339 (mobile) pjstadig (twitter) p...@stadig.name (jabber) Projects http://www.mycrossoverpoint.com/ http://www.reformedchurches.info/ On Thu, Aug 5, 2010 at 8:38 AM, Nicolas Oury nicolas.o...@gmail.com wrote: Just a quick follow-up. This is a big plus when you know (from meta reasons) that most successful equality tests will come from the identical? part of the test. Then you have most of the fail in O(1) by hashing and most of the successes in O(1) with identical?. While still being correct and complete. What I have in mind is one of my recurring rant about Hash Consing. http://en.wikipedia.org/wiki/Hash_consing With a clever caching of hash value and comparing the hash, you can have an equality for records that is O(1) with high expectation on any hash-consed values, while still being correct for non hash-consed value. Best, Nicolas. -- 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.comclojure%2bunsubscr...@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: Records can't be treated as functions anymore
In a word, no. :-) Records and maps share an API. Maps can be used as anonymous records. Records generally should not be used as maps. My address information is a record (whether you bother to create Address or just throw it into a plain ol' map). Everyone's address information keyed by SSN is a map. Stu Maybe Im just getting stuck on semantics, but I'm confused. If maps are collections, and records function as maps, aren't records also collections? Steve On Thu, Aug 5, 2010 at 8:52 AM, Stuart Halloway stuart.hallo...@gmail.com wrote: If records implemented IFn, you could treat them as collections, which they are not. There is an asymmetry here: Maps can be used as (impoverished but easy) records, but the reverse is not true: (:foo x) ; x is logically a record (though might be a map for simplicity). (x :foo) ; x is a collection (not a record, entity, etc.) Records not implementing IFn forces you to do what you should do anyway -- access records with the keyword first. Stu Hi BG, It is a common mistake to think that callability, corresponding to the clojure.lang.IFn interface, is part of the persistent map contract (I've done it myself, as did many others a Conj labs :). It is not. It is actually just a feature of clojure.lang.PersistentHashMap (and the other clojure map implementations). While I get that part, I wonder why records do not implement IFn, it'd be convenient if they did. -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -- 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: Programming Clojure: Snake: update-positions: What does the do do here?
2010/8/5 michele michelemen...@gmail.com ORIGINAL (defn update-positions [snake apple] (dosync (if (eats? @snake @apple) (do (ref-set apple (create-apple)) (alter snake move :grow)) (alter snake move))) nil) WITHOUT do (defn update-positions [snake apple] (dosync (if (eats? @snake @apple) ((ref-set apple (create-apple))-- Removed do from here (alter snake move :grow)) (alter snake move))) nil) Both versions work, so why does the do on line 4 contribute? I'm not sure you're asking the right question. The right question should be (IMO) why did the do disappear in second version. My guess is that second version is working by chance : the return value of (ref-set) may be a map, which is callable, thus gets called for the return value of the alter call as the key. the first version with the do is the right one. The do wraps the 2 sides effect ref-set and alter function calls as the succesful test branch of the if -- 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: Programming Clojure: Snake: update-positions: What does the do do here?
Adding to what Meikel said: A warning sign that the latter version is incorrect is the double open parens: ((ref-set ... Double open parens are fairly rare in Clojure code. Stu Hi, On Aug 5, 4:18 pm, michele michelemen...@gmail.com wrote: ORIGINAL (defn update-positions [snake apple] (dosync (if (eats? @snake @apple) (do (ref-set apple (create-apple)) (alter snake move :grow)) (alter snake move))) nil) WITHOUT do (defn update-positions [snake apple] (dosync (if (eats? @snake @apple) ((ref-set apple (create-apple))-- Removed do from here (alter snake move :grow)) (alter snake move))) nil) Both versions work, so why does the do on line 4 contribute? It is an accident that the second version works. Probably create-apple returns a map. Replacing (create-apple) with - say - 5, should trigger an exception. The do is required, because you can have only one expression for the then-branch or the else-branch in an if. If you want to have several expressions in a branch you need a do, which executes each expression in a row and returns the value of the last one. So this is mostly useful for side effects. In the example the side effects are the calls to ref-set and alter. Hope this helps. Sincerely Meikel -- 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: java.lang.OutOfMemoryError
the entire sequence being in memory. However, if you retain the head of the sequence elsewhere, you will see the same effect. I don't think my function retains the head? Please correct me if I am wrong. Not that I can see but I don't have the full context. I tried reproducing just now and I was not able to trigger any memory use beyond what I expected. Do you have a self-contained fully working example that you can point to (preferably with your actual data files + code, but otherwise just the code)? -- / 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
clojure compiler
Ok, this question is not about clojure itself, just a doubt I have. Clojure uses the ASM library to compile code to jvm bytecode. Let's suppose I created the foo.clj and bar.clj source files. The ns foo in foo.clj depends on the functions of bar in bar.clj. How the compiler manages file dependencies? Islon -- 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
(java.io BufferedReader FileReader) versus [clojure.contrib.duck-streams :only (read-lines)]
Hi, I don't understand why this doesn't work: (ns dpa (:gen-class) (:use [incanter.core :only ( matrix )] [clojure.core :only ( defn doseq line-seq println with-open )] [clojure.contrib.string :only ( blank? substring? )] (:import (java.io BufferedReader FileReader))) (defn process-dpa-file This makes the matrix of CA coordinates from a pdb file. [pdb-file chains] (def hold-coords []) ((with-open [rdr (BufferedReader. (FileReader. pdb-file))] (doseq [^String line (line-seq rdr)] ;; Make sure the file line is the correct length ;; We only want the atom entries ;; We don't want any repeated measurements for an atom ;; Is it a CA? ;; Are we using this chain? (if (and (= (.length line) 80) (= (str (.substring line 0 4) (.substring line 26 27) (.substring line 13 15)) ATOM CA) (substring? (.substring line 21 22) chains)) ;; This are the CA coordinates (def hold-coords (into hold-coords [ (Double. (.substring line 30 37)) (Double. (.substring line 38 45)) (Double. (.substring line 46 53)) ] ) (matrix hold-coords 3))) dpa (def my-mat (process-dpa-file /Users/daviddreisigmeyer/MyStuff/ DPA_release_12-JUL-2010/1RD8.pdb A) ) No message. [Thrown class java.lang.NullPointerException] Restarts: 0: [QUIT] Quit to the SLIME top level Backtrace: 0: dpa$process_dpa_file.invoke(NO_SOURCE_FILE:1) 1: clojure.lang.AFn.applyToHelper(AFn.java:165) 2: clojure.lang.AFn.applyTo(AFn.java:151) 3: clojure.lang.Compiler$InvokeExpr.eval(Compiler.java:2901) 4: clojure.lang.Compiler$DefExpr.eval(Compiler.java:361) 5: clojure.lang.Compiler.eval(Compiler.java:5424) 6: clojure.lang.Compiler.eval(Compiler.java:5386) 7: clojure.core$eval.invoke(core.clj:2382) 8: swank.commands.basic$eval_region.invoke(basic.clj:47) 9: swank.commands.basic$eval_region.invoke(basic.clj:37) 10: swank.commands.basic$eval799$listener_eval__800.invoke(basic.clj: 71) 11: clojure.lang.Var.invoke(Var.java:365) 12: dpa$eval9236.invoke(NO_SOURCE_FILE) 13: clojure.lang.Compiler.eval(Compiler.java:5419) 14: clojure.lang.Compiler.eval(Compiler.java:5386) 15: clojure.core$eval.invoke(core.clj:2382) 16: swank.core$eval_in_emacs_package.invoke(core.clj:90) 17: swank.core$eval_for_emacs.invoke(core.clj:237) 18: clojure.lang.Var.invoke(Var.java:373) 19: clojure.lang.AFn.applyToHelper(AFn.java:169) 20: clojure.lang.Var.applyTo(Var.java:482) 21: clojure.core$apply.invoke(core.clj:540) 22: swank.core$eval_from_control.invoke(core.clj:97) 23: swank.core$eval_loop.invoke(core.clj:102) 24: swank.core$spawn_repl_thread$fn__484$fn__485.invoke(core.clj:307) 25: clojure.lang.AFn.applyToHelper(AFn.java:159) 26: clojure.lang.AFn.applyTo(AFn.java:151) 27: clojure.core$apply.invoke(core.clj:540) 28: swank.core$spawn_repl_thread$fn__484.doInvoke(core.clj:304) 29: clojure.lang.RestFn.invoke(RestFn.java:398) 30: clojure.lang.AFn.run(AFn.java:24) 31: java.lang.Thread.run(Thread.java:637) But, this does work: (defn process-dpa-file This makes the matrix of CA coordinates from a pdb file. [pdb-file chains] (def hold-coords []) (doseq [^String line (read-lines pdb-file)] ;; Make sure the file line is the correct length ;; We only want the atom entries ;; We don't want any repeated measurements for an atom ;; Is it a CA? ;; Are we using this chain? (if (and (= (.length line) 80) (= (str (.substring line 0 4) (.substring line 26 27) (.substring line 13 15)) ATOM CA) (substring? (.substring line 21 22) chains)) ;; This are the CA coordinates (def hold-coords (into hold-coords [ (Double. (.substring line 30 37)) (Double. (.substring line 38 45)) (Double. (.substring line 46 53)) ] (matrix hold-coords 3)) dpa (def my-mat (process-dpa-file /Users/daviddreisigmeyer/MyStuff/ DPA_release_12-JUL-2010/1RD8.pdb A) ) #'dpa/my-mat I'd certainly appreciate any comments on the code in general. I only have a Matlab/R/Fortran 95 background. Thanks, -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: 2 links for beginners
Steve Yegge is badly mis-informed. Large real programs have been written entirely in lisp. I am the lead developer on Axiom which is a very large lisp project (about 1 million things of code) to do computer algebra. The help system and graphics were implemented in C but browsers did not exist at the time (1970s). These are being reimplemented in lisp using Firefox and the canvas facility. In the past I helped develop a product for building rule-based programs which was sold by IBM. It was entirely in lisp. I helped develop an expert system (FAME, a Finance and Marketing Expert) to price and sell IBM mainframe hardware. It was written entirely in lisp. I developed a language (KROPS) which was a symmetric representation of a knowledge language (KREP, Knowledge Representation) and a rule-based language (OPS5 A rule-based language). It was entirely in lisp. I developed a robot planning program to build and assemble objects from their computer-aided design descriptions (BOXER - A Design- to-Build system). It was entirely in lisp. Those are the systems I personally helped develop in lisp. I know of many more large lisp programs. Google just bought a company that developed in lisp. I have worked commercially in over 60 languages. Lisp is, by far, the fastest, easiest, and most flexible language. I am currently working in Java to re-implement an algorithm I prototyped in lisp. If I replace all of the required curly-braces and semicolons in Java with parens it turns out that the Java program has more parens than the lisp program. The lisp program is 20 lines, the Java program has crossed 100 lines and is still growing. Non-lispers often complain that there are a lack of lisp libraries. But if I contrast the lisp code I wrote with the Java code I find that I need things in Java that I don't need in lisp. For instance: In Java I need a graph library (JGraphT, about 10,000 lines of code if I remove comments). But in lisp I just embed the graph as part of the code making circular structures. In Java I need factory objects, visitors, and other such pieces of design patterns. In lisp, I have never needed to write a factory. The whole visitor pattern becomes a 1-line (map...) call. To a lisper design patterns are like dress patterns in sewing. If you can't sew (program) you can still make something to use by copying a pattern. But you can hardly consider yourself a Taylor (programmer). So, yes, lisp does not HAVE a lot of libraries. But what people miss is that lisp doesn't NEED libraries. Why have a graph library when you can just embed the graph naturally in the data? When I wear my Java hat I search for libraries to do what I want. When I wear my lisp hat I simply do what I need. I can't remember when I needed a library. So, to a lisper, libraries have the flavor of crutches. Having a large set of libraries (crutches) is not a feature. I won't go on about macros (where Steve has no idea what he is talking about) or CLOS (where Steve has no idea what he is talking about) or any of the other points he tries to make. Steve Yegge is clearly not a lisper. On the subject of lisp, I would not consider him an authority worth quoting. Instead I recommend watching the youtube MIT course on the Structure and Interpretation of Computer Programs: http://www.youtube.com/watch?v=2Op3QLzMgSY Tim Daly faenvie wrote: http://steve-yegge.blogspot.com/2006/04/lisp-is-not-acceptable-lisp.html a prophetic writing ... great ! thank you mike. -- 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
Hiring Clojure developers at Runa
Check us out here: http://www.workatruna.com/ -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: (java.io BufferedReader FileReader) versus [clojure.contrib.duck-streams :only (read-lines)]
Hi, Dave Why do you use 2 parenthesis before with-open in the first variant? And, as I know, it's not good practice to use def inside functions. Use let instead. I also advice you to split your program to smaller functions. Can you describe, what your program must do? Because don't understand :( On Thu, Aug 5, 2010 at 9:28 PM, Dave david.dreisigme...@gmail.com wrote: Hi, I don't understand why this doesn't work: (ns dpa (:gen-class) (:use [incanter.core :only ( matrix )] [clojure.core :only ( defn doseq line-seq println with-open )] [clojure.contrib.string :only ( blank? substring? )] (:import (java.io BufferedReader FileReader))) (defn process-dpa-file This makes the matrix of CA coordinates from a pdb file. [pdb-file chains] (def hold-coords []) ((with-open [rdr (BufferedReader. (FileReader. pdb-file))] (doseq [^String line (line-seq rdr)] ;; Make sure the file line is the correct length ;; We only want the atom entries ;; We don't want any repeated measurements for an atom ;; Is it a CA? ;; Are we using this chain? (if (and (= (.length line) 80) (= (str (.substring line 0 4) (.substring line 26 27) (.substring line 13 15)) ATOM CA) (substring? (.substring line 21 22) chains)) ;; This are the CA coordinates (def hold-coords (into hold-coords [ (Double. (.substring line 30 37)) (Double. (.substring line 38 45)) (Double. (.substring line 46 53)) ] ) (matrix hold-coords 3))) dpa (def my-mat (process-dpa-file /Users/daviddreisigmeyer/MyStuff/ DPA_release_12-JUL-2010/1RD8.pdb A) ) No message. [Thrown class java.lang.NullPointerException] Restarts: 0: [QUIT] Quit to the SLIME top level Backtrace: 0: dpa$process_dpa_file.invoke(NO_SOURCE_FILE:1) 1: clojure.lang.AFn.applyToHelper(AFn.java:165) 2: clojure.lang.AFn.applyTo(AFn.java:151) 3: clojure.lang.Compiler$InvokeExpr.eval(Compiler.java:2901) 4: clojure.lang.Compiler$DefExpr.eval(Compiler.java:361) 5: clojure.lang.Compiler.eval(Compiler.java:5424) 6: clojure.lang.Compiler.eval(Compiler.java:5386) 7: clojure.core$eval.invoke(core.clj:2382) 8: swank.commands.basic$eval_region.invoke(basic.clj:47) 9: swank.commands.basic$eval_region.invoke(basic.clj:37) 10: swank.commands.basic$eval799$listener_eval__800.invoke(basic.clj: 71) 11: clojure.lang.Var.invoke(Var.java:365) 12: dpa$eval9236.invoke(NO_SOURCE_FILE) 13: clojure.lang.Compiler.eval(Compiler.java:5419) 14: clojure.lang.Compiler.eval(Compiler.java:5386) 15: clojure.core$eval.invoke(core.clj:2382) 16: swank.core$eval_in_emacs_package.invoke(core.clj:90) 17: swank.core$eval_for_emacs.invoke(core.clj:237) 18: clojure.lang.Var.invoke(Var.java:373) 19: clojure.lang.AFn.applyToHelper(AFn.java:169) 20: clojure.lang.Var.applyTo(Var.java:482) 21: clojure.core$apply.invoke(core.clj:540) 22: swank.core$eval_from_control.invoke(core.clj:97) 23: swank.core$eval_loop.invoke(core.clj:102) 24: swank.core$spawn_repl_thread$fn__484$fn__485.invoke(core.clj:307) 25: clojure.lang.AFn.applyToHelper(AFn.java:159) 26: clojure.lang.AFn.applyTo(AFn.java:151) 27: clojure.core$apply.invoke(core.clj:540) 28: swank.core$spawn_repl_thread$fn__484.doInvoke(core.clj:304) 29: clojure.lang.RestFn.invoke(RestFn.java:398) 30: clojure.lang.AFn.run(AFn.java:24) 31: java.lang.Thread.run(Thread.java:637) But, this does work: (defn process-dpa-file This makes the matrix of CA coordinates from a pdb file. [pdb-file chains] (def hold-coords []) (doseq [^String line (read-lines pdb-file)] ;; Make sure the file line is the correct length ;; We only want the atom entries ;; We don't want any repeated measurements for an atom ;; Is it a CA? ;; Are we using this chain? (if (and (= (.length line) 80) (= (str (.substring line 0 4) (.substring line 26 27) (.substring line 13 15)) ATOM CA) (substring? (.substring line 21 22) chains)) ;; This are the CA coordinates (def hold-coords (into hold-coords [ (Double. (.substring line 30 37)) (Double. (.substring line 38 45)) (Double. (.substring line 46 53)) ] (matrix hold-coords 3)) dpa (def my-mat (process-dpa-file /Users/daviddreisigmeyer/MyStuff/ DPA_release_12-JUL-2010/1RD8.pdb A) ) #'dpa/my-mat I'd certainly appreciate any comments on the code in general. I only have a Matlab/R/Fortran 95 background. Thanks, -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
Re: 2 links for beginners
faenvie wrote: That is the most unsubstantiated, moronic piece of writing I've ever read in my life. I can't really tell what he's attacking, he's just swinging some dick-shaped sword around trying to hit stuff. i do not agree ... its clear that the article is a rant, does not go deep and misses important facts (does not mention any of the great features that clojure implements). but he unerringly focuses on the most critical point of clojure: its dependency on a host-runtime and a host-language. to abstract away from esp. java-language seems an crucial thing ... and moves like clojure in clojure address this. jvm7's dynamic-language-support will also mitigate that point. one thing i would like to know is: what are the advantages of common-lisp running on a lisp-machine compared to clojure running on the jvm ? have a successful time Well, on a Symbolics lisp machine, which I used for a couple years you could hit an error which would pop you into emacs at the point of the error. You could edit the file to correct the error and then continue the computation from the point of failure with the new code. The Symbolics machine (its kittens all the way down...) gave me the insight that one of the most important parts of programming is the time it takes to close the loop. Start from the point of failure, find the failure in source code, fix the failure, recompile, and re-execute. Measure the time that takes. Call this cycle the OODA loop (after the military acronym). http://en.wikipedia.org/wiki/OODA_loop On a Symbolics machine, the OODA loop takes seconds. In Java it can take many minutes to an hour or more. Common lisp on stock hardware takes about a factor of 10 less than Java. Your OODA loop time may vary. But the important point is that this OODA loop is a vital measure of how productive a language and its environment can be. By any measure, the Symbolics lisp machine was exceptional. In Clojure I find that I'm constantly struggling with something to do with the impedance mismatch between the Clojure code and the Java code. A large part of this is due to my lack of experience in Clojure but I find that my OODA loop takes a long time. I can code in either language but it is the mixture of the two that seems to be the source of my troubles. Measure your OODA loop in all the languages you know. See which one cycles fastest. I'd bet that's your favorite language. Tim Daly -- 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: 2 links for beginners
On Fri, Aug 6, 2010 at 12:31 AM, Tim Daly d...@axiom-developer.org wrote: Measure your OODA loop in all the languages you know. See which one cycles fastest. I'd bet that's your favorite language. Excellent observation! Definitely explains why, for all its lack of performance and minor quirks, ruby is still my favourite language. martin -- 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
Converting a AS3 Cave Generator to Clojure
Hi I am having trouble with converting this cave generator to clojure. Basically how would you implement the generateCave method with pop and push in a functional style? Here is a description to the algorithm: http://properundead.com/2009/03/cave-generator.html And here you can download the AS3 source: http://properundead.com/flash/caveas3.zip from: http://properundead.com/2009/07/procedural-generation-3-cave-source.html I put the Map.as file on pastebin for you guys to see: http://pastebin.com/b2qqDtwg It would also be an opportunity to learn by seeing other peoples solution. -- 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: Speeding up equals using the cached hash code?
Thanks for all the answers. It is a little bit embarrassing, but Paul Stadig seems to be totally right, it is already implemented. I don't know how I could have overlooked that - sorry. I guess it is not that bad of an idea after all then ;-) I'll be a little more thorough next time I post. Kind regards Sune On Aug 5, 4:36 pm, Paul Stadig p...@stadig.name wrote: I believe the code already does what you are asking about. Are you talking about something like this?http://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/AP... this?http://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/AP... and this?http://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/AP... Or am I misunderstanding the OP? Paul http://paul.stadig.name/(blog) 703-634-9339 (mobile) pjstadig (twitter) p...@stadig.name (jabber) Projectshttp://www.mycrossoverpoint.com/http://www.reformedchurches.info/ On Thu, Aug 5, 2010 at 8:38 AM, Nicolas Oury nicolas.o...@gmail.com wrote: Just a quick follow-up. This is a big plus when you know (from meta reasons) that most successful equality tests will come from the identical? part of the test. Then you have most of the fail in O(1) by hashing and most of the successes in O(1) with identical?. While still being correct and complete. What I have in mind is one of my recurring rant about Hash Consing. http://en.wikipedia.org/wiki/Hash_consing With a clever caching of hash value and comparing the hash, you can have an equality for records that is O(1) with high expectation on any hash-consed values, while still being correct for non hash-consed value. Best, Nicolas. -- 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.comclojure%2bunsubscr...@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
Error trying to use a GroovyShell from clojure
Hello all, long time listener first time caller. I've got a situation where I'm trying to apply some Groovy code against a clojure hashmap. I've got: (ns neat (:import (java.sql Timestamp) (groovy.lang Binding GroovyShell) (oracle.sql TIMESTAMP Datum) (java.util.concurrent Executors ThreadFactory ThreadPoolExecutor TimeUnit LinkedBlockingQueue ArrayBlockingQueue FutureTask) (java.util TreeMap TreeSet Map Set List ArrayList Calendar GregorianCalendar TimeZone)) (:use(clojure.contrib sql string def logging))) to bring in GroovyShell and binding objects. I try to use this as: (defn execute-groovy [event current-rule rule-list] (let [groovy_script (:groovy_script current-rule)] (if (nil? groovy_script) event (let [groovy-binding (new Binding)] (.setVariable groovy-binding rule current-rule) (.setVariable groovy-binding update (:response event {})) (.setVariable groovy-binding eventevent) (.setVariable groovy-binding ruleList rule-list) (let [groovy-shell (new GroovyShell groovy-binding)] (.evaluate groovy-shell groovy_script) (merge event {:response (merge (:response event {}) {:groovy_script (conj (:groovy_script (:response event {}) (list)) (:id current-rule))} (.getVariable groovy-binding update))}) ) This worked in one version of the code where I didn't use an ns but instead did: (import '(groovy.lang Binding GroovyShell)) into user. The problem is I get the following error when I use it within the namespace: No matching method found: evaluate for class groovy.lang.GroovyShell I don't think this has anything to do with Groovy. For some reason the code doesn't want to use groovy-shell as a GroovyShell. I can also do: (.evaluate (GroovyShell.) 1+1) in the REPL while in the neat ns. Any ideas? -- 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
Seattle Clojure meeting tonight
If you're in the Seattle area and interested in Clojure, come on by tonight! We are generally discussion- and code-centric rather than having presentations. All experience levels welcome, even if you're just curious. We are meeting at University Zoka at 7pm: http://maps.google.com/maps?f=qsource=s_qhl=engeocode=q=zoka,+university+district,+seattlesll=37.0625,-95.677068sspn=49.490703,90.791016ie=UTF8hq=zoka,hnear=University+District,+Seattle,+WAll=47.66624,-122.296629spn=0.010361,0.022166z=16iwloc=B Normally we take the big table way in the back. Be sure to grab a wifi code with your purchase as the network is password-protected. See also http://seajure.technomancy.us -Phil -- 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: existing idiom for delaying a future ?
On Thu, 5 Aug 2010 16:05:07 +0200 Laurent PETIT laurent.pe...@gmail.com wrote: My point was that by providing different interfaces/protocols to different users, it's more an implementation detail than anything else if they have the same object or not. I don't expect my users to program on types, but on protocols/interfaces. (ok, in this case, i'm my own user, so I have indeed some expectations on me ;) ) After all I was wrong, it's not a delayed delay I've written. How to rename things ? timed-delay - ? delay.util.Cancellable - ? isCancelled - ? cancel - ? timed-delay - ok Cancellable - Timed isCancelled - countdown-stopped? cancel - stop-countdown Maybe like this? I dunno. I'm bad at names. :] Hm, well .. let's say not worse than me :) It sounds like you're having trouble defining what the primitives of your interface are. If I may attempt it, I'll call this construct an idle speculative cache, i.e. you want to speculatively cache the evaluation some potentially expensive function over an input at a time when the input's value is not changing in a volatile manner, thus avoiding repeatedly and rapidly invalidating cached results of a potentially expensive operation. I can identify three or possibly four useful primitives on an idle speculative cache: (create-isc f timeout inital-input) (update-input! isc x) (deref isc) * 'create returns some opaque thing representing the evaluator, given the function it is to evaluate, the idle timeout for speculative evaluation, and the initial input value. * 'update-input! updates the input value and resets the timeout. * 'deref gets the output value, forcing an evaluation if the cached output is out of date. You might optionally implement another primitive for inspecting the state that does not force, that can either retrieve a possibly-stale result, or retrieve a fresh result and fail if it would require forcing. Given that interface, here's one implementation I came up with: (defn- update-cache [isc] (let [input @(:input isc) new-output-val ((:func isc) (:val input)) new-output {:val new-output-val :ts (:ts input)}] (reset! (:output isc) new-output) new-output-val)) (defn- isc-runner [_ isc] (let [input @(:input isc) quiescent-time (- (System/currentTimeMillis) (:ts input)) sleep-to-go(- (:timeout isc) quiescent-time)] (if (pos? sleep-to-go) (do (Thread/sleep sleep-to-go) (recur nil isc)) (do (update-cache isc) false (defn- deref-isc [isc] (let [output @(:output isc)] (if (= (:ts @(:input isc)) (:ts output)) (:val output) (update-cache isc (defrecord IdleSpeculativeCache [func input output timeout runner] clojure.lang.IDeref (deref [isc] (deref-isc isc))) (defn update-input! [isc x] (reset! (:input isc) {:val x :ts (System/currentTimeMillis)}) (when (not @(:runner isc)) (send-off (:runner isc) (constantly true)) (send-off (:runner isc) isc-runner isc)) nil) (defn create-isc [f in to] (let [isc (IdleSpeculativeCache. f (atom {:val nil :ts 0}) (atom {:val nil :ts 0}) to (agent false))] (update-input! isc in) isc)) This one has one bug I know of, which is that the speculative evaluator ('runner which monitors the i.s.c. input activity) does not check if the output is already fresh due to 'deref forcing before re-evaluating, but I think that could be fixed easily with a test in update-cache. I hope it helps, :) -Kyle -- 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: Error trying to use a GroovyShell from clojure
can you compile the groovy script to .class via groovyc? then you can use the groovy code within clojure via java interop. On Thu, Aug 5, 2010 at 2:33 PM, Chris Goellner cgoell...@gmail.com wrote: Hello all, long time listener first time caller. I've got a situation where I'm trying to apply some Groovy code against a clojure hashmap. I've got: (ns neat (:import (java.sql Timestamp) (groovy.lang Binding GroovyShell) (oracle.sql TIMESTAMP Datum) (java.util.concurrent Executors ThreadFactory ThreadPoolExecutor TimeUnit LinkedBlockingQueue ArrayBlockingQueue FutureTask) (java.util TreeMap TreeSet Map Set List ArrayList Calendar GregorianCalendar TimeZone)) (:use (clojure.contrib sql string def logging))) to bring in GroovyShell and binding objects. I try to use this as: (defn execute-groovy [event current-rule rule-list] (let [groovy_script (:groovy_script current-rule)] (if (nil? groovy_script) event (let [groovy-binding (new Binding)] (.setVariable groovy-binding rule current-rule) (.setVariable groovy-binding update (:response event {})) (.setVariable groovy-binding event event) (.setVariable groovy-binding ruleList rule-list) (let [groovy-shell (new GroovyShell groovy-binding)] (.evaluate groovy-shell groovy_script) (merge event {:response (merge (:response event {}) {:groovy_script (conj (:groovy_script (:response event {}) (list)) (:id current-rule))} (.getVariable groovy-binding update))}) ) This worked in one version of the code where I didn't use an ns but instead did: (import '(groovy.lang Binding GroovyShell)) into user. The problem is I get the following error when I use it within the namespace: No matching method found: evaluate for class groovy.lang.GroovyShell I don't think this has anything to do with Groovy. For some reason the code doesn't want to use groovy-shell as a GroovyShell. I can also do: (.evaluate (GroovyShell.) 1+1) in the REPL while in the neat ns. Any ideas? -- 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 -- Omnem crede diem tibi diluxisse supremum. -- 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: (java.io BufferedReader FileReader) versus [clojure.contrib.duck-streams :only (read-lines)]
Thanks for the extra parentheses catch. I just noticed that while working on a different function (after hours of trying to figure it out). The program is reading in a pdb file line-by-line. I only want the xyz-coordinates of carbon atoms, avoiding any repeats when the coordinate of an atom is uncertain. Also, a protein may have multiple sub-units, and the chains parameter can pick out the desired sub- unit(s). So I need to: 1) make sure the line is long enough 2) make sure I have an atom 3) make sure it's not a repeated measurement 4) make sure it's a C_{alpha} atom If the current pdb-file line matches those criteria, I'll then put its xyz-coordinates into the output matrix. I tried this using let: (defn process-dpa-file2 This makes the matrix of CA coordinates from a pdb file. [pdb-file chains] (def hold-coords []) (doseq [^String line (read-lines pdb-file)] ;; Make sure the file line is the correct length ;; We only want the atom entries ;; We don't want any repeated measurements for an atom ;; Is it a CA? ;; Are we using this chain? (if (and (= (.length line) 80) (= (str (.substring line 0 4) (.substring line 26 27) (.substring line 13 15)) ATOM CA) (substring? (.substring line 21 22) chains)) ;; These are the CA coordinates (let [coords (into hold-coords [ (Double. (.substring line 30 37)) (Double. (.substring line 38 45)) (Double. (.substring line 46 53))]) hold-coords coords])) (matrix hold-coords 3))) but the output gives: dpa (def my-mat (process-dpa-file2 /Users/daviddreisigmeyer/MyStuff/ DPA_release_12-JUL-2010/1RD8.pdb A) ) #'dpa/my-mat dpa my-mat nil A simpler example: dpa (def y [5 6 7]) (let [x (into y [2 3 4]) y x ] y) [5 6 7 2 3 4] dpa y [5 6 7] So it seems that in process-dpa-file2 I have the coordinates of the 1st carbon atom in hold-coords, and then the 2nd, the 3rd ... After finding the 3rd carbon, I'd want: hold-coords = [x1 y1 z1 x2 y2 z2 x3 y3 z3] (**) but instead I get hold-coords = [x3 y3 z3]. Any idea about how I could get (**) instead? Thanks! -Dave On Aug 5, 2:46 pm, Nikita Beloglazov nikelandj...@gmail.com wrote: Hi, Dave Why do you use 2 parenthesis before with-open in the first variant? And, as I know, it's not good practice to use def inside functions. Use let instead. I also advice you to split your program to smaller functions. Can you describe, what your program must do? Because don't understand :( On Thu, Aug 5, 2010 at 9:28 PM, Dave david.dreisigme...@gmail.com wrote: Hi, I don't understand why this doesn't work: (ns dpa (:gen-class) (:use [incanter.core :only ( matrix )] [clojure.core :only ( defn doseq line-seq println with-open )] [clojure.contrib.string :only ( blank? substring? )] (:import (java.io BufferedReader FileReader))) (defn process-dpa-file This makes the matrix of CA coordinates from a pdb file. [pdb-file chains] (def hold-coords []) ((with-open [rdr (BufferedReader. (FileReader. pdb-file))] (doseq [^String line (line-seq rdr)] ;; Make sure the file line is the correct length ;; We only want the atom entries ;; We don't want any repeated measurements for an atom ;; Is it a CA? ;; Are we using this chain? (if (and (= (.length line) 80) (= (str (.substring line 0 4) (.substring line 26 27) (.substring line 13 15)) ATOM CA) (substring? (.substring line 21 22) chains)) ;; This are the CA coordinates (def hold-coords (into hold-coords [ (Double. (.substring line 30 37)) (Double. (.substring line 38 45)) (Double. (.substring line 46 53)) ] ) (matrix hold-coords 3))) dpa (def my-mat (process-dpa-file /Users/daviddreisigmeyer/MyStuff/ DPA_release_12-JUL-2010/1RD8.pdb A) ) No message. [Thrown class java.lang.NullPointerException] Restarts: 0: [QUIT] Quit to the SLIME top level Backtrace: 0: dpa$process_dpa_file.invoke(NO_SOURCE_FILE:1) 1: clojure.lang.AFn.applyToHelper(AFn.java:165) 2: clojure.lang.AFn.applyTo(AFn.java:151) 3: clojure.lang.Compiler$InvokeExpr.eval(Compiler.java:2901) 4: clojure.lang.Compiler$DefExpr.eval(Compiler.java:361) 5: clojure.lang.Compiler.eval(Compiler.java:5424) 6: clojure.lang.Compiler.eval(Compiler.java:5386) 7: clojure.core$eval.invoke(core.clj:2382) 8: swank.commands.basic$eval_region.invoke(basic.clj:47) 9: swank.commands.basic$eval_region.invoke(basic.clj:37) 10: swank.commands.basic$eval799$listener_eval__800.invoke(basic.clj: 71) 11: clojure.lang.Var.invoke(Var.java:365) 12: dpa$eval9236.invoke(NO_SOURCE_FILE) 13: clojure.lang.Compiler.eval(Compiler.java:5419) 14: clojure.lang.Compiler.eval(Compiler.java:5386) 15:
Re: (java.io BufferedReader FileReader) versus [clojure.contrib.duck-streams :only (read-lines)]
See my variant of your application: https://gist.github.com/efdb66487e899446332f I don't know if it works, because I can't test :( My thoughts about your example You shouldn't think about this procedure as about procedure where you use loop, like in other imperative languages with mutable data. As I understand you tried something like: for every line in file do if line matches then convert line to coords add coords to global variable hold-coords end if end for But it's not the clojure way, I think clojure way is: get all lines as sequence convert every element of this sequence to vector of coords concat all vectors to one And in your example dpa (def y [5 6 7]) (let [x (into y [2 3 4]) y x ] y) [5 6 7 2 3 4] dpa y [5 6 7] When you use y in let, it introduce new local variable y, which hides global y It you want to use mutable data (I don't think it's good), you can use atoms - it's special mmm... mechanism for mutable data: user (def y (atom [1 2 3])) #'user/y user @y [1 2 3] user (swap! y into [4 5 6]) [1 2 3 4 5 6] user @y [1 2 3 4 5 6] Here you bind to variable y an atom with initial value - vector [1 2 3]. To get value of atom you use @ before the variable name: @y To change value you call (swap! atom func x y z). First it calculates new value like this: (func @atom x y z), in our example it will calculate (into @y [4 5 6]). It returns vector [1 2 3 4 5 6], and this vector is set as new value of y. Regards, Nikita Beloglazov On Thu, Aug 5, 2010 at 11:49 PM, Dave david.dreisigme...@gmail.com wrote: Thanks for the extra parentheses catch. I just noticed that while working on a different function (after hours of trying to figure it out). The program is reading in a pdb file line-by-line. I only want the xyz-coordinates of carbon atoms, avoiding any repeats when the coordinate of an atom is uncertain. Also, a protein may have multiple sub-units, and the chains parameter can pick out the desired sub- unit(s). So I need to: 1) make sure the line is long enough 2) make sure I have an atom 3) make sure it's not a repeated measurement 4) make sure it's a C_{alpha} atom If the current pdb-file line matches those criteria, I'll then put its xyz-coordinates into the output matrix. I tried this using let: (defn process-dpa-file2 This makes the matrix of CA coordinates from a pdb file. [pdb-file chains] (def hold-coords []) (doseq [^String line (read-lines pdb-file)] ;; Make sure the file line is the correct length ;; We only want the atom entries ;; We don't want any repeated measurements for an atom ;; Is it a CA? ;; Are we using this chain? (if (and (= (.length line) 80) (= (str (.substring line 0 4) (.substring line 26 27) (.substring line 13 15)) ATOM CA) (substring? (.substring line 21 22) chains)) ;; These are the CA coordinates (let [coords (into hold-coords [ (Double. (.substring line 30 37)) (Double. (.substring line 38 45)) (Double. (.substring line 46 53))]) hold-coords coords])) (matrix hold-coords 3))) but the output gives: dpa (def my-mat (process-dpa-file2 /Users/daviddreisigmeyer/MyStuff/ DPA_release_12-JUL-2010/1RD8.pdb A) ) #'dpa/my-mat dpa my-mat nil A simpler example: dpa (def y [5 6 7]) (let [x (into y [2 3 4]) y x ] y) [5 6 7 2 3 4] dpa y [5 6 7] So it seems that in process-dpa-file2 I have the coordinates of the 1st carbon atom in hold-coords, and then the 2nd, the 3rd ... After finding the 3rd carbon, I'd want: hold-coords = [x1 y1 z1 x2 y2 z2 x3 y3 z3] (**) but instead I get hold-coords = [x3 y3 z3]. Any idea about how I could get (**) instead? Thanks! -Dave On Aug 5, 2:46 pm, Nikita Beloglazov nikelandj...@gmail.com wrote: Hi, Dave Why do you use 2 parenthesis before with-open in the first variant? And, as I know, it's not good practice to use def inside functions. Use let instead. I also advice you to split your program to smaller functions. Can you describe, what your program must do? Because don't understand :( On Thu, Aug 5, 2010 at 9:28 PM, Dave david.dreisigme...@gmail.com wrote: Hi, I don't understand why this doesn't work: (ns dpa (:gen-class) (:use [incanter.core :only ( matrix )] [clojure.core :only ( defn doseq line-seq println with-open )] [clojure.contrib.string :only ( blank? substring? )] (:import (java.io BufferedReader FileReader))) (defn process-dpa-file This makes the matrix of CA coordinates from a pdb file. [pdb-file chains] (def hold-coords []) ((with-open [rdr (BufferedReader. (FileReader. pdb-file))] (doseq [^String line (line-seq rdr)] ;; Make sure the file line is the correct length ;; We only want the atom entries ;; We don't want any repeated measurements for an atom ;; Is it a CA?
Re: Resource cleanup when lazy sequences are finalized
On Aug 3, 5:28 pm, Jeff Palmucci jpalmu...@gmail.com wrote: See my library athttp://github.com/jpalmucci/clj-yield, which makes this trivial. This looks really nice, Jeff. Thanks. Exactly what I was looking for. I notice that the garbage-monitor deftype yields a classname error in IBM Java6. I renamed it to garbage_monitor and all seems copacetic. -- 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: existing idiom for delaying a future ?
2010/8/5 Kyle Schaffrick k...@raidi.us On Thu, 5 Aug 2010 16:05:07 +0200 Laurent PETIT laurent.pe...@gmail.com wrote: My point was that by providing different interfaces/protocols to different users, it's more an implementation detail than anything else if they have the same object or not. I don't expect my users to program on types, but on protocols/interfaces. (ok, in this case, i'm my own user, so I have indeed some expectations on me ;) ) After all I was wrong, it's not a delayed delay I've written. How to rename things ? timed-delay - ? delay.util.Cancellable - ? isCancelled - ? cancel - ? timed-delay - ok Cancellable - Timed isCancelled - countdown-stopped? cancel - stop-countdown Maybe like this? I dunno. I'm bad at names. :] Hm, well .. let's say not worse than me :) It sounds like you're having trouble defining what the primitives of your interface are. If I may attempt it, I'll call this construct an idle speculative cache, i.e. you want to speculatively cache the evaluation some potentially expensive function over an input at a time when the input's value is not changing in a volatile manner, thus avoiding repeatedly and rapidly invalidating cached results of a potentially expensive operation. I can identify three or possibly four useful primitives on an idle speculative cache: (create-isc f timeout inital-input) (update-input! isc x) (deref isc) * 'create returns some opaque thing representing the evaluator, given the function it is to evaluate, the idle timeout for speculative evaluation, and the initial input value. * 'update-input! updates the input value and resets the timeout. * 'deref gets the output value, forcing an evaluation if the cached output is out of date. You might optionally implement another primitive for inspecting the state that does not force, that can either retrieve a possibly-stale result, or retrieve a fresh result and fail if it would require forcing. Given that interface, here's one implementation I came up with: (defn- update-cache [isc] (let [input @(:input isc) new-output-val ((:func isc) (:val input)) new-output {:val new-output-val :ts (:ts input)}] (reset! (:output isc) new-output) new-output-val)) (defn- isc-runner [_ isc] (let [input @(:input isc) quiescent-time (- (System/currentTimeMillis) (:ts input)) sleep-to-go(- (:timeout isc) quiescent-time)] (if (pos? sleep-to-go) (do (Thread/sleep sleep-to-go) (recur nil isc)) (do (update-cache isc) false (defn- deref-isc [isc] (let [output @(:output isc)] (if (= (:ts @(:input isc)) (:ts output)) (:val output) (update-cache isc (defrecord IdleSpeculativeCache [func input output timeout runner] clojure.lang.IDeref (deref [isc] (deref-isc isc))) (defn update-input! [isc x] (reset! (:input isc) {:val x :ts (System/currentTimeMillis)}) (when (not @(:runner isc)) (send-off (:runner isc) (constantly true)) (send-off (:runner isc) isc-runner isc)) nil) (defn create-isc [f in to] (let [isc (IdleSpeculativeCache. f (atom {:val nil :ts 0}) (atom {:val nil :ts 0}) to (agent false))] (update-input! isc in) isc)) This one has one bug I know of, which is that the speculative evaluator ('runner which monitors the i.s.c. input activity) does not check if the output is already fresh due to 'deref forcing before re-evaluating, but I think that could be fixed easily with a test in update-cache. I hope it helps, :) No offense, but ... are you serious ? Seriously, seeing all those intermingled derefs, reset!, send-off, :input, :output in such a little code base gives me a very bad smell. I still prefer my own version, repeated here for the record : (ns delay.util) (defprotocol Cancellable (isCancelled [this]) (cancel [this])) (defn timed-delay [pause fun] (let [d (delay (fun)) f (future (Thread/sleep pause) @d)] (reify clojure.lang.IDeref (deref [_] @d) delay.util.Cancellable (isCancelled [_] (future-cancelled? f)) (cancel [_] (future-cancel f) - the deref is on a delay, so it's causing no harm. - the code does not try to do too much at once : it only deals with one value, letting the client decide if the succession of values should be stored in an atom, in a ref, etc. Still not perfect for the names, but currently quite satisfied by the feature/code lines and feature/code simplicity ratios :-) -- 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
Re: existing idiom for delaying a future ?
On Fri, 6 Aug 2010 00:04:08 +0200 Laurent PETIT laurent.pe...@gmail.com wrote: No offense, but ... are you serious ? So my off-the-cuff, wrote-it-in-5 minutes code is laughable? If you mean no offense then why say this at all? :( I still prefer my own version, repeated here for the record : (ns delay.util) (defprotocol Cancellable (isCancelled [this]) (cancel [this])) (defn timed-delay [pause fun] (let [d (delay (fun)) f (future (Thread/sleep pause) @d)] (reify clojure.lang.IDeref (deref [_] @d) delay.util.Cancellable (isCancelled [_] (future-cancelled? f)) (cancel [_] (future-cancel f) - the deref is on a delay, so it's causing no harm. - the code does not try to do too much at once : it only deals with one value, letting the client decide if the succession of values should be stored in an atom, in a ref, etc. I can agree it does do a better job of separating the time-delayed concept from the rest of the problem than what I wrote. I suppose I misunderstood what you were asking about, since this doesn't appear to be the whole solution to the original scenario you spoke of: your consumer must cancel the old and create a new timed-delay manually if they wish to supersede the input value (i.e. whenever the user types something). But of course, if this is the contract you need then by all means, it's certainly much better. (Although, Java's big scary list of caveats and gotchas surrounding Future.cancel() kinda bother me personally...) Still not perfect for the names, but currently quite satisfied by the feature/code lines and feature/code simplicity ratios :-) Sounds good to me then. -Kyle -- 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: existing idiom for delaying a future ?
2010/8/6 Kyle Schaffrick k...@raidi.us On Fri, 6 Aug 2010 00:04:08 +0200 Laurent PETIT laurent.pe...@gmail.com wrote: No offense, but ... are you serious ? So my off-the-cuff, wrote-it-in-5 minutes code is laughable? If you mean no offense then why say this at all? I regret having written this. I was upset by a totally different subject, and should have thought twice before hitting send. It's not laughable. But it looked scary at first, to be honest. :( I still prefer my own version, repeated here for the record : (ns delay.util) (defprotocol Cancellable (isCancelled [this]) (cancel [this])) (defn timed-delay [pause fun] (let [d (delay (fun)) f (future (Thread/sleep pause) @d)] (reify clojure.lang.IDeref (deref [_] @d) delay.util.Cancellable (isCancelled [_] (future-cancelled? f)) (cancel [_] (future-cancel f) - the deref is on a delay, so it's causing no harm. - the code does not try to do too much at once : it only deals with one value, letting the client decide if the succession of values should be stored in an atom, in a ref, etc. I can agree it does do a better job of separating the time-delayed concept from the rest of the problem than what I wrote. I suppose I misunderstood what you were asking about, since this doesn't appear to be the whole solution to the original scenario you spoke of: your consumer must cancel the old and create a new timed-delay manually if they wish to supersede the input value (i.e. whenever the user types something). Yes, there are 2 types of consumers in the code: the one which just want to get the value out of the ref, which will depend on the IDeref interface, and the one which is responsible for updating the holder of the ref, and indeed it's also responsible for calling cancel with my scenario. It's a tradeoff I currently can leave with. Future (no pun intended) will tell whether I was wrong or not :) But of course, if this is the contract you need then by all means, it's certainly much better. (Although, Java's big scary list of caveats and gotchas surrounding Future.cancel() kinda bother me personally...) Still not perfect for the names, but currently quite satisfied by the feature/code lines and feature/code simplicity ratios :-) Sounds good to me then. -Kyle -- 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.comclojure%2bunsubscr...@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: (java.io BufferedReader FileReader) versus [clojure.contrib.duck-streams :only (read-lines)]
Thanks Nikita, I really appreciate your help. -Dave On Aug 5, 5:53 pm, Nikita Beloglazov nikelandj...@gmail.com wrote: See my variant of your application:https://gist.github.com/efdb66487e899446332f I don't know if it works, because I can't test :( My thoughts about your example You shouldn't think about this procedure as about procedure where you use loop, like in other imperative languages with mutable data. As I understand you tried something like: for every line in file do if line matches then convert line to coords add coords to global variable hold-coords end if end for But it's not the clojure way, I think clojure way is: get all lines as sequence convert every element of this sequence to vector of coords concat all vectors to one And in your exampledpa (def y [5 6 7]) (let [x (into y [2 3 4]) y x ] y) [5 6 7 2 3 4] dpa y [5 6 7] When you use y in let, it introduce new local variable y, which hides global y It you want to use mutable data (I don't think it's good), you can use atoms - it's special mmm... mechanism for mutable data: user (def y (atom [1 2 3])) #'user/y user @y [1 2 3] user (swap! y into [4 5 6]) [1 2 3 4 5 6] user @y [1 2 3 4 5 6] Here you bind to variable y an atom with initial value - vector [1 2 3]. To get value of atom you use @ before the variable name: @y To change value you call (swap! atom func x y z). First it calculates new value like this: (func @atom x y z), in our example it will calculate (into @y [4 5 6]). It returns vector [1 2 3 4 5 6], and this vector is set as new value of y. Regards, Nikita Beloglazov On Thu, Aug 5, 2010 at 11:49 PM, Dave david.dreisigme...@gmail.com wrote: Thanks for the extra parentheses catch. I just noticed that while working on a different function (after hours of trying to figure it out). The program is reading in a pdb file line-by-line. I only want the xyz-coordinates of carbon atoms, avoiding any repeats when the coordinate of an atom is uncertain. Also, a protein may have multiple sub-units, and the chains parameter can pick out the desired sub- unit(s). So I need to: 1) make sure the line is long enough 2) make sure I have an atom 3) make sure it's not a repeated measurement 4) make sure it's a C_{alpha} atom If the current pdb-file line matches those criteria, I'll then put its xyz-coordinates into the output matrix. I tried this using let: (defn process-dpa-file2 This makes the matrix of CA coordinates from a pdb file. [pdb-file chains] (def hold-coords []) (doseq [^String line (read-lines pdb-file)] ;; Make sure the file line is the correct length ;; We only want the atom entries ;; We don't want any repeated measurements for an atom ;; Is it a CA? ;; Are we using this chain? (if (and (= (.length line) 80) (= (str (.substring line 0 4) (.substring line 26 27) (.substring line 13 15)) ATOM CA) (substring? (.substring line 21 22) chains)) ;; These are the CA coordinates (let [coords (into hold-coords [ (Double. (.substring line 30 37)) (Double. (.substring line 38 45)) (Double. (.substring line 46 53))]) hold-coords coords])) (matrix hold-coords 3))) but the output gives: dpa (def my-mat (process-dpa-file2 /Users/daviddreisigmeyer/MyStuff/ DPA_release_12-JUL-2010/1RD8.pdb A) ) #'dpa/my-mat dpa my-mat nil A simpler example: dpa (def y [5 6 7]) (let [x (into y [2 3 4]) y x ] y) [5 6 7 2 3 4] dpa y [5 6 7] So it seems that in process-dpa-file2 I have the coordinates of the 1st carbon atom in hold-coords, and then the 2nd, the 3rd ... After finding the 3rd carbon, I'd want: hold-coords = [x1 y1 z1 x2 y2 z2 x3 y3 z3] (**) but instead I get hold-coords = [x3 y3 z3]. Any idea about how I could get (**) instead? Thanks! -Dave On Aug 5, 2:46 pm, Nikita Beloglazov nikelandj...@gmail.com wrote: Hi, Dave Why do you use 2 parenthesis before with-open in the first variant? And, as I know, it's not good practice to use def inside functions. Use let instead. I also advice you to split your program to smaller functions. Can you describe, what your program must do? Because don't understand :( On Thu, Aug 5, 2010 at 9:28 PM, Dave david.dreisigme...@gmail.com wrote: Hi, I don't understand why this doesn't work: (ns dpa (:gen-class) (:use [incanter.core :only ( matrix )] [clojure.core :only ( defn doseq line-seq println with-open )] [clojure.contrib.string :only ( blank? substring? )] (:import (java.io BufferedReader FileReader))) (defn process-dpa-file This makes the matrix of CA coordinates from a pdb file. [pdb-file chains] (def hold-coords []) ((with-open [rdr (BufferedReader. (FileReader.