Bug? Definline arguments multiply evaluated.

2009-07-30 Thread John Harrop
user=> (definline addsq [a b] `(+ (* ~a ~a) (* ~b ~b)))
#'hxr.clj.util/addsq
user=> (addsq (do (println "a evaluated") 1) 1)
a evaluated
a evaluated
2

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



Re: Exit delay from java when lazy?

2009-07-30 Thread mwillson

On Jul 29, 8:17 pm, Michael Wood  wrote:
> 2009/7/29 mwillson :
> >
> > I was experimenting with Clojure and XML and stumbled upon a lengthy
> > hang when exiting java which was tracked down to the use of
> > clojure.contrib.lazy-xml.  Here's a toy example which exhibits the
> > issue:
>
> I haven't looked at clojure.contrib.lazy-xml, but this sounds like
> what happens if you make use of agents.  Shutting down the agents with
> (shutdown-agents) should fix it if so.  Perhaps
> clojure.contrib.lazy-xml uses agents.

Michael,

Thanks for your reply.  You are quite right - adding (shutdown-agents)
does allow the script using lazy-xml to exit promptly.  From a cursory
scan of the lazy-xml/parse-seq code, it does use agents.

-mark

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

2009-07-30 Thread Frank Koenig

Thank you Stuart and Daniel for the help. I think I have to step back
from the idea to use clojure on this Java 1.4 project :-(

Let's hope my next Java project addresses a less archaic Java version.

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

2009-07-30 Thread Rich Hickey



On Jul 30, 1:29 am, John Harrop  wrote:
> user=> (definline addsq [a b] `(+ (* ~a ~a) (* ~b ~b)))
> #'hxr.clj.util/addsq
> user=> (addsq (do (println "a evaluated") 1) 1)
> a evaluated
> a evaluated
> 2

You write the expansion, so you are in control of multiple evaluation.

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



Bug? Primitives get boxed if passed out of let.

2009-07-30 Thread Rich Hickey

