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 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 > 
> 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 
>> 
>> 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 
>> 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 .
>> 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 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  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

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-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 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
> thing
> .
>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with
> your first post.
> To unsubscribe from 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
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 Divyansh Prakash
I looked into a port of Clojure to Parrot, and it basically does the same 
thing
.

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

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  or
> 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
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 to downloads page?

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

"Although it is possible to download Clojure directly here , 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  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 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-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  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 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  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 4:52 PM, blais  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:36:52 PM UTC-4, David Nolen wrote:
>
> On Thu, Apr 26, 2012 at 4:30 PM, blais  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:30 PM, blais  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
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 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  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 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  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 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 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 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 to clojure.tools.cli

2011-11-01 Thread Sean Corfield
On Tue, Nov 1, 2011 at 10:59 AM, gaz jones  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 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  wrote:
> It's strange that it hasn't made it to central yet.
...
> On Tue, Nov 1, 2011 at 1:59 PM, gaz jones  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 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  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 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 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
> Does anyone know how to update xml element attribute value on the zipper
> data structure?
> I have something like
> 
>     
>     
> 
> (: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-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 oddness

2010-06-04 Thread Chouser
On Fri, Jun 4, 2010 at 10:04 AM, Heinz N. Gies  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"  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 14:11 , Heinz N. Gies wrote:

> 
> On Jun 4, 2010, at 14:03 , Joost wrote:
> 
>> On Jun 4, 1:42 pm, "Heinz N. Gies"  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 Heinz N. Gies

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

> On Jun 4, 1:42 pm, "Heinz N. Gies"  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 Joost


On Jun 4, 2:03 pm, Joost  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 Joost
On Jun 4, 1:42 pm, "Heinz N. Gies"  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 Heinz N. Gies

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

> On Jun 4, 7:37 am, "Heinz N. Gies"  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, 7:37 am, "Heinz N. Gies"  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 and get-in why no default?

2010-02-02 Thread Meikel Brandmeyer
Hi,

On Feb 2, 2:31 pm, Timothy Pratley  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-02 Thread Timothy Pratley
On 2 February 2010 17:41, Meikel Brandmeyer  wrote:
> I would get rid of the if-let.

Ah yes! Ok patch updated to:

+  ([m ks not-found]
+   (if (seq ks)
+ (get (reduce get m (butlast ks)) (last ks) not-found)
+ m)))

Note that (seq ks) will throw an illegal argument exception if ks is 5
for instance, if ks is nil or empty the original map is preserved.


> 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?


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  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 Timothy Pratley
On 2 February 2010 17:55, Richard Newman  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-01 Thread Meikel Brandmeyer
Hi,

On Feb 2, 7:55 am, Richard Newman  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-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 Timothy,

On Feb 2, 1:19 am, Timothy Pratley  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 Timothy Pratley
On 2 February 2010 00:18, Meikel Brandmeyer  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,

On Feb 1, 1:57 pm, Timothy Pratley  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
> 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  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-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-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-29 Thread Timothy Pratley
2010/1/30 Rich Hickey :
> 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 and get-in why no default?

2010-01-29 Thread Rich Hickey


On Jan 29, 9:04 am, Sean Devlin  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 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  wrote:
> On Dec 30 2009, 6:18 am, Timothy Pratley 
> wrote:
>
> > On Dec 13, 1:24 am, Rich Hickey  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 Dec 30 2009, 6:18 am, Timothy Pratley 
wrote:
> On Dec 13, 1:24 am, Rich Hickey  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! (?)

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

On Jan 21, 12:40 am, brianh  wrote:
> Any chance you could rethink your approach & use a zipper?
>
> On Jan 20, 9:32 am, Gabi  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  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  
> > > 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  wrote:
> > > >> I need to add/delete much more frequently than just updating
> > > >> actually.
>
> > > >> On Jan 20, 4:59 pm, Sean Devlin  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  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  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  
> > > >> > > > 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  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  wrote:
>
> > > >> > > > >> > On Sun, Jan 17, 2010 at 8:25 AM, Gabi  
> > > >> > > > >> > 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
> > > >> 

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  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  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  
> > 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  wrote:
> > >> I need to add/delete much more frequently than just updating
> > >> actually.
>
> > >> On Jan 20, 4:59 pm, Sean Devlin  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  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  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  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  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  wrote:
>
> > >> > > > >> > On Sun, Jan 17, 2010 at 8:25 AM, Gabi  
> > >> > > > >> > 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 

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  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  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  wrote:
> >> I need to add/delete much more frequently than just updating
> >> actually.
>
> >> On Jan 20, 4:59 pm, Sean Devlin  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  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  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  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  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  wrote:
>
> >> > > > >> > On Sun, Jan 17, 2010 at 8:25 AM, Gabi  
> >> > > > >> > 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
> >> > > > > clo

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  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  wrote:
>> I need to add/delete much more frequently than just updating
>> actually.
>>
>> On Jan 20, 4:59 pm, Sean Devlin  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  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  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  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  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  wrote:
>>
>> > > > >> > On Sun, Jan 17, 2010 at 8:25 AM, Gabi  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@goog

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  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  wrote:
>
> > I need to add/delete much more frequently than just updating
> > actually.
>
> > On Jan 20, 4:59 pm, Sean Devlin  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  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  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  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  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  wrote:
>
> > > > > >> > On Sun, Jan 17, 2010 at 8:25 AM, Gabi  
> > > > > >> > 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 mem

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  wrote:
> I need to add/delete much more frequently than just updating
> actually.
>
> On Jan 20, 4:59 pm, Sean Devlin  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  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  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  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  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  wrote:
>
> > > > >> > On Sun, Jan 17, 2010 at 8:25 AM, Gabi  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  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  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  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  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  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  wrote:
>
> > > >> > On Sun, Jan 17, 2010 at 8:25 AM, Gabi  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  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  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  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  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  wrote:
>
> > >> > On Sun, Jan 17, 2010 at 8:25 AM, Gabi  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  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  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  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  wrote:
>
> >> > On Sun, Jan 17, 2010 at 8:25 AM, Gabi  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
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  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  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  wrote:
>>
>> > On Sun, Jan 17, 2010 at 8:25 AM, Gabi  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
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  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  wrote:
>
> > On Sun, Jan 17, 2010 at 8:25 AM, Gabi  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
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  wrote:
> On Sun, Jan 17, 2010 at 8:25 AM, Gabi  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 Chouser
On Sun, Jan 17, 2010 at 8:25 AM, Gabi  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
Forgot to mention that v in the example is defined to  [[1 2] [3 4]]

