Re: Update multiple values in vector at once

2015-04-03 Thread Leon Grapenthin
(defn upd-vec [input-vector ids new-values]
  (apply assoc input-vector (interleave ids new-values)))

(upd-vec [0 0 0 0 0] [1 3] [1.44 1.45])

;= [0 1.44 0 1.45 0] 


On Monday, March 30, 2015 at 8:05:44 PM UTC+2, Alexandr wrote:

 Hello everybody,

 How can I update values in the vector given vector of id-s and new values?

 For example

 (defn upd-vec [input-vector ids new-values]
 
 )

 (upd-vec [0 0 0 0 0] [1 3] [1.44 1.45]) 

 Output: [0 1.44 0 1.45 0]  (1st and 3rd elements are replaced)


-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
Clojure group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Update multiple values in vector at once

2015-03-30 Thread Michał Marczyk
(defn upd-vec [input-vector ids new-values]
  (reduce-kv #(assoc %1 %3 (new-values %2)) input-vector ids))

(upd-vec [0 0 0 0 0] [1 3] [1.44 1.45])
;= [0 1.44 0 1.45 0]


On 30 March 2015 at 20:05, Alexandr updates...@gmail.com wrote:

 Hello everybody,

 How can I update values in the vector given vector of id-s and new values?

 For example

 (defn upd-vec [input-vector ids new-values]
 
 )

 (upd-vec [0 0 0 0 0] [1 3] [1.44 1.45])

 Output: [0 1.44 0 1.45 0]  (1st and 3rd elements are replaced)

 --
 You received this message because you are subscribed to the Google
 Groups Clojure group.
 To post to this group, send email to clojure@googlegroups.com
 Note that posts from new members are moderated - please be patient with
 your first post.
 To unsubscribe from this group, send email to
 clojure+unsubscr...@googlegroups.com
 For more options, visit this group at
 http://groups.google.com/group/clojure?hl=en
 ---
 You received this message because you are subscribed to the Google Groups
 Clojure group.
 To unsubscribe from this group and stop receiving emails from it, send an
 email to clojure+unsubscr...@googlegroups.com.
 For more options, visit https://groups.google.com/d/optout.


-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
Clojure group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Update multiple values in vector at once

2015-03-30 Thread Alexandr
Thanks a lot!

On Monday, March 30, 2015 at 8:11:25 PM UTC+2, Michał Marczyk wrote:

 (defn upd-vec [input-vector ids new-values]
   (reduce-kv #(assoc %1 %3 (new-values %2)) input-vector ids))

 (upd-vec [0 0 0 0 0] [1 3] [1.44 1.45])
 ;= [0 1.44 0 1.45 0]


 On 30 March 2015 at 20:05, Alexandr updat...@gmail.com javascript: 
 wrote:

 Hello everybody,

 How can I update values in the vector given vector of id-s and new values?

 For example

 (defn upd-vec [input-vector ids new-values]
 
 )

 (upd-vec [0 0 0 0 0] [1 3] [1.44 1.45]) 

 Output: [0 1.44 0 1.45 0]  (1st and 3rd elements are replaced)

 -- 
 You received this message because you are subscribed to the Google
 Groups Clojure group.
 To post to this group, send email to clo...@googlegroups.com 
 javascript:
 Note that posts from new members are moderated - please be patient with 
 your first post.
 To unsubscribe from this group, send email to
 clojure+u...@googlegroups.com javascript:
 For more options, visit this group at
 http://groups.google.com/group/clojure?hl=en
 --- 
 You received this message because you are subscribed to the Google Groups 
 Clojure group.
 To unsubscribe from this group and stop receiving emails from it, send an 
 email to clojure+u...@googlegroups.com javascript:.
 For more options, visit https://groups.google.com/d/optout.




-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
Clojure group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Update

2014-04-29 Thread Divyansh Prakash
Why are Clojure features defined in terms of Java classes, instead of as 
bytecode primitives?
For eg: Cons is a class containing two objects: first and rest.
Is this only to achieve Java interoperability, or is there more to it?

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
Clojure group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Update

2014-04-29 Thread Andrew Chambers
Well, why write it in primitives when there is a perfectly good compiler 
from java to primitives? I dont quite understand why you think there would 
be benefit from manually writing everything with java bytecode. The JVM 
works with classes, thats how its designed, Clojure itself is just a java 
library.

On Tuesday, April 29, 2014 8:25:01 PM UTC+12, Divyansh Prakash wrote:

 Why are Clojure features defined in terms of Java classes, instead of as 
 bytecode primitives?
 For eg: Cons is a class containing two objects: first and rest.
 Is this only to achieve Java interoperability, or is there more to it?


-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
Clojure group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Update

2014-04-29 Thread David Powell
The JVM is very class-oriented.  It is basically designed for Java, and
corresponds pretty much to the things you can do in Java.  Code belongs to
methods which belong to classes, and calls are made using java method
calling conventions.  Data has to be stored in primitives, arrays, or
objects; and arrays aren't particularly to-the-metal in Java anyway.

The Byte Code Verifier keeps what you do fairly simple - eg you can't just
leave things in the stack and jump to another method.

Even if you wanted to do anything a bit different, the performance of the
JVM all comes from the assumptions made while executing the bytecodes at
runtime.  If you did anything very weird, you'd probably find that these
optimizations didn't kick in.



On Tue, Apr 29, 2014 at 9:25 AM, Divyansh Prakash 
divyanshprakas...@gmail.com wrote:

 Why are Clojure features defined in terms of Java classes, instead of as
 bytecode primitives?
 For eg: Cons is a class containing two objects: first and rest.
 Is this only to achieve Java interoperability, or is there more to it?

 --
 You received this message because you are subscribed to the Google
 Groups Clojure group.
 To post to this group, send email to clojure@googlegroups.com
 Note that posts from new members are moderated - please be patient with
 your first post.
 To unsubscribe from this group, send email to
 clojure+unsubscr...@googlegroups.com
 For more options, visit this group at
 http://groups.google.com/group/clojure?hl=en
 ---
 You received this message because you are subscribed to the Google Groups
 Clojure group.
 To unsubscribe from this group and stop receiving emails from it, send an
 email to clojure+unsubscr...@googlegroups.com.
 For more options, visit https://groups.google.com/d/optout.


-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
Clojure group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Update

2014-04-29 Thread Divyansh Prakash
Thank you for the explanation.
What if I target a non-OO-centric VM (like Parrot or LLVM)?

I've noticed that most Lisp implementations define lambda calculus 
primitives, and then use those as the core.
I wonder what would be if we had bytecode primitives, and defined 
everything else on top of that. 
I don't know to what end, this is just an exercise.

Do you know if this has been done before?

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
Clojure group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Update

2014-04-29 Thread Divyansh Prakash
I looked into a port of Clojure to Parrot, and it basically does the same 
thinghttps://github.com/ayardley/ClojurePVM/blob/master/src/c/lisp/microlisp/lisp.c
.

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
Clojure group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Update

2014-04-29 Thread Divyansh Prakash
Why not emit bytecode directly from the language?
Couldn't this potentially lead to tons of specialized optimizing macros? 

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
Clojure group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Update

2014-04-29 Thread Gary Trakhman
The hard part with other runtimes will be details around things like
garbage collection for the implementation of persistent data structures.

Clojurescript is a better example of how this is done since most of the
impls are implemented in the language itself, different from
clojure-proper.

Granted, printed-text compiler output sucks, but it all seems to work.

Here's the javascript emission stage:
https://github.com/clojure/clojurescript/blob/master/src/clj/cljs/compiler.clj#L206

It's been ported to gambit-scheme:
https://github.com/takeoutweight/clojure-scheme/blob/rewrite/src/clj/cljscm/compiler.clj



On Tue, Apr 29, 2014 at 10:45 AM, Divyansh Prakash 
divyanshprakas...@gmail.com wrote:

 I looked into a port of Clojure to Parrot, and it basically does the same
 thinghttps://github.com/ayardley/ClojurePVM/blob/master/src/c/lisp/microlisp/lisp.c
 .

 --
 You received this message because you are subscribed to the Google
 Groups Clojure group.
 To post to this group, send email to clojure@googlegroups.com
 Note that posts from new members are moderated - please be patient with
 your first post.
 To unsubscribe from this group, send email to
 clojure+unsubscr...@googlegroups.com
 For more options, visit this group at
 http://groups.google.com/group/clojure?hl=en
 ---
 You received this message because you are subscribed to the Google Groups
 Clojure group.
 To unsubscribe from this group and stop receiving emails from it, send an
 email to clojure+unsubscr...@googlegroups.com.
 For more options, visit https://groups.google.com/d/optout.


-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
Clojure group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Update

2014-04-29 Thread Divyansh Prakash
Check out my previous reply. The parrot vm provides gc and everything, But 
still the author defines lambda primitives in c, and then builds over it.

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
Clojure group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Update

2014-04-29 Thread Andrew Chambers
For the llvm based approach you can look at vmkit.

On Wednesday, April 30, 2014 3:39:21 AM UTC+12, Divyansh Prakash wrote:

 Check out my previous reply. The parrot vm provides gc and everything, But 
 still the author defines lambda primitives in c, and then builds over it.

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
Clojure group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Update

2014-04-28 Thread Divyansh Prakash
Jasmin would be a much better choice, btw, because it could be used as a 
dependency in Clojure.

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
Clojure group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Update

2014-04-28 Thread Gary Trakhman
Seen: https://github.com/clojure/tools.emitter.jvm ?
Here's the actual ASM emit:
https://github.com/clojure/tools.emitter.jvm/blob/master/src/main/clojure/clojure/tools/emitter/jvm/transform.clj


On Mon, Apr 28, 2014 at 5:43 PM, Divyansh Prakash 
divyanshprakas...@gmail.com wrote:

 ---IDEA---
 I was wondering if we could have a bytecode DSL that would map directly to
 JVM assembler, using either Jasmin http://jasmin.sourceforge.net/ or
 Krakatau https://github.com/Storyyeller/Krakatau.
 Then we could define primitives using these bytecode instructions.
 For eg:

 (defroutine + [a b]
 (push! a)
 (push! b)
 add!
 pop!)

 that could be used to call:

 (+ 2 3) ;= 5

 --
 We could define the lambda calculus primitives in the same way.
 This would be awesome because bottlenecks could be optimized by embedding
 assembly inside Lisp itself.
 We could do efficient bit-manipulation, write shader routines, and what
 not.

 --
 Thoughts?

 --
 You received this message because you are subscribed to the Google
 Groups Clojure group.
 To post to this group, send email to clojure@googlegroups.com
 Note that posts from new members are moderated - please be patient with
 your first post.
 To unsubscribe from this group, send email to
 clojure+unsubscr...@googlegroups.com
 For more options, visit this group at
 http://groups.google.com/group/clojure?hl=en
 ---
 You received this message because you are subscribed to the Google Groups
 Clojure group.
 To unsubscribe from this group and stop receiving emails from it, send an
 email to clojure+unsubscr...@googlegroups.com.
 For more options, visit https://groups.google.com/d/optout.


-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
Clojure group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Update

2014-04-28 Thread Divyansh Prakash


 Thanks!

 Exactly what I was looking for.

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
Clojure group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Update to downloads page?

2012-06-21 Thread Timothy Baldridge
Or perhaps something like this:

Although it is possible to download Clojure directly here link, for
a more complete package management system please see Leiningen.

But yes, I agree, we need a big fat notice that says don't download
directly unless you know what you're doing.

Timothy

On Thu, Jun 21, 2012 at 1:11 PM, John Gabriele jmg3...@gmail.com wrote:
 Hi,

 It appears to me that, at the top of http://clojure.org/downloads , it
 should say,

 Though, for typical use, install
 [Leiningen](http://leiningen.org/index.html) and have it take care of
 getting Clojure for you.

 Would it be possible to change this? I've sent in my CA, but don't
 know if Rich got it yet.

 Thanks,
 ---John

 --
 You received this message because you are subscribed to the Google
 Groups Clojure group.
 To post to this group, send email to clojure@googlegroups.com
 Note that posts from new members are moderated - please be patient with your 
 first post.
 To unsubscribe from this group, send email to
 clojure+unsubscr...@googlegroups.com
 For more options, visit this group at
 http://groups.google.com/group/clojure?hl=en



-- 
“One of the main causes of the fall of the Roman Empire was
that–lacking zero–they had no way to indicate successful termination
of their C programs.”
(Robert Firth)

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: (update-in) and getting the new value at the leaf efficiently

2012-04-26 Thread Andy Fingerhut
Here is one way to do it called update-in+.  It returns a vector consisting
of the new udpated value, like update-in does, followed by the original
value (in case you might want to see that for some reason), followed by the
updated value.

(defn update-in+
  ([m [k  ks] f  args]
 (if ks
   (let [[new-map old-val new-val] (apply update-in+ (get m k) ks f
args)]
 [(assoc m k new-map) old-val new-val])
   (let [old-val (get m k)
 new-val (apply f old-val args)]
 [(assoc m k new-val) old-val new-val]

Andy

On Thu, Apr 26, 2012 at 9:19 AM, Ambrose Bonnaire-Sergeant 
abonnaireserge...@gmail.com wrote:

 Hi,

 You shouldn't need mutation for such a function.

 If you look at the source of update-in, it's fairly straightforward.

 (defn update-in
   ([m [k  ks] f  args]
(if ks
  (assoc m k (apply update-in (get m k) ks f args))
  (assoc m k (apply f (get m k) args)

 Just create another function that returns a vector of the result of
 applying f, and the update-in result. It should be easy starting from
 update-in's source.

 (I'm not aware of an existing solution)

 Thanks,
 Ambrose

 On Fri, Apr 27, 2012 at 12:00 AM, blais goo...@furius.ca wrote:

 Hi,
 I have this use-case for (update-in) which keeps showing up in my code
 which I don't have a solution for and I'm wondering if there isn't a
 solution.
 How do I _efficiently_ obtain the new value created by an invocation of
 (update-in), that is, without having to get the modified value by lookups
 in the new map?

 Simplified example:

 (def m {:planet {:country {:state {:city {:borough 4})

 (let [mm (update-in m
 [:planet :country :state :city :borough]
 (fn [old] (if (nil? old) 0 (inc old]
   (get-in mm [:planet :country :state :city :borough]))

 (update-in) returns the new/modified map, but what I want is to obtain
 the new count returned by the anonymous function.
 Having to call (get-in) right after is inefficient.

 This is obviously a contrived example for this question, but I have a lot
 of real use cases for this (where at the top level of my app I have a ref
 for a deep structure which changes as a response to network events).

 Is there an idiomatic way to do this without having to resort to
 mutability?
 (The only solution that comes to my mind is to wrap up update-in and the
 modifier function with a special version that updates a local mutable and
 return both the new map and the new object.)
 Nasty?

 Thank you,



  --
 You received this message because you are subscribed to the Google
 Groups Clojure group.
 To post to this group, send email to clojure@googlegroups.com
 Note that posts from new members are moderated - please be patient with
 your first post.
 To unsubscribe from 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: (update-in) and getting the new value at the leaf efficiently

2012-04-26 Thread Jay Fields
I would have written the fn like this, if I was following what you've been
doing:

(def m {:planet {:country {:state {:city {:borough 4})

(let [mm (update-in m [:planet :country :state :city :borough ] (fnil inc
-1))]
  (get-in mm [:planet :country :state :city :borough ]))

However, when I run into this pattern I usually

(let [v ((fnil inc -1) (get-in m [:planet :country :state :city :borough
]))]
  (assoc-in m [:planet :country :state :city :borough ] v))

The update in does a get, and I do a get-in, so I'm guessing the
performance is pretty similar, though I haven't tested it.

Cheers, Jay

On Thu, Apr 26, 2012 at 12:00 PM, blais goo...@furius.ca wrote:

 Hi,
 I have this use-case for (update-in) which keeps showing up in my code
 which I don't have a solution for and I'm wondering if there isn't a
 solution.
 How do I _efficiently_ obtain the new value created by an invocation of
 (update-in), that is, without having to get the modified value by lookups
 in the new map?

 Simplified example:

 (def m {:planet {:country {:state {:city {:borough 4})

 (let [mm (update-in m
 [:planet :country :state :city :borough]
 (fn [old] (if (nil? old) 0 (inc old]
   (get-in mm [:planet :country :state :city :borough]))

 (update-in) returns the new/modified map, but what I want is to obtain the
 new count returned by the anonymous function.
 Having to call (get-in) right after is inefficient.

 This is obviously a contrived example for this question, but I have a lot
 of real use cases for this (where at the top level of my app I have a ref
 for a deep structure which changes as a response to network events).

 Is there an idiomatic way to do this without having to resort to
 mutability?
 (The only solution that comes to my mind is to wrap up update-in and the
 modifier function with a special version that updates a local mutable and
 return both the new map and the new object.)
 Nasty?

 Thank you,



  --
 You received this message because you are subscribed to the Google
 Groups Clojure group.
 To post to this group, send email to clojure@googlegroups.com
 Note that posts from new members are moderated - please be patient with
 your first post.
 To unsubscribe from 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: (update-in) and getting the new value at the leaf efficiently

2012-04-26 Thread blais
Thanks Andy,
Two comments:

1. Your version does not use a transient/mutable, which is great, but it 
does create one vector for each level. I thought that since this would be 
wrapped and hidden from external view, a mutable would have been more 
appropriate.  More generally, I still don't know yet where to position 
myself when I code in Clojure, in terms of performance: I'm used to coding 
in C where I care a lot about every little detail, like cache coherency, or 
in Python for glue code where I really don't worry about such minute 
optimizations. Perhaps I tend to eagerly overoptimize in Clojure? Don't 
know.  I like your version in any case, thank you.

2. More importantly: I don't understand why I'm often having to add some 
functionality which I think of as something that everyone would need 
everywhere, and that makes me think I'm thinking about it the wrong way. 
For example, when I'm being careful about not using any mutable objects 
anywehre I end up with code that essentially recreates a new path to the 
root application every time I need to modify/store something in memory 
(i.e., I get a new version of the world on every update). So I wonder... 
isn't anybody else in dire need for something like update-in+?  How come 
not?  Isn't it a really common case that you need to modify some object 
far from the root object of your application, and if so, that you may need 
to do multiple things with that new object, beyond storing it by 
recreating all the intervening objects?  (e.g. (dosync (alter update-in 
...))) )

(Generally I find I get too little cultural osmosis when it comes to 
practical application of Clojure, so questions like this one come up all 
the time while I'm coding. Meetups and books touch on topics I understand 
well but rarely do people talk about the kinds of issues I'm encountering, 
like the one above. Libraries and other people's code often doesn't help 
all that much because it's fairly easy to do away with mutability in a 
library context.  I'll just read more OPC for now I guess.)


-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: (update-in) and getting the new value at the leaf efficiently

2012-04-26 Thread David Nolen
On Thu, Apr 26, 2012 at 4:30 PM, blais goo...@furius.ca wrote:

 (Generally I find I get too little cultural osmosis when it comes to
 practical application of Clojure, so questions like this one come up all
 the time while I'm coding. Meetups and books touch on topics I understand
 well but rarely do people talk about the kinds of issues I'm encountering,
 like the one above. Libraries and other people's code often doesn't help
 all that much because it's fairly easy to do away with mutability in a
 library context.  I'll just read more OPC for now I guess.)


Do you need to represent your data with that much nesting?

(def m {:planet ...
   :country ...
   :state ...
   :city ...
   :borough 4})

What's wrong with this representation?

David

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Re: (update-in) and getting the new value at the leaf efficiently

2012-04-26 Thread blais
On Thursday, April 26, 2012 4:36:52 PM UTC-4, David Nolen wrote:

 On Thu, Apr 26, 2012 at 4:30 PM, blais goo...@furius.ca wrote:

 (Generally I find I get too little cultural osmosis when it comes to 
 practical application of Clojure, so questions like this one come up all 
 the time while I'm coding. Meetups and books touch on topics I understand 
 well but rarely do people talk about the kinds of issues I'm encountering, 
 like the one above. Libraries and other people's code often doesn't help 
 all that much because it's fairly easy to do away with mutability in a 
 library context.  I'll just read more OPC for now I guess.)


 Do you need to represent your data with that much nesting?

 (def m {:planet ...
:country ...
:state ...
:city ...
:borough 4})

 What's wrong with this representation?

 
Well this was just to simplify my original question; the real application 
has a root instance that is a networked application class, which contains 
some list of clients, each of which has a mapping of orders (per exchange / 
market, this is a trading application) which themselves map to events 
related to those orders.  So it's more like application - client-handler 
- feed - market - order-id - event.  These aren't necessarily pure 
data classes--some of these may be records with implementations of 
protocols. 

I suppose I could elect to move refs for modifiable things towards the 
leaves, but that seems to me like going against the grain and may have 
implications for concurrency (there are few but some threads running in 
parallel in this application).  In this specific example of an application 
tree, where would you recommend the mutable objects be placed?

Thanks,

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Re: (update-in) and getting the new value at the leaf efficiently

2012-04-26 Thread David Nolen
On Thu, Apr 26, 2012 at 4:52 PM, blais goo...@furius.ca wrote:

 I suppose I could elect to move refs for modifiable things towards the
 leaves, but that seems to me like going against the grain and may have
 implications for concurrency (there are few but some threads running in
 parallel in this application).  In this specific example of an application
 tree, where would you recommend the mutable objects be placed?


Why do you need refs at leaves?

David

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Re: (update-in) and getting the new value at the leaf efficiently

2012-04-26 Thread blais
On Thursday, April 26, 2012 4:59:31 PM UTC-4, David Nolen wrote:

 On Thu, Apr 26, 2012 at 4:52 PM, blais goo...@furius.ca wrote:

 I suppose I could elect to move refs for modifiable things towards the 
 leaves, but that seems to me like going against the grain and may have 
 implications for concurrency (there are few but some threads running in 
 parallel in this application).  In this specific example of an application 
 tree, where would you recommend the mutable objects be placed?


 Why do you need refs at leaves?


I receive events from a network. My application calls for storing these 
events and doing different things based on the changing status of orders 
attached to these events. I need to store them somewhere, I need to track 
this state in my app. At one extreme, I could store the changing state near 
the leaves (i.e. a list of events by order-id by ...). At another extreme, 
I could recreate the entire path of immutable objects all the way to the 
root application on every update (using update-in, and with a single ref 
for the root application).  And then there's all the other options in 
between, I could have refs are every level if I chose to (but that seems 
very, very wrong, somehow).

Java would call for mutability at the leaves.  
Clojure makes it easy to build it one way or another, but the language is 
calling for refs at the root. 

Isn't this a really common case of every type of application out there 
which has to store some changing state somewhere?

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: (update-in) and getting the new value at the leaf efficiently

2012-04-26 Thread David Nolen
On Thu, Apr 26, 2012 at 5:08 PM, blais goo...@furius.ca wrote:

 I receive events from a network. My application calls for storing these
 events and doing different things based on the changing status of orders
 attached to these events. I need to store them somewhere, I need to track
 this state in my app. At one extreme, I could store the changing state near
 the leaves (i.e. a list of events by order-id by ...). At another extreme,
 I could recreate the entire path of immutable objects all the way to the
 root application on every update (using update-in, and with a single ref
 for the root application).  And then there's all the other options in
 between, I could have refs are every level if I chose to (but that seems
 very, very wrong, somehow).

 Java would call for mutability at the leaves.
 Clojure makes it easy to build it one way or another, but the language is
 calling for refs at the root.

 Isn't this a really common case of every type of application out there
 which has to store some changing state somewhere?


You've already stated that your multithreaded needs are modest. Why not one
atom wrapping all your data, each piece indexed by the most relevant key,
and each actual piece of data is flat.

David

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Re: (update-in) and getting the new value at the leaf efficiently

2012-04-26 Thread kurtharriger
I think you are too concerned with micro optimizations.  get-in is probably 
just as efficient as attempting to bubble the state change back up and 
certainly simpler to work with.  In practice, optimizations like this do not 
have a significant impact on the overall performace.  
Measure before you optimize.  I might also add, parrelize before you optimize. 
Immutable data structures often makes it much easier to parrelize the 
algorithm, so even if you do have slow spots if the applications critical path 
is not affected you still may not need to optimize. 

There probably are several methods in clojure that can be significantly 
optimized and eventually someone will, but the best optimizations will come 
from real world performance problems not theoretical ones.  Do some research on 
clojures vector implementation and you'll see the fastest implementation in 
theory is comparitively slow in practice due to the way the caching works. 

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en


Re: Update an item from a list of maps in STM transaction

2012-04-02 Thread Stephen Compall
On Sat, 2012-03-31 at 11:00 -0700, Marcelo Macedo de Melo Silva wrote:
 I'm running multiple threads using this same list and need to update
 the value of an item inside a STM transaction.

If you mean by value of an item the value in the database: I suggest
you create an updater agent instead, shared by all the threads.  While
each thread is in a transaction, it can `send' an action to update the
database to this agent.  Agent sends are queued by the STM, so you can
be sure only one update happens, and only if a transaction succeeds.

If you mean to mutate the list of maps, you can't do that.

 I tried using one FUTURE for a REF but is not working.

Not sure what this means.  Futures are IDerefs...

-- 
Stephen Compall
^aCollection allSatisfy: [:each|aCondition]: less is better

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: Update swank classpath on the fly?

2011-11-04 Thread Jack Moffitt
 I've noticed that swank (which I run in emacs using M-x clojure-jack-
 in) doesn't pickup changes to the classpath on-the-fly. For example,
 if I update my leiningen project.clj with a new dependency and run
 lein deps, I need to restart swank to have it use the library. Is
 there a way to load something into a running swank without restarting
 it (which causes loss of state in the slime-repl).

I have the same project, which I suspect is a limitation of the JVM.
I'd settle for a fast way to restart the session.

jack.

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: Update swank classpath on the fly?

2011-11-04 Thread Chas Emerick

On Nov 4, 2011, at 11:53 AM, AndyK wrote:

 I've noticed that swank (which I run in emacs using M-x clojure-jack-
 in) doesn't pickup changes to the classpath on-the-fly. For example,
 if I update my leiningen project.clj with a new dependency and run
 lein deps, I need to restart swank to have it use the library. Is
 there a way to load something into a running swank without restarting
 it (which causes loss of state in the slime-repl).
 
 thx

This is part of what pomegranate provides:

https://github.com/cemerick/pomegranate

It won't pick up changes from your project.clj, but it does provide an 
`add-dependencies` function that works with leiningen-style dependency notation 
(and an improved `add-classpath` if you just have jars available on disk you 
want to dynamically add to your classpath).

However, I have at least one report that pomegranate fails under swank:

https://github.com/cemerick/pomegranate/issues/1

It'd be great to get confirmation or not of that issue (or, even better, a 
patch to make it work under swank!).  FWIW, it works fine in a command-line 
REPL and with nREPL (jark, counterclockwise).  I've yet to test it with 
swank/slime myself.

Cheers,

- Chas

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: update to clojure.tools.cli

2011-11-01 Thread Aaron Bedra
It's strange that it hasn't made it to central yet. This is normally a few
hours on the high end and it's been over 12 now.  I double checked that the
release hit sonatype

https://oss.sonatype.org/content/repositories/public/org/clojure/tools.cli/0.2.0/

We might need to summon the all mighty Stuart Sierra to see if he knows
what could have happened.

Cheers,

Aaron Bedra
--
Clojure/core
http://clojure.com

On Tue, Nov 1, 2011 at 1:59 PM, gaz jones gareth.e.jo...@gmail.com wrote:

 Hi,

 I have made some changes to tools.cli to fix an annoying bug arround
 boolean flags and the inability to collect 'trailing arguments'.
 Whilst gathering opinions on these changes, a few other suggestions
 were made such as removing all magic functions and System/exit calls.
 The update is therefore going to break the existing API which you
 obviously need to be aware of if you are currently using 0.1.0 and
 intend to upgrade to 0.2.0.

 The release has been cut, but the last time I checked it still hadn't
 hit maven central, so this is slightly advanced notice. To see details
 of the new api please see: https://github.com/clojure/tools.cli.

 There are a few things worth mentioning... support for grouped options
 has been removed, and the result of the call to cli is now a vector of
 [options, trailing arguments, usage banner] (originally it was just a
 hash of options). Automatic help is also no longer provided, an
 example of how to roll your own is at the bottom of the aforementioned
 page.

 a brief example of the differences (see the site for full details though):

 0.1.0:

 (cli [-p 8080 -v --foo bar some-filename]
 (optional [-p --port The port] #(Integer. %))
 (optional [-f --foo Some foos])
 (optional [-v --[no-]verbose Be chatty])

 = {:port 8080, :foo bar, :verbose true}

 0.2.0:

 (cli [-p 8080 --foo bar -v some-filename]
 [-p --port The port :parse-fn  #(Integer. %)]
 [-f --foo Some foos]
 [-v --[no-]verbose Be chatty :default false])

 = [{:port 8080, :foo bar, :verbose true}, [some-filename], *the
 usage banner*]

 Apologies for anyone upset by the timing / notification of the changes
 -- I will give greater advanced notice in future if there are any more
 breaking changes (hopefully there wont be :D)

 --
 You received this message because you are subscribed to the Google
 Groups Clojure group.
 To post to this group, send email to clojure@googlegroups.com
 Note that posts from new members are moderated - please be patient with
 your first post.
 To unsubscribe from 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: update to clojure.tools.cli

2011-11-01 Thread Sean Corfield
It's on Maven Central now...

On Tue, Nov 1, 2011 at 11:59 AM, Aaron Bedra aaron.be...@gmail.com wrote:
 It's strange that it hasn't made it to central yet.
...
 On Tue, Nov 1, 2011 at 1:59 PM, gaz jones gareth.e.jo...@gmail.com wrote:
 The release has been cut, but the last time I checked it still hadn't
 hit maven central, so this is slightly advanced notice. To see details
 of the new api please see: https://github.com/clojure/tools.cli.

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: update to clojure.tools.cli

2011-11-01 Thread Sean Corfield
On Tue, Nov 1, 2011 at 10:59 AM, gaz jones gareth.e.jo...@gmail.com wrote:
 The update is therefore going to break the existing API which you
 obviously need to be aware of if you are currently using 0.1.0 and
 intend to upgrade to 0.2.0.
...
 Apologies for anyone upset by the timing / notification of the changes
 -- I will give greater advanced notice in future if there are any more
 breaking changes (hopefully there wont be :D)

FWIW, I really like the changes and will be upgrading a number of
utilities to 0.2.0 shortly at World Singles (even tho' every one of
them needs changes!).
-- 
Sean A Corfield -- (904) 302-SEAN
An Architect's View -- http://corfield.org/
World Singles, LLC. -- http://worldsingles.com/

Perfection is the enemy of the good.
-- Gustave Flaubert, French realist novelist (1821-1880)

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: update xml attribute value

2011-06-02 Thread Allen Johnson
 Does anyone know how to update xml element attribute value on the zipper
 data structure?
 I have something like
 root
     element1 name=x1 description=d1/
     element2 name=x2 description=d2/
 /root
 (:require (clojure [xml :as xml] [zip :as zip])
      [clojure.contrib.zip-filter.xml :as zf])
 (let
   [src (- c:/my.xml io/file xml/parse zip/xml-zip)
    edf (zf/xml1- src :root :element1)
    n    (- (zf/attr :description) (zip/replace ))])
 and this is giving me java.lang.ClassCastException: java.lang.Character
 cannot be cast to clojure.lang.Associative (test-xml-zip.clj:0)

Given that 'loc is the proper location in your zipper:

(zip/edit loc assoc-in [:attrs :description] new value)

Allen

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: update xml attribute value

2011-06-02 Thread siyu798
Thanks Allen, it works, I did not know the loc can be treated like a hash.

siyu

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: update xml attribute value

2011-06-02 Thread Allen Johnson
 Thanks Allen, it works, I did not know the loc can be treated like a hash.

'loc itself isn't a map even though zip/edit makes it seem that way.
Behind the scenes zip/edit calls (zip/node loc) which will return a
map, at least in the case of this xml example. zip/edit then applies
the function you provided (assoc-in) to this map plus any supplied
args. The result of this replaces the node at loc.

https://github.com/clojure/clojure/blob/59b65669860a1f33825775494809e5d500c19c63/src/clj/clojure/zip.clj#L210

Allen

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: update-in oddness

2010-06-04 Thread Joost
On Jun 4, 7:37 am, Heinz N. Gies he...@licenser.net wrote:
 Update-in behaves oddly when getting an empty path. (update-in [] {1 2} 
 (constantly {2 3})) returns {nil {2 3} 1 2} not {2 3} as I'd expect. get-in 
 works well with empty pathes so I think this isn't a good behavior.

I don't know why you expect that to do anything - first of all, the
second argument to update-in should be a seq of keys. In any case, it
throws

nth not supported on this type: PersistentArrayMap
  [Thrown class java.lang.UnsupportedOperationException]

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: update-in oddness

2010-06-04 Thread Heinz N. Gies

On Jun 4, 2010, at 11:15 , Joost wrote:

 On Jun 4, 7:37 am, Heinz N. Gies he...@licenser.net wrote:
 Update-in behaves oddly when getting an empty path. (update-in [] {1 2} 
 (constantly {2 3})) returns {nil {2 3} 1 2} not {2 3} as I'd expect. get-in 
 works well with empty pathes so I think this isn't a good behavior.
 
 I don't know why you expect that to do anything - first of all, the
 second argument to update-in should be a seq of keys. In any case, it
 throws
 
 nth not supported on this type: PersistentArrayMap
  [Thrown class java.lang.UnsupportedOperationException]

Sorry I mixed arguments, it should be (update-in {1 2} [] (constantly {2 3})) 

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: update-in oddness

2010-06-04 Thread Joost
On Jun 4, 1:42 pm, Heinz N. Gies he...@licenser.net wrote:
 Sorry I mixed arguments, it should be (update-in {1 2} [] (constantly {2 3}))

Yes, that gives {nil {2 3}, 1 2}

You're not giving any key in the key list, so that is the reason
there's a nil key now, and {2 3} is just the value that you give it,
since that's what ((constantly {2 3}) nil) returns.

Seems correct as far as the documentation of update-in is concerned.

Joost.

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: update-in oddness

2010-06-04 Thread Joost


On Jun 4, 2:03 pm, Joost jo...@zeekat.nl wrote:
 Seems correct as far as the documentation of update-in is concerned.

Addendum: though I think you've got a point in that inserting a nil
key is unexpected.
Personally, I don't really know what to expect from that expression.

Joost.

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: update-in oddness

2010-06-04 Thread Heinz N. Gies

On Jun 4, 2010, at 14:03 , Joost wrote:

 On Jun 4, 1:42 pm, Heinz N. Gies he...@licenser.net wrote:
 Sorry I mixed arguments, it should be (update-in {1 2} [] (constantly {2 3}))
 
 Yes, that gives {nil {2 3}, 1 2}
 
 You're not giving any key in the key list, so that is the reason
 there's a nil key now, and {2 3} is just the value that you give it,
 since that's what ((constantly {2 3}) nil) returns.
 
 Seems correct as far as the documentation of update-in is concerned.
 
I'd expect that a empty key works on the entire  map, just as get-in with en 
empty key returns the entire map, this is kind of very important if you work 
with automatically with keys since otherwise you always have to handle the 
special case []. This is very annoying :(

here an example:

(if-let [r (butlast @path)]
  (do
(alter m update-in r dissoc (last @path))
(alter m update-in r assoc {:name @sr} c))
  (do
(alter m dissoc (last @path))
(alter m assoc {:name @sr} c)))

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Re: update-in oddness

2010-06-04 Thread Heinz N. Gies

On Jun 4, 2010, at 14:11 , Heinz N. Gies wrote:

 
 On Jun 4, 2010, at 14:03 , Joost wrote:
 
 On Jun 4, 1:42 pm, Heinz N. Gies he...@licenser.net wrote:
 Sorry I mixed arguments, it should be (update-in {1 2} [] (constantly {2 
 3}))
 
 Yes, that gives {nil {2 3}, 1 2}
 
 You're not giving any key in the key list, so that is the reason
 there's a nil key now, and {2 3} is just the value that you give it,
 since that's what ((constantly {2 3}) nil) returns.
 
 Seems correct as far as the documentation of update-in is concerned.


So for how I'd expect it to work:

(defn update-in*
  ([m [k  ks] f  args]
   (if ks
 (assoc m k (apply update-in* (get m k) ks f args))
 (if k
   (assoc m k (apply f (get m k) args))
   (apply f  m args)

user (get-in {1 2} [])
{1 2}
user (update-in* {1 2} [] assoc  1 3)
{1 3}

In opposite of how it works:

user (update-in {1 2} [] assoc  1 3)
{nil {1 3}, 1 2}



-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: update-in oddness

2010-06-04 Thread Chouser
On Fri, Jun 4, 2010 at 10:04 AM, Heinz N. Gies he...@licenser.net wrote:

 On Jun 4, 2010, at 14:11 , Heinz N. Gies wrote:


 On Jun 4, 2010, at 14:03 , Joost wrote:

 On Jun 4, 1:42 pm, Heinz N. Gies he...@licenser.net wrote:
 Sorry I mixed arguments, it should be (update-in {1 2} [] (constantly {2 
 3}))

 Yes, that gives {nil {2 3}, 1 2}

 You're not giving any key in the key list, so that is the reason
 there's a nil key now, and {2 3} is just the value that you give it,
 since that's what ((constantly {2 3}) nil) returns.

 Seems correct as far as the documentation of update-in is concerned.


 So for how I'd expect it to work:

 (defn update-in*
  ([m [k  ks] f  args]
   (if ks
     (assoc m k (apply update-in* (get m k) ks f args))
     (if k
       (assoc m k (apply f (get m k) args))
       (apply f  m args)

 user (get-in {1 2} [])
 {1 2}
 user (update-in* {1 2} [] assoc  1 3)
 {1 3}

I agree with the spirit of your argument, but not your
implementation:

  (update-in* {nil 2} [nil] (constantly 3))
  ;= 3

Perhaps:

  (defn update-in*
[m ks f  args]
(if-let [[k  mk] ks]
(if mk
(assoc m k (apply update-in* (get m k) mk f args))
(assoc m k (apply f (get m k) args)))
  (apply f m args)))

  (update-in* {nil 2} [nil] (constantly 3))
  ;= {nil 3}

--Chouser
http://joyofclojure.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: update-in oddness

2010-06-04 Thread Heinz N. Gies
On Jun 4, 2010, at 16:23 , Chouser wrote:

 
 I agree with the spirit of your argument, but not your
 implementation:
 
  (update-in* {nil 2} [nil] (constantly 3))
  ;= 3
As so often Chouser, you are of cause totally right :). I just realized the 
flaw when I was about to open a ticket but you were faster ;) well this are 
good news so since I don't have a CA signed yet (actually I do just not send it 
:P) so one could use your code as a fix.


Regards,
Heinz

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en


Re: update-in and get-in why no default?

2010-02-02 Thread Timothy Pratley
On 2 February 2010 17:55, Richard Newman holyg...@gmail.com wrote:
 If you view 'get-in' as an unwrapping operation, unwrapping by zero steps
 should return the existing collection, no?

Thanks for that description I completely agree.


 Can you explain why you think the result should be nil?

I was not thinking very clearly :) Loosely 'oh there is nothing to
look up'. Thanks for setting me straight.


 As above: I equate nil with the empty sequence.

Yup.


Ok patch updated - salient part is:
+  ([m ks not-found]
+   (if (seq ks)
+ (if-let [l (reduce get m (butlast ks))]
+   (get l (last ks) not-found)
+   not-found)
+ m)))

Which preserves all the desired behavior so far :)

http://www.assembla.com/spaces/clojure/tickets/256-get-in-optional-default-value


Regards,
Tim.

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: update-in and get-in why no default?

2010-02-02 Thread Meikel Brandmeyer
Hi,

On Feb 2, 1:48 pm, Timothy Pratley timothyprat...@gmail.com wrote:

  If you view 'get-in' as an unwrapping operation, unwrapping by zero steps
  should return the existing collection, no?

 Thanks for that description I completely agree.

Hmm.. I thought of get-in as a recursive application of get. get-in
now diverges from get. Maybe this version should be called unwrap
instead?

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: update-in and get-in why no default?

2010-02-02 Thread Meikel Brandmeyer
Hi,

On Feb 2, 2:31 pm, Timothy Pratley timothyprat...@gmail.com wrote:

  Hmm.. I thought of get-in as a recursive application of get. get-in
  now diverges from get. Maybe this version should be called unwrap
  instead?

 Zero applications of get to a map might be thought of as the map itself.
 Are you thinking of a particular scenario where throwing an exception
 would be better?

Ok. One could see this like that:

(get-in m [:a :b]) = (get (get m :a) :b)
(get-in m [:a])= (get m :a)
(get-in m [])  = m

In so far I understand the picture of what happens. But does it make
sense?

get-in does a lookup of a key sequence in a nested structure of
associative things. I think nil/[] are simply not in the domain of get-
in. However it can be extended to nil/[] as the identity.

So in the end it will probably boil down to some suitable definition
argument of the domain of get-in. And I see some applications, where
just returning the original thing might be handy.

I'm persuaded. :)

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: update-in and get-in why no default?

2010-02-01 Thread Timothy Pratley
 Am 31.01.2010 um 18:29 schrieb Daniel Werner:
 If I understand this arity version of get-in correctly, won't the
 default also be used if the value stored in the nested data structure
 evaluates to something false-y?

Thanks for spotting that early!


On 1 February 2010 05:46, Meikel Brandmeyer m...@kotka.de wrote:
 (if-let [l (reduce get m (pop ks))]
  (get l (peek ks) not-found)
  not-found))

Good idea, but peek and pop work differently on vectors and sequences,
seeing get-in is not constrained to use vectors this could lead to an
unexpected behavior:
user= (def m  {:a 1, :b 2, :c {:d 3, :e 4}, :f nil})
#'user/m
user= (get-in3 m '(:c :e) 2)   ;peek-pop keys applied in unexpected order
2
user= (get-in2 m '(:c :e) 2)   ;expected result
4

I've replaced the patch on assembla with this:
   (reduce #(get %1 %2 not-found) m ks)))
And added test cases for the falsey returns and seq args



Regards,
Tim.

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: update-in and get-in why no default?

2010-02-01 Thread Meikel Brandmeyer
Hi,

On Feb 1, 1:57 pm, Timothy Pratley timothyprat...@gmail.com wrote:

 Good idea, but peek and pop work differently on vectors and sequences,
 seeing get-in is not constrained to use vectors this could lead to an
 unexpected behavior:
 user= (def m  {:a 1, :b 2, :c {:d 3, :e 4}, :f nil})
 #'user/m
 user= (get-in3 m '(:c :e) 2)   ;peek-pop keys applied in unexpected order
 2
 user= (get-in2 m '(:c :e) 2)   ;expected result
 4

o.O Ok... 100% of my use-cases for get-in were with vectors up to now.
Didn't think about the allowing lists also.

 I've replaced the patch on assembla with this:
    (reduce #(get %1 %2 not-found) m ks)))
 And added test cases for the falsey returns and seq args

Consider this (admittedly constructed) case:

(get-in {:a {:b 1}} [:x :c] {:c :uhoh})

I would not mind only allowing vectors in the interface. I would
expect the length of such a chain sufficiently short for easy
conversion if necessary. Or to use butlast/last instead of peek/pop.
Again the damage would be limited by the short keychain length.
(Of course it would have to be considered: is the usual keychain
really short?)

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: update-in and get-in why no default?

2010-02-01 Thread Timothy Pratley
On 2 February 2010 00:18, Meikel Brandmeyer m...@kotka.de wrote:
 Consider this (admittedly constructed) case:
 (get-in {:a {:b 1}} [:x :c] {:c :uhoh})

Excellent point!


 Or to use butlast/last instead of peek/pop.

I think this is the best approach. butlast/last have linear time so
the overhead is small.

There are still some sharp edges I'm not sure about:
(A) user= (get-in {:a 1} [])
{:a 1}
;; this is existing behavior, but I feel the result should be nil

(B) user= (get-in {:a 1} nil)
{:a 1}
;; this is existing behavior, but I feel the result should be nil (nil
is a seq so not an exception)

(C) user= (get-in {:a 1} 5)
java.lang.IllegalArgumentException: Don't know how to create ISeq
from: java.lang.Integer (NO_SOURCE_FILE:0)
;; existing behavior, seems sensible to throw an exception here rather
than return nil

(D) user= (get-in {nil {:a 1}} [] 2)
{:a 1}
;; new behavior
;; using last/butlast only - this is wrong... need to check the seq size
;; the solution depends upon what is correct for the preceding cases
so need to establish those first

Alternatively one could take the view that [] and nil are illegal key
sequences, in which case should get-in enforce that (via preconditions
or just a check) or should it just be added to the doc-string that
using those values is undefined, or both?

I've marked the ticket back to new in the meantime... will update once resolved.


For reference here is a version that behaves most like existing get-in:

(defn get-in
  Returns the value in a nested associative structure,
  where ks is a sequence of keys. Returns nil if the key is not present,
  or the not-found value if supplied.
  ([m ks]
   (reduce get m ks))
  ([m ks not-found]
   (if (empty? ks)
 m
 (if-let [l (reduce get m (butlast ks))]
   (get l (last ks) not-found)
   not-found

I'm not convinced returning the map when given an empty key sequence
is the right thing to do, I'd prefer it to return nil or throw an
exception in both arity cases.


Regards,
Tim.

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: update-in and get-in why no default?

2010-02-01 Thread Meikel Brandmeyer
Hi Timothy,

On Feb 2, 1:19 am, Timothy Pratley timothyprat...@gmail.com wrote:

 There are still some sharp edges I'm not sure about:
 (A) user= (get-in {:a 1} [])
 {:a 1}
 ;; this is existing behavior, but I feel the result should be nil

+1 for nil

 (B) user= (get-in {:a 1} nil)
 {:a 1}
 ;; this is existing behavior, but I feel the result should be nil (nil
 is a seq so not an exception)

+1 for nil

 (C) user= (get-in {:a 1} 5)
 java.lang.IllegalArgumentException: Don't know how to create ISeq
 from: java.lang.Integer (NO_SOURCE_FILE:0)
 ;; existing behavior, seems sensible to throw an exception here rather
 than return nil

+1 for exception

 (D) user= (get-in {nil {:a 1}} [] 2)
 {:a 1}
 ;; new behavior
 ;; using last/butlast only - this is wrong... need to check the seq size
 ;; the solution depends upon what is correct for the preceding cases
 so need to establish those first

 Alternatively one could take the view that [] and nil are illegal key
 sequences, in which case should get-in enforce that (via preconditions
 or just a check) or should it just be added to the doc-string that
 using those values is undefined, or both?

I'm not sure about this too. I tend to an exception. (get m) will also
throw an exception...

 For reference here is a version that behaves most like existing get-in:

 (defn get-in
   Returns the value in a nested associative structure,
   where ks is a sequence of keys. Returns nil if the key is not present,
   or the not-found value if supplied.
   ([m ks]
    (reduce get m ks))
   ([m ks not-found]
    (if (empty? ks)
      m
      (if-let [l (reduce get m (butlast ks))]
        (get l (last ks) not-found)
        not-found

I would get rid of the if-let. Together with throwing an exception in
case of an empty key sequence we get:

(defn get-in
  Returns the value in a nested associative structure,
  where ks is a sequence of keys. Returns nil if the key is not
present,
  or the not-found value if supplied.
  ([m ks] (get-in m ks nil))
  ([m ks not-found]
   (if-let [ks (seq ks)]
 (get (reduce get m (butlast ks)) (last ks) not-found)
 (throw (Exception. key sequence must not be empty)

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: update-in and get-in why no default?

2010-02-01 Thread Richard Newman

There are still some sharp edges I'm not sure about:
(A) user= (get-in {:a 1} [])
{:a 1}
;; this is existing behavior, but I feel the result should be nil


+1 for nil


I think I disagree.

If you view 'get-in' as an unwrapping operation, unwrapping by zero  
steps should return the existing collection, no?


{:foo {:bar {:baz 1}}}

[] = {:foo ...
[:foo] = {:bar ...
[:foo :bar]= {:baz ...

This maps trivially to a sophisticated user's recursive mental model  
of get-in:


(defn get-in [m ks]
  (loop [looking-at m
 first-key  (first ks)
 remaining-keys (rest ks)]
(if-not first-key
  looking-at
  (recur (get looking-at first-key)
 (first remaining-keys)
 (rest  remaining-keys)

... if there are no keys, it returns m. That's intuitive to me, at  
least.


Can you explain why you think the result should be nil?


(B) user= (get-in {:a 1} nil)
{:a 1}
;; this is existing behavior, but I feel the result should be nil  
(nil

is a seq so not an exception)


+1 for nil


As above: I equate nil with the empty sequence.

--
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: update-in and get-in why no default?

2010-02-01 Thread Meikel Brandmeyer
Hi,

On Feb 2, 7:55 am, Richard Newman holyg...@gmail.com wrote:

 I think I disagree. Can you explain why you think the result should be nil?

Woops. I got confused. I didn't mean nil for empty key sequences. I
meant throwing an exception as does get.

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: update-in and get-in why no default?

2010-01-31 Thread Daniel Werner
  ([m ks not-found]
   (if-let [v (reduce get m ks)]
 v
 not-found)))

If I understand this arity version of get-in correctly, won't the
default also be used if the value stored in the nested data structure
evaluates to something false-y?

Anyway, thanks for creating the patches!

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: update-in and get-in why no default?

2010-01-31 Thread Meikel Brandmeyer
Hi,

Am 31.01.2010 um 18:29 schrieb Daniel Werner:

 ([m ks not-found]
  (if-let [v (reduce get m ks)]
v
not-found)))
 
 If I understand this arity version of get-in correctly, won't the
 default also be used if the value stored in the nested data structure
 evaluates to something false-y?

Yes. It should probably read:

(if-let [l (reduce get m (pop ks))]
  (get l (peek ks) not-found)
  not-found))

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: update-in and get-in why no default?

2010-01-29 Thread Rich Hickey


On Dec 30 2009, 6:18 am, Timothy Pratley timothyprat...@gmail.com
wrote:
 On Dec 13, 1:24 am, Rich Hickey richhic...@gmail.com wrote:

  fnil seems to me to have greater utility than patching all functions
  that apply functions with default-supplying arguments.

 Neat :) I like it.

  The get-in function could be enhanced, and would mirror get.

 Should I interpret 'could' as 'patch welcome' or 'let me think about
 it'?


Patches welcome for get-in, and my fnil.

Thanks,


Rich

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en


Re: update-in and get-in why no default?

2010-01-29 Thread Sean Devlin
Rich,
Your example didn't support a variadic signature.  Is that the long
term plan?

Sean

On Jan 29, 8:48 am, Rich Hickey richhic...@gmail.com wrote:
 On Dec 30 2009, 6:18 am, Timothy Pratley timothyprat...@gmail.com
 wrote:

  On Dec 13, 1:24 am, Rich Hickey richhic...@gmail.com wrote:

   fnil seems to me to have greater utility than patching all functions
   that apply functions with default-supplying arguments.

  Neat :) I like it.

   The get-in function could be enhanced, and would mirror get.

  Should I interpret 'could' as 'patch welcome' or 'let me think about
  it'?

 Patches welcome for get-in, and my fnil.

 Thanks,

 Rich

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en


Re: update-in and get-in why no default?

2010-01-29 Thread Rich Hickey


On Jan 29, 9:04 am, Sean Devlin francoisdev...@gmail.com wrote:
 Rich,
 Your example didn't support a variadic signature.  Is that the long
 term plan?


It's the short term plan. Let's see if there's any real need for more
than three. I've never needed more than one.

Rich

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en


Re: update-in and get-in why no default?

2010-01-29 Thread Timothy Pratley
2010/1/30 Rich Hickey richhic...@gmail.com:
 Patches welcome for get-in, and my fnil.

Groovy! uploaded to:
https://www.assembla.com/spaces/clojure/tickets/256-get-in-optional-default-value
https://www.assembla.com/spaces/clojure/tickets/257-add-fnil-for-wrapping-functions-to-handle-nil


Regards,
Tim.

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: update-in! (?)

2010-01-21 Thread Gabi
I don't think zipper would help in this case

On Jan 21, 12:40 am, brianh brian.h.w...@gmail.com wrote:
 Any chance you could rethink your approach  use a zipper?

 On Jan 20, 9:32 am, Gabi bugspy...@gmail.com wrote:

  I posted a question on SO about it. Interesting 
  discussion:http://stackoverflow.com/questions/2102606/algorithm-to-implement-non...

  On Jan 20, 5:39 pm, Christophe Grand christo...@cgrand.net wrote:

   I concur: a map (or a sorted map if you need to emulate access to a
   subtree) can be an option.

   [[1 2] [3 4]] is represented by {[0 0] 1, [0 1] 2, [1 0] 3, [1 1] 4}

   On Wed, Jan 20, 2010 at 4:24 PM, Sean Devlin francoisdev...@gmail.com 
   wrote:
How about a sorted set w/ a custom comparator?  Of course, this rules
out transients, but maybe the flatness will make up for it?

On Jan 20, 10:15 am, Gabi bugspy...@gmail.com wrote:
I need to add/delete much more frequently than just updating
actually.

On Jan 20, 4:59 pm, Sean Devlin francoisdev...@gmail.com wrote:

 Gabi,
 A similar technique is used with sparse matrices.  You usually have
 severals arrays, one for the non-zero elements, and another one for
 indexing the column and a third for indexing the rows.

http://pasadena.wr.usgs.gov/office/baagaard/research/papers/thesis/fi...

 This should be fast as long as you're only updating.  If you're
 inserting/deleting, you might be able to get away with using a
 collection of 1D trees.

 Sean

 On Jan 20, 9:18 am, Gabi bugspy...@gmail.com wrote:

  These vectors represent trees which need to updated very 
  frequently.
  So If there was an efficient way to use transients to represent
  transient trees the whole process would be much more efficient (so
  each update to a tree would be done in place instead of creating 
  new
  one.) As discussed above, naive usage of transients won't help.
  Another approach would be implement in Java, but I wish there would
  some way to achieve this directly from Clojure.
  Now that I think about it, maybe the solution is to represent the 
  tree
  as one dimensional vector instead of nested one (any good clojure
  algorithm for this ? Representing and traversing non binary trees 
  as
  one dimensional vector?)

  Jan 20, 12:53 pm, Christophe Grand christo...@cgrand.net wrote:

   Hi Gabi!

   Can you tell us more about your problem, what do those deeply 
   nested
   vectors represent and how are you going to update them? (are all
   updates batched in one part of your program?)

   With transients current implementation you can't write an 
   efficient update-in!

   Christophe

   On Wed, Jan 20, 2010 at 9:15 AM, Gabi bugspy...@gmail.com 
   wrote:
Guys, I really need your expertise here.
I have lots of deeply nested vectors, which i need to 
manipulate
frequently (thousands of times)
What is the most effective way to do this ?

On Jan 17, 4:27 pm, Gabi bugspy...@gmail.com wrote:
Right. I thought that transient performing deep 
'transientivity'.
Here is a fixed version. It takes a regular coll converts 
whatever it
can to transient and update the stuff.
The problem is that doing persistent!(assoc!(transient m)) on 
each
level probably misses the whole point of performance.
So while it work, it probably slower than the regular 
update-in.
I need a better solution.

(defn update-in!!
  modified version of core/update-in that works on, and 
return
transiants
  ([m [k  ks] f  args]
   (if ks
     (persistent!(assoc! (transient m) k (apply update-in!! 
(get m k)
ks f args)))
     (persistent!(assoc! (transient m) k (apply f (get m k) 
args))

On Jan 17, 3:57 pm, Chouser chou...@gmail.com wrote:

 On Sun, Jan 17, 2010 at 8:25 AM, Gabi bugspy...@gmail.com 
 wrote:

  user= (persistent!(update-in!(transient v) [0] reverse))

  Forgot to mention that v in the example is defined to  
  [[1 2] [3 4]]

 So you've got a transient vector of persistent vectors of
 numbers.  The problem is your update-in! then calls assoc! 
 on
 each level, but of course assoc! on the inner persistent 
 vector
 fails.

 You either need to make the inner vectors transient (and 
 then
 call persist! on them when you're done) or use assoc! only 
 at the
 outer level.

 --Chouserhttp://joyofclojure.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 

Re: update-in! (?)

2010-01-20 Thread Gabi
Guys, I really need your expertise here.
I have lots of deeply nested vectors, which i need to manipulate
frequently (thousands of times)
What is the most effective way to do this ?

On Jan 17, 4:27 pm, Gabi bugspy...@gmail.com wrote:
 Right. I thought that transient performing deep 'transientivity'.
 Here is a fixed version. It takes a regular coll converts whatever it
 can to transient and update the stuff.
 The problem is that doing persistent!(assoc!(transient m)) on each
 level probably misses the whole point of performance.
 So while it work, it probably slower than the regular update-in.
 I need a better solution.

 (defn update-in!!
   modified version of core/update-in that works on, and return
 transiants
   ([m [k  ks] f  args]
    (if ks
      (persistent!(assoc! (transient m) k (apply update-in!! (get m k)
 ks f args)))
      (persistent!(assoc! (transient m) k (apply f (get m k) args))

 On Jan 17, 3:57 pm, Chouser chou...@gmail.com wrote:

  On Sun, Jan 17, 2010 at 8:25 AM, Gabi bugspy...@gmail.com wrote:

   user= (persistent!(update-in!(transient v) [0] reverse))

   Forgot to mention that v in the example is defined to  [[1 2] [3 4]]

  So you've got a transient vector of persistent vectors of
  numbers.  The problem is your update-in! then calls assoc! on
  each level, but of course assoc! on the inner persistent vector
  fails.

  You either need to make the inner vectors transient (and then
  call persist! on them when you're done) or use assoc! only at the
  outer level.

  --Chouserhttp://joyofclojure.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: update-in! (?)

2010-01-20 Thread Christophe Grand
Hi Gabi!

Can you tell us more about your problem, what do those deeply nested
vectors represent and how are you going to update them? (are all
updates batched in one part of your program?)

With transients current implementation you can't write an efficient update-in!

Christophe

On Wed, Jan 20, 2010 at 9:15 AM, Gabi bugspy...@gmail.com wrote:
 Guys, I really need your expertise here.
 I have lots of deeply nested vectors, which i need to manipulate
 frequently (thousands of times)
 What is the most effective way to do this ?

 On Jan 17, 4:27 pm, Gabi bugspy...@gmail.com wrote:
 Right. I thought that transient performing deep 'transientivity'.
 Here is a fixed version. It takes a regular coll converts whatever it
 can to transient and update the stuff.
 The problem is that doing persistent!(assoc!(transient m)) on each
 level probably misses the whole point of performance.
 So while it work, it probably slower than the regular update-in.
 I need a better solution.

 (defn update-in!!
   modified version of core/update-in that works on, and return
 transiants
   ([m [k  ks] f  args]
    (if ks
      (persistent!(assoc! (transient m) k (apply update-in!! (get m k)
 ks f args)))
      (persistent!(assoc! (transient m) k (apply f (get m k) args))

 On Jan 17, 3:57 pm, Chouser chou...@gmail.com wrote:

  On Sun, Jan 17, 2010 at 8:25 AM, Gabi bugspy...@gmail.com wrote:

   user= (persistent!(update-in!(transient v) [0] reverse))

   Forgot to mention that v in the example is defined to  [[1 2] [3 4]]

  So you've got a transient vector of persistent vectors of
  numbers.  The problem is your update-in! then calls assoc! on
  each level, but of course assoc! on the inner persistent vector
  fails.

  You either need to make the inner vectors transient (and then
  call persist! on them when you're done) or use assoc! only at the
  outer level.

  --Chouserhttp://joyofclojure.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




-- 
Professional: http://cgrand.net/ (fr)
On Clojure: http://clj-me.cgrand.net/ (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: update-in! (?)

2010-01-20 Thread Gabi
These vectors represent trees which need to updated very frequently.
So If there was an efficient way to use transients to represent
transient trees the whole process would be much more efficient (so
each update to a tree would be done in place instead of creating new
one.) As discussed above, naive usage of transients won't help.
Another approach would be implement in Java, but I wish there would
some way to achieve this directly from Clojure.
Now that I think about it, maybe the solution is to represent the tree
as one dimensional vector instead of nested one (any good clojure
algorithm for this ? Representing and traversing non binary trees as
one dimensional vector?)


Jan 20, 12:53 pm, Christophe Grand christo...@cgrand.net wrote:
 Hi Gabi!

 Can you tell us more about your problem, what do those deeply nested
 vectors represent and how are you going to update them? (are all
 updates batched in one part of your program?)

 With transients current implementation you can't write an efficient update-in!

 Christophe



 On Wed, Jan 20, 2010 at 9:15 AM, Gabi bugspy...@gmail.com wrote:
  Guys, I really need your expertise here.
  I have lots of deeply nested vectors, which i need to manipulate
  frequently (thousands of times)
  What is the most effective way to do this ?

  On Jan 17, 4:27 pm, Gabi bugspy...@gmail.com wrote:
  Right. I thought that transient performing deep 'transientivity'.
  Here is a fixed version. It takes a regular coll converts whatever it
  can to transient and update the stuff.
  The problem is that doing persistent!(assoc!(transient m)) on each
  level probably misses the whole point of performance.
  So while it work, it probably slower than the regular update-in.
  I need a better solution.

  (defn update-in!!
    modified version of core/update-in that works on, and return
  transiants
    ([m [k  ks] f  args]
     (if ks
       (persistent!(assoc! (transient m) k (apply update-in!! (get m k)
  ks f args)))
       (persistent!(assoc! (transient m) k (apply f (get m k) args))

  On Jan 17, 3:57 pm, Chouser chou...@gmail.com wrote:

   On Sun, Jan 17, 2010 at 8:25 AM, Gabi bugspy...@gmail.com wrote:

user= (persistent!(update-in!(transient v) [0] reverse))

Forgot to mention that v in the example is defined to  [[1 2] [3 4]]

   So you've got a transient vector of persistent vectors of
   numbers.  The problem is your update-in! then calls assoc! on
   each level, but of course assoc! on the inner persistent vector
   fails.

   You either need to make the inner vectors transient (and then
   call persist! on them when you're done) or use assoc! only at the
   outer level.

   --Chouserhttp://joyofclojure.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

 --
 Professional:http://cgrand.net/(fr)
 On Clojure:http://clj-me.cgrand.net/(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: update-in! (?)

2010-01-20 Thread Sean Devlin
Gabi,
A similar technique is used with sparse matrices.  You usually have
severals arrays, one for the non-zero elements, and another one for
indexing the column and a third for indexing the rows.

http://pasadena.wr.usgs.gov/office/baagaard/research/papers/thesis/figs/methods/sparseMatrix.gif

This should be fast as long as you're only updating.  If you're
inserting/deleting, you might be able to get away with using a
collection of 1D trees.

Sean

On Jan 20, 9:18 am, Gabi bugspy...@gmail.com wrote:
 These vectors represent trees which need to updated very frequently.
 So If there was an efficient way to use transients to represent
 transient trees the whole process would be much more efficient (so
 each update to a tree would be done in place instead of creating new
 one.) As discussed above, naive usage of transients won't help.
 Another approach would be implement in Java, but I wish there would
 some way to achieve this directly from Clojure.
 Now that I think about it, maybe the solution is to represent the tree
 as one dimensional vector instead of nested one (any good clojure
 algorithm for this ? Representing and traversing non binary trees as
 one dimensional vector?)

 Jan 20, 12:53 pm, Christophe Grand christo...@cgrand.net wrote:

  Hi Gabi!

  Can you tell us more about your problem, what do those deeply nested
  vectors represent and how are you going to update them? (are all
  updates batched in one part of your program?)

  With transients current implementation you can't write an efficient 
  update-in!

  Christophe

  On Wed, Jan 20, 2010 at 9:15 AM, Gabi bugspy...@gmail.com wrote:
   Guys, I really need your expertise here.
   I have lots of deeply nested vectors, which i need to manipulate
   frequently (thousands of times)
   What is the most effective way to do this ?

   On Jan 17, 4:27 pm, Gabi bugspy...@gmail.com wrote:
   Right. I thought that transient performing deep 'transientivity'.
   Here is a fixed version. It takes a regular coll converts whatever it
   can to transient and update the stuff.
   The problem is that doing persistent!(assoc!(transient m)) on each
   level probably misses the whole point of performance.
   So while it work, it probably slower than the regular update-in.
   I need a better solution.

   (defn update-in!!
     modified version of core/update-in that works on, and return
   transiants
     ([m [k  ks] f  args]
      (if ks
        (persistent!(assoc! (transient m) k (apply update-in!! (get m k)
   ks f args)))
        (persistent!(assoc! (transient m) k (apply f (get m k) args))

   On Jan 17, 3:57 pm, Chouser chou...@gmail.com wrote:

On Sun, Jan 17, 2010 at 8:25 AM, Gabi bugspy...@gmail.com wrote:

 user= (persistent!(update-in!(transient v) [0] reverse))

 Forgot to mention that v in the example is defined to  [[1 2] [3 4]]

So you've got a transient vector of persistent vectors of
numbers.  The problem is your update-in! then calls assoc! on
each level, but of course assoc! on the inner persistent vector
fails.

You either need to make the inner vectors transient (and then
call persist! on them when you're done) or use assoc! only at the
outer level.

--Chouserhttp://joyofclojure.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

  --
  Professional:http://cgrand.net/(fr)
  On Clojure:http://clj-me.cgrand.net/(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: update-in! (?)

2010-01-20 Thread Gabi
I need to add/delete much more frequently than just updating
actually.


On Jan 20, 4:59 pm, Sean Devlin francoisdev...@gmail.com wrote:
 Gabi,
 A similar technique is used with sparse matrices.  You usually have
 severals arrays, one for the non-zero elements, and another one for
 indexing the column and a third for indexing the rows.

 http://pasadena.wr.usgs.gov/office/baagaard/research/papers/thesis/fi...

 This should be fast as long as you're only updating.  If you're
 inserting/deleting, you might be able to get away with using a
 collection of 1D trees.

 Sean

 On Jan 20, 9:18 am, Gabi bugspy...@gmail.com wrote:

  These vectors represent trees which need to updated very frequently.
  So If there was an efficient way to use transients to represent
  transient trees the whole process would be much more efficient (so
  each update to a tree would be done in place instead of creating new
  one.) As discussed above, naive usage of transients won't help.
  Another approach would be implement in Java, but I wish there would
  some way to achieve this directly from Clojure.
  Now that I think about it, maybe the solution is to represent the tree
  as one dimensional vector instead of nested one (any good clojure
  algorithm for this ? Representing and traversing non binary trees as
  one dimensional vector?)

  Jan 20, 12:53 pm, Christophe Grand christo...@cgrand.net wrote:

   Hi Gabi!

   Can you tell us more about your problem, what do those deeply nested
   vectors represent and how are you going to update them? (are all
   updates batched in one part of your program?)

   With transients current implementation you can't write an efficient 
   update-in!

   Christophe

   On Wed, Jan 20, 2010 at 9:15 AM, Gabi bugspy...@gmail.com wrote:
Guys, I really need your expertise here.
I have lots of deeply nested vectors, which i need to manipulate
frequently (thousands of times)
What is the most effective way to do this ?

On Jan 17, 4:27 pm, Gabi bugspy...@gmail.com wrote:
Right. I thought that transient performing deep 'transientivity'.
Here is a fixed version. It takes a regular coll converts whatever it
can to transient and update the stuff.
The problem is that doing persistent!(assoc!(transient m)) on each
level probably misses the whole point of performance.
So while it work, it probably slower than the regular update-in.
I need a better solution.

(defn update-in!!
  modified version of core/update-in that works on, and return
transiants
  ([m [k  ks] f  args]
   (if ks
     (persistent!(assoc! (transient m) k (apply update-in!! (get m k)
ks f args)))
     (persistent!(assoc! (transient m) k (apply f (get m k) args))

On Jan 17, 3:57 pm, Chouser chou...@gmail.com wrote:

 On Sun, Jan 17, 2010 at 8:25 AM, Gabi bugspy...@gmail.com wrote:

  user= (persistent!(update-in!(transient v) [0] reverse))

  Forgot to mention that v in the example is defined to  [[1 2] [3 
  4]]

 So you've got a transient vector of persistent vectors of
 numbers.  The problem is your update-in! then calls assoc! on
 each level, but of course assoc! on the inner persistent vector
 fails.

 You either need to make the inner vectors transient (and then
 call persist! on them when you're done) or use assoc! only at the
 outer level.

 --Chouserhttp://joyofclojure.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

   --
   Professional:http://cgrand.net/(fr)
   On Clojure:http://clj-me.cgrand.net/(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: update-in! (?)

2010-01-20 Thread Sean Devlin
How about a sorted set w/ a custom comparator?  Of course, this rules
out transients, but maybe the flatness will make up for it?

On Jan 20, 10:15 am, Gabi bugspy...@gmail.com wrote:
 I need to add/delete much more frequently than just updating
 actually.

 On Jan 20, 4:59 pm, Sean Devlin francoisdev...@gmail.com wrote:

  Gabi,
  A similar technique is used with sparse matrices.  You usually have
  severals arrays, one for the non-zero elements, and another one for
  indexing the column and a third for indexing the rows.

 http://pasadena.wr.usgs.gov/office/baagaard/research/papers/thesis/fi...

  This should be fast as long as you're only updating.  If you're
  inserting/deleting, you might be able to get away with using a
  collection of 1D trees.

  Sean

  On Jan 20, 9:18 am, Gabi bugspy...@gmail.com wrote:

   These vectors represent trees which need to updated very frequently.
   So If there was an efficient way to use transients to represent
   transient trees the whole process would be much more efficient (so
   each update to a tree would be done in place instead of creating new
   one.) As discussed above, naive usage of transients won't help.
   Another approach would be implement in Java, but I wish there would
   some way to achieve this directly from Clojure.
   Now that I think about it, maybe the solution is to represent the tree
   as one dimensional vector instead of nested one (any good clojure
   algorithm for this ? Representing and traversing non binary trees as
   one dimensional vector?)

   Jan 20, 12:53 pm, Christophe Grand christo...@cgrand.net wrote:

Hi Gabi!

Can you tell us more about your problem, what do those deeply nested
vectors represent and how are you going to update them? (are all
updates batched in one part of your program?)

With transients current implementation you can't write an efficient 
update-in!

Christophe

On Wed, Jan 20, 2010 at 9:15 AM, Gabi bugspy...@gmail.com wrote:
 Guys, I really need your expertise here.
 I have lots of deeply nested vectors, which i need to manipulate
 frequently (thousands of times)
 What is the most effective way to do this ?

 On Jan 17, 4:27 pm, Gabi bugspy...@gmail.com wrote:
 Right. I thought that transient performing deep 'transientivity'.
 Here is a fixed version. It takes a regular coll converts whatever it
 can to transient and update the stuff.
 The problem is that doing persistent!(assoc!(transient m)) on each
 level probably misses the whole point of performance.
 So while it work, it probably slower than the regular update-in.
 I need a better solution.

 (defn update-in!!
   modified version of core/update-in that works on, and return
 transiants
   ([m [k  ks] f  args]
    (if ks
      (persistent!(assoc! (transient m) k (apply update-in!! (get m k)
 ks f args)))
      (persistent!(assoc! (transient m) k (apply f (get m k) 
 args))

 On Jan 17, 3:57 pm, Chouser chou...@gmail.com wrote:

  On Sun, Jan 17, 2010 at 8:25 AM, Gabi bugspy...@gmail.com wrote:

   user= (persistent!(update-in!(transient v) [0] reverse))

   Forgot to mention that v in the example is defined to  [[1 2] [3 
   4]]

  So you've got a transient vector of persistent vectors of
  numbers.  The problem is your update-in! then calls assoc! on
  each level, but of course assoc! on the inner persistent vector
  fails.

  You either need to make the inner vectors transient (and then
  call persist! on them when you're done) or use assoc! only at the
  outer level.

  --Chouserhttp://joyofclojure.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

--
Professional:http://cgrand.net/(fr)
On Clojure:http://clj-me.cgrand.net/(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: update-in! (?)

2010-01-20 Thread Gabi
Can you elaborate more ? How can trees be represented in sorted sets?

On Jan 20, 5:24 pm, Sean Devlin francoisdev...@gmail.com wrote:
 How about a sorted set w/ a custom comparator?  Of course, this rules
 out transients, but maybe the flatness will make up for it?

 On Jan 20, 10:15 am, Gabi bugspy...@gmail.com wrote:

  I need to add/delete much more frequently than just updating
  actually.

  On Jan 20, 4:59 pm, Sean Devlin francoisdev...@gmail.com wrote:

   Gabi,
   A similar technique is used with sparse matrices.  You usually have
   severals arrays, one for the non-zero elements, and another one for
   indexing the column and a third for indexing the rows.

  http://pasadena.wr.usgs.gov/office/baagaard/research/papers/thesis/fi...

   This should be fast as long as you're only updating.  If you're
   inserting/deleting, you might be able to get away with using a
   collection of 1D trees.

   Sean

   On Jan 20, 9:18 am, Gabi bugspy...@gmail.com wrote:

These vectors represent trees which need to updated very frequently.
So If there was an efficient way to use transients to represent
transient trees the whole process would be much more efficient (so
each update to a tree would be done in place instead of creating new
one.) As discussed above, naive usage of transients won't help.
Another approach would be implement in Java, but I wish there would
some way to achieve this directly from Clojure.
Now that I think about it, maybe the solution is to represent the tree
as one dimensional vector instead of nested one (any good clojure
algorithm for this ? Representing and traversing non binary trees as
one dimensional vector?)

Jan 20, 12:53 pm, Christophe Grand christo...@cgrand.net wrote:

 Hi Gabi!

 Can you tell us more about your problem, what do those deeply nested
 vectors represent and how are you going to update them? (are all
 updates batched in one part of your program?)

 With transients current implementation you can't write an efficient 
 update-in!

 Christophe

 On Wed, Jan 20, 2010 at 9:15 AM, Gabi bugspy...@gmail.com wrote:
  Guys, I really need your expertise here.
  I have lots of deeply nested vectors, which i need to manipulate
  frequently (thousands of times)
  What is the most effective way to do this ?

  On Jan 17, 4:27 pm, Gabi bugspy...@gmail.com wrote:
  Right. I thought that transient performing deep 'transientivity'.
  Here is a fixed version. It takes a regular coll converts whatever 
  it
  can to transient and update the stuff.
  The problem is that doing persistent!(assoc!(transient m)) on each
  level probably misses the whole point of performance.
  So while it work, it probably slower than the regular update-in.
  I need a better solution.

  (defn update-in!!
    modified version of core/update-in that works on, and return
  transiants
    ([m [k  ks] f  args]
     (if ks
       (persistent!(assoc! (transient m) k (apply update-in!! (get m 
  k)
  ks f args)))
       (persistent!(assoc! (transient m) k (apply f (get m k) 
  args))

  On Jan 17, 3:57 pm, Chouser chou...@gmail.com wrote:

   On Sun, Jan 17, 2010 at 8:25 AM, Gabi bugspy...@gmail.com 
   wrote:

user= (persistent!(update-in!(transient v) [0] reverse))

Forgot to mention that v in the example is defined to  [[1 2] 
[3 4]]

   So you've got a transient vector of persistent vectors of
   numbers.  The problem is your update-in! then calls assoc! on
   each level, but of course assoc! on the inner persistent vector
   fails.

   You either need to make the inner vectors transient (and then
   call persist! on them when you're done) or use assoc! only at the
   outer level.

   --Chouserhttp://joyofclojure.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

 --
 Professional:http://cgrand.net/(fr)
 On Clojure:http://clj-me.cgrand.net/(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: update-in! (?)

2010-01-20 Thread Christophe Grand
I concur: a map (or a sorted map if you need to emulate access to a
subtree) can be an option.

[[1 2] [3 4]] is represented by {[0 0] 1, [0 1] 2, [1 0] 3, [1 1] 4}

On Wed, Jan 20, 2010 at 4:24 PM, Sean Devlin francoisdev...@gmail.com wrote:
 How about a sorted set w/ a custom comparator?  Of course, this rules
 out transients, but maybe the flatness will make up for it?

 On Jan 20, 10:15 am, Gabi bugspy...@gmail.com wrote:
 I need to add/delete much more frequently than just updating
 actually.

 On Jan 20, 4:59 pm, Sean Devlin francoisdev...@gmail.com wrote:

  Gabi,
  A similar technique is used with sparse matrices.  You usually have
  severals arrays, one for the non-zero elements, and another one for
  indexing the column and a third for indexing the rows.

 http://pasadena.wr.usgs.gov/office/baagaard/research/papers/thesis/fi...

  This should be fast as long as you're only updating.  If you're
  inserting/deleting, you might be able to get away with using a
  collection of 1D trees.

  Sean

  On Jan 20, 9:18 am, Gabi bugspy...@gmail.com wrote:

   These vectors represent trees which need to updated very frequently.
   So If there was an efficient way to use transients to represent
   transient trees the whole process would be much more efficient (so
   each update to a tree would be done in place instead of creating new
   one.) As discussed above, naive usage of transients won't help.
   Another approach would be implement in Java, but I wish there would
   some way to achieve this directly from Clojure.
   Now that I think about it, maybe the solution is to represent the tree
   as one dimensional vector instead of nested one (any good clojure
   algorithm for this ? Representing and traversing non binary trees as
   one dimensional vector?)

   Jan 20, 12:53 pm, Christophe Grand christo...@cgrand.net wrote:

Hi Gabi!

Can you tell us more about your problem, what do those deeply nested
vectors represent and how are you going to update them? (are all
updates batched in one part of your program?)

With transients current implementation you can't write an efficient 
update-in!

Christophe

On Wed, Jan 20, 2010 at 9:15 AM, Gabi bugspy...@gmail.com wrote:
 Guys, I really need your expertise here.
 I have lots of deeply nested vectors, which i need to manipulate
 frequently (thousands of times)
 What is the most effective way to do this ?

 On Jan 17, 4:27 pm, Gabi bugspy...@gmail.com wrote:
 Right. I thought that transient performing deep 'transientivity'.
 Here is a fixed version. It takes a regular coll converts whatever 
 it
 can to transient and update the stuff.
 The problem is that doing persistent!(assoc!(transient m)) on each
 level probably misses the whole point of performance.
 So while it work, it probably slower than the regular update-in.
 I need a better solution.

 (defn update-in!!
   modified version of core/update-in that works on, and return
 transiants
   ([m [k  ks] f  args]
    (if ks
      (persistent!(assoc! (transient m) k (apply update-in!! (get m 
 k)
 ks f args)))
      (persistent!(assoc! (transient m) k (apply f (get m k) 
 args))

 On Jan 17, 3:57 pm, Chouser chou...@gmail.com wrote:

  On Sun, Jan 17, 2010 at 8:25 AM, Gabi bugspy...@gmail.com wrote:

   user= (persistent!(update-in!(transient v) [0] reverse))

   Forgot to mention that v in the example is defined to  [[1 2] 
   [3 4]]

  So you've got a transient vector of persistent vectors of
  numbers.  The problem is your update-in! then calls assoc! on
  each level, but of course assoc! on the inner persistent vector
  fails.

  You either need to make the inner vectors transient (and then
  call persist! on them when you're done) or use assoc! only at the
  outer level.

  --Chouserhttp://joyofclojure.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

--
Professional:http://cgrand.net/(fr)
On Clojure:http://clj-me.cgrand.net/(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




-- 
Professional: http://cgrand.net/ (fr)
On Clojure: 

Re: update-in! (?)

2010-01-20 Thread Gabi
I posted a question on SO about it. Interesting discussion:
http://stackoverflow.com/questions/2102606/algorithm-to-implement-non-binary-trees-using-1-dimensional-vector

On Jan 20, 5:39 pm, Christophe Grand christo...@cgrand.net wrote:
 I concur: a map (or a sorted map if you need to emulate access to a
 subtree) can be an option.

 [[1 2] [3 4]] is represented by {[0 0] 1, [0 1] 2, [1 0] 3, [1 1] 4}



 On Wed, Jan 20, 2010 at 4:24 PM, Sean Devlin francoisdev...@gmail.com wrote:
  How about a sorted set w/ a custom comparator?  Of course, this rules
  out transients, but maybe the flatness will make up for it?

  On Jan 20, 10:15 am, Gabi bugspy...@gmail.com wrote:
  I need to add/delete much more frequently than just updating
  actually.

  On Jan 20, 4:59 pm, Sean Devlin francoisdev...@gmail.com wrote:

   Gabi,
   A similar technique is used with sparse matrices.  You usually have
   severals arrays, one for the non-zero elements, and another one for
   indexing the column and a third for indexing the rows.

  http://pasadena.wr.usgs.gov/office/baagaard/research/papers/thesis/fi...

   This should be fast as long as you're only updating.  If you're
   inserting/deleting, you might be able to get away with using a
   collection of 1D trees.

   Sean

   On Jan 20, 9:18 am, Gabi bugspy...@gmail.com wrote:

These vectors represent trees which need to updated very frequently.
So If there was an efficient way to use transients to represent
transient trees the whole process would be much more efficient (so
each update to a tree would be done in place instead of creating new
one.) As discussed above, naive usage of transients won't help.
Another approach would be implement in Java, but I wish there would
some way to achieve this directly from Clojure.
Now that I think about it, maybe the solution is to represent the tree
as one dimensional vector instead of nested one (any good clojure
algorithm for this ? Representing and traversing non binary trees as
one dimensional vector?)

Jan 20, 12:53 pm, Christophe Grand christo...@cgrand.net wrote:

 Hi Gabi!

 Can you tell us more about your problem, what do those deeply nested
 vectors represent and how are you going to update them? (are all
 updates batched in one part of your program?)

 With transients current implementation you can't write an efficient 
 update-in!

 Christophe

 On Wed, Jan 20, 2010 at 9:15 AM, Gabi bugspy...@gmail.com wrote:
  Guys, I really need your expertise here.
  I have lots of deeply nested vectors, which i need to manipulate
  frequently (thousands of times)
  What is the most effective way to do this ?

  On Jan 17, 4:27 pm, Gabi bugspy...@gmail.com wrote:
  Right. I thought that transient performing deep 'transientivity'.
  Here is a fixed version. It takes a regular coll converts 
  whatever it
  can to transient and update the stuff.
  The problem is that doing persistent!(assoc!(transient m)) on each
  level probably misses the whole point of performance.
  So while it work, it probably slower than the regular update-in.
  I need a better solution.

  (defn update-in!!
    modified version of core/update-in that works on, and return
  transiants
    ([m [k  ks] f  args]
     (if ks
       (persistent!(assoc! (transient m) k (apply update-in!! (get 
  m k)
  ks f args)))
       (persistent!(assoc! (transient m) k (apply f (get m k) 
  args))

  On Jan 17, 3:57 pm, Chouser chou...@gmail.com wrote:

   On Sun, Jan 17, 2010 at 8:25 AM, Gabi bugspy...@gmail.com 
   wrote:

user= (persistent!(update-in!(transient v) [0] reverse))

Forgot to mention that v in the example is defined to  [[1 2] 
[3 4]]

   So you've got a transient vector of persistent vectors of
   numbers.  The problem is your update-in! then calls assoc! on
   each level, but of course assoc! on the inner persistent vector
   fails.

   You either need to make the inner vectors transient (and then
   call persist! on them when you're done) or use assoc! only at 
   the
   outer level.

   --Chouserhttp://joyofclojure.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

 --
 Professional:http://cgrand.net/(fr)
 On Clojure:http://clj-me.cgrand.net/(en)

  --
  You received this message because you are subscribed to the Google
  Groups Clojure group.
  To post to this group, send email to 

Re: update-in! (?)

2010-01-20 Thread brianh
Any chance you could rethink your approach  use a zipper?

On Jan 20, 9:32 am, Gabi bugspy...@gmail.com wrote:
 I posted a question on SO about it. Interesting 
 discussion:http://stackoverflow.com/questions/2102606/algorithm-to-implement-non...

 On Jan 20, 5:39 pm, Christophe Grand christo...@cgrand.net wrote:



  I concur: a map (or a sorted map if you need to emulate access to a
  subtree) can be an option.

  [[1 2] [3 4]] is represented by {[0 0] 1, [0 1] 2, [1 0] 3, [1 1] 4}

  On Wed, Jan 20, 2010 at 4:24 PM, Sean Devlin francoisdev...@gmail.com 
  wrote:
   How about a sorted set w/ a custom comparator?  Of course, this rules
   out transients, but maybe the flatness will make up for it?

   On Jan 20, 10:15 am, Gabi bugspy...@gmail.com wrote:
   I need to add/delete much more frequently than just updating
   actually.

   On Jan 20, 4:59 pm, Sean Devlin francoisdev...@gmail.com wrote:

Gabi,
A similar technique is used with sparse matrices.  You usually have
severals arrays, one for the non-zero elements, and another one for
indexing the column and a third for indexing the rows.

   http://pasadena.wr.usgs.gov/office/baagaard/research/papers/thesis/fi...

This should be fast as long as you're only updating.  If you're
inserting/deleting, you might be able to get away with using a
collection of 1D trees.

Sean

On Jan 20, 9:18 am, Gabi bugspy...@gmail.com wrote:

 These vectors represent trees which need to updated very frequently.
 So If there was an efficient way to use transients to represent
 transient trees the whole process would be much more efficient (so
 each update to a tree would be done in place instead of creating new
 one.) As discussed above, naive usage of transients won't help.
 Another approach would be implement in Java, but I wish there would
 some way to achieve this directly from Clojure.
 Now that I think about it, maybe the solution is to represent the 
 tree
 as one dimensional vector instead of nested one (any good clojure
 algorithm for this ? Representing and traversing non binary trees as
 one dimensional vector?)

 Jan 20, 12:53 pm, Christophe Grand christo...@cgrand.net wrote:

  Hi Gabi!

  Can you tell us more about your problem, what do those deeply 
  nested
  vectors represent and how are you going to update them? (are all
  updates batched in one part of your program?)

  With transients current implementation you can't write an 
  efficient update-in!

  Christophe

  On Wed, Jan 20, 2010 at 9:15 AM, Gabi bugspy...@gmail.com wrote:
   Guys, I really need your expertise here.
   I have lots of deeply nested vectors, which i need to manipulate
   frequently (thousands of times)
   What is the most effective way to do this ?

   On Jan 17, 4:27 pm, Gabi bugspy...@gmail.com wrote:
   Right. I thought that transient performing deep 
   'transientivity'.
   Here is a fixed version. It takes a regular coll converts 
   whatever it
   can to transient and update the stuff.
   The problem is that doing persistent!(assoc!(transient m)) on 
   each
   level probably misses the whole point of performance.
   So while it work, it probably slower than the regular update-in.
   I need a better solution.

   (defn update-in!!
     modified version of core/update-in that works on, and return
   transiants
     ([m [k  ks] f  args]
      (if ks
        (persistent!(assoc! (transient m) k (apply update-in!! 
   (get m k)
   ks f args)))
        (persistent!(assoc! (transient m) k (apply f (get m k) 
   args))

   On Jan 17, 3:57 pm, Chouser chou...@gmail.com wrote:

On Sun, Jan 17, 2010 at 8:25 AM, Gabi bugspy...@gmail.com 
wrote:

 user= (persistent!(update-in!(transient v) [0] reverse))

 Forgot to mention that v in the example is defined to  [[1 
 2] [3 4]]

So you've got a transient vector of persistent vectors of
numbers.  The problem is your update-in! then calls assoc! on
each level, but of course assoc! on the inner persistent 
vector
fails.

You either need to make the inner vectors transient (and then
call persist! on them when you're done) or use assoc! only at 
the
outer level.

--Chouserhttp://joyofclojure.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: update-in! (?)

2010-01-17 Thread Gabi
Forgot to mention that v in the example is defined to  [[1 2] [3 4]]

On Jan 17, 3:19 pm, Gabi bugspy...@gmail.com wrote:
 I really needed an update-in! version that works on transients. I
 couldn't find one so I just modified the original update-in core (just
 replaced assoc assoc!):

 (defn update-in!
   modified version of core/update-in that works on, and return
 transients
   ([m [k  ks] f  args]
    (if ks
      (assoc! m k (apply update-in! (get m k) ks f args))
      (assoc! m k (apply f (get m k) args)

 user= (persistent!(update-in!(transient v) [0] reverse))
 [(2 1) [3 4]]

 BUT when using nested paths, it fails:

 user=(persistent!(update-in!(transient v) [0 0] inc))
 java.lang.ClassCastException: clojure.lang.PersistentVector cannot be
 cast to clojure.lang.ITransientAssociative

 Any idea how to solve 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: update-in! (?)

2010-01-17 Thread Chouser
On Sun, Jan 17, 2010 at 8:25 AM, Gabi bugspy...@gmail.com wrote:

 user= (persistent!(update-in!(transient v) [0] reverse))

 Forgot to mention that v in the example is defined to  [[1 2] [3 4]]

So you've got a transient vector of persistent vectors of
numbers.  The problem is your update-in! then calls assoc! on
each level, but of course assoc! on the inner persistent vector
fails.

You either need to make the inner vectors transient (and then
call persist! on them when you're done) or use assoc! only at the
outer level.

--Chouser
http://joyofclojure.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: update-in! (?)

2010-01-17 Thread Gabi
Right. I thought that transient performing deep 'transientivity'.
Here is a fixed version. It takes a regular coll converts whatever it
can to transient and update the stuff.
The problem is that doing persistent!(assoc!(transient m)) on each
level probably misses the whole point of performance.
So while it work, it probably slower than the regular update-in.
I need a better solution.

(defn update-in!!
  modified version of core/update-in that works on, and return
transiants
  ([m [k  ks] f  args]
   (if ks
 (persistent!(assoc! (transient m) k (apply update-in!! (get m k)
ks f args)))
 (persistent!(assoc! (transient m) k (apply f (get m k) args))

On Jan 17, 3:57 pm, Chouser chou...@gmail.com wrote:
 On Sun, Jan 17, 2010 at 8:25 AM, Gabi bugspy...@gmail.com wrote:

  user= (persistent!(update-in!(transient v) [0] reverse))

  Forgot to mention that v in the example is defined to  [[1 2] [3 4]]

 So you've got a transient vector of persistent vectors of
 numbers.  The problem is your update-in! then calls assoc! on
 each level, but of course assoc! on the inner persistent vector
 fails.

 You either need to make the inner vectors transient (and then
 call persist! on them when you're done) or use assoc! only at the
 outer level.

 --Chouserhttp://joyofclojure.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: update-in and get-in why no default?

2010-01-02 Thread Timothy Pratley
2010/1/2 Sean Devlin francoisdev...@gmail.com:
 I don't think your version of the signature supports variadic defaults well.

Hi Sean,

Thanks for commenting.

Just by way of clarification, taking the function as the last argument
seems to work fine in my experiments. I'm sure it could be better but
here what I've been using:

(defn fnil
  Creates a new function that if passed nil as an argument,
  operates with supplied arguments instead. The function must be
  passed as the last argument.
  [ more]
  (fn [ m] (apply (last more)
   (map #(if (nil? %1) %2 %1)
m
(concat (butlast more)
(drop (count (butlast more)) m))

Relating to your examples:
user= (def nil+ (fnil 0 1 2 3 4 5 6 +))
user= (nil+ 0 0 0 0 0 0 nil)
6
user= (nil+ 0 0 0 0 0 0 0 nil)
java.lang.NullPointerException (NO_SOURCE_FILE:0)
user= ((fnil 1 +) nil 2 3 4 5)
15

; note fnil-2 does not handle the last case, though of course it could
easily if you wanted it to:
user= ((fnil-2 1 +) nil 2 3 4 5)
java.lang.ClassCastException: java.lang.Integer cannot be cast to
clojure.lang.IFn (NO_SOURCE_FILE:0)

; in principle I don't think one form is any more restrictive than the
other, it just comes down to a matter of preference which is the key
part I wanted to generate discussion about.


 matches the signature of partial better, which I personally prefer.

Yes that is precisely why it catches me out to write (fnil + 1)
because it looks like a partial application. Partial applications are
actually very common even when partial is not explicitly used:
user= (swap! (atom 1) + 1)
2
So I'm used to seeing arguments to the right of a function get
absorbed so to speak, and used to seeing conditionals occur in the
middle of the form. Again just clarifying that I too like partial
application style but have the opposite reaction in this case of
wanting to contrast that for fnil as it is not a partial application.
This of course is just my preference and I'm glad to hear reasoning
for the other style.


Regards,
Tim.

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: update-in and get-in why no default?

2010-01-02 Thread Timothy Pratley
2010/1/2 Timothy Pratley timothyprat...@gmail.com:
 user= ((fnil-2 1 +) nil 2 3 4 5)
 java.lang.ClassCastException: java.lang.Integer cannot be cast to
 clojure.lang.IFn (NO_SOURCE_FILE:0)

Correction, I just realized of course it doesn't work if I specify the
arguments around the wrong way! I should have done:
user= ((fnil-2 + 1) nil 2 3 4 5)
1
; I think this should result in 15, but that's just an implementation detail.

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: update-in and get-in why no default?

2010-01-01 Thread Timothy Pratley
On Dec 13, 1:24 am, Rich Hickey richhic...@gmail.com wrote:
 fnil seems to me to have greater utility than patching all functions
 that apply functions with default-supplying arguments.


Hi Rich,

To further comment on fnil, after having experimented with it a bit
now, I've come to slightly prefer specifying the 'default' value
before the function just because I think it reads nicer:
(fnil 0 inc)   ;; instead of (fnil inc 0)
(fnil [] conj) ;; instead of (fnil conj [])
I read it as fill nil with 0 for inc
I suppose fill nil of inc with 0 makes just as much sense but I find
inc 0 leads my eye to believe 0 will always be passed to inc,
whereas 0 inc does not. Putting the function last makes it clearer
to me that the 0 is conditional. It also looks more like if nil 0.
This contrasts with get, which makes perfect sense having the default
last, but I think at this point fnil and get are sufficiently far
apart that a different argument order would not be surprising.

Just a small observation I thought I'd raise for discussion to see
what preferences are out there if this function becomes widespread.


Regards,
Tim.

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: update-in and get-in why no default?

2010-01-01 Thread Sean Devlin
Tim,
I don't think your version of the signature supports variadic defaults
well.  Also, I'd (initially) implement fnil differently that Rich.
Here's my fnil-2 that I *suspect* has the intended behavior

(defn fnil-2
  [f  defaults]
  (fn[ args]
(let [used-args (map (fn [default-value value]
   (if value value default-value))
 defaults args)]
  (apply f used-args

user=(def nil+ (fnil-2 + 0 1 2 3 4 5 6))

user=(nil+ nil)
0

user=(nil+ 0 nil)
1

user=(nil+ 0 0 nil)
2

user=(nil+ 0 0 0 nil)
3

...

user=(nil+ 0 0 0 0 0 0 nil)
6

;This example exceeds the provided # of nil values
user=(nil+ 0 0 0 0 0 0 0 nil)
NPE

You get the idea.  Also, Rich's style matches the signature of partial
better, which I personally prefer.

Just my $.02

Sean


On Jan 1, 6:45 pm, Timothy Pratley timothyprat...@gmail.com wrote:
 On Dec 13, 1:24 am, Rich Hickey richhic...@gmail.com wrote:

  fnil seems to me to have greater utility than patching all functions
  that apply functions with default-supplying arguments.

 Hi Rich,

 To further comment on fnil, after having experimented with it a bit
 now, I've come to slightly prefer specifying the 'default' value
 before the function just because I think it reads nicer:
 (fnil 0 inc)   ;; instead of (fnil inc 0)
 (fnil [] conj) ;; instead of (fnil conj [])
 I read it as fill nil with 0 for inc
 I suppose fill nil of inc with 0 makes just as much sense but I find
 inc 0 leads my eye to believe 0 will always be passed to inc,
 whereas 0 inc does not. Putting the function last makes it clearer
 to me that the 0 is conditional. It also looks more like if nil 0.
 This contrasts with get, which makes perfect sense having the default
 last, but I think at this point fnil and get are sufficiently far
 apart that a different argument order would not be surprising.

 Just a small observation I thought I'd raise for discussion to see
 what preferences are out there if this function becomes widespread.

 Regards,
 Tim.

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: update-in and get-in why no default?

2009-12-30 Thread Timothy Pratley


On Dec 13, 1:24 am, Rich Hickey richhic...@gmail.com wrote:
 fnil seems to me to have greater utility than patching all functions
 that apply functions with default-supplying arguments.

Neat :) I like it.


 The get-in function could be enhanced, and would mirror get.

Should I interpret 'could' as 'patch welcome' or 'let me think about
it'?


Regards,
Tim.

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: update-in and get-in why no default?

2009-12-12 Thread Rich Hickey
On Thu, Dec 10, 2009 at 7:20 AM, Timothy Pratley
timothyprat...@gmail.com wrote:
 Hi,

 update-in is an especially useful function but I find the update
 function inevitably requires a check for nil. If I could supply a not-
 found value then my code would get better golf scores.

 When I reach for update-in, I usually want to pass it a numerical
 operator like inc or +, but these don't play nicely with nil. Another
 scenario is when I want to pass conj, which is fine if I want to
 create lists, except if I usually want the data structure to be
 something else. I've never come across a scenario where I didn't want
 to supply a not-found value, are there any common ones?

 If others have similar experience perhaps it is a candidate for
 change. Ideally I'd like to see a not-found parameter added to update-
 in and an extra arity overload for get-in as outlined below:

 (defn update-in2
  'Updates' a value in a nested associative structure, where ks is a
  sequence of keys and f is a function that will take the old value
  and any supplied args and return the new value, and returns a new
  nested structure.  If any levels do not exist, hash-maps will be
  created. If there is no value to update, default is supplied to f. 
  ([m [k  ks] not-found f  args]
   (if ks
 (assoc m k (apply update-in2 (get m k) ks f args))
 (assoc m k (apply f (get m k not-found) args)

 user= (reduce #(update-in2 %1 [%2] 0 inc) {} [fun counting
 words fun])
 {words 1, counting 1, fun 2}
 user= (reduce #(update-in2 %1 [(first %2)] [] conj (second %2)) {}
 [[:a 1] [:a 2] [:b 3]])
 {:b [3], :a [1 2]}


 (defn get-in2
  returns the value in a nested associative structure, where ks is a
 sequence of keys
  ([m ks]
   (reduce get m ks))
  ([m ks not-found]
   (if-let [v (reduce get m ks)]
 v
 not-found)))

 user= (get-in2 {:a {:b 1}} [:a :b] 0)
 1
 user= (get-in2 {:a {:b 1}} [:a :b :c] 0)
 0

 Changing update-in would be a breaking change unfortunately. To avoid
 this you could consider checking the argument type for f to be
 function or value (making an assumption here that you would rarely
 want a function as the not-found value which is not 100% watertight).
 Or you could have a similarly named update-in-or function (which is
 less aesthetically pleasing), or maybe there is another even better
 way?


The get-in function could be enhanced, and would mirror get.

As for update-in, a breaking change and type testing is out of the
question. However, the general case is one of applying functions to
missing/nil arguments that don't expect them, or whose behavior given
nil you'd like to change. If it is just a substitution (and it often
is, as you desire in update-in), something like this could cover many
applying functions, without having to add extra what-to-do-if-nil
arguments:

(defn fnil
  Takes a function f, and returns a function that calls f, replacing
  a nil first argument to f with the supplied value x. Higher arity
  versions can replace arguments in the second and third
  positions (y, z). Note that the function f can take any number of
  arguments, not just the one(s) being nil-patched.
  ([f x]
 (fn
   ([a] (f (if (nil? a) x a)))
   ([a b] (f (if (nil? a) x a) b))
   ([a b c] (f (if (nil? a) x a) b c))
   ([a b c  ds] (apply f (if (nil? a) x a) b c ds
  ([f x y]
 (fn
   ([a b] (f (if (nil? a) x a) (if (nil? b) y b)))
   ([a b c] (f (if (nil? a) x a) (if (nil? b) y b) c))
   ([a b c  ds] (apply f (if (nil? a) x a) (if (nil? b) y b) c ds
  ([f x y z]
 (fn
   ([a b] (f (if (nil? a) x a) (if (nil? b) y b)))
   ([a b c] (f (if (nil? a) x a) (if (nil? b) y b) (if (nil? c) z c)))
   ([a b c  ds] (apply f (if (nil? a) x a) (if (nil? b) y b) (if
(nil? c) z c) ds)

usaage:

((fnil + 0) nil 42)
- 42

((fnil conj []) nil 42)
- [42]

(reduce #(update-in %1 [%2] (fnil inc 0)) {} [fun counting words fun])
-{words 1, counting 1, fun 2}

(reduce #(update-in %1 [(first %2)] (fnil conj []) (second %2))
{} [[:a 1] [:a 2] [:b 3]])
- {:b [3], :a [1 2]}


fnil seems to me to have greater utility than patching all functions
that apply functions with default-supplying arguments.

Rich

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en


Re: update-in and get-in why no default?

2009-12-10 Thread Sean Devlin
Tim,
I like both of these ideas.  I agree, get-in2 seems to make sense as a
drop in replacement.

With update-in2 I prefer a new name, because I do occasionally write
code that constructs lists of functions.  I'd hate to get a weird bug
while doing this.

Sean

On Dec 10, 7:20 am, Timothy Pratley timothyprat...@gmail.com wrote:
 Hi,

 update-in is an especially useful function but I find the update
 function inevitably requires a check for nil. If I could supply a not-
 found value then my code would get better golf scores.

 When I reach for update-in, I usually want to pass it a numerical
 operator like inc or +, but these don't play nicely with nil. Another
 scenario is when I want to pass conj, which is fine if I want to
 create lists, except if I usually want the data structure to be
 something else. I've never come across a scenario where I didn't want
 to supply a not-found value, are there any common ones?

 If others have similar experience perhaps it is a candidate for
 change. Ideally I'd like to see a not-found parameter added to update-
 in and an extra arity overload for get-in as outlined below:

 (defn update-in2
   'Updates' a value in a nested associative structure, where ks is a
   sequence of keys and f is a function that will take the old value
   and any supplied args and return the new value, and returns a new
   nested structure.  If any levels do not exist, hash-maps will be
   created. If there is no value to update, default is supplied to f. 
   ([m [k  ks] not-found f  args]
    (if ks
      (assoc m k (apply update-in2 (get m k) ks f args))
      (assoc m k (apply f (get m k not-found) args)

 user= (reduce #(update-in2 %1 [%2] 0 inc) {} [fun counting
 words fun])
 {words 1, counting 1, fun 2}
 user= (reduce #(update-in2 %1 [(first %2)] [] conj (second %2)) {}
 [[:a 1] [:a 2] [:b 3]])
 {:b [3], :a [1 2]}

 (defn get-in2
   returns the value in a nested associative structure, where ks is a
 sequence of keys
   ([m ks]
    (reduce get m ks))
   ([m ks not-found]
    (if-let [v (reduce get m ks)]
      v
      not-found)))

 user= (get-in2 {:a {:b 1}} [:a :b] 0)
 1
 user= (get-in2 {:a {:b 1}} [:a :b :c] 0)
 0

 Changing update-in would be a breaking change unfortunately. To avoid
 this you could consider checking the argument type for f to be
 function or value (making an assumption here that you would rarely
 want a function as the not-found value which is not 100% watertight).
 Or you could have a similarly named update-in-or function (which is
 less aesthetically pleasing), or maybe there is another even better
 way?

 Thanks for your consideration.

 Regards,
 Tim.

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: update-in and get-in why no default?

2009-12-10 Thread ataggart
Seconded; I like the intention of both changes, and do something
similar in a lot of my code (e.g., parsing functions that take an
extra arg if the parse is unsuccessful).  Also, testing the type of
update-in2's second arg is a bad idea, imo.

As for the breaking change of adding another arg to update-in, I can't
think of a time when nil was actually the default value I wanted
there, though sometimes the function I was using behaved well with
nils (e.g., conj).  In every other case, I had to explicitly handle
nils (e.g., inc).

I don't have a lot of production code that would need retrofitting, so
I'm inclined to prefer breaking things for the better (at least while
things are young).  I imagine others might feel differently.


On Dec 10, 7:27 am, Sean Devlin francoisdev...@gmail.com wrote:
 Tim,
 I like both of these ideas.  I agree, get-in2 seems to make sense as a
 drop in replacement.

 With update-in2 I prefer a new name, because I do occasionally write
 code that constructs lists of functions.  I'd hate to get a weird bug
 while doing this.

 Sean

 On Dec 10, 7:20 am, Timothy Pratley timothyprat...@gmail.com wrote:



  Hi,

  update-in is an especially useful function but I find the update
  function inevitably requires a check for nil. If I could supply a not-
  found value then my code would get better golf scores.

  When I reach for update-in, I usually want to pass it a numerical
  operator like inc or +, but these don't play nicely with nil. Another
  scenario is when I want to pass conj, which is fine if I want to
  create lists, except if I usually want the data structure to be
  something else. I've never come across a scenario where I didn't want
  to supply a not-found value, are there any common ones?

  If others have similar experience perhaps it is a candidate for
  change. Ideally I'd like to see a not-found parameter added to update-
  in and an extra arity overload for get-in as outlined below:

  (defn update-in2
    'Updates' a value in a nested associative structure, where ks is a
    sequence of keys and f is a function that will take the old value
    and any supplied args and return the new value, and returns a new
    nested structure.  If any levels do not exist, hash-maps will be
    created. If there is no value to update, default is supplied to f. 
    ([m [k  ks] not-found f  args]
     (if ks
       (assoc m k (apply update-in2 (get m k) ks f args))
       (assoc m k (apply f (get m k not-found) args)

  user= (reduce #(update-in2 %1 [%2] 0 inc) {} [fun counting
  words fun])
  {words 1, counting 1, fun 2}
  user= (reduce #(update-in2 %1 [(first %2)] [] conj (second %2)) {}
  [[:a 1] [:a 2] [:b 3]])
  {:b [3], :a [1 2]}

  (defn get-in2
    returns the value in a nested associative structure, where ks is a
  sequence of keys
    ([m ks]
     (reduce get m ks))
    ([m ks not-found]
     (if-let [v (reduce get m ks)]
       v
       not-found)))

  user= (get-in2 {:a {:b 1}} [:a :b] 0)
  1
  user= (get-in2 {:a {:b 1}} [:a :b :c] 0)
  0

  Changing update-in would be a breaking change unfortunately. To avoid
  this you could consider checking the argument type for f to be
  function or value (making an assumption here that you would rarely
  want a function as the not-found value which is not 100% watertight).
  Or you could have a similarly named update-in-or function (which is
  less aesthetically pleasing), or maybe there is another even better
  way?

  Thanks for your consideration.

  Regards,
  Tim.

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: update-proxy doc - what is this ?

2009-11-01 Thread Alex Osborne

msappler wrote:
 user= (doc update-proxy)
 
 It says:the first arg corresponding to this
 
 What is meant with this?

this means the proxy object itself (like the this keyword in Java).

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: update/update-in

2009-04-29 Thread David Nolen
Because update-in can use any function to do the update.

On Wed, Apr 29, 2009 at 6:54 PM, mifrai fraim...@gmail.com wrote:


 Hi,

 I was wondering why there was no update to update-in? But there is
 an assoc to assoc-in and a get to a get-in.

 - 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
To unsubscribe from 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: update/update-in

2009-04-29 Thread mifrai

Thanks for the quick reply and I understand that's the functionality
of it.

But just like get-in is the recursive form of get - I'm just wondering
why there's no singular form of update-in.

I know it's not much more work to go (update-in map [:single-key] conj
3) - but from experience there tends be really good reasons behind
these kinds of decisions and I'm just curious.

On Apr 29, 4:05 pm, David Nolen dnolen.li...@gmail.com wrote:
 Because update-in can use any function to do the update.

 On Wed, Apr 29, 2009 at 6:54 PM, mifrai fraim...@gmail.com wrote:

  Hi,

  I was wondering why there was no update to update-in? But there is
  an assoc to assoc-in and a get to a get-in.

  - 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
To unsubscribe from 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: update/update-in

2009-04-29 Thread David Nolen
I see what you mean, does seem like a useful addition:
(defn update [m k f  args]
  (assoc m k (apply f (k m) args)))

(update {:foo 0} :foo inc)

vs.

(assoc {:foo 0} :foo (inc (:foo {:foo 0})))

On Wed, Apr 29, 2009 at 7:13 PM, mifrai fraim...@gmail.com wrote:


 Thanks for the quick reply and I understand that's the functionality
 of it.

 But just like get-in is the recursive form of get - I'm just wondering
 why there's no singular form of update-in.

 I know it's not much more work to go (update-in map [:single-key] conj
 3) - but from experience there tends be really good reasons behind
 these kinds of decisions and I'm just curious.

 On Apr 29, 4:05 pm, David Nolen dnolen.li...@gmail.com wrote:
  Because update-in can use any function to do the update.
 
  On Wed, Apr 29, 2009 at 6:54 PM, mifrai fraim...@gmail.com wrote:
 
   Hi,
 
   I was wondering why there was no update to update-in? But there is
   an assoc to assoc-in and a get to a get-in.
 
   - 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
To unsubscribe from 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: update-in wildcards?

2009-04-13 Thread Ozzi Lee

Well, I expected someone to tell my that was a horrible idea, not to
implement it for me. Thanks!

One thing that concerns me is that :* could conceivable be used as a
key in a hash-map. Perhaps a separate distinct value should be used as
a wildcard? Does clojure have a facility for creating a value that
will never be considered equal to any other value?
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
Clojure group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from 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: update-in wildcards?

2009-04-13 Thread Ozzi Lee

 Does clojure have a facility for creating a value that
 will never be considered equal to any other value?

Duh, brainfart. Gensym will work nicely, of course.
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
Clojure group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from 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: update-in wildcards?

2009-04-12 Thread Mitch

(use '[clojure.contrib.generic.functor :only (fmap)])

(defn update-in-wildcard
  Like update-in, but with :* as a wildcard matcher
  ([m [k  ks] f  args]
   (condp = [(= k :*) (boolean ks)]
 [true true] (fmap #(apply update-in-wildcard % ks f args) m)
 [true false] (fmap f m)
 [false true] (assoc m k (apply update-in-wildcard (get m k) ks f
args))
 [false false] (assoc m k (apply f (get m k) args)

This seems to do what you want.  I had a similar situation but hadn't
thought of abstracting it out in this way until I read your post.  The
condp is somewhat ugly, but I didn't want nested if's checking for the
same condition.  If anyone can think of a nicer way of doing the
conditional, let me know.



On Apr 10, 11:32 am, Ozzi Lee ozzi...@gmail.com wrote:
 I have a structure of nested Maps and Vectors as follows:

 (def document
      {:sections
       [{:items
         [{:quantity 1}
          {:quantity 2}]}
        {:items
         [{:quantity 3}
          {:quantity 4}]}]})

 The document has a vector of sections (one, in this case), each
 section has a vector of items (two, here).

 I want to increment the quantity of every item in every section. The
 cleanest solution I've found this far is as follows:

 (defn update-item [item]
   (update-in item [:quantity] inc))

 (defn update-section [section]
   (update-in section [:items] (partial map update-item)))

 (update-in document [:sections]
         (partial map update-section))

 I'm not concerned about map turning vectors into seqs.

 If update-in supported some kind of wildcard, I could write this:

  (update-in document [:sections * :items * :quantity] inc)

 Where * is a wildcard, meaning any key.

 Does the wildcard idea have any merit? Is there a better way to go
 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
To unsubscribe from 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: update-values for clojure.contrib.sql

2009-01-13 Thread Stephen C. Gilardi


On Jan 11, 2009, at 10:42 AM, Stephen C. Gilardi wrote:

I'd like to include something like this in clojure.contrib.sql. That  
will go smoothest if I can base it directly on what you've written  
and that's only possible if you send in a contributor agreement.  
Would you please send one in?



Hi budu,

While I still encourage you (and everyone who thinks they may want to  
contribute) to send in a contributor agreement, I came up with an  
original implementation for this function. Please see my recent update  
to clojure.contrib.sql. Thanks for bringing the need for it to the fore.


--Steve



smime.p7s
Description: S/MIME cryptographic signature


Re: update-values for clojure.contrib.sql

2009-01-11 Thread Stephen C. Gilardi


On Jan 2, 2009, at 2:21 AM, budu wrote:


Hi, I was experimenting with clojure-contrib's sql features and found
that there wasn't any update-values function. I've written my own and
I'm sharing it here:

(defn update-values [table where column-names  values]
 Update columns of a table with values. columns-names is a vector of
 column names (strings or keywords) and the rest of arguments are the
 values for those columns.
 (let [columns (map #(str (the-str %)  = ?) column-names)
   template (if (seq column-names)
 (apply str (interpose , columns))
 )]
   (apply do-prepared
  (format update %s set %s where %s
  (the-str table) template where)
  [values])))

It only send one set of values to do-prepared because of the where
clause that would have to change according to each sets. I'm ready for
your commentaries and/or suggestions.


Hi budu,

I'd like to include something like this in clojure.contrib.sql. That  
will go smoothest if I can base it directly on what you've written and  
that's only possible if you send in a contributor agreement. Would you  
please send one in?


Please see http://clojure.org/contributing for more info.

Thanks,

--Steve



smime.p7s
Description: S/MIME cryptographic signature


Re: update in place for unique references

2009-01-09 Thread Timothy Pratley

 Most structures of this type would start life as a uniquely-referenced
 structure (either empty or a copy of an immutable), and have
 lots of mutations effectively applied to them in a safe environment,
 until they are ready to be frozen and released to the world as
 an immutable version of the structure.

It is possible to achieve this behavior explicitly if you really
wanted to:
(defn create-add-2 []
  (with-local-vars [x 1]
(do
  (var-set x 1)
  (var-set x (inc @x))
  (let [z @x]
(fn [y] (+ y z))


 (Some structures would
 stay uniquely-referenced their whole life - used for performance
 in some single-threaded encapsulated mutation-based algorithm.)

Such an aggressive optimizer might be unhappy with a runtime check and
opt for an unsafe mutable:
user= (def p (java.awt.Point. 0 0))
#'user/p
user= p
#Point java.awt.Point[x=0,y=0]
user= (.setLocation p 1 2)
nil
user= p
#Point java.awt.Point[x=1,y=2]
But might still be unhappy with having to use object calls, at which
point I don't think Clojure is the right language. However lucky for
them they could still go away and implement an incredibly efficient
java api and call it from within Clojure very easily. They would still
want to wring the last few drops of performance and write it in C.
Actually they could still invoke that code at a high level via JNI but
of course would want to keep the calls to a minimum to avoid calling
overhead.

 I should also clarify one point.  I am not asking for this language
 feature so much as asking whether people have thought
 about it.  There may (or may not) be good reasons for not offering
 such a language feature.  I'm just wondering if it has been
 considered.  (And trying to get a feel for the strengths and
 weaknesses of Clojure - I am very new to it.)

I'm just an observer, but if I can't see such a feature appealing to
the performance user because it wont ever be as fast as they want it
to be. To appeal to the general user transparent implementation, which
it can't be if you want to preserve all the features. A subset between
these exist, but is quite small and not a far step from moving up or
down.

   * uniquely-referenced (arbitrary mutation changes effectively
 allowed, but only ever referred to uniquely (runtime enforced)).

I think that pretty accurately describes C++, its not fun debugging a
runtime enforced coredump full of crap. :)
I know that's not what your proposing sorry but I couldn't resist the
analogy! I'm not saying its a bad idea, I just don't find it
compelling to me personally.


Regards,
Tim.
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
Clojure group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from 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: update in place for unique references

2009-01-09 Thread Stuart Sierra

On Jan 8, 10:45 pm, Mark P pierh...@gmail.com wrote:
 I should also clarify one point.  I am not asking for this language
 feature so much as asking whether people have thought
 about it.  There may (or may not) be good reasons for not offering
 such a language feature.  I'm just wondering if it has been
 considered.  (And trying to get a feel for the strengths and
 weaknesses of Clojure - I am very new to it.)

I think the big strength of Clojure is how easy it is to integrate
Java code. If you have some performance-critical code you can always
drop down to Java. Certainly, performance is important to Clojure, but
I think the assumption is that it will never compete with pure Java on
speed.

-Stuart Sierra
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
Clojure group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from 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: update in place for unique references

2009-01-09 Thread Mark P

Hi Tim,

I appreciate your comments.

 It is possible to achieve this behavior explicitly if you really
 wanted to:
 (defn create-add-2 []
   (with-local-vars [x 1]
     (do
       (var-set x 1)
       (var-set x (inc @x))
       (let [z @x]
         (fn [y] (+ y z))

That's true.  Only the (inc @x) isn't update-in-place.  Presumably
some java something could be used here instead to get true update
in place.

 Such an aggressive optimizer might be unhappy with a runtime check and
 opt for an unsafe mutable:
 user= (def p (java.awt.Point. 0 0))
 #'user/p
 user= p
 #Point java.awt.Point[x=0,y=0]
 user= (.setLocation p 1 2)
 nil
 user= p
 #Point java.awt.Point[x=1,y=2]
 But might still be unhappy with having to use object calls, at which
 point I don't think Clojure is the right language. However lucky for
 them they could still go away and implement an incredibly efficient
 java api and call it from within Clojure very easily. They would still
 want to wring the last few drops of performance and write it in C.
 Actually they could still invoke that code at a high level via JNI but
 of course would want to keep the calls to a minimum to avoid calling
 overhead.

What you're saying could well be true.  Ie a runtime check of
unique reference might not be acceptable where performance
is a major concern.  But there are two ways around this.

1. Have the ability to turn runtime uniqueness checking on or off.
This way code can be tested with the check on, but then run
with it off once we are convinced the code is correct (at coder's
own risk of course).

2. Take up Mark Fredrickson's suggestion of a code walking
analysis macro to prove uniqueness before running the code.
That way no runtime check is needed.

The fact that java method calls are always expensive is still
a problem though.  As you say, ultimately a call to a C or C++
routine via JNI might be the only real performance answer.

I wish there were a better way.

 I'm just an observer, but if I can't see such a feature appealing to
 the performance user because it wont ever be as fast as they want it
 to be. To appeal to the general user transparent implementation, which
 it can't be if you want to preserve all the features. A subset between
 these exist, but is quite small and not a far step from moving up or
 down.

You might be right here, though I still feel uniqueness is a
good tool for writing safe and somewhat transparent equivalent to
mutation based code.  C++ is (unfortunately) my current main
language and I use a runtime uniqueness framework to ensure
much more reliable mutation based code there.  But I think Java's
insistence on virtual function calls may make a highly efficient
uniqueness approach difficult to achieve in Clojure.

    * uniquely-referenced (arbitrary mutation changes effectively
      allowed, but only ever referred to uniquely (runtime enforced)).

 I think that pretty accurately describes C++, its not fun debugging a
 runtime enforced coredump full of crap. :)
 I know that's not what your proposing sorry but I couldn't resist the
 analogy! I'm not saying its a bad idea, I just don't find it
 compelling to me personally.

But adhering to a uniqueness discipline within C++, together with
a functional approach like FC++, does lead to more reliable
and more transparent (and somewhat efficient) C++ code.  And
uniqueness in a lisp language should be much more elegant
than my C++ implementation.

But I think you and Mark Fredrickson are right to point out that
limitations within the JVM itself may make efficiency via
uniqueness that is competative with C/C++, impossible to
achieve.  I'm still hopeful there may be a way, but I can't see
it just now.

Cheers,

Mark P.

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
Clojure group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from 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: update in place for unique references

2009-01-08 Thread Mark Engelberg

Clean doesn't allow mutation, so it has to do tricks like this or else
you'd never be able to write a useful program.

Clojure gives you a set of data structures that do very fast
non-destructive update.  Clojure also gives you tools like atoms,
refs, and full access to Java's mutable behavior to specify update in
place if that's what you want.

Since Clojure gives you a full range of immutable/mutable update
choices, I fail to see how Clean's uniqueness typing is at all
relevant to Clojure.

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
Clojure group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from 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: update in place for unique references

2009-01-08 Thread Mark P

 Clojure gives you a set of data structures that do very fast
 non-destructive update.  Clojure also gives you tools like atoms,
 refs, and full access to Java's mutable behavior to specify update in
 place if that's what you want.

Yes, I can see that one could implement this oneself
via Java.  But it wouldn't be an official part of the language.

What I am wondering is whether update-in-place for unique
references could lead to greater efficiencies (in some cases)
than Clojure's current non-destructive updates.  And without
harming referential transparency or concurrency benefits.

Fundamentally I would have thought update-in-place beats
update-by-replace in both execution speed and in memory
usage.  The only problem with it is that it usually breaks
referential transparency as well as causing problems
with concurrency.  But in the case of a unique reference
that is about to disappear, update-in-place does no harm!
The memory is about to become obsolete soon anyway
so why not commandeer it?  And if commandeered, why
not update it in place - as nothing else is looking at it.

I realize there are issues, but maybe these could be solved
and it could lead to even more efficient (both time and memory)
code from Clojure, while not sacrificing its strengths.

I'm just wondering whether anyone has thought about it.
And if so, whether it has potential, or whether there are
good reasons why it is not practical.

Cheers,

Mark P.

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
Clojure group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from 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: update in place for unique references

2009-01-08 Thread Mark P

Hi Mark F,

Thanks for your responses.

 1. Data: Is this really a problem that is slowing down Clojure
 programs in practice? Can you provide some data to that effect? I
 would suggest writing a couple of Java benchmarks - one that updates a
 simple structure in place and one that only creates new data. Time
 them. Write more benchmarks, but this time do it in Clojure (though
 perhaps with some straight Java calls to make the updates). Are there
 differences in the Java versions from the Clojure versions? Are there
 differences in the update vs new data versions?

Writing some test code is not a bad idea, but from what I
heard Rich Hickey say in his online talks, probably unnecessary
to establish that using Clojure built-in data structures
involves a performance hit (in the single-thread case anyway).
I got the impression that Clojure structures are somewhere
in the range of 1.5 to 4 times worse than mutation based
structures.  Of course, this performance is quite an achievement,
given the advantages of Clojure's approach.  But for applications
which are performance critical, I am wondering whether
a uniqueness-based update-in-place would offer a
complementary well performing alternative.

 2. Take a page from the Scheme playbook. Don't ask the language to
 implement this feature, ask for the minimal set of tools that you need
 to implement it. I would think a code walking escape analysis macro
 could be very useful. Instead of run-time reference counting, the
 macro could find data that is guaranteed not to escape its scope via a
 closure (e.g. let bound locals that are not used in any (fn
 [] ...)s ). What would you need access to? Additional JVM byte-code
 instructions? Post-compile processing by user code? Update in place
 methods for the normally immutable types?  I don't know exactly what
 you'd need, but ask for that before asking for a much bigger feature.

The escape analysis macro sounds interesting.  But an initial approach
might be, for each of these new data structures (mutation based under
the hood) to have two versions of each structure:

  * immutable (ie no more changes will ever occur - if you want a
modification you will have to make a full copy); and

  * uniquely-referenced (arbitrary mutation changes effectively
allowed, but only ever referred to uniquely (runtime enforced)).

Most structures of this type would start life as a uniquely-referenced
structure (either empty or a copy of an immutable), and have
lots of mutations effectively applied to them in a safe environment,
until they are ready to be frozen and released to the world as
an immutable version of the structure.  (Some structures would
stay uniquely-referenced their whole life - used for performance
in some single-threaded encapsulated mutation-based algorithm.)

I should also clarify one point.  I am not asking for this language
feature so much as asking whether people have thought
about it.  There may (or may not) be good reasons for not offering
such a language feature.  I'm just wondering if it has been
considered.  (And trying to get a feel for the strengths and
weaknesses of Clojure - I am very new to it.)

 3. Remember that Clojure relies on the JVM for its allocation and GC.
 Clojure is not issuing malloc and free calls. The JVM will not make it
 easy to repurpose the storage of one object with a new object, without
 going through a method.

Maybe the way to handle this (at least initially) would be to only
provide
uniqueness interfaces to some of Java's main structures.  Perhaps not
as general as would be ideal, but would easily allow repurposing via
a
method.

Thanks again for your input.

Cheers,

Mark P.

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
Clojure group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from 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: update-values for clojure.contrib.sql

2009-01-02 Thread Christian Vest Hansen

Well, one thing that sticks out (particularly to me) is the fact that
you forgot to put your doc-string *before* your [params*] list :)
(ahem)

On Fri, Jan 2, 2009 at 8:21 AM, budu nbudu...@gmail.com wrote:

 Hi, I was experimenting with clojure-contrib's sql features and found
 that there wasn't any update-values function. I've written my own and
 I'm sharing it here:

 (defn update-values [table where column-names  values]
  Update columns of a table with values. columns-names is a vector of
  column names (strings or keywords) and the rest of arguments are the
  values for those columns.
  (let [columns (map #(str (the-str %)  = ?) column-names)
template (if (seq column-names)
  (apply str (interpose , columns))
  )]
(apply do-prepared
   (format update %s set %s where %s
   (the-str table) template where)
   [values])))

 It only send one set of values to do-prepared because of the where
 clause that would have to change according to each sets. I'm ready for
 your commentaries and/or suggestions.
 




-- 
Venlig hilsen / Kind regards,
Christian Vest Hansen.

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
Clojure group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from 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: update-values for clojure.contrib.sql

2009-01-02 Thread budu

D'oh! I have a hard time kicking out that old habit. And changing code
after testing it too!

On Jan 2, 4:21 am, Christian Vest Hansen karmazi...@gmail.com
wrote:
 Well, one thing that sticks out (particularly to me) is the fact that
 you forgot to put your doc-string *before* your [params*] list :)
 (ahem)



 On Fri, Jan 2, 2009 at 8:21 AM, budu nbudu...@gmail.com wrote:

  Hi, I was experimenting with clojure-contrib's sql features and found
  that there wasn't any update-values function. I've written my own and
  I'm sharing it here:

  (defn update-values [table where column-names  values]
   Update columns of a table with values. columns-names is a vector of
   column names (strings or keywords) and the rest of arguments are the
   values for those columns.
   (let [columns (map #(str (the-str %)  = ?) column-names)
         template (if (seq column-names)
                   (apply str (interpose , columns))
                   )]
     (apply do-prepared
            (format update %s set %s where %s
                    (the-str table) template where)
            [values])))

  It only send one set of values to do-prepared because of the where
  clause that would have to change according to each sets. I'm ready for
  your commentaries and/or suggestions.

 --
 Venlig hilsen / Kind regards,
 Christian Vest Hansen.
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
Clojure group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from 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: update a ref struct

2008-11-24 Thread Kevin Downey

I know you are asking about refs, but you might want to think about
using reduce to walk the line-seq. the nature of reduce lets you have
access to the line-seq, two lines at a time no need for a ref.

On Mon, Nov 24, 2008 at 2:17 PM, Brian Doyle [EMAIL PROTECTED] wrote:
 I am parsing a file and to compare the current line
 with the previous line of the file.  I am using line-seq
 to go thru the file and I thought I would create a
 ref to store the previous line.   When I want to update
 the previous line value I can't seem to do it.  I've
 never used refs before so I'm sure I'm doing something
 very stupid.

 (defstruct line :lat :lon :name)

 (defn convert [file]
   (let [prev-line (ref (struct line))]
 (with-open [r (reader file)]
(doseq [l (line-seq r)]
  (let [ps (split #, l)
 c-line (struct line (ps 0) (ps 1) (ps 2))]
(if (not= c-line @pre-line)
  (do ; do stuff here then update pre-line
 (dosync ref-set pre-line (apply struct line (vals c-line)))
 (println @pre-line  ; this prints out all nils
 doesn't seem to work



 Sorry if this email is not formatted correctly.  Something is wrong with my
 browser
 currently typing in a textarea.  Thanks.



 




-- 
The Mafia way is that we pursue larger goals under the guise of
personal relationships.
Fisheye

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
Clojure group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: update a ref struct

2008-11-24 Thread Brian Doyle
Thanks Kevin, I will try using reduce instead.  I would like to know what
I'm doing wrong with updating the ref for future reference.  Thanks.

On Mon, Nov 24, 2008 at 3:23 PM, Kevin Downey [EMAIL PROTECTED] wrote:


 I know you are asking about refs, but you might want to think about
 using reduce to walk the line-seq. the nature of reduce lets you have
 access to the line-seq, two lines at a time no need for a ref.

 On Mon, Nov 24, 2008 at 2:17 PM, Brian Doyle [EMAIL PROTECTED]
 wrote:
  I am parsing a file and to compare the current line
  with the previous line of the file.  I am using line-seq
  to go thru the file and I thought I would create a
  ref to store the previous line.   When I want to update
  the previous line value I can't seem to do it.  I've
  never used refs before so I'm sure I'm doing something
  very stupid.
 
  (defstruct line :lat :lon :name)
 
  (defn convert [file]
(let [prev-line (ref (struct line))]
  (with-open [r (reader file)]
 (doseq [l (line-seq r)]
   (let [ps (split #, l)
  c-line (struct line (ps 0) (ps 1) (ps 2))]
 (if (not= c-line @pre-line)
   (do ; do stuff here then update pre-line
  (dosync ref-set pre-line (apply struct line (vals
 c-line)))
  (println @pre-line  ; this prints out all nils
  doesn't seem to work
 
 
 
  Sorry if this email is not formatted correctly.  Something is wrong with
 my
  browser
  currently typing in a textarea.  Thanks.
 
 
 
  
 



 --
 The Mafia way is that we pursue larger goals under the guise of
 personal relationships.
Fisheye

 


--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
Clojure group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: update a ref struct

2008-11-24 Thread Kevin Downey

ref-set needs its one set of parens, and the last thing in the ref-set
call needs to be a function either (fn [x] ...) or a symbol for a var
that holds a function

On Mon, Nov 24, 2008 at 2:30 PM, Brian Doyle [EMAIL PROTECTED] wrote:
 Thanks Kevin, I will try using reduce instead.  I would like to know what
 I'm doing wrong with updating the ref for future reference.  Thanks.

 On Mon, Nov 24, 2008 at 3:23 PM, Kevin Downey [EMAIL PROTECTED] wrote:

 I know you are asking about refs, but you might want to think about
 using reduce to walk the line-seq. the nature of reduce lets you have
 access to the line-seq, two lines at a time no need for a ref.

 On Mon, Nov 24, 2008 at 2:17 PM, Brian Doyle [EMAIL PROTECTED]
 wrote:
  I am parsing a file and to compare the current line
  with the previous line of the file.  I am using line-seq
  to go thru the file and I thought I would create a
  ref to store the previous line.   When I want to update
  the previous line value I can't seem to do it.  I've
  never used refs before so I'm sure I'm doing something
  very stupid.
 
  (defstruct line :lat :lon :name)
 
  (defn convert [file]
(let [prev-line (ref (struct line))]
  (with-open [r (reader file)]
 (doseq [l (line-seq r)]
   (let [ps (split #, l)
  c-line (struct line (ps 0) (ps 1) (ps 2))]
 (if (not= c-line @pre-line)
   (do ; do stuff here then update pre-line
  (dosync ref-set pre-line (apply struct line (vals
  c-line)))
  (println @pre-line  ; this prints out all nils
  doesn't seem to work
 
 
 
  Sorry if this email is not formatted correctly.  Something is wrong with
  my
  browser
  currently typing in a textarea.  Thanks.
 
 
 
  
 



 --
 The Mafia way is that we pursue larger goals under the guise of
 personal relationships.
Fisheye




 




-- 
The Mafia way is that we pursue larger goals under the guise of
personal relationships.
Fisheye

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
Clojure group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: update a ref struct

2008-11-24 Thread Kevin Downey

On Mon, Nov 24, 2008 at 2:34 PM, Kevin Downey [EMAIL PROTECTED] wrote:
 ref-set needs its one set of parens, and the last thing in the ref-set
 call needs to be a function either (fn [x] ...) or a symbol for a var
 that holds a function

I made a mistake here. I was thinking of alter, not ref-set.


 On Mon, Nov 24, 2008 at 2:30 PM, Brian Doyle [EMAIL PROTECTED] wrote:
 Thanks Kevin, I will try using reduce instead.  I would like to know what
 I'm doing wrong with updating the ref for future reference.  Thanks.

 On Mon, Nov 24, 2008 at 3:23 PM, Kevin Downey [EMAIL PROTECTED] wrote:

 I know you are asking about refs, but you might want to think about
 using reduce to walk the line-seq. the nature of reduce lets you have
 access to the line-seq, two lines at a time no need for a ref.

 On Mon, Nov 24, 2008 at 2:17 PM, Brian Doyle [EMAIL PROTECTED]
 wrote:
  I am parsing a file and to compare the current line
  with the previous line of the file.  I am using line-seq
  to go thru the file and I thought I would create a
  ref to store the previous line.   When I want to update
  the previous line value I can't seem to do it.  I've
  never used refs before so I'm sure I'm doing something
  very stupid.
 
  (defstruct line :lat :lon :name)
 
  (defn convert [file]
(let [prev-line (ref (struct line))]
  (with-open [r (reader file)]
 (doseq [l (line-seq r)]
   (let [ps (split #, l)
  c-line (struct line (ps 0) (ps 1) (ps 2))]
 (if (not= c-line @pre-line)
   (do ; do stuff here then update pre-line
  (dosync ref-set pre-line (apply struct line (vals
  c-line)))
  (println @pre-line  ; this prints out all nils
  doesn't seem to work
 
 
 
  Sorry if this email is not formatted correctly.  Something is wrong with
  my
  browser
  currently typing in a textarea.  Thanks.
 
 
 
  
 



 --
 The Mafia way is that we pursue larger goals under the guise of
 personal relationships.
Fisheye




 




 --
 The Mafia way is that we pursue larger goals under the guise of
 personal relationships.
Fisheye




-- 
The Mafia way is that we pursue larger goals under the guise of
personal relationships.
Fisheye

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
Clojure group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



  1   2   >