On Thu, Jul 30, 2009 at 1:28 AM, John Harrop wrote:
> user=> (loop [i 0 j (double 1.0)]
>   (if (= i 1) j (recur 1 (+ j j
> 2.0
> user=> (loop [i 0 j (double 1.0)]
>   (if (= i 1) j (recur 1 (let [a j b j] (+ a b)
> # java.lang.IllegalArgumentException: recur arg for primitive local: j must be
> matching primitive (NO_SOURCE_FILE:0)>
> user=> (loop [i 0 j (double 1.0)]
>   (if (= i 1) j (let [a j b j] (recur 1 (+ a b)
> 2.0
> So when j is a lowercase-d double, inside (let [a j b j] ... ) a and b are
> lowercase-d doubles, and (+ a b) is a lowercase-d double, but the type of
> the expression (let [a j b j] (+ a b)) is apparently capital-D Double.
> This seems like a bug to me, and could cripple performance in some
> conceivable cases. Primitives should not get boxed when not passed across
> function-call boundaries, and let is not a function.
>

Currently only host expressions and bindings to host expressions of
primitive types can have primitives type. let expressions etc cannot.

One reason is that let etc can have more than one 'type' by containing
conditionals or making calls to polymorphic functions:

;let might have type double or String
(let [j (double 42.0)] (if x j "42"))

Currently there is no analysis to determine that potentially composite
expressions yield a uniform type, which would be required to let a
primitive flow out of a let. It would be a nice enhancement.

Rich

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



Re: Possible bug report

2009-07-30 Thread Rich Hickey



On Jul 29, 6:09 pm, Jason Wolfe  wrote:
> Is this a bug?
>
> user> (eval `(make-array ~Byte/TYPE 2))
> ; Evaluation aborted. (ExceptionInInitializerError)
>
> Compare:
>
> user> (eval `(make-array ~Byte 2))
> #
>
> user> (eval `(make-array Byte/TYPE 2))
> #
>
> user> (make-array (eval Byte/TYPE) 2)
> #
>
> If not, can someone please help me understand what's going on here?
>

Yes, currently you cannot embed constants of primitive Class types.
This arises from an asymmetry in Java:

user=> (.getName Byte)
"java.lang.Byte"

user=> (Class/forName "java.lang.Byte")
java.lang.Byte

user=> (.getName Byte/TYPE)
"byte"

user=> (Class/forName "byte")
java.lang.ClassNotFoundException: byte (NO_SOURCE_FILE:0)

A patch to support reading, and embedded constants, of primitive Class
objects would be welcome. The current print-dup support won't do it.

If anyone is interested in contributing this patch please bring it up
on the clojure-dev group before proceeding and I can give you some
guidance as to what needs to be changed.

Thanks for the report,

Rich

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



Re: Possible bug report

2009-07-30 Thread Aaron Cohen
At my day job, we've always used a custom classloader to get around that
asymmetry.
-- Aaron


On Thu, Jul 30, 2009 at 9:51 AM, Rich Hickey  wrote:

>
>
>
> On Jul 29, 6:09 pm, Jason Wolfe  wrote:
> > Is this a bug?
> >
> > user> (eval `(make-array ~Byte/TYPE 2))
> > ; Evaluation aborted. (ExceptionInInitializerError)
> >
> > Compare:
> >
> > user> (eval `(make-array ~Byte 2))
> > #
> >
> > user> (eval `(make-array Byte/TYPE 2))
> > #
> >
> > user> (make-array (eval Byte/TYPE) 2)
> > #
> >
> > If not, can someone please help me understand what's going on here?
> >
>
> Yes, currently you cannot embed constants of primitive Class types.
> This arises from an asymmetry in Java:
>
> user=> (.getName Byte)
> "java.lang.Byte"
>
> user=> (Class/forName "java.lang.Byte")
> java.lang.Byte
>
> user=> (.getName Byte/TYPE)
> "byte"
>
> user=> (Class/forName "byte")
> java.lang.ClassNotFoundException: byte (NO_SOURCE_FILE:0)
>
> A patch to support reading, and embedded constants, of primitive Class
> objects would be welcome. The current print-dup support won't do it.
>
> If anyone is interested in contributing this patch please bring it up
> on the clojure-dev group before proceeding and I can give you some
> guidance as to what needs to be changed.
>
> Thanks for the report,
>
> Rich
>
> >
>

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



Re: java 1.4 class files

2009-07-30 Thread Sean Devlin

This is slightly unrelated, but...

How much work would it be to run the old code on a Java 5/6 VM?  I
didn't get into Java until 5, so I'm not sure how much work is
actually involved w/ upgrading a JVM installation.

On Jul 30, 7:07 am, Frank Koenig  wrote:
> Thank you Stuart and Daniel for the help. I think I have to step back
> from the idea to use clojure on this Java 1.4 project :-(
>
> Let's hope my next Java project addresses a less archaic Java version.
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: Possible bug report

2009-07-30 Thread Jason Wolfe


On Jul 30, 2009, at 6:51 AM, Rich Hickey wrote:
> On Jul 29, 6:09 pm, Jason Wolfe  wrote:
>> Is this a bug?
>>
>> user> (eval `(make-array ~Byte/TYPE 2))
>> ; Evaluation aborted. (ExceptionInInitializerError)
>>
>> Compare:
>>
>> user> (eval `(make-array ~Byte 2))
>> #
>>
>> user> (eval `(make-array Byte/TYPE 2))
>> #
>>
>> user> (make-array (eval Byte/TYPE) 2)
>> #
>>
>> If not, can someone please help me understand what's going on here?
>>
>
> Yes, currently you cannot embed constants of primitive Class types.
> This arises from an asymmetry in Java:
>
> user=> (.getName Byte)
> "java.lang.Byte"
>
> user=> (Class/forName "java.lang.Byte")
> java.lang.Byte
>
> user=> (.getName Byte/TYPE)
> "byte"
>
> user=> (Class/forName "byte")
> java.lang.ClassNotFoundException: byte (NO_SOURCE_FILE:0)
>
> A patch to support reading, and embedded constants, of primitive Class
> objects would be welcome. The current print-dup support won't do it.
>
> If anyone is interested in contributing this patch please bring it up
> on the clojure-dev group before proceeding and I can give you some
> guidance as to what needs to be changed.
>
> Thanks for the report,
>
> Rich

Thanks for the clear explanation.

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



Re: Bug? Definline arguments multiply evaluated.

2009-07-30 Thread Nicolas Oury

Hello,

I am not sure to agree.

If I get it right, definline is used to replace defn for function that
we want to be inlined.

So replacing defn by definline should have no impact on the semantic of
the program.


Best regards,


Nicolas.

On Thu, 2009-07-30 at 05:34 -0700, Rich Hickey wrote:
> 
> 
> On Jul 30, 1:29 am, John Harrop  wrote:
> > user=> (definline addsq [a b] `(+ (* ~a ~a) (* ~b ~b)))
> > #'hxr.clj.util/addsq
> > user=> (addsq (do (println "a evaluated") 1) 1)
> > a evaluated
> > a evaluated
> > 2
> 
> You write the expansion, so you are in control of multiple evaluation.
> 
> Rich
> > 


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



Good memory profilers (program or human)?

2009-07-30 Thread Andy Fingerhut

I'm gradually adding a few more Clojure benchmark programs to my
repository here:

git://github.com/jafingerhut/clojure-benchmarks.git

The one I wrote for the "reverse-complement" benchmark is here:

http://github.com/jafingerhut/clojure-benchmarks/blob/4ab4f41c6f963445e1e0973a668ac64939be1c7f/rcomp/revcomp.clj-4.clj

revcomp.clj-4.clj is the best I've got so far, but it runs out of
memory on the full size benchmark.

If you clone the repository, and successfully run the init.sh script
to generate the big input and expected output files, the file rcomp/
long-input.txt contains 3 DNA sequences in FASTA format. The first is
50,000,000 characters long, the second is 75,000,000 characters long,
and the third is 125,000,000 characters long. Each needs to be
reversed, have each character replaced with a different one, and
printed out, so we need to store each of the strings one at a time,
but it is acceptable to deallocate/garbage-collect the previous one
when starting on the next. I think my code should be doing that, but I
don't know how to verify that.

I've read that a Java String takes 2 bytes per character, plus about
38 bytes of overhead per string. That is about 250 Mbytes for the
longest one. I also read in a seq of lines, and these long strings are
split into lines with 60 characters (plus a newline) each. Thus the
string's data needs to be stored at least twice temporarily -- once
for the many 60-character strings, plus the final long one.  Also, the
Java StringBuilder that Clojure's (str ...) function uses probably
needs to be copied and reallocated periodically as it outgrows its
current allocation. So I could imagine needing about 3 * 250 Mbytes
temporarily, but that doesn't explain why my 1536 Mbytes of JVM memory
are being exhausted.

It would be possible to improve things by not creating all of the
separate strings, one for each line, and then concatenating them
together. But first I'd like to explain why it is using so much,
because I must be missing something.

Thank,
Andy

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

2009-07-30 Thread Rich Hickey

On Thu, Jul 30, 2009 at 1:26 PM, Nicolas Oury wrote:
>
> Hello,
>
> I am not sure to agree.
>
> If I get it right, definline is used to replace defn for function that
> we want to be inlined.
>
> So replacing defn by definline should have no impact on the semantic of
> the program.
>

The docs for definline state it is expansion like macro expansion.

Rich

>
> On Thu, 2009-07-30 at 05:34 -0700, Rich Hickey wrote:
>>
>>
>> On Jul 30, 1:29 am, John Harrop  wrote:
>> > user=> (definline addsq [a b] `(+ (* ~a ~a) (* ~b ~b)))
>> > #'hxr.clj.util/addsq
>> > user=> (addsq (do (println "a evaluated") 1) 1)
>> > a evaluated
>> > a evaluated
>> > 2
>>
>> You write the expansion, so you are in control of multiple evaluation.
>>
>> Rich
>> >
>
>
> >
>

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



Re: Bug? Definline arguments multiply evaluated.

2009-07-30 Thread Laurent PETIT
BTW,

is definline still considered experimental (I know it is still mentioned in
the doc, just asking whether it's up to date or not) ?

2009/7/30 Stuart Halloway 

>
> The documentation is explicit that definline observes defmacro-like
> semantics.
>
> A.K.A. "What Rich said" :-)
>
> Stu
>
> > Hello,
> >
> > I am not sure to agree.
> >
> > If I get it right, definline is used to replace defn for function that
> > we want to be inlined.
> >
> > So replacing defn by definline should have no impact on the semantic
> > of
> > the program.
> >
> >
> > Best regards,
> >
> >
> > Nicolas.
> >
> > On Thu, 2009-07-30 at 05:34 -0700, Rich Hickey wrote:
> >>
> >>
> >> On Jul 30, 1:29 am, John Harrop  wrote:
> >>> user=> (definline addsq [a b] `(+ (* ~a ~a) (* ~b ~b)))
> >>> #'hxr.clj.util/addsq
> >>> user=> (addsq (do (println "a evaluated") 1) 1)
> >>> a evaluated
> >>> a evaluated
> >>> 2
> >>
> >> You write the expansion, so you are in control of multiple
> >> evaluation.
> >>
> >> Rich
> >>>
> >
> >
> > >
>
>
> >
>

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



struct-map niggle

2009-07-30 Thread Richard Newman

I understand what's going on here (and I don't regard it as a bug that  
needs fixing) but I thought I'd share something that caught me off- 
guard, and perhaps should be mentioned in the docs for struct-maps.

Clojure 1.0.0-
user=> (defstruct foo :bar :baz)
#'user/foo
user=> (def foo-bar (accessor foo :bar))
#'user/foo-bar
user=> (= (struct foo 1 2) (eval (struct foo 1 2)))
true
user=> (foo-bar (struct foo 1 2))
1
user=> (foo-bar (eval (struct foo 1 2)))
java.lang.ClassCastException: clojure.lang.PersistentArrayMap cannot  
be cast to clojure.lang.PersistentStructMap (NO_SOURCE_FILE:0)


i.e., struct-map-ness does not persist through evaluation.

Client code must either avoid accessors for data that might be  
evaluated, or post-process the result of calling eval. I have a  
defstruct* macro that defines a structure and its accessors, so it's  
straightforward for me to also define a map->foo function that  
rebuilds the struct from the resultant map.

-R

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

2009-07-30 Thread Stuart Halloway

The documentation is explicit that definline observes defmacro-like  
semantics.

A.K.A. "What Rich said" :-)

Stu

> Hello,
>
> I am not sure to agree.
>
> If I get it right, definline is used to replace defn for function that
> we want to be inlined.
>
> So replacing defn by definline should have no impact on the semantic  
> of
> the program.
>
>
> Best regards,
>
>
> Nicolas.
>
> On Thu, 2009-07-30 at 05:34 -0700, Rich Hickey wrote:
>>
>>
>> On Jul 30, 1:29 am, John Harrop  wrote:
>>> user=> (definline addsq [a b] `(+ (* ~a ~a) (* ~b ~b)))
>>> #'hxr.clj.util/addsq
>>> user=> (addsq (do (println "a evaluated") 1) 1)
>>> a evaluated
>>> a evaluated
>>> 2
>>
>> You write the expansion, so you are in control of multiple  
>> evaluation.
>>
>> Rich
>>>
>
>
> >


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



Re: struct-map niggle

2009-07-30 Thread ataggart

The problem is you aren't quoting the forms fed to eval.

This:
(eval (struct foo 1 2))
mean this:
(eval {:bar 1 :baz 2})

And small literal maps are eval'd as a PersistentArrayMap


Now if instead you do:
(eval '(struct foo 1 2))
then eval is eval'ing the form (struct foo 1 2), thus the return from
eval is as you would expect:

user=> (foo-bar (eval '(struct foo 1 2)))
1




On Jul 30, 11:57 am, Richard Newman  wrote:
> I understand what's going on here (and I don't regard it as a bug that  
> needs fixing) but I thought I'd share something that caught me off-
> guard, and perhaps should be mentioned in the docs for struct-maps.
>
> Clojure 1.0.0-
> user=> (defstruct foo :bar :baz)
> #'user/foo
> user=> (def foo-bar (accessor foo :bar))
> #'user/foo-bar
> user=> (= (struct foo 1 2) (eval (struct foo 1 2)))
> true
> user=> (foo-bar (struct foo 1 2))
> 1
> user=> (foo-bar (eval (struct foo 1 2)))
> java.lang.ClassCastException: clojure.lang.PersistentArrayMap cannot  
> be cast to clojure.lang.PersistentStructMap (NO_SOURCE_FILE:0)
>
> i.e., struct-map-ness does not persist through evaluation.
>
> Client code must either avoid accessors for data that might be  
> evaluated, or post-process the result of calling eval. I have a  
> defstruct* macro that defines a structure and its accessors, so it's  
> straightforward for me to also define a map->foo function that  
> rebuilds the struct from the resultant map.
>
> -R
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: struct-map niggle

2009-07-30 Thread Richard Newman

> The problem is you aren't quoting the forms fed to eval.

That was intentional. Imagine a broader example, where I want to read  
in a form, examine/print/etc. parts of it, then evaluate it.

Printing a struct-map produces map syntax.

Reading the output produces a literal map with unevaluated contents.

E.g.,

user=> (read-string "{:foo (fn [x] (+ 1 x)) :bar 2}")
{:foo (fn [x] (+ 1 x)), :bar 2}

;; Now I can examine the syntactic form of the function, but fetch it  
with (:foo x).
;; I can eval this to get a final object.

user=> (eval *1)
{:foo #, :bar 2}


Evaluating the read forms produces a literal map with evaluated  
contents. Modulo unreadable things like functions, the original struct- 
map and the read+eval'ed struct map are identical, but have different  
types.


> This:
>(eval (struct foo 1 2))
> mean this:
>(eval {:bar 1 :baz 2})
>
> And small literal maps are eval'd as a PersistentArrayMap

I know. The reason this is a gotcha is that -- just like sorted maps  
and sets -- these data structures are not quite homoiconic. That is,  
reading the printed representation of a data structure returns a  
structure with similar but different properties.

If I wasn't using accessors, it would never have occurred to me that  
my in-memory struct maps would come back as plain ol' maps. It doesn't  
confound me, I just didn't think of it in advance.


> Now if instead you do:
>(eval '(struct foo 1 2))
> then eval is eval'ing the form (struct foo 1 2), thus the return from
> eval is as you would expect:
>
> user=> (foo-bar (eval '(struct foo 1 2)))

Indeed. That is all basic stuff that a novice Lisper would know.

The scenario here, though, is different: given an *existing* struct- 
map (which prints as {:foo 1 :bar 2} -- not a form), one cannot print  
it in such a way that the struct-map-ness is preserved when it is re- 
read. You can discover that it's a struct-map (type =>  
PersistentStructMap), but not what kind of struct-map it is.

The same is true of sorted maps and sets, and assorted other data  
structures. Clojure's situation is much better than that of Common  
Lisp, and (as I said) I don't regard it as a bug that not all  
attributes of a structure are preserved through printing and re- 
reading, but I thought others might benefit from my experience…  
particularly because accessors would seem to offer additional speed  
for free.

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

2009-07-30 Thread Chouser

On Thu, Jul 30, 2009 at 4:20 PM, Richard Newman wrote:
>
> The scenario here, though, is different: given an *existing* struct-
> map (which prints as {:foo 1 :bar 2} -- not a form), one cannot print
> it in such a way that the struct-map-ness is preserved when it is re-
> read. You can discover that it's a struct-map (type =>
> PersistentStructMap), but not what kind of struct-map it is.
>
> The same is true of sorted maps and sets, and assorted other data
> structures.

Are you aware of *print-dup* ?  It causes the printer to
preserve more of the specific type information than normal
printing:

user=> (binding [*print-dup* true] (prn (hash-map :a 1, :b 2)))
{:a 1, :b 2}
nil
user=> (binding [*print-dup* true] (prn (sorted-map :a 1, :b 2)))
#=(clojure.lang.PersistentTreeMap/create {:a 1, :b 2})
nil
user=> (binding [*print-dup* true] (prn {:a 1, :b 2}))
#=(clojure.lang.PersistentArrayMap/create {:a 1, :b 2})
nil

The #=() is an intentionally under-documented reader macro
specifically to allow such preservation.

Having said that, it's important to note it doesn't help
your original scenario, because *print-dup* doesn't support
struct maps (yet):

(-> (binding [*print-dup* true] (prn-str (struct foo 1 2)))
java.io.StringReader. java.io.PushbackReader. read class)
java.lang.IllegalArgumentException: No matching method found: create
(NO_SOURCE_FILE:0)

sorted-maps work, but lose any custom sort-by fn:

(-> (binding [*print-dup* true] (prn-str (sorted-map :a 1, :b 2)))
java.io.StringReader. java.io.PushbackReader. read class)
clojure.lang.PersistentTreeMap

(-> (binding [*print-dup* true]
  (prn-str (sorted-map-by #(compare %2 %1) :a 1, :b 2)))
java.io.StringReader. java.io.PushbackReader. read)
{:a 1, :b 2}

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



Idiomatic parsing of objects from several lines of a text file

2009-07-30 Thread David Plumpton

I'm trying to find an idiomatic way to read through a text file (e.g.
a Git history log) where an object will be represented by several
lines of text, and when we find a line that starts a new entry we
create the old entry and continue. For example here's my first clumsy
attempt. Can anybody advise on how to do this in a more functional
style?

(def *line-re* #"[^\n]{1,}")

(defstruct commit :id :parent :msg)

(defn parse-log [filename]
  (let [text (slurp filename)
lines (re-seq *line-re* text)]
(with-local-vars
  [commits {}
  commit-id ""
  parent ""
  msg ""]
  (doseq [line lines]
(if (.startsWith line "commit ")
  (do
(if (not= @commit-id "")
  (do
(var-set commits (conj @commits {...@commit-id (struct
commit @commit-id @parent @msg)}))
(var-set msg "")
(var-set parent nil)))
(var-set commit-id (subs line 7
(if (.startsWith line "parent ")
  (var-set parent (subs line 7)))
(if (.startsWith line "")
  (var-set msg (str @msg "\n" (subs line 4)
  (var-set commits (assoc @commits @commit-id (struct commit
@commit-id @parent @msg)))
  @commits)))



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

2009-07-30 Thread Meikel Brandmeyer

Hi,

I would suggest to have a look at fnparse[1]. It's
really cool. A commit-log parser might look like
this:

(def linebreak
  (alt (conc (opt (lit \return)) (lit \newline))
   (lit \return)))

(def hex-digit
  (alt-lit-seq "0123456789abcdef"))

(def checksum
  (semantics (rep+ hex-digit) #(apply str %)))

(def commit
  (complex [_ (conc-lit-seq "commit ")
commit-id checksum
_ linebreak
_ (conc-lit-seq "parent ")
parent-id checksum
_ (rep= 2 linebreak)
msg   (semantics (rep* (except anything
   (conc linebreak
 (conc-lit-seq  
"commit "

 #(apply str %))]
{:id commit-id :parent parent-id :message msg}))

(def commit-log
  (rep* commit))

This should parse a log like:

commit a2b5927f24c
parent c726fe5211a

This is
the
message
commit 285abb36e12
parent 81f2e35bc61

Another
message.

The result would be:
[{:id a2b5927f24c :parent c726fe5211a :message "This is\nthe\nmessage"}
 {:id 285abb36e12 :parent 81f2e35bc61 :message "Another\nmessage."}]

Note, the code is not tested, but should be close.

Hope this helps.

Sincerely
Meikel

[1]: http://github.com/joshua-choi/fnparse/tree/master




smime.p7s
Description: S/MIME cryptographic signature


Re: struct-map niggle

2009-07-30 Thread Richard Newman

> Are you aware of *print-dup* ?  It causes the printer to
> preserve more of the specific type information than normal
> printing:

It's one of those things that hasn't yet crept close enough on my  
radar for me to absorb. This is the impetus...

> Having said that, it's important to note it doesn't help
> your original scenario, because *print-dup* doesn't support
> struct maps (yet):

Ah, good and bad :)

I expect there are plenty of dangerous edge cases to handle -- e.g.,  
what to do if there is no struct by that name, or if it's a different  
struct with the same name.

I suspect that in my case the right approach is either to switch to  
pure maps (which round-trip perfectly), or to take more control over  
the upstream serialization, and produce a (struct foo ...) form  
instead of just prn-ing the struct-map. I started down the avenue of  
converting maps into struct-maps, though, so perhaps I'll see how that  
turns out. This data is accessed much more often than it's loaded, so  
the overhead is likely worthwhile.

Thanks for the discussion!

-R

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

2009-07-30 Thread Richard Newman

On  30 Jul 2009, at 2:26 PM, David Plumpton wrote:

> I'm trying to find an idiomatic way to read through a text file (e.g.
> a Git history log)

Sidenote: I'm hacking on this:

http://github.com/rnewman/clj-git/tree/master

I haven't got to commit messages etc. yet -- I'm primarily using git  
as a backing store, not accessing existing repositories, so there are  
much more pressing things -- but there might be something useful there  
for you.

The usual caveats of hacky, bad, probably-buggy code apply :)

-R


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

2009-07-30 Thread Rich Hickey

On Thu, Jul 30, 2009 at 2:52 PM, Laurent PETIT wrote:
> BTW,
>
> is definline still considered experimental (I know it is still mentioned in
> the doc, just asking whether it's up to date or not) ?
>

Yes, still experimental.

Rich

> 2009/7/30 Stuart Halloway 
>>
>> The documentation is explicit that definline observes defmacro-like
>> semantics.
>>
>> A.K.A. "What Rich said" :-)
>>
>> Stu
>>
>> > Hello,
>> >
>> > I am not sure to agree.
>> >
>> > If I get it right, definline is used to replace defn for function that
>> > we want to be inlined.
>> >
>> > So replacing defn by definline should have no impact on the semantic
>> > of
>> > the program.
>> >
>> >
>> > Best regards,
>> >
>> >
>> > Nicolas.
>> >
>> > On Thu, 2009-07-30 at 05:34 -0700, Rich Hickey wrote:
>> >>
>> >>
>> >> On Jul 30, 1:29 am, John Harrop  wrote:
>> >>> user=> (definline addsq [a b] `(+ (* ~a ~a) (* ~b ~b)))
>> >>> #'hxr.clj.util/addsq
>> >>> user=> (addsq (do (println "a evaluated") 1) 1)
>> >>> a evaluated
>> >>> a evaluated
>> >>> 2
>> >>
>> >> You write the expansion, so you are in control of multiple
>> >> evaluation.
>> >>
>> >> Rich
>> >>>
>> >
>> >
>> > >
>>
>>
>>
>
>
>
>
> >
>

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



Re: struct-map niggle

2009-07-30 Thread Stuart Sierra

On Jul 30, 5:03 pm, Chouser  wrote:
> Are you aware of *print-dup* ?  It causes the printer to
> preserve more of the specific type information than normal
> printing:
>
> user=> (binding [*print-dup* true] (prn (hash-map :a 1, :b 2)))
> {:a 1, :b 2}
> nil
> user=> (binding [*print-dup* true] (prn (sorted-map :a 1, :b 2)))
> #=(clojure.lang.PersistentTreeMap/create {:a 1, :b 2})
> nil

This doesn't actually work for structs, which may be a bug.  That is,
you can prn a struct, but you can't read it back in.
-SS
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: Idiomatic parsing of objects from several lines of a text file

2009-07-30 Thread Aaron Cohen
What is this convention you are using with the -> ?
Are you coming from a C or C++ background or is this something lispy I
haven't seen before?
-- Aaron


On Thu, Jul 30, 2009 at 7:56 PM, Richard Newman  wrote:

>
> On  30 Jul 2009, at 2:26 PM, David Plumpton wrote:
>
> > I'm trying to find an idiomatic way to read through a text file (e.g.
> > a Git history log)
>
> Sidenote: I'm hacking on this:
>
> http://github.com/rnewman/clj-git/tree/master
>
> I haven't got to commit messages etc. yet -- I'm primarily using git
> as a backing store, not accessing existing repositories, so there are
> much more pressing things -- but there might be something useful there
> for you.
>
> The usual caveats of hacky, bad, probably-buggy code apply :)
>
> -R
>
>
> >
>

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

2009-07-30 Thread Richard Newman

> What is this convention you are using with the -> ?
>
> Are you coming from a C or C++ background or is this something lispy  
> I haven't seen before?

A fair proportion of Common Lispers do that (though I've witnessed  
debates about its merit, usually in the context of low-level code  
where the symbols are already cluttered with [-_+>] etc), exploiting  
the much richer options for symbol names than most languages. It's  
certainly not a dereferencing operation, which is the only context in  
which it would arise for a C/C++ user.

Usually it means "to", either as a conversion or lookup.

(defn ref->commit [ref]
   ...)

thus means "take this ref and give me the corresponding commit (in the  
context of this repo)". Similarly,

(defn tree-entry->map [e]
   ...)

takes a Git tree entry string and returns a Clojure map that  
represents it. This is slightly less confusing than `tree-entry-map`,  
which could very well mean some mapping construct over a tree entry,  
or a map of multiple tree entries, or something else.

I haven't been entirely consistent, though -- witness `tree-entry- 
seq`, which should really be `tree-entry->seq`. I said it was a work  
in progress :)

I suppose in Clojure we could use a real arrow character, with UTF-8  
available in symbol names...

-R


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

2009-07-30 Thread Chas Emerick

It turns out that a framework we've been using is able to serialize
*any* Java class, whether it implements Serializable or not -- so,
we've been happily serializing keywords without them explicitly
supporting it for some time.

However, making Keyword formally Serializable has other benefits,
specifically that a proper patch would ensure that deserialized
Keywords are interned as one would expect out.

So, I may make a run at this sooner rather than later...

- Chas

On Jul 24, 7:06 pm, Chris Kent  wrote:
> Hi
>
> Are there any fundamental reasons why the Keyword class shouldn't be
> serializable?  I've been playing around with Clojure and Wicket and
> it's not possible to use maps containingKeywordsin Wicket page
> classes.  Wicket pages are serialized and stored in the session
> between requests and this fails if the page refers to anyKeywords.
> UsingKeywordsin maps is common in Clojure (and in clj-record in
> particular) and it would be a really useful change.
>
> I'd be happy to supply a (very small) patch if people think it's a
> good idea.
>
> Thanks
> Chris
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: Idiomatic parsing of objects from several lines of a text file

2009-07-30 Thread Daniel Lyons

On Jul 30, 2009, at 7:24 PM, Aaron Cohen wrote:

> Are you coming from a C or C++ background or is this something lispy  
> I haven't seen before?


I first ran into this in Scheme, where I think its use is somewhat  
more idiomatic than in CL. As the author observes, it's generally used  
instead of "to" in the CL libraries on my system, though it wouldn't  
surprise me much to see it used in code wrapping C structures. CL  
usually takes the most verbose option available, confirmed anecdotally  
by 241 occurrences of "-to-" in a function name in the selection of  
libraries on my system, versus 129 occurrences of "->." This structure  
is even employed in SRFI #4, published in 1998, suggesting that its  
use in the Scheme community has been uncontroversial for at least 11  
years. Scheme has always prized a terse kind of elegance where Lisp  
has sought comprehensiveness.


On Jul 30, 2009, at 7:37 PM, Richard Newman wrote:

> I suppose in Clojure we could use a real arrow character, with UTF-8
> available in symbol names...


Clojure being the 21st century language it is, I would be delighted to  
see '¬ instead of 'not, 'ƒ instead of 'fn, '∑ instead of a  
hypothetical 'sum builtin, and → instead of ->. I'm sure I'd enjoy  
reading code with such conventions, but I think I would find typing it  
out is somewhat tedious. You might find the Emacs mode "Pretty Lambda"  
to be useful; the effect on Haskell code is really quite nice:

http://alexott.blogspot.com/2009/02/emacs-haskell-pretty-lambda.html

It can be customized for other languages, but I can't find any  
references to anyone doing it with Clojure yet. Details on the mode  
here:

http://www.emacswiki.org/emacs/PrettyLambda

—
Daniel Lyons


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