finding a key which does not exist in the map

2011-05-26 Thread Sunil S Nandihalli
Hello everybody,
 I was wondering if there is a way to find a key which does not exist in a
map in an efficient way. you can assume that all the keys are integers.
I currently do something like 

(defn non-existent-key [mp]
(first (filter (comp not mp) (range


Is there a possibly more efficient way of doing this?
Thanks,
Sunil.

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

Re: finding a key which does not exist in the map

2011-05-26 Thread Andreas Kostler
If you have control over the creation of the map, you could use something like 
a global counter to provide the next valid key.
You could also use a sorted map and just increment to last (biggest) key in the 
map.
Or you could use a random number. If the range is big enough, the probability 
of collisions will be low. In case of a collision you just draw again. 

On 26/05/2011, at 8:43 PM, Sunil S Nandihalli wrote:

> Hello everybody,
>  I was wondering if there is a way to find a key which does not exist in a 
> map in an efficient way. you can assume that all the keys are integers. 
> I currently do something like 
> 
> (defn non-existent-key [mp]
> (first (filter (comp not mp) (range
> 
> 
> Is there a possibly more efficient way of doing this?
> Thanks,
> Sunil.
> 
> -- 
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with your 
> first post.
> To unsubscribe from 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: Efficient sparse vector representation...

2011-05-26 Thread Andreas Kostler
This is what I've come up with so far...it should give a bit of an idea of what 
I'm using it for:

(defprotocol PSparseVec
  (norm [this])
  (cnt [this])
  (ith-val [this i])
  (unit-vec [this])
  (assc [this i o]))

(defrecord SparseVec [indices vals]
  PSparseVec
  (cnt [this] (count indices))
  (norm [this] (Math/sqrt (reduce + (map #(* % %) vals
  (unit-vec [this] (let [l-inv (/ 1 (norm this))] (SparseVec. indices (vec (map 
#(* l-inv %) vals)
  (assc [this i o]
(let [idx (bin-search indices i)
  val (get vals idx nil)]
  (if val (SparseVec. indices (assoc vals idx o))
  (let [new-indices (sort (conj indices i))
new-idx (bin-search new-indices i)
[chunk1 chunk2] (split-at new-idx vals)]
(SparseVec. new-indices (into (conj (vec chunk1) o) chunk2))
  (ith-val [this i]
(get vals (bin-search indices i) 0)))

Can you guys think of ways of making this more idiomatic and/or performant?

Cheers
Andreas

On 26/05/2011, at 1:12 PM, Ken Wesson wrote:

> On Wed, May 25, 2011 at 10:22 PM, Andreas Kostler
>  wrote:
>> Yes and no. I need efficient two way lookup.
>> 
>> So, I need to do something like
>> For every key in {12 "a" 23 "aa" 234 ""}
>> Get the token in a map that is organised like this:
>> {token1 id1 token2 id2 token2 id3}
>> 
>> Naively, I could have two maps with the reverse lookups.
>> l1 = {token1 id1 token2 id2 token3 id3}
>> reverse = {id1 token1 id2 token2 ...}
>> 
>> Given that there will be many, many tokens this seems a bit too much 
>> overhead.
>> 
>> You could basically do a binarySearch on a sorted hash map (sorted by vals 
>> (e.g. ids)) but I thought
>> doing the search on a vec of vectors would be more efficient and the vec of 
>> vecs representation would
>> be more compact.
>> 
>> I guess that's what I'm trying to figure out.
>> 
>> Andreas
>> 
>> P.S. Lookup by token is more frequent than lookup by id, hence the bin 
>> search on id.
> 
> If the token and id sets are disjoint (no single object can ever
> appear as each -- only one of those at most) then you can use a single
> map with a function put defined as:
> 
> (defn put [m k v]
>  (assoc (assoc m k v) v k))
> 
> which adds mappings in both directions. Then just use (m k) or (m v)
> to perform lookups in either direction. The overhead may be less than
> with two separate hashmaps, and the code is certainly simpler.
> 
> -- 
> Protege: What is this seething mass of parentheses?!
> Master: Your father's Lisp REPL. This is the language of a true
> hacker. Not as clumsy or random as C++; a language for a more
> civilized age.
> 
> -- 
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with your 
> first post.
> To unsubscribe from 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: ANN: SoyMacchiato - JDK7 for OS X

2011-05-26 Thread rogerdpack
> I've been doing some experimentation with Clojure on various setups of
> Java/JDK 1.7, including the DaVinci Machine enhancements.

Do you find it reasonably stable on OS X?

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


Re: Efficient sparse vector representation...

2011-05-26 Thread Ken Wesson
On Thu, May 26, 2011 at 8:19 AM, Andreas Kostler
 wrote:
>          (let [new-indices (sort (conj indices i))
>                new-idx (bin-search new-indices i)
>                [chunk1 chunk2] (split-at new-idx vals)]
>            (SparseVec. new-indices (into (conj (vec chunk1) o) chunk2))
>  (ith-val [this i]
>    (get vals (bin-search indices i) 0)))
>
> Can you guys think of ways of making this more idiomatic and/or performant?

Yes. Drop the sort and avoid split-at. Just use binary search to find
the correct value for new-idx (the position of the next index higher
than i, or else the indices vector's length) and then

(SparseVec.
  (into (conj (subvec indices 0 new-idx) i) (subvec indices new-idx))
  (into (conj (subvec vals 0 new-idx) o) (subvec vals new-idx)))

The binary search you're doing anyway, and subvec is cheap. There's
one more into on vectors, but the sort would have been n log2 n and
the into is n log32 n, indeed k log32 k where k is the length of the
tail. The latter logarithmic factors are much smaller at a given
length of vector.

Tune this, then test its performance against a naive solution using a
plain-jane hash map.

-- 
Protege: What is this seething mass of parentheses?!
Master: Your father's Lisp REPL. This is the language of a true
hacker. Not as clumsy or random as C++; a language for a more
civilized age.

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


Re: Efficient sparse vector representation...

2011-05-26 Thread Steve Miner
I've used this approach before. It was simple and worked well.  Note that assoc 
can take multiple keys and vals so you can simplify it to (assoc m k v v k) 
instead of nesting the assoc calls.  If there's any chance of a collision, you 
could be defensive and test for (contains? m k) or (contains? m v) and take 
appropriate action (maybe throw).  It might be a good thing to put into a 
pre-condition.


On May 25, 2011, at 11:12 PM, Ken Wesson wrote:

> If the token and id sets are disjoint (no single object can ever
> appear as each -- only one of those at most) then you can use a single
> map with a function put defined as:
> 
> (defn put [m k v]
>  (assoc (assoc m k v) v k))
> 
> which adds mappings in both directions. Then just use (m k) or (m v)
> to perform lookups in either direction. The overhead may be less than
> with two separate hashmaps, and the code is certainly simpler.

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


Architecture for a Clojure project

2011-05-26 Thread Max Weber
Hi,

imaging you could do a software project from scratch and Clojure is the main
programming language. What architecture would you choose? Of course it
depends, so here are some requirements and basic conditions:

   - Let's assume that we are building a web application for some social
   media stuff
   - So it has to handle a lot of data
   - And it has to scale (there are a lot more read than write operations)
   - Your data store is a NoSQL document database (e.g. MongoDB)
   - Your deployment environment is cloud based (e.g. EC2).
   - It should be an architecture which fits the functional programming
   paradigma: side effects should be rare and controllable
   - The application should be extendable and maintainable

It is obvious that an application cannot been done which fulfills all the
criteria mentioned above one hundred percent. However you may get very close
to one hundred percent for some of the points.

At the moment I would say that CQRS  is the most
promising architectural pattern to do scalable, maintainable and extendable
web applications. Nevertheless I've a very hard time to adapt the common
practices of a CQRS application to the "functional world". Most of the CQRS
stuff today comes from an object oriented world, particularly there are a
lot of .Net projects . There is also a CQRS
Framework for Java named Axon .

Regrettably, there are not much writings about what architecture you should
use, if you are working with a functional programming language in the
context mentioned above. May be I just not find the right websites or books.
So here is my initial question again: What architecture would you choose?

Best regards

Max

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

Re: San Francisco Clojure Users

2011-05-26 Thread Emeka
David,

Yes. I am in Nigeria.

Emeka

On Tue, May 24, 2011 at 9:43 AM, David Jagoe  wrote:

> Are you in Nigeria?
>
> Anyone else on this list in Africa?
>
>
>
> On Sunday, 22 May 2011, Emeka  wrote:
> > Okay.
> > I live in Africa... maybe we should have online meetups for now.
> > Emeka
> >
> > On Thu, May 19, 2011 at 4:29 PM, David Jagoe 
> wrote:
> > On 18 May 2011 18:54, Emeka  wrote:
> >> David,
> >> How is Clojure doing in Africa?
> >
> > There really aren't that many people using it among the people that I
> > have spoken to. I've worked in the UK, Europe and the US and in
> > comparison South Africa is a little bit behind and quite conservative
> > when it comes to technology choices.
> >
> >
> > Cheers,
> > 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
> >
> > --
> > Satajanus  Nig. Ltd
> >
> >
> >
> >
> >
> >
> >
> > --
> > You received this message because you are subscribed to the Google
> > Groups "Clojure" group.
> > To post to this group, send email to clojure@googlegroups.com
> > Note that posts from new members are moderated - please be patient with
> your first post.
> > To unsubscribe from 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
>



-- 
*Satajanus  Nig. Ltd


*

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

Re: How to convert a string to a data structure

2011-05-26 Thread ron peterson
Thank you everyone for the solution.

Ron.

On May 25, 6:24 pm, Luc Prefontaine 
wrote:
> Use:
>
> (read-string (read-string "[{:a \"blah\" :b 23} {:d 34 :c \"hello\"}]")
>
> I believe your expression is wrong, (:d should be {:d.
>
> Luc P.
>
> On Wed, 25 May 2011 18:04:11 -0700 (PDT)
>
> ron peterson  wrote:
> > Hi,
>
> > If I have a following string for example:
>
> > [{:a "blah" :b 23}(:d 34 :c "hello"}]
>
> > how can I convert it to a clojure data structure?
>
> > Thanks,
> > Ron.
>
> --
> Luc P.
>
> 
> The rabid Muppet

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


Re: finding a key which does not exist in the map

2011-05-26 Thread Walter van der Laan
You could use this:
(defn non-existing-key [mp] (inc (reduce max (keys mp

For example:
(non-existing-key {1 "a" 2 "b"}) => 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: Debian packages

2011-05-26 Thread Phil Hagelberg
On May 25, 7:39 pm, Rob Lachlan  wrote:
> I'm curious about this as well, because of the ICFP programming
> contest. The contest organizers are soliciting requests for Debian packages to
> be installed on the contest environment.  I don't suppose that this is
> the reason that you're asking?

No, I am working on a Leiningen package and want an up-to-date .deb on
which to depend.

-Phil

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


Recur and primitives?!?

2011-05-26 Thread Andreas Kostler
Hi guys,
I'm kinda lost as to what's going on here...With clojure-1.2.0 

(defn bin-search [v k c]
  (loop [l 0
 h (dec (count v))]
(if (> l h) false
(let [m (quot (+ l h) 2)
  m-v (v m)]
  (cond (> m-v k) (recur (inc m) h)
(> k m-v) (recur l (dec m))
:else m)

This bombs out with:
java.lang.IllegalArgumentException: recur arg for primitive local: h must be 
matching primitive

With 1.3.0-master-SNAPSHOT it works fine. Any ideas what I'm doing wrong?
Andreas

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


Re: Recur and primitives?!?

2011-05-26 Thread Luc Prefontaine
h gets boxed somehow from integer to something else when the recur is executed.

No idea where however. Look at this, it may help:

http://groups.google.com/group/clojure/browse_thread/thread/e4574bbb01155c4d


On Fri, 27 May 2011 09:54:19 +1000
Andreas Kostler  wrote:

> Hi guys,
> I'm kinda lost as to what's going on here...With clojure-1.2.0 
> 
> (defn bin-search [v k c]
>   (loop [l 0
>  h (dec (count v))]
> (if (> l h) false
> (let [m (quot (+ l h) 2)
>   m-v (v m)]
>   (cond (> m-v k) (recur (inc m) h)
> (> k m-v) (recur l (dec m))
> :else m)
> 
> This bombs out with:
> java.lang.IllegalArgumentException: recur arg for primitive local: h
> must be matching primitive
> 
> With 1.3.0-master-SNAPSHOT it works fine. Any ideas what I'm doing
> wrong? Andreas
> 



-- 
Luc P.


The rabid Muppet

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


Re: Efficient sparse vector representation...

2011-05-26 Thread Andreas Kostler
Thanks Ken,
using this approach brings a ~1000 times speedup :)

(def a (sparse-vec (range 10) (range 10)))

(def b (time (assc-ken a 11 0)))
"Elapsed time: 0.249 msecs"

(def b (time (assc a 11 0)))
"Elapsed time: 252.06 msecs"

Very worthwhile and it's clearer as well.
Cheers
Andreas


On 26/05/2011, at 11:11 PM, Ken Wesson wrote:

> On Thu, May 26, 2011 at 8:19 AM, Andreas Kostler
>  wrote:
>>  (let [new-indices (sort (conj indices i))
>>new-idx (bin-search new-indices i)
>>[chunk1 chunk2] (split-at new-idx vals)]
>>(SparseVec. new-indices (into (conj (vec chunk1) o) chunk2))
>>  (ith-val [this i]
>>(get vals (bin-search indices i) 0)))
>> 
>> Can you guys think of ways of making this more idiomatic and/or performant?
> 
> Yes. Drop the sort and avoid split-at. Just use binary search to find
> the correct value for new-idx (the position of the next index higher
> than i, or else the indices vector's length) and then
> 
> (SparseVec.
>  (into (conj (subvec indices 0 new-idx) i) (subvec indices new-idx))
>  (into (conj (subvec vals 0 new-idx) o) (subvec vals new-idx)))
> 
> The binary search you're doing anyway, and subvec is cheap. There's
> one more into on vectors, but the sort would have been n log2 n and
> the into is n log32 n, indeed k log32 k where k is the length of the
> tail. The latter logarithmic factors are much smaller at a given
> length of vector.
> 
> Tune this, then test its performance against a naive solution using a
> plain-jane hash map.
> 
> -- 
> Protege: What is this seething mass of parentheses?!
> Master: Your father's Lisp REPL. This is the language of a true
> hacker. Not as clumsy or random as C++; a language for a more
> civilized age.
> 
> -- 
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with your 
> first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en

--
"Test-driven Dentistry (TDD!) - Not everything should be test driven"
- Michael Fogus
-- 
**
Andreas Koestler, Software Engineer
Leica Geosystems Pty Ltd
270 Gladstone Road, Dutton Park QLD 4102
Main: +61 7 3891 9772 Direct: +61 7 3117 8808
Fax: +61 7 3891 9336
Email: andreas.koest...@leica-geosystems.com

www.leica-geosystems.com*

when it has to be right, Leica Geosystems

Please  consider the environment before printing this email.

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


Re: Efficient sparse vector representation...

2011-05-26 Thread Ken Wesson
On Thu, May 26, 2011 at 8:50 PM, Andreas Kostler
 wrote:
> Thanks Ken,
> using this approach brings a ~1000 times speedup :)
>
> (def a (sparse-vec (range 10) (range 10)))
>
> (def b (time (assc-ken a 11 0)))
> "Elapsed time: 0.249 msecs"
>
> (def b (time (assc a 11 0)))
> "Elapsed time: 252.06 msecs"
>
> Very worthwhile and it's clearer as well.

You're welcome. Keep in mind that this is a best-case insert, right at
the end, for the algo I posted. Inserts at the beginning won't be very
much faster than before, and in the middle will be in the middle.

-- 
Protege: What is this seething mass of parentheses?!
Master: Your father's Lisp REPL. This is the language of a true
hacker. Not as clumsy or random as C++; a language for a more
civilized age.

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


Re: Efficient sparse vector representation...

2011-05-26 Thread Andreas Kostler
That explains the good performance. Either way, the implementation is quite a 
bit clearer.

I've also compared some operations of sparse-vec vs. plain map. 
The inner product is slightly faster for vecs with < 10 elements, then map 
takes over.
norm and unit-vector operations are quite in favour of sparse-vecs (~ 4 times 
faster than map based implementations).

Obviously, assoc on a map is way faster than the sparse-vec implementation of 
assc below...

Kind Regards
Andreas


On 27/05/2011, at 11:11 AM, Ken Wesson wrote:

> On Thu, May 26, 2011 at 8:50 PM, Andreas Kostler
>  wrote:
>> Thanks Ken,
>> using this approach brings a ~1000 times speedup :)
>> 
>> (def a (sparse-vec (range 10) (range 10)))
>> 
>> (def b (time (assc-ken a 11 0)))
>> "Elapsed time: 0.249 msecs"
>> 
>> (def b (time (assc a 11 0)))
>> "Elapsed time: 252.06 msecs"
>> 
>> Very worthwhile and it's clearer as well.
> 
> You're welcome. Keep in mind that this is a best-case insert, right at
> the end, for the algo I posted. Inserts at the beginning won't be very
> much faster than before, and in the middle will be in the middle.
> 
> -- 
> Protege: What is this seething mass of parentheses?!
> Master: Your father's Lisp REPL. This is the language of a true
> hacker. Not as clumsy or random as C++; a language for a more
> civilized age.
> 
> -- 
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with your 
> first post.
> To unsubscribe from 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: Recur and primitives?!?

2011-05-26 Thread Armando Blancas
Coercing m to int somehow prevents h from being boxed:

user=> (defn bin-search [v k c]
  (loop [l 0
 h (dec (count v))]
(if (> l h) false
(let [m (int (quot (+ l h) 2))
  m-v (v m)]
  (cond (> m-v k) (recur (inc m) h)
(> k m-v) (recur l (dec m))
:else m)
#'user/bin-search
user=>

On May 26, 5:08 pm, Luc Prefontaine 
wrote:
> h gets boxed somehow from integer to something else when the recur is 
> executed.
>
> No idea where however. Look at this, it may help:
>
> http://groups.google.com/group/clojure/browse_thread/thread/e4574bbb0...
>
> On Fri, 27 May 2011 09:54:19 +1000
>
>
>
> Andreas Kostler  wrote:
> > Hi guys,
> > I'm kinda lost as to what's going on here...With clojure-1.2.0
>
> > (defn bin-search [v k c]
> >   (loop [l 0
> >          h (dec (count v))]
> >     (if (> l h) false
> >         (let [m (quot (+ l h) 2)
> >               m-v (v m)]
> >           (cond (> m-v k) (recur (inc m) h)
> >                 (> k m-v) (recur l (dec m))
> >                 :else m)
>
> > This bombs out with:
> > java.lang.IllegalArgumentException: recur arg for primitive local: h
> > must be matching primitive
>
> > With 1.3.0-master-SNAPSHOT it works fine. Any ideas what I'm doing
> > wrong? Andreas
>
> --
> Luc P.
>
> 
> The rabid Muppet

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


Re: Debian packages

2011-05-26 Thread Daigo Moriwaki
I also long for the latest Clojure in Debian.
The current main packager seems to be too busy to responsive.

With discussion at debian-java mail list, I have just uploaded Clojure
1.2.0. Since it is a brand new source version, it will take several
days for FTP Masters to accept it.

If you have comments specific to Debian, please post at debian-java.

Regards,
Daigo

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


Re: Recur and primitives?!?

2011-05-26 Thread Ken Wesson
On Thu, May 26, 2011 at 10:28 PM, Armando Blancas
 wrote:
> Coercing m to int somehow prevents h from being boxed:
>
> user=> (defn bin-search [v k c]
>  (loop [l 0
>         h (dec (count v))]
>    (if (> l h) false
>        (let [m (int (quot (+ l h) 2))
>              m-v (v m)]
>          (cond (> m-v k) (recur (inc m) h)
>                (> k m-v) (recur l (dec m))
>                :else m)
> #'user/bin-search
> user=>

I doubt it. Rather, m is now an int so (dec m) can be a valid recur for h.

The real question is why h was primitive to begin with, since there's
no coercion of h to int in either version of the code.

To make this really fast you will want to use int throughout, though,
and unchecked arithmetic:

(defn bin-search-fast [v k]
  (loop [l (int 0)
 h (int (dec (count v)))]
(if (> l h) false
  (let [m (unchecked-divide (unchecked-add l h) 2)
m-v (v m)]
(cond
  (< m-v k) (recur (unchecked-inc m) h)
  (< k m-v) (recur l (unchecked-dec m))
  :else m)

This works on ascending values:

=> (bin-search-fast (vec (map #(* % %) (range 1000))) 4096)
64

And despite the proliferation of fast, wrapping unchecked-foo
operations, it is perfectly safe.

The thing that would overflow and wrap first is the sum of l and h.
The worst case occurs when the target's right at the end of the
vector, and l ends up nearly equal to h, which stays one less than the
length of the vector. Then we're adding length - 1 and length - 2 for
2*length - 3. This has to stay below 2147483647, so the maximum vector
length this can support is 2147483650/2 or 1073741825.

Over a billion items; that takes up 4GB just for the object pointers
in the vector. You cannot hit this limit on 32-bit hardware -- OOME
would be thrown first -- and on 64-bit there'd be no penalty from
changing the code to use long instead of int, which makes the maximum
vector size enormously larger than you're likely to use in the
foreseeable future even on 64-bit hardware.

The speed difference is about a factor of two:

=> (defn bin-search-slow [v k]
 (loop [l 0
h (Integer/valueOf (dec (count v)))]
   (if (> l h) false
 (let [m (quot (+ l h) 2)
   m-v (v m)]
   (cond
 (< m-v k) (recur (inc m) h)
 (< k m-v) (recur l (dec m))
 :else m)
#'user/bin-search-slow
=> (def squares (vec (map #(* % %) (range 1000
#'user/squares
=> (time (dotimes [_ 1000] (bin-search-slow squares 4096)))
"Elapsed time: 1.37656 msecs"
=> (time (dotimes [_ 1000] (bin-search-fast squares 4096)))
"Elapsed time: 0.7608 msecs"

(Each timing is after several repetitions of the (time ...) line
preceding it, once the numbers have settled down as the JIT has done
its thing, on the hotspot server VM.)

-- 
Protege: What is this seething mass of parentheses?!
Master: Your father's Lisp REPL. This is the language of a true
hacker. Not as clumsy or random as C++; a language for a more
civilized age.

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


Re: Recur and primitives?!?

2011-05-26 Thread Andreas Kostler
The question is though, why doesn't this work to begin with and why does it 
work on 1.3.0-master-SNAPSHOT...?
Is it broken or am I doing something wrong? :)
Andreas


On 27/05/2011, at 1:28 PM, Ken Wesson wrote:

> On Thu, May 26, 2011 at 10:28 PM, Armando Blancas
>  wrote:
>> Coercing m to int somehow prevents h from being boxed:
>> 
>> user=> (defn bin-search [v k c]
>>  (loop [l 0
>> h (dec (count v))]
>>(if (> l h) false
>>(let [m (int (quot (+ l h) 2))
>>  m-v (v m)]
>>  (cond (> m-v k) (recur (inc m) h)
>>(> k m-v) (recur l (dec m))
>>:else m)
>> #'user/bin-search
>> user=>
> 
> I doubt it. Rather, m is now an int so (dec m) can be a valid recur for h.
> 
> The real question is why h was primitive to begin with, since there's
> no coercion of h to int in either version of the code.
> 
> To make this really fast you will want to use int throughout, though,
> and unchecked arithmetic:
> 
> (defn bin-search-fast [v k]
>  (loop [l (int 0)
> h (int (dec (count v)))]
>(if (> l h) false
>  (let [m (unchecked-divide (unchecked-add l h) 2)
>m-v (v m)]
>(cond
>  (< m-v k) (recur (unchecked-inc m) h)
>  (< k m-v) (recur l (unchecked-dec m))
>  :else m)
> 
> This works on ascending values:
> 
> => (bin-search-fast (vec (map #(* % %) (range 1000))) 4096)
> 64
> 
> And despite the proliferation of fast, wrapping unchecked-foo
> operations, it is perfectly safe.
> 
> The thing that would overflow and wrap first is the sum of l and h.
> The worst case occurs when the target's right at the end of the
> vector, and l ends up nearly equal to h, which stays one less than the
> length of the vector. Then we're adding length - 1 and length - 2 for
> 2*length - 3. This has to stay below 2147483647, so the maximum vector
> length this can support is 2147483650/2 or 1073741825.
> 
> Over a billion items; that takes up 4GB just for the object pointers
> in the vector. You cannot hit this limit on 32-bit hardware -- OOME
> would be thrown first -- and on 64-bit there'd be no penalty from
> changing the code to use long instead of int, which makes the maximum
> vector size enormously larger than you're likely to use in the
> foreseeable future even on 64-bit hardware.
> 
> The speed difference is about a factor of two:
> 
> => (defn bin-search-slow [v k]
> (loop [l 0
>h (Integer/valueOf (dec (count v)))]
>   (if (> l h) false
> (let [m (quot (+ l h) 2)
>   m-v (v m)]
>   (cond
> (< m-v k) (recur (inc m) h)
> (< k m-v) (recur l (dec m))
> :else m)
> #'user/bin-search-slow
> => (def squares (vec (map #(* % %) (range 1000
> #'user/squares
> => (time (dotimes [_ 1000] (bin-search-slow squares 4096)))
> "Elapsed time: 1.37656 msecs"
> => (time (dotimes [_ 1000] (bin-search-fast squares 4096)))
> "Elapsed time: 0.7608 msecs"
> 
> (Each timing is after several repetitions of the (time ...) line
> preceding it, once the numbers have settled down as the JIT has done
> its thing, on the hotspot server VM.)
> 
> -- 
> Protege: What is this seething mass of parentheses?!
> Master: Your father's Lisp REPL. This is the language of a true
> hacker. Not as clumsy or random as C++; a language for a more
> civilized age.
> 
> -- 
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with your 
> first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en

--
"Test-driven Dentistry (TDD!) - Not everything should be test driven"
- Michael Fogus
-- 
**
Andreas Koestler, Software Engineer
Leica Geosystems Pty Ltd
270 Gladstone Road, Dutton Park QLD 4102
Main: +61 7 3891 9772 Direct: +61 7 3117 8808
Fax: +61 7 3891 9336
Email: andreas.koest...@leica-geosystems.com

www.leica-geosystems.com*

when it has to be right, Leica Geosystems

Please  consider the environment before printing this email.

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


Re: Radically simplified Emacs and SLIME setup

2011-05-26 Thread J.R. Garcia
I compiled a new version of emacs from source and started it up.
clojure-jack-in just worked flawlessly. This is stupid simple! Thanks
for your hard work! It's much appreciated for emacs newcomers like me
(I'm a vim user)!

Thanks again,
J.R. Garcia

On May 24, 6:55 pm, Phil Hagelberg  wrote:
> On May 24, 1:28 pm, "J.R. Garcia"  wrote:
>
> > I'm having an issue when running clojure-jack-in. I followed the steps
> > in the video and once I get to the point of using clojure-jack-in I
> > get: "Symbol's function definition is void: locate-dominating-file". I
> > am running GNU Emacs 22.1.1 (mac-apple-darwin) if that matters. I'll
> > try following along on with Emacs.app and Aquamacs and see if that
> > changes anything.
>
> Yeah, sorry--22 is quite old (~4 years?) and no longer supported. I
> should make that clearer in the docs.
>
> -Phil

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


Re: Recur and primitives?!?

2011-05-26 Thread Ken Wesson
On Thu, May 26, 2011 at 11:31 PM, Andreas Kostler
 wrote:
> The question is though, why doesn't this work to begin with and why does it 
> work on 1.3.0-master-SNAPSHOT...?
> Is it broken or am I doing something wrong? :)

On further investigation, it looks like Clojure considers the type of
(count v) with v a vector to be a primitive int, which is not the
typical behavior for a function return value (other than an arithmetic
function on primitive arguments) in 1.2. In 1.3.0 it's possible that
quot on primitives returns primitives, given the new primitive
function argument and return support in 1.3.0, making the problem go
away.

-- 
Protege: What is this seething mass of parentheses?!
Master: Your father's Lisp REPL. This is the language of a true
hacker. Not as clumsy or random as C++; a language for a more
civilized age.

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


Re: Recur and primitives?!?

2011-05-26 Thread Luc Prefontaine
Nope it's not broken, in 1.3 numeric computations changed.
Rich wanted to streamline the behavior and gain performance in numeric 
computations.

Non floating point values are now all longs except if you cast them explicitly 
(java interop needs this),
floats are now all doubles (the widest type of the two).

The idea is to get max. performance by using JVM primitive types and avoid auto 
boxing as much as possible.

Now I do not follow things in 1.3 closely but I would not be surprised that 
auto boxing
does not occur here because the computation involves only long values.

A mixed type operation (long with double, ...) would likely auto box the 
results except if you take in care
in casting the result (like Armando did).

At first look, all the operations in (quot (+ l h) 2)) should yield an integer 
(or long in 1.3)
but in 1.2 for some unknown reason to me, it created an auto boxed value. 

No mystery here. Life should be simpler in 1.3 in numeric computations.

Luc P.

On Fri, 27 May 2011 13:31:46 +1000
Andreas Kostler  wrote:

> The question is though, why doesn't this work to begin with and why
> does it work on 1.3.0-master-SNAPSHOT...? Is it broken or am I doing
> something wrong? :) Andreas
> 
> 
> On 27/05/2011, at 1:28 PM, Ken Wesson wrote:
> 
> > On Thu, May 26, 2011 at 10:28 PM, Armando Blancas
> >  wrote:
> >> Coercing m to int somehow prevents h from being boxed:
> >> 
> >> user=> (defn bin-search [v k c]
> >>  (loop [l 0
> >> h (dec (count v))]
> >>(if (> l h) false
> >>(let [m (int (quot (+ l h) 2))
> >>  m-v (v m)]
> >>  (cond (> m-v k) (recur (inc m) h)
> >>(> k m-v) (recur l (dec m))
> >>:else m)
> >> #'user/bin-search
> >> user=>
> > 
> > I doubt it. Rather, m is now an int so (dec m) can be a valid recur
> > for h.
> > 
> > The real question is why h was primitive to begin with, since
> > there's no coercion of h to int in either version of the code.
> > 
> > To make this really fast you will want to use int throughout,
> > though, and unchecked arithmetic:
> > 
> > (defn bin-search-fast [v k]
> >  (loop [l (int 0)
> > h (int (dec (count v)))]
> >(if (> l h) false
> >  (let [m (unchecked-divide (unchecked-add l h) 2)
> >m-v (v m)]
> >(cond
> >  (< m-v k) (recur (unchecked-inc m) h)
> >  (< k m-v) (recur l (unchecked-dec m))
> >  :else m)
> > 
> > This works on ascending values:
> > 
> > => (bin-search-fast (vec (map #(* % %) (range 1000))) 4096)
> > 64
> > 
> > And despite the proliferation of fast, wrapping unchecked-foo
> > operations, it is perfectly safe.
> > 
> > The thing that would overflow and wrap first is the sum of l and h.
> > The worst case occurs when the target's right at the end of the
> > vector, and l ends up nearly equal to h, which stays one less than
> > the length of the vector. Then we're adding length - 1 and length -
> > 2 for 2*length - 3. This has to stay below 2147483647, so the
> > maximum vector length this can support is 2147483650/2 or
> > 1073741825.
> > 
> > Over a billion items; that takes up 4GB just for the object pointers
> > in the vector. You cannot hit this limit on 32-bit hardware -- OOME
> > would be thrown first -- and on 64-bit there'd be no penalty from
> > changing the code to use long instead of int, which makes the
> > maximum vector size enormously larger than you're likely to use in
> > the foreseeable future even on 64-bit hardware.
> > 
> > The speed difference is about a factor of two:
> > 
> > => (defn bin-search-slow [v k]
> > (loop [l 0
> >h (Integer/valueOf (dec (count v)))]
> >   (if (> l h) false
> > (let [m (quot (+ l h) 2)
> >   m-v (v m)]
> >   (cond
> > (< m-v k) (recur (inc m) h)
> > (< k m-v) (recur l (dec m))
> > :else m)
> > #'user/bin-search-slow
> > => (def squares (vec (map #(* % %) (range 1000
> > #'user/squares
> > => (time (dotimes [_ 1000] (bin-search-slow squares 4096)))
> > "Elapsed time: 1.37656 msecs"
> > => (time (dotimes [_ 1000] (bin-search-fast squares 4096)))
> > "Elapsed time: 0.7608 msecs"
> > 
> > (Each timing is after several repetitions of the (time ...) line
> > preceding it, once the numbers have settled down as the JIT has done
> > its thing, on the hotspot server VM.)
> > 
> > -- 
> > Protege: What is this seething mass of parentheses?!
> > Master: Your father's Lisp REPL. This is the language of a true
> > hacker. Not as clumsy or random as C++; a language for a more
> > civilized age.
> > 
> > -- 
> > You received this message because you are subscribed to the Google
> > Groups "Clojure" group.
> > To post to this group, send email to clojure@googlegroups.com
> > Note that posts from new members are moderated - please be patient
> > with your first post. To unsubscribe from this group, send email to
> > clojure+unsubscr...@googlegroups.com
> > For more options, vi

Re: finding a key which does not exist in the map

2011-05-26 Thread Sunil S Nandihalli
I don't think yours is going to be anymore efficient than the one I had
initially posted .. In fact it might be slower in majority of the cases..
Thanks,
Sunil.

On Fri, May 27, 2011 at 12:57 AM, Walter van der Laan <
waltervanderl...@gmail.com> wrote:

> You could use this:
> (defn non-existing-key [mp] (inc (reduce max (keys mp
>
> For example:
> (non-existing-key {1 "a" 2 "b"}) => 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
>

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