Re: printf output from threads

2010-12-28 Thread Robert McIntyre
seems there's no type hint required:

(def t nil)
(Thread. t)

also works...

How are you able to determine that it's calling the String constructor?

--Robert McIntyre




On Tue, Dec 28, 2010 at 3:08 AM, Alex Osborne a...@meshy.org wrote:
 Robert McIntyre r...@mit.edu writes:

 what the heck...

 mailing-list.print-from-threads (Thread. ((constantly nil)))
 #Thread Thread[Thread-100,5,main]
 mailing-list.print-from-threads (Thread. ((fn  [])))
 #Thread Thread[Thread-101,5,main]
 mailing-list.print-from-threads (Thread. ((fn  [] nil)))
 #Thread Thread[Thread-102,5,main]
 mailing-list.print-from-threads (Thread. (let [this-is-nil ((fn  []
 nil))] this-is-nil))
 #Thread Thread[Thread-103,5,main]
 mailing-list.print-from-threads (Thread. nil)
 ; Evaluation aborted.
 mailing-list.print-from-threads (= nil (let [this-is-nil ((fn  []
 nil))] this-is-nil) ((fn  [])) ((constantly nil)))
 true
 mailing-list.print-from-threads

 all of these things are referentially transparent, so how is clojure
 differentiating between things that evaluate to nil and nil itself?

 It's picking the Thread(String name), constructor for some reason when
 it gets an Object type hint.

 user (let [^Object o nil] (Thread. o))
 #Thread Thread[Thread-8,5,main]

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

2010-12-28 Thread Alex Osborne
Robert McIntyre r...@mit.edu writes:

 seems there's no type hint required:

 (def t nil)
 (Thread. t)

 also works...

 How are you able to determine that it's calling the String constructor?

 --Robert McIntyre

Ah, no I'm wrong.  I was jumping to conclusions.  It's the Runnable
one:

(let [^String o nil] (Thread. o)) ; error

(let [^Runnable o nil] (Thread. o)) ; no error

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

2010-12-28 Thread Alex Osborne
Robert McIntyre r...@mit.edu writes:

 So there's some sort of boxing going on here where the nil produced
 as the values of s-expressions are actually Objects which are nulls,
 while literal nils are actually nulls?

No, there's no boxing going on.  They're both just regular Java nulls
(and null is not an Object).  The only difference is in the byte code
generation: which constructor gets picked (if any).  It seems as if the
runtime reflection code when encountering a null will just pick the
first constructor it sees, while the compile-time code notices the
ambiguity and throws an error.

It's kind of annoying that you can't type-hint the nil too.

  (Thread. ^Runnable nil) ; error, nil can't hold metadata

and have to resort to binding it and hinting the binding.

  (let [^Runnable s nil] (Thread. s)) ; ok

 Such as in java where:

   Object t = null;
   Thread r = new Thread((String) t);

 is valid but

   Thread r = new Thread(null);
 is not ?

In this case you've explicitly told Java the type with a string cast so
it can generate bytecode that refers the String constructor.  You can do
that directly too:

Thread r = new Thread((String) null);

Being statically typed Java never does runtime reflection (unless you
explicitly code it) so this issue cannot actually arise in it.

 Isn't this breaking referential transparency that (Thread. ((fn [])))
 and (Thread. nil) are not the same (you can't replace a function call
 with it's value in this case)?  This is not the behaviour I would
 expect at all, as it would make any clojure function with a nil in
 it's range no longer pure.

Ambiguous code is arguably invalid in some sense anyway when running
on a deterministic machine model, so I'm not sure it makes sense to talk
about the purity of it.

Suppose I do this and never actually call the resulting fn, just throw
it away:

  #(Thread. nil) ; throws an error at compile time

  #(Thread. (identity nil)) ; doesn't and can't

How could they be made consistent?  I guess either:

1) Resolve the ambiguity by consistently picking one of the constructors
(perhaps the first alphabetically).

2) Delay the exception throwing in the direct nil case to runtime, so
the compiler would replace the form with:

#(throw (java.lang.IllegalArgumentException.))

And have the reflection code in the second detect ambiguity and throw at
runtime as well.

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


Quicksort with accumulator

2010-12-28 Thread Baishampayan Ghose
Hello,

I tried writing a naive implementation of quicksort using an
accumulator. Right now, the code is stack-consuming and returns a
stackoverflowerror on large lists. Is there any way to prevent it from
consuming stack with some changes? The code is as follows -

