Re: adding a member to a set in a map in a map in a map in a ref

2009-07-05 Thread Meikel Brandmeyer

Hi,

Am 05.07.2009 um 07:27 schrieb Rowdy Rednose:


user=> (dosync (alter gnu-rms update-in [:key1 :key2 :key3] #(conj %
"foo")))

{:key1 {:key2 {:key3 #{"foo"


You actually don't need the anonymous function...

(dosync
  (alter gnu-rms update-in [:key1 :key2 :key3] conj "foo"))

Sincerely
Meikel



smime.p7s
Description: S/MIME cryptographic signature


Re: loneclojurian at ICFP programming contest

2009-07-05 Thread Nicolas Oury
Hello,

Thanks to Rich's advices, I managed to make your ICFP program run very fast.
I have made a few modifications:
- changed the code following Rich's advices in order to have primitive array
access everywhere.
- I didn't managed to do it for booleans, so I used a java object
conataining only a public boolean for StatusReg.
- The biggest speep-up was the chunking of the generated program. It seems
that the fact that the program was so big prevented
the JIT to compile it. So I changed the code to emit it by chunk of around
50 guest VM instructions. (after a few tries, it seemed this was a good
figure. On my computer, the performance seems to be highly sensitive on the
size of the chunk. I don't really understand why and it worries me a bit on
the correctness of my program. )
To do so, I create intermediate local functions that I call.

- I generate the program at compile time, in order to only mesure execution
time and not compilation time.


After, when I run the benchmark in -server with a big enough CacheCode area
(1000m), and enough iterations to have everything JITed, I get more than
860.000 iterations per second. (I benchmarked 100 000 000 iterations in 121
sec, on my 2.4GHz computer).

When you look at the profile, 98.7% is spent in compiled code, 1.3% in
interpreted and 0% in stub. This proves that input program actually get
translated to Clojure, compiled to byte code, recompiled to native
instructions and then executed natively.

This is so fast, that I actually wonder whether too many things get
optimized away and the program is not benchmarking anything anymore. Or
maybe my code transformation is completly wrong and throws everything away.

igorrumiha, I am going to send you the source in a private mail so you can
check whether the program still works, and put it in your git hub if it
does.
(I don't know what is the policy of this list regarding attaching files.)

If it does work, and I have not made some stupid mistakes, is is a nice
example of program where Clojure's performance can compete with C and even
outperform it, because you can write easily a better implementation.
 (The code I wrote is really ugly, because it was made as multiple hacks,
but I think with more experience than me and more cleverness in the design,
you can keep the code really expressive and clear, while achieving the same
level of performance.).

Best,

Nicolas.

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



Re: adding a member to a set in a map in a map in a map in a ref

2009-07-05 Thread Rowdy Rednose

You're right, the scenario that I described doesn't need it. In my
actual code I need it because the function actually reads
#(conj (or % #{}) constraint#)

If I don't do that, I get a list instead of a set.

On Jul 5, 5:12 pm, Meikel Brandmeyer  wrote:
> Hi,
>
> Am 05.07.2009 um 07:27 schrieb Rowdy Rednose:
>
> > user=> (dosync (alter gnu-rms update-in [:key1 :key2 :key3] #(conj %
> > "foo")))
>
> > {:key1 {:key2 {:key3 #{"foo"
>
> You actually don't need the anonymous function...
>
> (dosync
>    (alter gnu-rms update-in [:key1 :key2 :key3] conj "foo"))
>
> Sincerely
> Meikel
>
>  smime.p7s
> 2KViewDownload
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: loneclojurian at ICFP programming contest

2009-07-05 Thread fft1976

On Jul 5, 2:31 am, Nicolas Oury  wrote:

> After, when I run the benchmark in -server with a big enough CacheCode area
> (1000m), and enough iterations to have everything JITed, I get more than
> 860.000 iterations per second. (I benchmarked 100 000 000 iterations in 121
> sec, on my 2.4GHz computer).

That's 3000 clock cycles per VM instruction? I'm not very familiar
with the problem, but I thought "straight" C bytecode interpreters
were at around 30 and compiling the VM code to native code (with JIT)
reduced it to 7. Is this right?

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

2009-07-05 Thread Timothy Pratley

Interesting talk Stuart, thanks for the link.


On Jul 4, 1:12 pm, Stuart Halloway  wrote:
> Corey Haines, the touring software journeyman, recently spent a few  
> days at Relevance (including a day pairing on a Clojure project). At  
> the end, he videoed a conversation with me [1]. In Part 2 of the video  
> we talk about Clojure.
>
> The conversation does not go at all deep technically, but if you need  
> something to show your manager that real people are using Clojure you  
> might find it interesting.
>
> [1]http://programmingtour.blogspot.com/2009/07/conversation-with-stuart-...
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Adding type hint causes compiler error

2009-07-05 Thread philip.hazel...@gmail.com

Hi,

The following code works as expected:

(import 'javax.imageio.ImageIO 'java.io.File
'java.awt.image.BufferedImage)
(defn bi-get-pixels
  [bi]
  (vec (.. bi (getData) (getPixels 0 0 (.getWidth bi) (.getHeight bi)
nil
(bi-get-pixels (. ImageIO read (File. "/home/phil/prog/small-
test.png")))

But if *warn-on-reflection* is true, it generates four warnings. If we
try to shut it up with a type hint:

(defn bi-get-pixels
  [#^BufferedImage bi]
  (vec (.. bi (getData) (getPixels 0 0 (.getWidth bi) (.getHeight bi)
nil

Exception in thread "main" java.lang.IllegalArgumentException: More
than one matching method found: getPixels (imagio-test.clj:7)
at clojure.lang.Compiler.analyzeSeq(Compiler.java:4558)
...
Caused by: java.lang.IllegalArgumentException: More than one matching
method found: getPixels
at clojure.lang.Compiler.getMatchingParams(Compiler.java:2122)
at clojure.lang.Compiler$InstanceMethodExpr.
(Compiler.java:1159)
at clojure.lang.Compiler$HostExpr$Parser.parse(Compiler.java:
810)
at clojure.lang.Compiler.analyzeSeq(Compiler.java:4551)
... 34 more

The problem here is that getPixels has three forms: (
http://java.sun.com/j2se/1.4.2/docs/api/java/awt/image/Raster.html )
 double[]   getPixels(int x, int y, int w, int h, double[] dArray)
  Returns a double array containing all samples for a
rectangle of pixels, one sample per array element.
 float[]getPixels(int x, int y, int w, int h, float[] fArray)
  Returns a float array containing all samples for a rectangle
of pixels, one sample per array element.
 int[]  getPixels(int x, int y, int w, int h, int[] iArray)
  Returns an int array containing all samples for a rectangle
of pixels, one sample per array element.

In each case, if the final argument is NULL it is ignored, and if not
the array is populated with the return data from the call (generating
an error if it's not large enough).

Is it possible to specify which invocation of getPixels I intend
without passing an array? I've tried putting #^ints in some likely-
looking places, but nil can't be type-hinted and the others seem to
have no effect. I've also tried splitting the .. up:

(defn bi-get-pixels
  [#^BufferedImage bi]
  (let [rast (.getData bi)
#^ints pi (.getPixels rast 0 0 (.getWidth bi) (.getHeight bi) nil)]
pi))

But this doesn't work either. I could do manual reflection on Raster
to get the correct method and .invoke it, but that seems far more
complicated than necessary. Any other ideas?

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



Mysterious ClassFormatError after simple code change.

2009-07-05 Thread John Harrop

I had this:

(defn- subexpressions-of-sum** [[n p] terms]
  (let-print [sum (cons '+ (map #(factor-term % n p) terms))
prod (rest (make-product* n p))]
(concat [sum] (subexpressions-of-product (cons sum prod)

in a source file with other definitions. Load-file worked. I then
changed it to this:

(defn- subexpressions-of-sum** [[n p] terms]
  (let-print [sum (cons '+ (map #(factor-term % n p) terms))
prod (rest (make-product* n p))]
(cons sum
  (map #(cons '* (cons sum (rest %)))
(concat prod (subexpressions-of-product prod))

and got:

#

when I tried to do a load-file.

That function definition was the ONLY thing I changed, but I'm at a
loss to find any kind of error in it. Delimiters balance, all of the
referenced functions exist, basically there's nothing wrong.

The full exception trace, which required evaluating (.printStackTrace
(.getCause *e)) at the repl, is:

java.lang.ClassFormatError: Unknown constant tag 32 in class file
com/mycompany/myfile$eval__14598
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:621)
at java.lang.ClassLoader.defineClass(ClassLoader.java:466)
at 
clojure.lang.DynamicClassLoader.defineClass(DynamicClassLoader.java:42)
at clojure.lang.Compiler$FnExpr.getCompiledClass(Compiler.java:3417)
at clojure.lang.Compiler$FnExpr.eval(Compiler.java:3428)
at clojure.lang.Compiler.eval(Compiler.java:4531)
at clojure.core$eval__3990.invoke(core.clj:1728)
at clojure.main$repl__5813$read_eval_print__5825.invoke(main.clj:176)
at clojure.main$repl__5813.doInvoke(main.clj:193)
at clojure.lang.RestFn.invoke(RestFn.java:548)
at 
org.enclojure.repl.main$create_clojure_repl__53$repl_thread_fn__55.invoke(main.clj:96)
at clojure.lang.AFn.run(AFn.java:37)
at java.lang.Thread.run(Thread.java:619)

It does not point to any line of my source file.

Perhaps the rewritten version of the function provokes a compiler bug?
If there is a known bug that would cause this, let me know of the
known workaround. If there is an error in the second version of my
function, let me know. (It has intentionally different semantics from
the first version, so that's not an error in and of itself.)

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

2009-07-05 Thread Nicolas Oury
Each iteration contains 266 instructions. So, it is more like 10.5 clock
cycle per instructions.
Probably the cost of the method call, that I had to introduce in order to
have the JIT compile, or the fact that the status register is
not directly in a local variable but with an indirection, because we can't
set the value of a local variable directly.
 I could improve that by threading the status reg as a local parameter with
let instructions, but that would mean change a lot of things in the code...
And I got lazy.

If the program is correct, of which I am not sure yet, it is already quite
good as it is quite straightforward and probably far more
readable/maintanable than the implementations in other languages.

Moreover, Clojure is young and being so close from the best solution would
already be great.

Actually, that would be so good, that I actually think there is a mistake
somewhere either in my program or my computation of the speed.
Let's wait for igorrumiha to check and to test this implementation.


Best regards,
Nicolas.





On Sun, Jul 5, 2009 at 12:18 PM, fft1976  wrote:

>
> On Jul 5, 2:31 am, Nicolas Oury  wrote:
>
> > After, when I run the benchmark in -server with a big enough CacheCode
> area
> > (1000m), and enough iterations to have everything JITed, I get more than
> > 860.000 iterations per second. (I benchmarked 100 000 000 iterations in
> 121
> > sec, on my 2.4GHz computer).
>
> That's 3000 clock cycles per VM instruction? I'm not very familiar
> with the problem, but I thought "straight" C bytecode interpreters
> were at around 30 and compiling the VM code to native code (with JIT)
> reduced it to 7. Is this right?
>
> >
>

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

2009-07-05 Thread Tom Faulhaber

Parth,

I've created a little wrapper as promised at: http://gist.github.com/141001.

It gives you my-pprint:

user> (binding [*print-base* 2] (my-pprint (range 10)))
(0 1 10 11 100 101 110 111 1000 1001)
nil
user>

While doing this, I realized to my horror that ~r doesn't do 0
correctly for non-standard bases. I'll fix that soon.

Also, I've started to implement *print-radix* and *print-base* for
real in cl-format and the pretty printer, so those should be available
soon.

Enjoy,

Tom


On Jul 3, 3:16 am, Parth  wrote:
> On Jul 3, 11:25 am, Tom Faulhaber  wrote:
>
> > Parth,
>
> > I was thinking about this a little more today and I came up with a way
> > to extend the pretty printer easily to support *print-radix* with a
> > little wrapper. I'll try to get a chance to write it up for you
> > tomorrow.
>
> > Tom
>
> Sounds perfect. Thanks very much :)
>
> Regards,
> Parth
>
> > On Jul 2, 6:29 pm, Parth  wrote:
>
> > > On Jul 3, 6:15 am, Parth  wrote:
>
> > > > Tom, Chouser, Thanks for your responses.
>
> > > > As of now I am doing the same thing as suggested.
> > > > However, this tends be become painful the moment structures
> > > > start to nest. For e.g. I am using Clojure to decode a bit
> > > > of assembly and below is what I end up doing to see the
> > > > values of interest in hex:
>
> > > > user=> (decode :b32 (nth test-ops 3))
> > > > {:inst {:prefix (), :code (199 69 248 10 0 0 0), :op :movl, :args
> > > > [{:type :Ev-mem, :arg {:reg :ebp, :disp -8}} 10]}, :more ()}
> > > > user=> (def r (decode :b32 (nth test-ops 3)))
> > > > #'user/r
> > > > user=> (map hex (get-in r [:inst :code]))
> > > > ("c7" "45" "f8" "a" "0" "0" "0")
> > > > user=> (hex (second (get-in r [:inst :args])))
> > > > "a"
> > > > user=>
>
> > > > Basically, I need to extract each number seq or value
> > > > individually and print it in hex for every instruction I
> > > > decode and view.
>
> > > > This isn't too much fun to do in the middle of  a debug session :)
>
> > > > Having something like *print-base* would be ideal IMHO
> > > > would make scenarios like this really easy as one could
> > > > simply do:
>
> > > > user=> (set! *print-base* 16)
> > > > user=> (decode :b32 (nth test-ops 3))
> > > > {:inst {:prefix (), :code (c7 47 f8 a 0 0 0), :op :movl, :args
> > > > [{:type :Ev-mem, :arg {:reg :ebp, :disp f8}} a]}, :more ()}
>
> > > > In the absence of this I thought of writing a function
> > > > that would take an arbitrary Clojure structure/coll and print
> > > > it out in the manner like above. But then it won't
> > > > be much different from pprint with radix support but without
> > > > the pretty part.
>
> > > > I suppose what I am hoping is that a feature request for
> > > > *print-base* sort of a mechanism get considered
> > > > for Clojure as it makes scenarios like the above very
> > > > easy to deal with. Any chance of this being somewhere
> > > > on the Clojue todo? :)
>
> > > Rich,
>
> > > If this is something you think would be a good addition
> > > to Clojure I could give a shot at creating a patch for
> > > this (with a CA of course). Please let me know.
>
> > > I think rather than a generic radix support, if
> > > we have hex, bin and octal supported, most uses
> > > cases should be covered.
>
> > > Regards,
> > > Parth
>
> > > > I will probably create a poor mans radix based print
> > > > in the mean time for the this scenario. That should
> > > > be an interesting exercise.
>
> > > > Thanks,
> > > > Parth
>
> > > > On Jul 2, 10:58 pm, Chouser  wrote:
>
> > > > > On Thu, Jul 2, 2009 at 4:51 AM, Parth
>
> > > > > Malwankar wrote:
>
> > > > > > I frequently deal with hex and binary numbers.
> > > > > > As of now when I need to view a list of numbers
> > > > > > I just map a little hex function to it to translate it
> > > > > > into a list of hex strings at the repl.
>
> > > > > > Having something like *print-base* / *print-radix* [1] may be
> > > > > > valuable in such a scenario
>
> > > > > I don't think Java's built-in formatter is nearly as
> > > > > flexible as those, but getting hex or octal strings is easy
> > > > > enough:
>
> > > > > user=> (format "%d" 255)
> > > > > "255"
> > > > > user=> (format "%o" 255)
> > > > > "377"
> > > > > user=> (format "%x" 255)
> > > > > "ff"
> > > > > user=> (format "%X" 255)
> > > > > "FF"
>
> > > > > --Chouser
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: loneclojurian at ICFP programming contest

2009-07-05 Thread igorrumiha

On Jul 5, 3:05 pm, Nicolas Oury  wrote:
> Actually, that would be so good, that I actually think there is a mistake
> somewhere either in my program or my computation of the speed.
> Let's wait for igorrumiha to check and to test this implementation.
>

OK, I did my tests, I found and fixed two small bugs and as far as I
can tell the VM is now working correctly. I couldn't, however,
reproduce the timings Nicolas had, on my machine (a 2 Ghz MacBook with
java 1.6 build 1.6.0_13-b03-211) I got timings between 570 and 637
seconds for 100 000 000 executions. So, this translates, on average,
to 163585 executions/second. That translates to 45.9 clock cycles per
guest VM instruction.

I used these tuning options for the Java VM:
-XX:InitialCodeCacheSize=768m
-XX:ReservedCodeCacheSize=1024m
-Xms768M
-Xmx768M
-server

I consider this an excellent result, about 2.5 times faster than my
simple Java implementation of the VM.

I can't explain the 5.2x difference between my and Nicolas' timings,
though :)

What I can say is that my quest for Orbital Virtual Machine speed is
satisfied. With a simulation time limit of 3 million seconds (set by
the contest rules) this VM now reaches that limit in ~19 seconds of
wallclock time. That's even good enough for interactive exploration of
problem solutions (I think it's very likely that it will usually take
more than 19 seconds to write a new version of a solution and then run
it in the REPL :))

I think it's safe to say that once again it's proved that Clojure
easily matches the Java level of performance.

What I've learned from this is:
1. I need to read the documentation more carefully :),
2. I need to learn how to write macros,
3. I need to get myself acquainted with the underlying JVM platform,
4. When in trouble, the clojure group is an excellent place to get
help.
5. Write lots and lots of Clojure code, that is the only way to get
enough experience for the next ICFP contest :)

Thanks a bunch everyone, especially Nicolas for being so persistent :)


p.s.
I'll update my git repo in a day or two, I need to clean up the code a
bit and port the game logic code to use the new VM.


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

2009-07-05 Thread B Smith-Mannschott

On Tue, Jun 30, 2009 at 18:01, Rich Hickey wrote:
>
> On Tue, Jun 30, 2009 at 7:50 AM, Krukow wrote:
>>
>> On Jun 29, 7:51 pm, B Smith-Mannschott  wrote:
>> [snip...]
>>> much on my netbook. The problem seems to be that with only a single
>>> (hyperthreaded) core the render agent is almost constantly interrupted
>>> by some pesky ant while attempting to snapshot the world, forcing the
>>> render agent to automatically retry. And so, the ants run merrily
>>> around the world, only I can't see it.
>>
>> If my understanding of the STM is correct (and it may very well not
>> be) the render function should not retry. The render function reads
>> all the refs that define ant positions, but does not modify any ref.
>> So I suspect that the missing renders are caused by a thread
>> starvation rather than retries.
>>
>> But I'd like to hear if Rich agrees ;-)
>>
>
> MVCC history in Clojure's STM is dynamic, created by need. There is no
> read tracking, and more important for this case, no transaction
> tracking. So, if a read transaction is unable to satisfy its snapshot
> view from history, it will flag the offending ref with a fault and
> retry. When a writer sees a ref with a read fault it will grow history
> for that ref. In this way only as much history is created as is needed
> to satisfy the dynamic contention patterns, and
> tracking/synchronization is minimized.
>
> The problem for scanning readers like render is that the ref that
> caused the fault this pass is unlikely to be the ref that causes the
> fault next time, and it will take a while to accumulate even one step
> of history for each scanned ref using the fault system.
>
> This has caused me to implement (in git master) some long-planned
> controls on ref history. You can now supply :min-history and
> :max-history args to ref. The defaults are 0 and 10 respectively. By
> setting min-history to some positive value, history will be
> accumulated even in the absence of faults, providing a window, if you
> will, for scanning readers like render.
>
> You can see this history acquisition by periodically running:
>
> (map ref-history-count (world 20))
>
> while the ants demo is going.
>
> So, now you can preemptively maintain history in the ants demo by
> modifying the world init with some min-history (the value 2 below is
> your 'knob' for accommodating the duration of the render sweep)
>
> (def world ... (ref (struct cell 0 0) :min-history 2) ...)
>
> Please let me know how that works for you, and, everyone else, please
> let me know if max-history default of 10 causes you any trouble
> ("Transaction failed after reaching retry limit").

Sorry it took me so long to try this out...

I've tried this with a build of
a1397390d8b3b63f2039359520629d87b152d717 (July 4), I tried
:min-history values of 2 and 9, which didn't help, meaning the window
stayed blank because the rendering agent does not run to completion. I
was able to get something to display by dialing :min-history up to
100. It draws less than one frame per second, but it does draw.
(Perhaps it's too much to expect for a single core to juggle some 50
threads.)

I'm going to play around with it some more and see what I find.

// Ben

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

2009-07-05 Thread John Newman
I'm on an hp mini.  It runs on an Atom processor.  I ran ants.clj and it was
frozen for a little while.  Then after maybe 30 seconds it looked normal --
a tick every second or half second or so.  I'm running a lot of applications
though.  On Ubuntu here too.

On Sun, Jul 5, 2009 at 11:17 PM, B Smith-Mannschott
wrote:

>
> On Tue, Jun 30, 2009 at 18:01, Rich Hickey wrote:
> >
> > On Tue, Jun 30, 2009 at 7:50 AM, Krukow wrote:
> >>
> >> On Jun 29, 7:51 pm, B Smith-Mannschott  wrote:
> >> [snip...]
> >>> much on my netbook. The problem seems to be that with only a single
> >>> (hyperthreaded) core the render agent is almost constantly interrupted
> >>> by some pesky ant while attempting to snapshot the world, forcing the
> >>> render agent to automatically retry. And so, the ants run merrily
> >>> around the world, only I can't see it.
> >>
> >> If my understanding of the STM is correct (and it may very well not
> >> be) the render function should not retry. The render function reads
> >> all the refs that define ant positions, but does not modify any ref.
> >> So I suspect that the missing renders are caused by a thread
> >> starvation rather than retries.
> >>
> >> But I'd like to hear if Rich agrees ;-)
> >>
> >
> > MVCC history in Clojure's STM is dynamic, created by need. There is no
> > read tracking, and more important for this case, no transaction
> > tracking. So, if a read transaction is unable to satisfy its snapshot
> > view from history, it will flag the offending ref with a fault and
> > retry. When a writer sees a ref with a read fault it will grow history
> > for that ref. In this way only as much history is created as is needed
> > to satisfy the dynamic contention patterns, and
> > tracking/synchronization is minimized.
> >
> > The problem for scanning readers like render is that the ref that
> > caused the fault this pass is unlikely to be the ref that causes the
> > fault next time, and it will take a while to accumulate even one step
> > of history for each scanned ref using the fault system.
> >
> > This has caused me to implement (in git master) some long-planned
> > controls on ref history. You can now supply :min-history and
> > :max-history args to ref. The defaults are 0 and 10 respectively. By
> > setting min-history to some positive value, history will be
> > accumulated even in the absence of faults, providing a window, if you
> > will, for scanning readers like render.
> >
> > You can see this history acquisition by periodically running:
> >
> > (map ref-history-count (world 20))
> >
> > while the ants demo is going.
> >
> > So, now you can preemptively maintain history in the ants demo by
> > modifying the world init with some min-history (the value 2 below is
> > your 'knob' for accommodating the duration of the render sweep)
> >
> > (def world ... (ref (struct cell 0 0) :min-history 2) ...)
> >
> > Please let me know how that works for you, and, everyone else, please
> > let me know if max-history default of 10 causes you any trouble
> > ("Transaction failed after reaching retry limit").
>
> Sorry it took me so long to try this out...
>
> I've tried this with a build of
> a1397390d8b3b63f2039359520629d87b152d717 (July 4), I tried
> :min-history values of 2 and 9, which didn't help, meaning the window
> stayed blank because the rendering agent does not run to completion. I
> was able to get something to display by dialing :min-history up to
> 100. It draws less than one frame per second, but it does draw.
> (Perhaps it's too much to expect for a single core to juggle some 50
> threads.)
>
> I'm going to play around with it some more and see what I find.
>
> // Ben
>
> >
>


-- 
John

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



Re: loneclojurian at ICFP programming contest

2009-07-05 Thread Nicolas Oury
I don't know if it will help, but I used another flag. I have not my
computer at hand but I think it was in the lines of -XX
agressiveoptimizations.

Moreover, the performance goes from 200 000 to 800 000 depending on the size
of the chunks. I tried to launch for 1 or 10 millions iterations to find the
fastest on my computer. That is quite strange the fact that the size xhange
so much the result.

Really a fun exercize in writing benchmarking clojure, though.

Best,

Nicolas.

On Jul 5, 2009 6:53 PM, "igorrumiha"  wrote:

On Jul 5, 3:05 pm, Nicolas Oury  wrote: > Actually,
that would be so good, ...
OK, I did my tests, I found and fixed two small bugs and as far as I
can tell the VM is now working correctly. I couldn't, however,
reproduce the timings Nicolas had, on my machine (a 2 Ghz MacBook with
java 1.6 build 1.6.0_13-b03-211) I got timings between 570 and 637
seconds for 100 000 000 executions. So, this translates, on average,
to 163585 executions/second. That translates to 45.9 clock cycles per
guest VM instruction.

I used these tuning options for the Java VM:
-XX:InitialCodeCacheSize=768m
-XX:ReservedCodeCacheSize=1024m
-Xms768M
-Xmx768M
-server

I consider this an excellent result, about 2.5 times faster than my
simple Java implementation of the VM.

I can't explain the 5.2x difference between my and Nicolas' timings,
though :)

What I can say is that my quest for Orbital Virtual Machine speed is
satisfied. With a simulation time limit of 3 million seconds (set by
the contest rules) this VM now reaches that limit in ~19 seconds of
wallclock time. That's even good enough for interactive exploration of
problem solutions (I think it's very likely that it will usually take
more than 19 seconds to write a new version of a solution and then run
it in the REPL :))

I think it's safe to say that once again it's proved that Clojure
easily matches the Java level of performance.

What I've learned from this is:
1. I need to read the documentation more carefully :),
2. I need to learn how to write macros,
3. I need to get myself acquainted with the underlying JVM platform,
4. When in trouble, the clojure group is an excellent place to get
help.
5. Write lots and lots of Clojure code, that is the only way to get
enough experience for the next ICFP contest :)

Thanks a bunch everyone, especially Nicolas for being so persistent :)


p.s.
I'll update my git repo in a day or two, I need to clean up the code a
bit and port the game logic code to use the new VM.


Igor.

--~--~-~--~~~---~--~~ You received this
message because you are subs...

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

2009-07-05 Thread Stephen C. Gilardi

On Jul 5, 2009, at 2:01 AM, John Harrop wrote:


and got:

#32 in class file com/mycompany/myfile$eval__14598 (NO_SOURCE_FILE:0)>


Are there large literals elsewhere in the same namespace?

Here's some info from a previous report of this error:

http://groups.google.com/group/clojure/browse_frm/thread/e556434a382de814/f8183c88db8fa257?lnk=gst&q=oct+18+2008#f8183c88db8fa257

--Steve



smime.p7s
Description: S/MIME cryptographic signature


Re: ANN: FnParse, a functional parsing library

2009-07-05 Thread samppi

If you need a JSON parser, there's already a good one included with
clojure.contrib. The one with the FnParse library is just a sample to
show how it works. But please feel free to use it however it can be
useful to you. :)

On Jul 4, 1:45 pm, Wilson MacGyver  wrote:
> Very timely, I need to parse a bunch on JSON files on Monday :) good  
> work
>
> Sent from my iPhone
>
> On Jul 4, 2009, at 3:16 PM, samppi  wrote:
>
>
>
>
>
> > I'm pleased to announce FnParse, a monadic functional parsing library
> > for Clojure, half a year in the making. I started on FnParse in
> > December as my first Clojure project, and now it has matured to
> > something that I believe is very and immediately useful. Currently,
> > I'm writing a YAML parser using FnParse.
>
> > With FnParse, you can easily parse a string or any sequence of tokens
> > into native data structures. FnParse is based on the concept of the
> > rule, a self-contained function that accepts a state data structure,
> > containing a sequence of tokens, and either consumes some tokens--
> > turning them into new data--or fails. Rules correspond nicely to EBNF
> > productions and productions in other sort of grammars. FnParse
> > provides common rules, functions that create new rules, and functions
> > that facilitate using rules.
>
> > A sample JSON parser is 
> > athttp://wiki.github.com/joshua-choi/fnparse/sample-json-parser
> > .
> > Online documentation is available 
> > at:http://wiki.github.com/joshua-choi/fnparse
> > .
> > The source is at:http://github.com/joshua-choi/fnparse.
>
> > If you are confused about anything or find any bugs, please create an
> > issue on GitHub (http://github.com/joshua-choi/fnparse/issues) or send
> > me a message on GitHub.
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: Adding type hint causes compiler error

2009-07-05 Thread Mark Triggs

Hi Phil,

Part of me hopes there's a nicer way of doing this, but I was able to
get it working using:

(defn bi-get-pixels
  [#^BufferedImage bi]
  (let [raster (.getData bi)
pixels (.getPixels raster 0 0 (.getWidth bi) (.getHeight bi)
   (cast (Class/forName "[I") nil))]
(vec pixels)))

Cheers,

Mark


On Jul 5, 10:18 pm, "philip.hazel...@gmail.com"
 wrote:
> Hi,
>
> The following code works as expected:
>
> (import 'javax.imageio.ImageIO 'java.io.File
> 'java.awt.image.BufferedImage)
> (defn bi-get-pixels
>   [bi]
>   (vec (.. bi (getData) (getPixels 0 0 (.getWidth bi) (.getHeight bi)
> nil
> (bi-get-pixels (. ImageIO read (File. "/home/phil/prog/small-
> test.png")))
>
> But if *warn-on-reflection* is true, it generates four warnings. If we
> try to shut it up with a type hint:
>
> (defn bi-get-pixels
>   [#^BufferedImage bi]
>   (vec (.. bi (getData) (getPixels 0 0 (.getWidth bi) (.getHeight bi)
> nil
>
> Exception in thread "main" java.lang.IllegalArgumentException: More
> than one matching method found: getPixels (imagio-test.clj:7)
>         at clojure.lang.Compiler.analyzeSeq(Compiler.java:4558)
> ...
> Caused by: java.lang.IllegalArgumentException: More than one matching
> method found: getPixels
>         at clojure.lang.Compiler.getMatchingParams(Compiler.java:2122)
>         at clojure.lang.Compiler$InstanceMethodExpr.
> (Compiler.java:1159)
>         at clojure.lang.Compiler$HostExpr$Parser.parse(Compiler.java:
> 810)
>         at clojure.lang.Compiler.analyzeSeq(Compiler.java:4551)
>         ... 34 more
>
> The problem here is that getPixels has three forms: 
> (http://java.sun.com/j2se/1.4.2/docs/api/java/awt/image/Raster.html)
>  double[]       getPixels(int x, int y, int w, int h, double[] dArray)
>           Returns a double array containing all samples for a
> rectangle of pixels, one sample per array element.
>  float[]        getPixels(int x, int y, int w, int h, float[] fArray)
>           Returns a float array containing all samples for a rectangle
> of pixels, one sample per array element.
>  int[]  getPixels(int x, int y, int w, int h, int[] iArray)
>           Returns an int array containing all samples for a rectangle
> of pixels, one sample per array element.
>
> In each case, if the final argument is NULL it is ignored, and if not
> the array is populated with the return data from the call (generating
> an error if it's not large enough).
>
> Is it possible to specify which invocation of getPixels I intend
> without passing an array? I've tried putting #^ints in some likely-
> looking places, but nil can't be type-hinted and the others seem to
> have no effect. I've also tried splitting the .. up:
>
> (defn bi-get-pixels
>   [#^BufferedImage bi]
>   (let [rast (.getData bi)
>         #^ints pi (.getPixels rast 0 0 (.getWidth bi) (.getHeight bi) nil)]
>     pi))
>
> But this doesn't work either. I could do manual reflection on Raster
> to get the correct method and .invoke it, but that seems far more
> complicated than necessary. Any other ideas?
>
> -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: Adding type hint causes compiler error

2009-07-05 Thread Kevin Downey

On Sun, Jul 5, 2009 at 5:18 AM,
philip.hazel...@gmail.com wrote:
>
> Hi,
>
> The following code works as expected:
>
> (import 'javax.imageio.ImageIO 'java.io.File
> 'java.awt.image.BufferedImage)
> (defn bi-get-pixels
>  [bi]
>  (vec (.. bi (getData) (getPixels 0 0 (.getWidth bi) (.getHeight bi)
> nil
> (bi-get-pixels (. ImageIO read (File. "/home/phil/prog/small-
> test.png")))
>
> But if *warn-on-reflection* is true, it generates four warnings. If we
> try to shut it up with a type hint:
>
> (defn bi-get-pixels
>  [#^BufferedImage bi]
>  (vec (.. bi (getData) (getPixels 0 0 (.getWidth bi) (.getHeight bi)
> nil
>
> Exception in thread "main" java.lang.IllegalArgumentException: More
> than one matching method found: getPixels (imagio-test.clj:7)
>        at clojure.lang.Compiler.analyzeSeq(Compiler.java:4558)
> ...
> Caused by: java.lang.IllegalArgumentException: More than one matching
> method found: getPixels
>        at clojure.lang.Compiler.getMatchingParams(Compiler.java:2122)
>        at clojure.lang.Compiler$InstanceMethodExpr.
> (Compiler.java:1159)
>        at clojure.lang.Compiler$HostExpr$Parser.parse(Compiler.java:
> 810)
>        at clojure.lang.Compiler.analyzeSeq(Compiler.java:4551)
>        ... 34 more
>
> The problem here is that getPixels has three forms: (
> http://java.sun.com/j2se/1.4.2/docs/api/java/awt/image/Raster.html )
>  double[]       getPixels(int x, int y, int w, int h, double[] dArray)
>          Returns a double array containing all samples for a
> rectangle of pixels, one sample per array element.
>  float[]        getPixels(int x, int y, int w, int h, float[] fArray)
>          Returns a float array containing all samples for a rectangle
> of pixels, one sample per array element.
>  int[]  getPixels(int x, int y, int w, int h, int[] iArray)
>          Returns an int array containing all samples for a rectangle
> of pixels, one sample per array element.
>
> In each case, if the final argument is NULL it is ignored, and if not
> the array is populated with the return data from the call (generating
> an error if it's not large enough).
>
> Is it possible to specify which invocation of getPixels I intend
> without passing an array? I've tried putting #^ints in some likely-
> looking places, but nil can't be type-hinted and the others seem to
> have no effect. I've also tried splitting the .. up:
>
> (defn bi-get-pixels
>  [#^BufferedImage bi]
>  (let [rast (.getData bi)
>        #^ints pi (.getPixels rast 0 0 (.getWidth bi) (.getHeight bi) nil)]
>    pi))

you change (.getPixels rast 0 0 (.getWidth bi) (.getHeight bi) nil)
to something like (.getPixels rast (int 0) (int 0) (.getWidth bi)
(.getHeight bi) nil)

>
> But this doesn't work either. I could do manual reflection on Raster
> to get the correct method and .invoke it, but that seems far more
> complicated than necessary. Any other ideas?
>
> -Phil
> >
>



-- 
And what is good, Phaedrus,
And what is not good—
Need we ask anyone to tell us these things?

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

2009-07-05 Thread fft1976

On Jul 5, 10:53 am, igorrumiha  wrote:

> I think it's safe to say that once again it's proved that Clojure
> easily matches the Java level of performance.

I think one shouldn't generalize from one [unverified] example.

Personally, I'll wait for Jon Harrop or someone to port the relevant
Shootout benchmarks or his "Ray tracing" benchmark to Clojure and see
what time they get and what the code looks like.

For example, some people claim that Haskell is as fast as C, while
also being very high-level, but when you look at the Shootout, you'll
see that it's BS: they are doing pointer arithmetic in Haskell, for
Christ's sake!

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

2009-07-05 Thread John Harrop

I'm not doing any funny things with load-string. The largest literal
at this time is

[2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79
 83 89 97 101 103 107 109 113 127 131 137 139 149 151 157 163
 167 173 179 181 191 193 197 199 211 223 227 229 233 239 241 251
 257 263 269 271 277 281 283 293 307 311 313 317 331 337 347 349
 353 359 367 373 379 383 389 397 401 409 419 421 431 433 439 443
 449 457 461 463 467 479 487 491 499 503 509 521 523 541 547 557
 563 569 571 577 587 593 599 601 607 613 617 619 631 641 643 647
 653 659 661 673 677 683 691 701 709 719 727 733 739 743 751 757
 761 769 773 787 797 809 811 821 823 827 829 839 853 857 859 863
 877 881 883 887 907 911 919 929 937 941 947 953 967 971 977 983
 991 997]

and has been in there a while without causing problems. The function
definition in my original post is the ONLY change between working and
not-working. With the first version, the file loads consistently. With
the second version, it fails consistently. The error is definitely in
that function and not elsewhere, or else it is in the implementation
of load-file, the compiler, or even Java or the JVM.

The JVM is 1.6.0_something, I forget what. It's pretty current.

The literal generated in the post you linked to took a list of four
items and doubled it up 13 times, for a grand total of 2^15 = 32768
items. There's nothing that large in that function, nor anything in
the second version of it that would expand (say, via a macro) into
something that large from a number being changed.

This is frankly quite baffling. The changes to the function are
innocent from a large-literal or pretty much any other perspective.

On 7/5/09, Stephen C. Gilardi  wrote:
> On Jul 5, 2009, at 2:01 AM, John Harrop wrote:
>
>> and got:
>>
>> #> 32 in class file com/mycompany/myfile$eval__14598 (NO_SOURCE_FILE:0)>
>
> Are there large literals elsewhere in the same namespace?
>
> Here's some info from a previous report of this error:
>
> http://groups.google.com/group/clojure/browse_frm/thread/e556434a382de814/f8183c88db8fa257?lnk=gst&q=oct+18+2008#f8183c88db8fa257
>
> --Steve
>
>

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



sanity check needed

2009-07-05 Thread Mark Volkmann

I wrote some fairly simple code to demonstrate use of StructMaps and
Refs. It's 80 lines including comments. I'd appreciate it if someone
could look it over and let me know if I've done anything that isn't
very idiomatic.

The program models sports teams and players. The main functionality is
the ability to trade sets of players between teams. Both teams and
players are held by Refs. Players have a reference to their team.
Teams have references to their players.

The output from the code follows:

Before trade:
Oilers roster:
  Wayne Gretzky
  Mike Krushelnyski
  Marty McSorley
Kings roster:
  Jimmy Carson
  Martin Gelinas

After trade:
Oilers roster:
  Martin Gelinas
  Jimmy Carson
Kings roster:
  Wayne Gretzky
  Mike Krushelnyski
  Marty McSorley

Here's the code:

; A player knows his team, if any.
(defstruct player-struct :name :team-ref)

; A team knows its players.
(defstruct team-struct :name :player-refs)

; Makes a new Ref to a player-struct that isn't on any team.
(defn make-player [name]
  (ref (struct player-struct name)))

; Makes a new Ref to a team-struct that contains no players.
(defn make-team [name]
  (ref (struct team-struct name [])))

(defn assign-player-to-team [player-ref new-team-ref]
  (dosync
; If the player has a former team, remove them from it.
(if-let [old-team-ref (@player-ref :team-ref)]
  (let [old-player-refs (@old-team-ref :player-refs)
new-player-refs (remove #(= % player-ref) old-player-refs)]
(alter old-team-ref assoc :player-refs new-player-refs)))

; Add the player to their new team.
(let [old-player-refs (@new-team-ref :player-refs)
  new-player-refs (conj old-player-refs player-ref)]
  (alter player-ref assoc :team-ref new-team-ref)
  (alter new-team-ref assoc :player-refs new-player-refs

; Returns a string describing a given player.
(defn player-to-string [player-ref]
  (dosync
(str (@player-ref :name) " plays for "
  (if-let [team-ref (@player-ref :team-ref)]
(str "the " (@team-ref :name))
"nobody")
  ".")))

; Returns a string describing a given team.
(defn team-to-string [team-ref]
  (dosync
(apply str
  (@team-ref :name) " roster:"
  (map
(fn [player-ref] (str "\n  " (@player-ref :name)))
(@team-ref :player-refs)

; players1 and players2 are collections of Refs to player StructMaps.
; Neither can be empty.
; All players in a collection must be on the same team.
(defn trade [players1 players2]
  (dosync
(let [team1 ((first players1) :team-ref)
  team2 ((first players2) :team-ref)]
  (doseq [p players1]
(assign-player-to-team p team2))
  (doseq [p players2]
(assign-player-to-team p team1)

(let [oilers (make-team "Oilers")
  kings (make-team "Kings")
  p1 (make-player "Wayne Gretzky")
  p2 (make-player "Mike Krushelnyski")
  p3 (make-player "Marty McSorley")
  p4 (make-player "Jimmy Carson")
  p5 (make-player "Martin Gelinas")]

  (doseq [p [p1 p2 p3]]
(assign-player-to-team p oilers))
  (doseq [p [p4 p5]]
(assign-player-to-team p kings))

  (println "Before trade:")
  (println (team-to-string oilers))
  (println (team-to-string kings))

  (trade [p1 p2 p3] [p4 p5])

  (println "\nAfter trade:")
  (println (team-to-string oilers))
  (println (team-to-string kings)))

-- 
R. Mark Volkmann
Object Computing, Inc.

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

2009-07-05 Thread Wilson MacGyver

Thanks for the tip on looking at clojure.contrib. I keep forgetting to  
check there.

On Jul 5, 2009, at 4:20 PM, samppi  wrote:

>
> If you need a JSON parser, there's already a good one included with
> clojure.contrib. The one with the FnParse library is just a sample to
> show how it works. But please feel free to use it however it can be
> useful to you. :)
>
> On Jul 4, 1:45 pm, Wilson MacGyver  wrote:
>> Very timely, I need to parse a bunch on JSON files on Monday :) good
>> work
>>
>> Sent from my iPhone
>>
>> On Jul 4, 2009, at 3:16 PM, samppi  wrote:
>>
>>
>>
>>
>>
>>> I'm pleased to announce FnParse, a monadic functional parsing  
>>> library
>>> for Clojure, half a year in the making. I started on FnParse in
>>> December as my first Clojure project, and now it has matured to
>>> something that I believe is very and immediately useful. Currently,
>>> I'm writing a YAML parser using FnParse.
>>
>>> With FnParse, you can easily parse a string or any sequence of  
>>> tokens
>>> into native data structures. FnParse is based on the concept of the
>>> rule, a self-contained function that accepts a state data structure,
>>> containing a sequence of tokens, and either consumes some tokens--
>>> turning them into new data--or fails. Rules correspond nicely to  
>>> EBNF
>>> productions and productions in other sort of grammars. FnParse
>>> provides common rules, functions that create new rules, and  
>>> functions
>>> that facilitate using rules.
>>
>>> A sample JSON parser is athttp://wiki.github.com/joshua-choi/ 
>>> fnparse/sample-json-parser
>>> .
>>> Online documentation is available at:http://wiki.github.com/joshua- 
>>> choi/fnparse
>>> .
>>> The source is at:http://github.com/joshua-choi/fnparse.
>>
>>> If you are confused about anything or find any bugs, please create  
>>> an
>>> issue on GitHub (http://github.com/joshua-choi/fnparse/issues) or  
>>> send
>>> me a message on GitHub.
> >

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

2009-07-05 Thread ataggart

A set might be better to hold the player-refs, then you can just call
(disj player-refs player-ref) without doing any extra checking.

Also you can access ref values without needing to be in a dosync.
Things being immutable, the value you get from, say, @team-ref won't
change once you have it.

On Jul 5, 5:12 pm, Mark Volkmann  wrote:
> I wrote some fairly simple code to demonstrate use of StructMaps and
> Refs. It's 80 lines including comments. I'd appreciate it if someone
> could look it over and let me know if I've done anything that isn't
> very idiomatic.
>
> The program models sports teams and players. The main functionality is
> the ability to trade sets of players between teams. Both teams and
> players are held by Refs. Players have a reference to their team.
> Teams have references to their players.
>
> The output from the code follows:
>
> Before trade:
> Oilers roster:
>   Wayne Gretzky
>   Mike Krushelnyski
>   Marty McSorley
> Kings roster:
>   Jimmy Carson
>   Martin Gelinas
>
> After trade:
> Oilers roster:
>   Martin Gelinas
>   Jimmy Carson
> Kings roster:
>   Wayne Gretzky
>   Mike Krushelnyski
>   Marty McSorley
>
> Here's the code:
>
> ; A player knows his team, if any.
> (defstruct player-struct :name :team-ref)
>
> ; A team knows its players.
> (defstruct team-struct :name :player-refs)
>
> ; Makes a new Ref to a player-struct that isn't on any team.
> (defn make-player [name]
>   (ref (struct player-struct name)))
>
> ; Makes a new Ref to a team-struct that contains no players.
> (defn make-team [name]
>   (ref (struct team-struct name [])))
>
> (defn assign-player-to-team [player-ref new-team-ref]
>   (dosync
>     ; If the player has a former team, remove them from it.
>     (if-let [old-team-ref (@player-ref :team-ref)]
>       (let [old-player-refs (@old-team-ref :player-refs)
>             new-player-refs (remove #(= % player-ref) old-player-refs)]
>         (alter old-team-ref assoc :player-refs new-player-refs)))
>
>     ; Add the player to their new team.
>     (let [old-player-refs (@new-team-ref :player-refs)
>           new-player-refs (conj old-player-refs player-ref)]
>       (alter player-ref assoc :team-ref new-team-ref)
>       (alter new-team-ref assoc :player-refs new-player-refs
>
> ; Returns a string describing a given player.
> (defn player-to-string [player-ref]
>   (dosync
>     (str (@player-ref :name) " plays for "
>       (if-let [team-ref (@player-ref :team-ref)]
>         (str "the " (@team-ref :name))
>         "nobody")
>       ".")))
>
> ; Returns a string describing a given team.
> (defn team-to-string [team-ref]
>   (dosync
>     (apply str
>       (@team-ref :name) " roster:"
>       (map
>         (fn [player-ref] (str "\n  " (@player-ref :name)))
>         (@team-ref :player-refs)
>
> ; players1 and players2 are collections of Refs to player StructMaps.
> ; Neither can be empty.
> ; All players in a collection must be on the same team.
> (defn trade [players1 players2]
>   (dosync
>     (let [team1 ((first players1) :team-ref)
>           team2 ((first players2) :team-ref)]
>       (doseq [p players1]
>         (assign-player-to-team p team2))
>       (doseq [p players2]
>         (assign-player-to-team p team1)
>
> (let [oilers (make-team "Oilers")
>       kings (make-team "Kings")
>       p1 (make-player "Wayne Gretzky")
>       p2 (make-player "Mike Krushelnyski")
>       p3 (make-player "Marty McSorley")
>       p4 (make-player "Jimmy Carson")
>       p5 (make-player "Martin Gelinas")]
>
>   (doseq [p [p1 p2 p3]]
>     (assign-player-to-team p oilers))
>   (doseq [p [p4 p5]]
>     (assign-player-to-team p kings))
>
>   (println "Before trade:")
>   (println (team-to-string oilers))
>   (println (team-to-string kings))
>
>   (trade [p1 p2 p3] [p4 p5])
>
>   (println "\nAfter trade:")
>   (println (team-to-string oilers))
>   (println (team-to-string kings)))
>
> --
> R. Mark Volkmann
> Object Computing, Inc.
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: sanity check needed

2009-07-05 Thread Stephen C. Gilardi


On Jul 5, 2009, at 8:12 PM, Mark Volkmann wrote:


I'd appreciate it if someone
could look it over and let me know if I've done anything that isn't
very idiomatic.



A few recommendations just at the "look and feel" level:

- use doc strings for functions in place of comments
- global delete of "-ref". Those suffixes make the code look noisy  
without adding enough value to warrant that.
- refs don't need to be dereferenced explicitly when in calling  
position. Whenever possible, elide @: (@foo ...) -> (foo ...), again  
for visual noise reduction.


--Steve



smime.p7s
Description: S/MIME cryptographic signature


Re: sanity check needed

2009-07-05 Thread ataggart

I should have been more clear when I said to use (disj ...); I meant
sending that via an alter.

On Jul 5, 6:05 pm, ataggart  wrote:
> A set might be better to hold the player-refs, then you can just call
> (disj player-refs player-ref) without doing any extra checking.
>
> Also you can access ref values without needing to be in a dosync.
> Things being immutable, the value you get from, say, @team-ref won't
> change once you have it.
>
> On Jul 5, 5:12 pm, Mark Volkmann  wrote:
>
>
>
> > I wrote some fairly simple code to demonstrate use of StructMaps and
> > Refs. It's 80 lines including comments. I'd appreciate it if someone
> > could look it over and let me know if I've done anything that isn't
> > very idiomatic.
>
> > The program models sports teams and players. The main functionality is
> > the ability to trade sets of players between teams. Both teams and
> > players are held by Refs. Players have a reference to their team.
> > Teams have references to their players.
>
> > The output from the code follows:
>
> > Before trade:
> > Oilers roster:
> >   Wayne Gretzky
> >   Mike Krushelnyski
> >   Marty McSorley
> > Kings roster:
> >   Jimmy Carson
> >   Martin Gelinas
>
> > After trade:
> > Oilers roster:
> >   Martin Gelinas
> >   Jimmy Carson
> > Kings roster:
> >   Wayne Gretzky
> >   Mike Krushelnyski
> >   Marty McSorley
>
> > Here's the code:
>
> > ; A player knows his team, if any.
> > (defstruct player-struct :name :team-ref)
>
> > ; A team knows its players.
> > (defstruct team-struct :name :player-refs)
>
> > ; Makes a new Ref to a player-struct that isn't on any team.
> > (defn make-player [name]
> >   (ref (struct player-struct name)))
>
> > ; Makes a new Ref to a team-struct that contains no players.
> > (defn make-team [name]
> >   (ref (struct team-struct name [])))
>
> > (defn assign-player-to-team [player-ref new-team-ref]
> >   (dosync
> >     ; If the player has a former team, remove them from it.
> >     (if-let [old-team-ref (@player-ref :team-ref)]
> >       (let [old-player-refs (@old-team-ref :player-refs)
> >             new-player-refs (remove #(= % player-ref) old-player-refs)]
> >         (alter old-team-ref assoc :player-refs new-player-refs)))
>
> >     ; Add the player to their new team.
> >     (let [old-player-refs (@new-team-ref :player-refs)
> >           new-player-refs (conj old-player-refs player-ref)]
> >       (alter player-ref assoc :team-ref new-team-ref)
> >       (alter new-team-ref assoc :player-refs new-player-refs
>
> > ; Returns a string describing a given player.
> > (defn player-to-string [player-ref]
> >   (dosync
> >     (str (@player-ref :name) " plays for "
> >       (if-let [team-ref (@player-ref :team-ref)]
> >         (str "the " (@team-ref :name))
> >         "nobody")
> >       ".")))
>
> > ; Returns a string describing a given team.
> > (defn team-to-string [team-ref]
> >   (dosync
> >     (apply str
> >       (@team-ref :name) " roster:"
> >       (map
> >         (fn [player-ref] (str "\n  " (@player-ref :name)))
> >         (@team-ref :player-refs)
>
> > ; players1 and players2 are collections of Refs to player StructMaps.
> > ; Neither can be empty.
> > ; All players in a collection must be on the same team.
> > (defn trade [players1 players2]
> >   (dosync
> >     (let [team1 ((first players1) :team-ref)
> >           team2 ((first players2) :team-ref)]
> >       (doseq [p players1]
> >         (assign-player-to-team p team2))
> >       (doseq [p players2]
> >         (assign-player-to-team p team1)
>
> > (let [oilers (make-team "Oilers")
> >       kings (make-team "Kings")
> >       p1 (make-player "Wayne Gretzky")
> >       p2 (make-player "Mike Krushelnyski")
> >       p3 (make-player "Marty McSorley")
> >       p4 (make-player "Jimmy Carson")
> >       p5 (make-player "Martin Gelinas")]
>
> >   (doseq [p [p1 p2 p3]]
> >     (assign-player-to-team p oilers))
> >   (doseq [p [p4 p5]]
> >     (assign-player-to-team p kings))
>
> >   (println "Before trade:")
> >   (println (team-to-string oilers))
> >   (println (team-to-string kings))
>
> >   (trade [p1 p2 p3] [p4 p5])
>
> >   (println "\nAfter trade:")
> >   (println (team-to-string oilers))
> >   (println (team-to-string kings)))
>
> > --
> > R. Mark Volkmann
> > Object Computing, Inc.
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: sanity check needed

2009-07-05 Thread Mark Volkmann

On Sun, Jul 5, 2009 at 8:05 PM, ataggart wrote:
>
> A set might be better to hold the player-refs, then you can just call
> (disj player-refs player-ref) without doing any extra checking.

Thanks, I llke that much better!

> Also you can access ref values without needing to be in a dosync.
> Things being immutable, the value you get from, say, @team-ref won't
> change once you have it.

Yeah, but in my case I am accessing more than one ref value inside
each dosync and I want to make sure I get consistent values. For
example, if a trade is being executed in one thread and one of the
teams involved is being printed in another thread, I could get
inconsistent output without the dosyncs.

Thanks for the feedback!

-- 
R. Mark Volkmann
Object Computing, Inc.

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

2009-07-05 Thread Mark Volkmann

On Sun, Jul 5, 2009 at 8:14 PM, Stephen C. Gilardi wrote:
>
> On Jul 5, 2009, at 8:12 PM, Mark Volkmann wrote:
>
> I'd appreciate it if someone
> could look it over and let me know if I've done anything that isn't
> very idiomatic.
>
> A few recommendations just at the "look and feel" level:
> - use doc strings for functions in place of comments

Thanks! I temporarily forget about those.

> - global delete of "-ref". Those suffixes make the code look noisy without
> adding enough value to warrant that.

I agree it makes the code look noisy, but I like that it helps me
remember that a value is a ref. I'll remove them though because I know
I'm in the minority on that viewpoint.

> - refs don't need to be dereferenced explicitly when in calling position.
> Whenever possible, elide @: (@foo ...) -> (foo ...), again for visual noise
> reduction.

Wow! I don't know how I missed out on that rule. I don't recall every
hearing about that feature. Very cool! Is this discussed in the
"Programming Clojure" book?

-- 
R. Mark Volkmann
Object Computing, Inc.

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

2009-07-05 Thread Parth



On Jul 5, 9:02 pm, Tom Faulhaber  wrote:
> Parth,
>
> I've created a little wrapper as promised at:http://gist.github.com/141001.
>
> It gives you my-pprint:
>
> user> (binding [*print-base* 2] (my-pprint (range 10)))
> (0 1 10 11 100 101 110 111 1000 1001)
> nil
> user>
>

Thanks Tom. This works beautifully :)

Here is the example that earlier example in the thread:

user=> (binding [wrap-base/*print-base* 16] (wrap-base/my-pprint
(decode :b32 (test-ops 3
{:inst
 {:prefix (),
  :code (c7 45 f8 a 0 0 0),
  :op :movl,
  :args [{:type :Ev-mem, :arg {:reg :ebp, :disp -8}} a]},
 :more ()}
nil
user=>



> While doing this, I realized to my horror that ~r doesn't do 0
> correctly for non-standard bases. I'll fix that soon.
>
> Also, I've started to implement *print-radix* and *print-base* for
> real in cl-format and the pretty printer, so those should be available
> soon.
>


Fantastic ... pprint just keeps getting better :)

Regards,
Parth

> Enjoy,
>
> Tom
>
> On Jul 3, 3:16 am, Parth  wrote:
>
> > On Jul 3, 11:25 am, Tom Faulhaber  wrote:
>
> > > Parth,
>
> > > I was thinking about this a little more today and I came up with a way
> > > to extend the pretty printer easily to support *print-radix* with a
> > > little wrapper. I'll try to get a chance to write it up for you
> > > tomorrow.
>
> > > Tom
>
> > Sounds perfect. Thanks very much :)
>
> > Regards,
> > Parth
>
> > > On Jul 2, 6:29 pm, Parth  wrote:
>
> > > > On Jul 3, 6:15 am, Parth  wrote:
>
> > > > > Tom, Chouser, Thanks for your responses.
>
> > > > > As of now I am doing the same thing as suggested.
> > > > > However, this tends be become painful the moment structures
> > > > > start to nest. For e.g. I am using Clojure to decode a bit
> > > > > of assembly and below is what I end up doing to see the
> > > > > values of interest in hex:
>
> > > > > user=> (decode :b32 (nth test-ops 3))
> > > > > {:inst {:prefix (), :code (199 69 248 10 0 0 0), :op :movl, :args
> > > > > [{:type :Ev-mem, :arg {:reg :ebp, :disp -8}} 10]}, :more ()}
> > > > > user=> (def r (decode :b32 (nth test-ops 3)))
> > > > > #'user/r
> > > > > user=> (map hex (get-in r [:inst :code]))
> > > > > ("c7" "45" "f8" "a" "0" "0" "0")
> > > > > user=> (hex (second (get-in r [:inst :args])))
> > > > > "a"
> > > > > user=>
>
> > > > > Basically, I need to extract each number seq or value
> > > > > individually and print it in hex for every instruction I
> > > > > decode and view.
>
> > > > > This isn't too much fun to do in the middle of  a debug session :)
>
> > > > > Having something like *print-base* would be ideal IMHO
> > > > > would make scenarios like this really easy as one could
> > > > > simply do:
>
> > > > > user=> (set! *print-base* 16)
> > > > > user=> (decode :b32 (nth test-ops 3))
> > > > > {:inst {:prefix (), :code (c7 47 f8 a 0 0 0), :op :movl, :args
> > > > > [{:type :Ev-mem, :arg {:reg :ebp, :disp f8}} a]}, :more ()}
>
> > > > > In the absence of this I thought of writing a function
> > > > > that would take an arbitrary Clojure structure/coll and print
> > > > > it out in the manner like above. But then it won't
> > > > > be much different from pprint with radix support but without
> > > > > the pretty part.
>
> > > > > I suppose what I am hoping is that a feature request for
> > > > > *print-base* sort of a mechanism get considered
> > > > > for Clojure as it makes scenarios like the above very
> > > > > easy to deal with. Any chance of this being somewhere
> > > > > on the Clojue todo? :)
>
> > > > Rich,
>
> > > > If this is something you think would be a good addition
> > > > to Clojure I could give a shot at creating a patch for
> > > > this (with a CA of course). Please let me know.
>
> > > > I think rather than a generic radix support, if
> > > > we have hex, bin and octal supported, most uses
> > > > cases should be covered.
>
> > > > Regards,
> > > > Parth
>
> > > > > I will probably create a poor mans radix based print
> > > > > in the mean time for the this scenario. That should
> > > > > be an interesting exercise.
>
> > > > > Thanks,
> > > > > Parth
>
> > > > > On Jul 2, 10:58 pm, Chouser  wrote:
>
> > > > > > On Thu, Jul 2, 2009 at 4:51 AM, Parth
>
> > > > > > Malwankar wrote:
>
> > > > > > > I frequently deal with hex and binary numbers.
> > > > > > > As of now when I need to view a list of numbers
> > > > > > > I just map a little hex function to it to translate it
> > > > > > > into a list of hex strings at the repl.
>
> > > > > > > Having something like *print-base* / *print-radix* [1] may be
> > > > > > > valuable in such a scenario
>
> > > > > > I don't think Java's built-in formatter is nearly as
> > > > > > flexible as those, but getting hex or octal strings is easy
> > > > > > enough:
>
> > > > > > user=> (format "%d" 255)
> > > > > > "255"
> > > > > > user=> (format "%o" 255)
> > > > > > "377"
> > > > > > user=> (format "%x" 255)
> > > > > > "ff"
> > > > > > user=> (format "%X" 255)
> > > > > > "FF"
>
> > > > > > --Chouser
--~--~-

Re: Clojure at LispNYC tonight 7pm

2009-07-05 Thread Daniel Jomphe

I second this suggestion to add the video to clojure.blip.tv. It felt
very awkward in 2009 to have to download this thing instead of stream
it. :)

I just watched it and wanted to say it's a very nice show of Clojure's
Java interop in practice. Congrats to Stuart. It was also very nice to
learn the history behind some of Stuart's contribs.

Now, I think it would be very great for Stuart to present this again,
but this time to a java audience, and put that too on blip.


On Jun 16, 11:10 am, Paul Stadig  wrote:
> On Wed, Jun 10, 2009 at 11:37 AM, Stuart Sierra 
> > wrote:
>
> > On Jun 9, 10:32 am, Stuart Sierra  wrote:
> > > Join us Tuesday, June 9 from 7:00-9:00 for Stuart Sierra's
> > > presentation:
>
> > >     Implementing AltLaw.org in Clojure
>
> > Slides and video here:http://lispnyc.org/wiki.clp?page=past-meetings
> > We'll try to get something lighter than a 3GB mpeg soon.
>
> > -Stuart
>
> I watched this video. Thanks for posting it! There is some great information
> in there, especially the "from the trenches" tips about working with Java
> libraries.
>
> Since you're one of the more active contributors to Clojure, would it be
> appropriate to post the video to clojure.blip.tv?
>
> Paul
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



tests involving threads

2009-07-05 Thread Timothy Pratley

Very glad that test is now part of clojure core.

I've run into 2 strange behaviours when trying to write tests where
threads are involved. My case is a little complex so here is a minimal
version which shows what I mean:

test-test.clj:
(ns test-test
  (:use clojure.test))

(deftest testathon
  (let [f1 (future (is (= 1 2)))
f2 (future (future (/ 1 0)))]
@f1
@f2))

(run-tests)
(shutdown-agents)



$ clj test-test.clj

Testing test-test

FAIL in clojure.lang.persistentlist$emptyl...@1 (test-test.clj:5)
expected: (= 1 2)
  actual: (not (= 1 2))

Ran 1 tests containing 0 assertions.
0 failures, 0 errors.

f1 failed, and a FAIL message is printed, but the end report indicates
0 failures.
f2 raised an exception silently.

I guess I'm just not "doing it right"!


Regards,
Tim.

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



Re: loneclojurian at ICFP programming contest

2009-07-05 Thread Bradbev

On Jul 5, 3:18 am, fft1976  wrote:
> On Jul 5, 2:31 am, Nicolas Oury  wrote:
>
> > After, when I run the benchmark in -server with a big enough CacheCode area
> > (1000m), and enough iterations to have everything JITed, I get more than
> > 860.000 iterations per second. (I benchmarked 100 000 000 iterations in 121
> > sec, on my 2.4GHz computer).
>
> That's 3000 clock cycles per VM instruction? I'm not very familiar
> with the problem, but I thought "straight" C bytecode interpreters
> were at around 30 and compiling the VM code to native code (with JIT)
> reduced it to 7. Is this right?

On modern architectures, measuring performance in clock cycles is
almost meaningless.  I spend a reasonably amount of my working life
making code run faster on game consoles; what I say here applies even
more to modern x86 chips.  After you have the best algorithm for the
job, you very quickly find that going fast is entirely bound by memory
speed (actually latency) - cache misses are the enemy.
Obviously, in higher level languages like Clojure you need to take a
few extra steps - get the right algorithm & make sure you are writing
your code in a way that the JIT can optimize well.  Once that is done
you would ideally run a profiler that points out where you have cache
misses - I think vTune does this.  You can fake pre-fetching by
issuing a read one cacheline ahead in your mainloop, though the JVM
may drop this as useless work.  If the JVM supported proper cache line
fetching & zeroing, that would make high performance Java programs
easier to write.
BTW, I noticed that you mention that Clojure is not living up to its
performance hype.  In my experience, the biggest performance impact on
code is who wrote it.  It makes me cry when I see linear linked-list
search of 5000+ strings using strcmp.

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