On Jan 17, 3:19 pm, Gabi  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 and get-in why no default?

2010-01-02 Thread Timothy Pratley
2010/1/2 Timothy Pratley :
> 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-02 Thread Timothy Pratley
2010/1/2 Sean Devlin :
> 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-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  wrote:
> On Dec 13, 1:24 am, Rich Hickey  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 Timothy Pratley
On Dec 13, 1:24 am, Rich Hickey  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  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
 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 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  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  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 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  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
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  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  wrote:
> > Because update-in can use any function to do the update.
> >
> > On Wed, Apr 29, 2009 at 6:54 PM, mifrai  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  wrote:
> Because update-in can use any function to do the update.
>
> On Wed, Apr 29, 2009 at 6:54 PM, mifrai  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
Because update-in can use any function to do the update.

On Wed, Apr 29, 2009 at 6:54 PM, mifrai  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

> 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-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-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  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-14 Thread budu

Good, anyway it was only a relatively minor modification of insert-
values function. I'm sending my contributor agreement today, hoping to
contribute further in a near future. Thanks

On Jan 14, 12:13 am, "Stephen C. Gilardi"  wrote:
> 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
> 3KViewDownload
--~--~-~--~~~---~--~~
You 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 Mark P

Hi Stuart,

> 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.

Yes you are right, the ability to drop down to Java is a plus.

But a unique reference approach in theory would be better
still as it allows one to maintain purity (referential transparency
and theoretically equivalent to no mutation) while under-the-hood
getting the efficiency of update-in-place.

But as I've discovered through this thread, the limitations of the
JVM might make this "sweet spot" somewhat smaller than I
would have liked.

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-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
> #
> user=> (.setLocation p 1 2)
> nil
> user=> p
> #
> 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-09 Thread Stuart Sierra

On Jan 8, 10:45 pm, Mark P  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 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
#
user=> (.setLocation p 1 2)
nil
user=> p
#
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-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 in place for unique references

2009-01-08 Thread Mark Fredrickson

Time for another person named Mark to chime in. I expect to hear from  
all the other Marks before this thread is over.

I have three responses to your suggestion:

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?

My intuition is that you are not going to see a big speed up for this,  
but let's put the hypothesis to the test. As I understand it, short  
lived data is cheap to make and discard, as the copying collector  
doesn't have much to do if nursery data is discarded quickly. But, of  
course, there are costs to allocation, etc. Perhaps I am wrong. I  
would be interested to see data on the subject.

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.

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. As I see it, all functions would require an  
update-in-place version. The compiler could swap these behind the  
scenes, but writing them would be a lot of work. I could be wrong  
about this, as I am not a JVM expert, but without direct access to  
pointers, how else would this be accomplished?

All in all, an interesting research topic -- especially if data show  
that a big speed up could be found by implementing it.

Best of luck,
-Mark

On Jan 7, 2009, at 8:01 PM, Mark P wrote:

>
> I am new to clojure, but it seems very interesting.
>
> Has anyone thought about allowing "update in place"
> for situations where it is safe?
>
> Suppose you have
>
>  (def y (tripleit x))
>
> and you know that there is only a single reference to x
> at this point, then it would be safe to implement it as
>
>  "y takes on the storage of x and this is multiplied
>   by 3 in-place".
>
> Well, I should say it's safe as long as "x" loses scope
> at this point.  The fact that y has gained its storage and
> done an update in place shouldn't bother anyone or
> cause any loss in purity.
>
> This is what "uniqueness types" are used for in the
> "Clean" functional lanugage.  (And logic language
> Mercury uses "unique modes".)
>
> Now I realize there is the question in Clojure of
> "how do we know whether it's unique".  Clean does it
> via the type system.  But one could have other
> mechanisms for ensuring uniqueness.  One would be
> to keep a runtime track of references and only allow an
> update-in-place primitive in the case of a single reference.
> If this were attempted when multiple references existed,
> a runtime error would occur.
>
> Has anyone thought about this kind of update-in-place
> methodology?  It seems to be one of the reasons why
> both Clean and Mercury achieve good performance.
>
> Perhaps there are good reasons why this approach is
> not workable in clojure (or not useful), but I'd be
> interested to hear why.
>
> Thanks,
>
> Mark.
>
> >


--~--~-~--~~~---~--~~
You 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 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-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" 
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  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 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  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
-~--~~~~--~~--~--~---



  1   2   >