(declare qsort qsort* partify)

(defn partify
  [item coll [less equal greater] acc]
  (if (empty? coll)
(qsort* less (concat equal (qsort* greater acc)))
(let [[head  tail] coll]
  (cond
   ( head item) (recur item tail [(cons head less) equal greater] acc)
   ( head item) (recur item tail [less equal (cons head greater)] acc)
   :else (recur item tail [less (cons head equal) greater] acc)

(defn qsort*
  [coll acc]
  (if-let [coll (seq coll)]
(partify (first coll) (rest coll) [[] [(first coll)] []] acc)
acc))

(defn qsort
  Perform Quicksort, with apologies to C.A.R. Hoare
  [coll]
  (if-let [coll (seq coll)]
(qsort* coll [])
[]))

Regards,
BG

-- 
Baishampayan Ghose
b.ghose at gmail.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: printf output from threads

2010-12-28 Thread justinhj
On Dec 27, 10:59 pm, Alex Osborne a...@meshy.org wrote:
 justinhj justi...@gmail.com writes:
  On Dec 26, 11:42 pm, Alex Osborne a...@meshy.org wrote:
  (defn test-threads [n out]
    (dotimes [x n]
      (.start (Thread. (#(sleeper-thread %1 %2 %3) out x (+ 2000 (rand-
  int 5000)))

 Ah.  The problem is here.  You're calling that lambda in the main thread
 and then passing the return value of sleeper-thread to (Thread.) (which
 doesn't make much sense).

 Try this:

 (defn test-threads [n out]
   (dotimes [x n]
     (.start (Thread. #(sleeper-thread out x (+ 2000 (rand-int 5000)))

 Or even:

 (defn test-threads [n out]
   (dotimes [x n]
     (future (sleeper-thread out x (+ 2000 (rand-int 5000))

 Or forgetting about passing the out argument around:

 (defn test-threads [n]
   (dotimes [x n]
     (let [out *out*]
       (future
         (binding [*out* out]
           (sleeper-thread x (+ 2000 (rand-int 5000))

 You could turn that into a macro:

 (defmacro future-with-out [ body]
   `(let [out# *out*]
      (future (binding [*out* out#] ~...@body)))

 And then use it like:

 (defn test-threads [n]
   (dotimes [x n]
     (future-with-out (sleeper-thread x (+ 2000 (rand-int 5000))

Thanks Alex, I'm still struggling a bit with the different syntax
between Clojure and Common Lisp, but I made your first change and it
works now.

Justin

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

2010-12-28 Thread Petr Gladkikh
Why do you call qsort* inside of partify? I do not really grasp your
logic behind this.

On Tue, Dec 28, 2010 at 8:20 PM, Baishampayan Ghose b.gh...@gmail.com wrote:
 Hello,

 I tried writing a naive implementation of quicksort using an
 accumulator. Right now, the code is stack-consuming and returns a
 stackoverflowerror on large lists. Is there any way to prevent it from
 consuming stack with some changes? The code is as follows -

 (declare qsort qsort* partify)

 (defn partify
  [item coll [less equal greater] acc]
  (if (empty? coll)
    (qsort* less (concat equal (qsort* greater acc)))
    (let [[head  tail] coll]
      (cond
       ( head item) (recur item tail [(cons head less) equal greater] acc)
       ( head item) (recur item tail [less equal (cons head greater)] acc)
       :else (recur item tail [less (cons head equal) greater] acc)

 (defn qsort*
  [coll acc]
  (if-let [coll (seq coll)]
    (partify (first coll) (rest coll) [[] [(first coll)] []] acc)
    acc))

 (defn qsort
  Perform Quicksort, with apologies to C.A.R. Hoare
  [coll]
  (if-let [coll (seq coll)]
    (qsort* coll [])
    []))

 Regards,
 BG

 --
 Baishampayan Ghose
 b.ghose at gmail.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



-- 
Petr Gladkikh

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

2010-12-28 Thread Petr Gladkikh
And also qsort may take up to n stack frames for collection of n
elements if you partition function is not optimal. In your case - if
input collection is sorted (as long as you split by first element).

On Tue, Dec 28, 2010 at 11:13 PM, Petr Gladkikh petrg...@gmail.com wrote:
 Why do you call qsort* inside of partify? I do not really grasp your
 logic behind this.

 On Tue, Dec 28, 2010 at 8:20 PM, Baishampayan Ghose b.gh...@gmail.com wrote:
 Hello,

 I tried writing a naive implementation of quicksort using an
 accumulator. Right now, the code is stack-consuming and returns a
 stackoverflowerror on large lists. Is there any way to prevent it from
 consuming stack with some changes? The code is as follows -

 (declare qsort qsort* partify)

 (defn partify
  [item coll [less equal greater] acc]
  (if (empty? coll)
    (qsort* less (concat equal (qsort* greater acc)))
    (let [[head  tail] coll]
      (cond
       ( head item) (recur item tail [(cons head less) equal greater] acc)
       ( head item) (recur item tail [less equal (cons head greater)] acc)
       :else (recur item tail [less (cons head equal) greater] acc)

 (defn qsort*
  [coll acc]
  (if-let [coll (seq coll)]
    (partify (first coll) (rest coll) [[] [(first coll)] []] acc)
    acc))

 (defn qsort
  Perform Quicksort, with apologies to C.A.R. Hoare
  [coll]
  (if-let [coll (seq coll)]
    (qsort* coll [])
    []))

 Regards,
 BG

 --
 Baishampayan Ghose
 b.ghose at gmail.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



 --
 Petr Gladkikh




-- 
Petr Gladkikh

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

2010-12-28 Thread Mike Meyer
On Tue, 28 Dec 2010 19:50:28 +0530
Baishampayan Ghose b.gh...@gmail.com wrote:

 Hello,
 
 I tried writing a naive implementation of quicksort using an
 accumulator. Right now, the code is stack-consuming and returns a
 stackoverflowerror on large lists. Is there any way to prevent it from
 consuming stack with some changes? The code is as follows -

You don't say what your test data is, but pretty much any quicksort
implementation will have some nasty test cases for which its memory
usage is nasty and its performance is worse. Given that this is a
simple implementation, data that is already sorted is the degenerate
case.

I don't think you can keep it from using any stack - a non-recursive
implementation would just have to maintain it's own stack state. You
can do some things to make it use less stack, though.

First, deal with sorted data better by picking a median value from
coll instead of the first one.

Once the sequences get small enough, change to a non-recursive sorting
method to sort them.

If you're up to serious refactoring, fix the code to generate the
partitions inside of qsort*, and then use recur for the tail call of
qsort* - and make sure that call is on longer of less and greater.

  mike

 (declare qsort qsort* partify)
 
 (defn partify
   [item coll [less equal greater] acc]
   (if (empty? coll)
 (qsort* less (concat equal (qsort* greater acc)))
 (let [[head  tail] coll]
   (cond
( head item) (recur item tail [(cons head less) equal greater] acc)
( head item) (recur item tail [less equal (cons head greater)] acc)
:else (recur item tail [less (cons head equal) greater] acc)
 
 (defn qsort*
   [coll acc]
   (if-let [coll (seq coll)]
 (partify (first coll) (rest coll) [[] [(first coll)] []] acc)
 acc))
 
 (defn qsort
   Perform Quicksort, with apologies to C.A.R. Hoare
   [coll]
   (if-let [coll (seq coll)]
 (qsort* coll [])
 []))
 
 Regards,
 BG
 


-- 
Mike Meyer m...@mired.org http://www.mired.org/consulting.html
Independent Network/Unix/Perforce consultant, email for more information.

O ascii ribbon campaign - stop html mail - www.asciiribbon.org

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

2010-12-28 Thread Baishampayan Ghose
 I tried writing a naive implementation of quicksort using an
 accumulator. Right now, the code is stack-consuming and returns a
 stackoverflowerror on large lists. Is there any way to prevent it from
 consuming stack with some changes? The code is as follows -

 You don't say what your test data is, but pretty much any quicksort
 implementation will have some nasty test cases for which its memory
 usage is nasty and its performance is worse. Given that this is a
 simple implementation, data that is already sorted is the degenerate
 case.

 I don't think you can keep it from using any stack - a non-recursive
 implementation would just have to maintain it's own stack state. You
 can do some things to make it use less stack, though.

This is just a toy implementation, not something real :) I am
interested in learning about making this code truly tail recursive
and/or lazy. Identical implementations on Haskell work just fine, so I
wrote this one for some testing...

When you try using some large numbers like 10 million, it blows the
stack. A completely lazy solution is possible in Clojure, as shown in
The Joy of Clojure.

Regards,
BG

-- 
Baishampayan Ghose
b.ghose at gmail.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: Clojure Conj 2011?

2010-12-28 Thread scott
fwiw - there was a number of lucky folks who I met at Strange Loop in
St. Louis the week before Conj 2010 who were able to go to both. It
seemed like there was quite a bit of overlap in interest of those two
events. I could have probably gone to both if there was at least a few
weeks time between the two.

Scott Hickey (no relation)

On Dec 27, 8:07 pm, Alan Dipert a...@dipert.org wrote:
 Hi,

 On Mon, Dec 27, 2010 at 7:41 PM, Sean Corfield seancorfi...@gmail.com wrote:
  Now that videos are being posted for the 2010 conj, I figured it might
  be worth asking if there has been any discussion about when/where the
  2011 conj might happen?

 Conj 2011 will most likely be in either Raleigh or Durham, North
 Carolina, and probably will happen around the same time of year as the
 last Conj.  We've reviewed all the feedback we've gotten, and are
 looking for a venue.  Our hope is to announce the time and place as
 soon as possible.

 Sorry you couldn't make it to the last one, but looking forward to
 seeing you at the next one!
 Alan





  I had a schedule conflict last year (actually a double conflict) so
  I'd like to get this year's event on my calendar as early as possible
  so I don't miss it again :)
  --
  Sean A Corfield -- (904) 302-SEAN
  Railo Technologies, Inc. --http://getrailo.com/
  An Architect's View --http://corfield.org/

  If you're not annoying somebody, you're not really alive.
  -- Margaret Atwood

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

 - Show quoted text -

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


osx + clojure + emacs + leiningen blog posts

2010-12-28 Thread gaz jones
oh hi,

i put together a couple of blog posts around how i use clojure + emacs
+ leiningen on OSX (but applies to linux too) in the hope it may help
someone get up and running faster:

http://blog.gaz-jones.com/post/2486737162/setting-up-clojure-development-on-osx-using-emacs-and
http://blog.gaz-jones.com/post/2501842155/interactive-clojure-development-in-emacs-with-leiningen

suggestions for improvements / things im doing crazy are welcome!

cheers
gaz

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


From Binary Search Trees to the Dining Philosopher

2010-12-28 Thread Todd
Thanks Ken, Mark, David and Alex for your comments regarding Binary 
Search trees. I've read that thread several times, and ordered Okasaki's 
Purely Functional Data Structures, too. I'll return to this a bit later.


Meanwhile, I decided to tackle learning Clojure from a different 
angle...in this case, implementing a solution for the Dining Philosopher 
problem.


I've posted my code here:

https://gist.github.com/757925

General comments/questions:

1. I suppose it's from years of OO programming, but it still feels so 
weird not to be creating objects and then hanging methods off those 
objects. In fact, my first approach was to create protocols and records 
for each of the 'objects': chopsticks, philosophers, even the table. But 
this started to get painful, so I shifted gears...


2. I'm using a number of symbols (:tablestate, :seats, :chopsticks, 
:servings, etc). Shouldn't these be defined somewhere? It feels like I'm 
driving w/o a seatbelt. I'm so used to encapsulating this sort of thing 
in an enum or something, and then relying on java typing to enforce the 
allowed values.


3. Starting a thread with (future ... This couldn't be easier. Very cool.

4. I tried making the table an agent instead of a ref. Then I was 
sending methods to the table like, start-tableservice or 
stop-tabelservice... I'll investigate further, but is it idiomatic to 
start threads within the agent?


(BTW - Chapter 6 on State Management of Practical Clojure was 
particularly helpful to me for figuring out the syntax for refs and agents.)


Anyone feel like tearing my code apart? I'd like to make it as clean and 
clojure-ish as possible.


-Todd

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

2010-12-28 Thread Alex Miller
I have not yet set a date for Strange Loop (although I am talking to
venues now).  I'm currently looking at Sept 29-30 as the target date.
JavaOne is the following week.

Alex

On Dec 28, 1:50 pm, scott jscotthic...@gmail.com wrote:
 fwiw - there was a number of lucky folks who I met at Strange Loop in
 St. Louis the week before Conj 2010 who were able to go to both. It
 seemed like there was quite a bit of overlap in interest of those two
 events. I could have probably gone to both if there was at least a few
 weeks time between the two.

 Scott Hickey (no relation)

 On Dec 27, 8:07 pm, Alan Dipert a...@dipert.org wrote:







  Hi,

  On Mon, Dec 27, 2010 at 7:41 PM, Sean Corfield seancorfi...@gmail.com 
  wrote:
   Now that videos are being posted for the 2010 conj, I figured it might
   be worth asking if there has been any discussion about when/where the
   2011 conj might happen?

  Conj 2011 will most likely be in either Raleigh or Durham, North
  Carolina, and probably will happen around the same time of year as the
  last Conj.  We've reviewed all the feedback we've gotten, and are
  looking for a venue.  Our hope is to announce the time and place as
  soon as possible.

  Sorry you couldn't make it to the last one, but looking forward to
  seeing you at the next one!
  Alan

   I had a schedule conflict last year (actually a double conflict) so
   I'd like to get this year's event on my calendar as early as possible
   so I don't miss it again :)
   --
   Sean A Corfield -- (904) 302-SEAN
   Railo Technologies, Inc. --http://getrailo.com/
   An Architect's View --http://corfield.org/

   If you're not annoying somebody, you're not really alive.
   -- Margaret Atwood

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

  - Show quoted text -

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

2010-12-28 Thread David Nolen
On Tue, Dec 28, 2010 at 2:58 AM, Sunil S Nandihalli 
sunil.nandiha...@gmail.com wrote:

 with my preliminary examination it seems like it does enhance storage
 efficiency and improve runtime performance.. How would still love to hear
 what you all have to say 


You are correct.

Another nice thing - type hinted members do not need to be type hinted
within defrecord method bodies.

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

Speed of clojure hash map vs java hash map

2010-12-28 Thread Mark Engelberg
Just for fun, I was curious to see what it would be like,
performance-wise, to simulate a synchronized mutable hash map by
putting a clojure hash map inside an atom, and making this accessible
to Java code via the map interface.

I didn't try to implement the entire map interface, but just the major
things for testing purposes.  The code is below.

Benchmarking insertions on my machine, I'm seeing that the Clojure
code (Clojure 1.2, java -server) takes roughly 8-20x longer (depending
on how large the hashmap is).

To test, for example, I do something like
(def ^com.justforfun.NonBlockingHashMap h (com.justforfun.NonBlockingHashMap.))
(def ^java.util.Map j (. java.util.Collections synchronizedMap
(java.util.HashMap.)))

(time (doseq [i (range 10)] (.put h i 2)))   ;900ms
(time (doseq [i (range 10)] (.put j i 2)));70ms

Does this seem reasonable, or is there a better way to do this test?
Frankly, I was expecting Clojure's numbers to compare a bit more
favorably.
If you repeat the run, shoving new values into the existing hash
table, make sure to change the value you're sticking into the hash
table (Clojure optimizes when you store the same value in the hash
table that's already there).

[Code]

(ns com.justforfun.NonBlockingHashMap
  (:gen-class
   :implements [java.lang.Iterable]
   :init init
   :constructors {[] []}
   :state state
   :methods [[get [Object] Object]
 [put [Object Object] void]
 [clear [] void]
 [remove [Object] void]
 [isEmpty [] boolean]
 [size [] int]]))

(defn -init []
  [[] (atom {})])

(defn -clear [this]
  (reset! (.state this) {}))

(defn -get [this k]
  (get @(.state this) k nil))

(defn -put [this k v]
  (swap! (.state this) assoc k v))

(defn -remove [this k]
  (swap! (.state this) dissoc k))

(defn -isEmpty [this]
  (zero? (count @(.state this

(defn -size [this]
  (count @(.state this)))

(defn -iterator [this]
  (.iterator @(.state 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: osx + clojure + emacs + leiningen blog posts

2010-12-28 Thread Phil Hagelberg
On Dec 28, 2:32 pm, gaz jones gareth.e.jo...@gmail.com wrote:
 i put together a couple of blog posts around how i use clojure + emacs
 + leiningen on OSX (but applies to linux too) in the hope it may help
 someone get up and running faster:

Looks good. I should mention that installing the elisp for swank-
clojure is actually no longer necessary. Also it's a little more
convenient to use C-c C-k instead of C-c C-l to compile the current
file.

It might be nice to link to the Leiningen tutorial for further
reference since it goes into more detail:
https://github.com/technomancy/leiningen/blob/master/TUTORIAL.md

very nice,
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: Speed of clojure hash map vs java hash map

2010-12-28 Thread David Nolen
On Tue, Dec 28, 2010 at 8:57 PM, Mark Engelberg mark.engelb...@gmail.comwrote:

 Just for fun, I was curious to see what it would be like,
 performance-wise, to simulate a synchronized mutable hash map by
 putting a clojure hash map inside an atom, and making this accessible
 to Java code via the map interface.


;; ~50ms-60ms
(dotimes [_ 10]
  (let [m (atom {})
r (range 1e5)]
   (time
(doseq [i r]
  (swap! m assoc i 2)

;; same as above
(dotimes [_ 10]
  (let [m {}
r (range 1e5)]
   (time
(loop [m m r r]
  (if (nil? r)
m
(recur (assoc m (first r) 2) (next r)))

(def ^java.util.Map j (. java.util.Collections synchronizedMap
(java.util.HashMap.)))

;; ~10ms
(dotimes [_ 10]
 (time (doseq [i (range 1e5)] (.put j i 2

So it's about 5X-6X slower for 1e5. But it looks to me there's no overhead
from atom operations.

I note that for 1e3 keys the difference is around 2X.

Of course this isn't much of a comparison IMO because the Java HashMap isn't
persistent. The Clojure version can add many keys as an atomic operation.
Much more useful if you're using a map as some kind of in-memory data store.

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: Speed of clojure hash map vs java hash map

2010-12-28 Thread Mark Engelberg
On Tue, Dec 28, 2010 at 6:46 PM, David Nolen dnolen.li...@gmail.com wrote:
 So it's about 5X-6X slower for 1e5. But it looks to me there's no overhead
 from atom operations.

I got similar results (5x slower) on the same sorts of tests.  Calling
it from the class generated by genclass seemed to cause another 2x
slowdown, resulting in the 10x difference I was seeing.  It slows down
more as you go to 10e6, which indicates that it's not just a constant
factor slower than Java.  I know that Clojure's data structures are
actually log32n, but I'm so used to thinking of that as essentially
constant that I was surprised to see such a noticeable difference in
how much slower it was on 10e6 elements vs 10e5.

 I note that for 1e3 keys the difference is around 2X.
 Of course this isn't much of a comparison IMO because the Java HashMap isn't
 persistent. The Clojure version can add many keys as an atomic operation.
 Much more useful if you're using a map as some kind of in-memory data store.

I ran this test because I was having a discussion with someone about
the benefits of Clojure's persistent data structures, and how
concurrency is handled by sticking an immutable data structure into an
atom, ref, or agent, rather than through synchronized blocks.  The
discussion went in the direction of memory caches as an example of the
two approaches.  The discussion went like this.  I said,
So you get the benefit of no blocking on reading, you can even
iterate over a snapshot of the hash table without blocking -- it's
just a whole lot cleaner.
That must be wildly inefficient.
It's not as inefficient as you might think.  [Insert discussion of
log32, shared structure, etc.]
But surely you're still paying a pretty high price.  And why would
you want that to be the default, paying that price all the time?

Clearly, I couldn't really answer that question without doing some
investigating to see what the speed difference is like.  I was even
hoping that if the speed difference were small enough, I could bundle
up a little library that implements HashMap as a Clojure hash map in
an atom, so that my Java pals could start using Clojure's hash maps as
a drop-in replacement for Java's (that's where the gen-class piece of
the experiment comes in).  But with a 10x speed difference and so much
more memory churn, I think that's going to be a tough sell.  It's
possible that Clojure becomes more competitive with Java under a lot
of contention for access from different threads, but I haven't tested
that out yet.

Anyway, thanks for confirming that the ratio of speeds on your machine
are similar to mine.

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: Question about when to use protocol+record and compilation warnings

2010-12-28 Thread Damon Snyder
Thanks everyone for all of the feedback. I think I have a solution to
the warnings and if I understand deftype/defrecord, I should be able
to replace defrecord with deftype in my implementation. I'll give it a
try and report back when I have a chance.

Thanks,
Damon

On Dec 26, 7:31 pm, David Nolen dnolen.li...@gmail.com wrote:
 On Sun, Dec 26, 2010 at 9:00 PM, Ken Wesson kwess...@gmail.com wrote:
  On Sun, Dec 26, 2010 at 9:25 PM, Alex Osborne a...@meshy.org wrote:
   Ken Wesson kwess...@gmail.com writes:

   Actually you don't need to AOT compile records or types. They work fine
   for interactive development.

   Eh. That's not what I saw written elsewhere. Or is it just protocols?
   Though usually those are used hand-in-hand with records.

   Perhaps you're thinking of gen-class?

  No.

   Protocols are also fine for interactive development.

  Someone here definitely said, recently and specifically, that at least
  one of the feature-complex around deftype/defprotocol/defrecord
  required AOT compilation.

 definterface/deftype/defprotocol/et al do not require AOT. structmaps are a
 legacy feature. defrecord is the way to go now.

 I've encountered some odd behavior at the SLIME REPL on occasion, but I
 haven't yet pinpointed a specific flow to recreate. It wasn't serious enough
 to impede interactive development.

 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: Speed of clojure hash map vs java hash map

2010-12-28 Thread Todd
I thought it'd be interesting to look closer at the insertion times as a 
fx of the size of the Map. The results are at:


https://gist.github.com/758198

At first I thought I'd found something interesting, only to investigate 
further and realize that I'd been testing through a fx that was using 
reflection (see trial results at bottom, Trials 1-4), and this was 
completely swamping the results.


In Trial #5, I realized what I'd done, and broke my generic test fx into 
two separate functions w/ proper type hinting (my-test-map and 
my-test-nbhm). Now my results are on par w/ yours, and I don't see any 
significant change in insertion times as a fx of map size up to 1e5.


Overall, NonBlockingHashMap insertions to take ~10x longer than the 
SynchronizedHashMap.


I think your idea of measuring under heavy contention would be very useful.

-Todd

On 12/28/10 9:27 PM, Mark Engelberg wrote:

On Tue, Dec 28, 2010 at 6:46 PM, David Nolendnolen.li...@gmail.com  wrote:

So it's about 5X-6X slower for 1e5. But it looks to me there's no overhead
from atom operations.


I got similar results (5x slower) on the same sorts of tests.  Calling
it from the class generated by genclass seemed to cause another 2x
slowdown, resulting in the 10x difference I was seeing.  It slows down
more as you go to 10e6, which indicates that it's not just a constant
factor slower than Java.  I know that Clojure's data structures are
actually log32n, but I'm so used to thinking of that as essentially
constant that I was surprised to see such a noticeable difference in
how much slower it was on 10e6 elements vs 10e5.


I note that for 1e3 keys the difference is around 2X.
Of course this isn't much of a comparison IMO because the Java HashMap isn't
persistent. The Clojure version can add many keys as an atomic operation.
Much more useful if you're using a map as some kind of in-memory data store.


I ran this test because I was having a discussion with someone about
the benefits of Clojure's persistent data structures, and how
concurrency is handled by sticking an immutable data structure into an
atom, ref, or agent, rather than through synchronized blocks.  The
discussion went in the direction of memory caches as an example of the
two approaches.  The discussion went like this.  I said,
So you get the benefit of no blocking on reading, you can even
iterate over a snapshot of the hash table without blocking -- it's
just a whole lot cleaner.
That must be wildly inefficient.
It's not as inefficient as you might think.  [Insert discussion of
log32, shared structure, etc.]
But surely you're still paying a pretty high price.  And why would
you want that to be the default, paying that price all the time?

Clearly, I couldn't really answer that question without doing some
investigating to see what the speed difference is like.  I was even
hoping that if the speed difference were small enough, I could bundle
up a little library that implements HashMap as a Clojure hash map in
an atom, so that my Java pals could start using Clojure's hash maps as
a drop-in replacement for Java's (that's where the gen-class piece of
the experiment comes in).  But with a 10x speed difference and so much
more memory churn, I think that's going to be a tough sell.  It's
possible that Clojure becomes more competitive with Java under a lot
of contention for access from different threads, but I haven't tested
that out yet.

Anyway, thanks for confirming that the ratio of speeds on your machine
are similar to mine.



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

2010-12-28 Thread David Nolen
On Wed, Dec 29, 2010 at 12:27 AM, Mark Engelberg
mark.engelb...@gmail.comwrote:

 Clearly, I couldn't really answer that question without doing some
 investigating to see what the speed difference is like.  I was even
 hoping that if the speed difference were small enough, I could bundle
 up a little library that implements HashMap as a Clojure hash map in
 an atom, so that my Java pals could start using Clojure's hash maps as
 a drop-in replacement for Java's (that's where the gen-class piece of
 the experiment comes in).  But with a 10x speed difference and so much
 more memory churn, I think that's going to be a tough sell.  It's
 possible that Clojure becomes more competitive with Java under a lot
 of contention for access from different threads, but I haven't tested
 that out yet.

 Anyway, thanks for confirming that the ratio of speeds on your machine
 are similar to mine.


Even in in a single threaded context raw insert performance isn't the final
word. What if you want to be able to deliver a snapshot for reporting? In
Clojure that's free. In Java that's a blocking copy of a HashMap with 1e5
keys. Ick.

That's the problem with naive benchmarks. They only sound good until you
have to write real programs that do real work.

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: Speed of clojure hash map vs java hash map

2010-12-28 Thread Mark Engelberg
On Tue, Dec 28, 2010 at 10:15 PM, David Nolen dnolen.li...@gmail.com wrote:
 Even in in a single threaded context raw insert performance isn't the final
 word. What if you want to be able to deliver a snapshot for reporting?

What if you don't?

Seriously, I agree with you that Clojure's data structures have some
significant advantages -- if you need those advantages.  There are
still plenty of apps that use hash tables in a single-threaded manner,
or use them in a multithreaded way where contention is unlikely and
persistence is unnecessary.  In many areas, Clojure has a
pay-for-what-you-need philosophy -- this just isn't one of those
areas.  With respect to data structures, Clojure is very opinionated,
with an attitude of Write it with immutable data structures -- you'll
thank me later. :)  Since all the existing Java structures are easy
enough to access if you want them, this isn't necessarily a bad thing.
 It just means I have to rethink my proselytizing strategy -- I was
definitely overselling the speed of the persistent data structures.

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: Question about when to use protocol+record and compilation warnings

2010-12-28 Thread Damon Snyder
This worked as expected. I just replaced defrecord with deftype here
https://github.com/drsnyder/beanstalk/blob/82f301f1f825bb05aa14d85a220ec57c1dea61b2/src/beanstalk/core.clj#L117
and re-ran my tests.

The suggestion from Baishampayan to add (:refer-clojure :exclude [read
peek use]) also worked. I added this to the core.clj and the tests and
there are no warnings.

Thanks!

Damon

On Dec 28, 9:45 pm, Damon Snyder drsny...@gmail.com wrote:
 Thanks everyone for all of the feedback. I think I have a solution to
 the warnings and if I understand deftype/defrecord, I should be able
 to replace defrecord with deftype in my implementation. I'll give it a
 try and report back when I have a chance.

 Thanks,
 Damon

 On Dec 26, 7:31 pm, David Nolen dnolen.li...@gmail.com wrote:







  On Sun, Dec 26, 2010 at 9:00 PM, Ken Wesson kwess...@gmail.com wrote:
   On Sun, Dec 26, 2010 at 9:25 PM, Alex Osborne a...@meshy.org wrote:
Ken Wesson kwess...@gmail.com writes:

Actually you don't need to AOT compile records or types. They work 
fine
for interactive development.

Eh. That's not what I saw written elsewhere. Or is it just protocols?
Though usually those are used hand-in-hand with records.

Perhaps you're thinking of gen-class?

   No.

Protocols are also fine for interactive development.

   Someone here definitely said, recently and specifically, that at least
   one of the feature-complex around deftype/defprotocol/defrecord
   required AOT compilation.

  definterface/deftype/defprotocol/et al do not require AOT. structmaps are a
  legacy feature. defrecord is the way to go now.

  I've encountered some odd behavior at the SLIME REPL on occasion, but I
  haven't yet pinpointed a specific flow to recreate. It wasn't serious enough
  to impede interactive development.

  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: Speed of clojure hash map vs java hash map

2010-12-28 Thread Jason Wolfe


On Dec 28, 10:28 pm, Mark Engelberg mark.engelb...@gmail.com wrote:
 On Tue, Dec 28, 2010 at 10:15 PM, David Nolen dnolen.li...@gmail.com wrote:
  Even in in a single threaded context raw insert performance isn't the final
  word. What if you want to be able to deliver a snapshot for reporting?

 What if you don't?

Use transients?

(dotimes [_ 10]
  (let [m (atom (transient {}))
r (range 1e5)]
   (time
(doseq [i r]
  (swap! m assoc! i 2)

is within 50% the speed of an ordinary java.util.HashMap, by my
measurements.  And if you want snapshots at every step, in the worst
case you pay the price you've measured above.

-Jason

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