Re: Speeding up equals using the cached hash code?

2010-08-05 Thread Nicolas Oury
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 ?

2010-08-05 Thread Meikel Brandmeyer
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-08-05 Thread Laurent PETIT
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 ?

2010-08-05 Thread Laurent PETIT
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

2010-08-05 Thread Moritz Ulrich
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 ?

2010-08-05 Thread Meikel Brandmeyer
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?

2010-08-05 Thread abhinav sarkar
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

2010-08-05 Thread faenvie
 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-08-05 Thread Laurent PETIT
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-08-05 Thread Laurent PETIT
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-08-05 Thread Laurent PETIT
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 ?

2010-08-05 Thread Meikel Brandmeyer
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?

2010-08-05 Thread Nicolas Oury
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-08-05 Thread Laurent PETIT
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

2010-08-05 Thread Randy Hudson
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-08-05 Thread Laurent PETIT
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

2010-08-05 Thread faenvie

  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 ?

2010-08-05 Thread Meikel Brandmeyer
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

2010-08-05 Thread Stuart Halloway
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 ?

2010-08-05 Thread Meikel Brandmeyer
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-08-05 Thread Laurent PETIT
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-08-05 Thread Laurent PETIT
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?

2010-08-05 Thread michele

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

2010-08-05 Thread Steve Molitor
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?

2010-08-05 Thread Meikel Brandmeyer
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?

2010-08-05 Thread Peter Schuller
 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?

2010-08-05 Thread Paul Stadig
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

2010-08-05 Thread Stuart Halloway
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-08-05 Thread Laurent PETIT
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?

2010-08-05 Thread Stuart Halloway
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

2010-08-05 Thread Peter Schuller
 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

2010-08-05 Thread Islon Scherer
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)]

2010-08-05 Thread Dave
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

2010-08-05 Thread Tim Daly

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

2010-08-05 Thread George Jahad
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)]

2010-08-05 Thread Nikita Beloglazov
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

2010-08-05 Thread Tim Daly



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

2010-08-05 Thread Martin DeMello
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

2010-08-05 Thread msappler
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?

2010-08-05 Thread sune.simonsen
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

2010-08-05 Thread Chris Goellner
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

2010-08-05 Thread Phil Hagelberg
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 ?

2010-08-05 Thread Kyle Schaffrick
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

2010-08-05 Thread Wilson MacGyver
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)]

2010-08-05 Thread Dave
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)]

2010-08-05 Thread Nikita Beloglazov
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

2010-08-05 Thread David Andrews
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-08-05 Thread Laurent PETIT
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 ?

2010-08-05 Thread Kyle Schaffrick
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-08-05 Thread Laurent PETIT
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)]

2010-08-05 Thread Dave
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.