Re: Enhanced Primitive Support

2010-06-19 Thread Aaron Cohen
On Sat, Jun 19, 2010 at 11:22 PM, Mike Meyer
 wrote:
>
> "Rob Lachlan"  wrote:
>
>>Actually, Mike, your two functions work just fine.  (Equal branch).
>>Mind you I checked that out over two hours ago, so this information
>>might be out of date.
>>
>>Rob
>>
>>On Jun 19, 6:59 pm, Mike Meyer 
> Ok, why does this work but the fact fail? Or does the fact example still fail 
> on that build?
>
> The fact that this requires explanation is a pretty good argument the fact 
> behavior.
>

>> (defn fact [n]
>>  (loop [n n r 1]
>>   (if (zero? n)
>> r
>> (recur (dec n) (* r n)


(The quoting in this thread is getting out-of-hand, everyone please
reply on the bottom)

The difference between your examples and the fact examples is that

(inc prim) -> prim

while

(* prim boxed) -> boxed

In the fact example, the type of n as an initializer in the loop
statement is unknown at compile time and thus must be boxed. The fact
that you need to know that, is very much what some people are arguing
against.

The choices are to do either:

(loop [n n r (num 1)]

or

(loop [n (long n) r 1]

Either option will make (* r n) return a primitive or boxed value of
the appropriate type. Both versions will overflow and throw an
exception at (fact 21).

To have a fact that works for large numbers you need:

(defn fact [n]
 (loop [n n r (num 1)]
   (if-not (pos? n)
 r
 (recur (dec n) (*' r n)

Most of the versions posted so far were broken for negative n by the way.

-- 
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: Enhanced Primitive Support

2010-06-19 Thread Mike Meyer

"Rob Lachlan"  wrote:

>Because the compiler is upset that it doesn't know what n is.  r is a
>long, but n is ???.  The following works:
>
>(defn ^:static fact [^long n]
>  (loop [n n r 1]
>(if (zero? n)
>  r
>  (recur (dec n) (* r n)
>
>Or see Dnolen's version above.  But yeah, I wish that it still worked,
>because it used to work just fine.

Is there reason the compiler can't box r instead of throwing an exception?
-- 
Sent from my Android phone with K-9 Mail. Please excuse my brevity.

-- 
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: Enhanced Primitive Support

2010-06-19 Thread Rob Lachlan
Because the compiler is upset that it doesn't know what n is.  r is a
long, but n is ???.  The following works:

(defn ^:static fact [^long n]
  (loop [n n r 1]
(if (zero? n)
  r
  (recur (dec n) (* r n)

Or see Dnolen's version above.  But yeah, I wish that it still worked,
because it used to work just fine.

Rob

On Jun 19, 8:22 pm, Mike Meyer  wrote:
> "Rob Lachlan"  wrote:
> >Actually, Mike, your two functions work just fine.  (Equal branch).
> >Mind you I checked that out over two hours ago, so this information
> >might be out of date.
>
> >Rob
>
> >On Jun 19, 6:59 pm, Mike Meyer 
> Ok, why does this work but the fact fail? Or does the fact example still fail 
> on that build?
>
> The fact that this requires explanation is a pretty good argument the fact 
> behavior.
>
> >> (defn count-in [value col]
> >>    (loop [value value col col res 0]
> >>       (if (empty? col)
> >>           res
> >>           (recur value (rest col) (if (= (first col) value) (inc res) 
> >> res)
>
> >> (defn ones-n-zeros [vectors]
> >>   (loop [vectors vectors m-zeros 0 m-ones 0]
> >>      (if (empty? vectors)
> >>          [m-zeros m-ones]
> >>          (let [data (first vectors)
> >>                zeros (count-in 0 data)
> >>                ones (count-in 1 data)]
> >>             (recur (rest vectors) (if (> zeros ones) (inc m-zeros) m-zeros)
> >>                                   (if (> ones zeros) (inc m-ones) 
> >> m-ones))
>
> --
> Sent from my Android phone with K-9 Mail. Please excuse my brevity.

-- 
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: Enhanced Primitive Support

2010-06-19 Thread Mike Meyer

"Rob Lachlan"  wrote:

>Actually, Mike, your two functions work just fine.  (Equal branch).
>Mind you I checked that out over two hours ago, so this information
>might be out of date.
>
>Rob
>
>On Jun 19, 6:59 pm, Mike Meyer > (defn count-in [value col]
>>    (loop [value value col col res 0]
>>       (if (empty? col)
>>           res
>>           (recur value (rest col) (if (= (first col) value) (inc res) 
>> res)
>>
>> (defn ones-n-zeros [vectors]
>>   (loop [vectors vectors m-zeros 0 m-ones 0]
>>      (if (empty? vectors)
>>          [m-zeros m-ones]
>>          (let [data (first vectors)
>>                zeros (count-in 0 data)
>>                ones (count-in 1 data)]
>>             (recur (rest vectors) (if (> zeros ones) (inc m-zeros) m-zeros)
>>                                   (if (> ones zeros) (inc m-ones) 
>> m-ones))

-- 
Sent from my Android phone with K-9 Mail. Please excuse my brevity.

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


Re: How to use Clojure with Robocode

2010-06-19 Thread nakkaya
This answer is couple months too late but I was messing with robocode
this weekend, had the same problem OP had. The solution is to unzip
clojure.jar into the folder where your compiled class files are. That
makes the error go away but it will also increase robocode's boot time
by 20-30 secs.

Hope this helps...
--
Nurullah Akkaya
http://nakkaya.com

On Mar 19, 10:56 am, ubolonton  wrote:
> Hi,
>
> Has anyone been able to use Clojure with Robocode?
> I've followed thishttp://www.fatvat.co.uk/2009/05/clojure-and-robocode.html
> but got the error
>
> Round 1 initializing..
> Let the games begin!
> java.lang.ExceptionInInitializerError
>         at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native
> Method)
>         at
> sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAcce 
> ssorImpl.java:
> 39)
>         at
> sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstru 
> ctorAccessorImpl.java:
> 27)
>         at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
>         at java.lang.Class.newInstance0(Class.java:355)
>         at java.lang.Class.newInstance(Class.java:308)
>         at
> net.sf.robocode.host.security.RobotClassLoader.createRobotInstance(RobotCla 
> ssLoader.java:
> 272)
>         at
> net.sf.robocode.host.proxies.HostingRobotProxy.loadRobotRound(HostingRobotP 
> roxy.java:
> 201)
>         at
> net.sf.robocode.host.proxies.HostingRobotProxy.run(HostingRobotProxy.java:
> 242)
>         at java.lang.Thread.run(Thread.java:637)
> Caused by: java.lang.NullPointerException
>         at clojure.lang.Var.setMeta(Var.java:179)
>         at clojure.lang.Var.internPrivate(Var.java:96)
>         at ubolonton.MyRobot.(Unknown Source)
>         ... 10 more
>
> Thanks

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


Re: Enhanced Primitive Support

2010-06-19 Thread Rob Lachlan
I don't think my computer has enough memory to test that.  But, you're
right, I might have spoken hastily.

Rob

On Jun 19, 7:26 pm, Aaron Cohen  wrote:
> I actually believe it will throw an overflow exception if col contains
> more than Integer.MAX_VALUE elements. Hard to confirm without getting
> bored though.
>
> -- Aaron
>
>
>
> On Sat, Jun 19, 2010 at 10:19 PM, Rob Lachlan  wrote:
> > Actually, Mike, your two functions work just fine.  (Equal branch).
> > Mind you I checked that out over two hours ago, so this information
> > might be out of date.
>
> > Rob
>
> > On Jun 19, 6:59 pm, Mike Meyer  > 620...@mired.org> wrote:
> >> On Sat, 19 Jun 2010 20:40:13 -0400
>
> >> David Nolen  wrote:
> >> > Mark and Mike you fail to address my deeper question.
>
> >> Maybe because you've failed to ask in your hurry to claim code is
> >> non-idiomatic or calling our example rhetoric.
>
> >> > I've been using
> >> > many different Clojure libraries all day long with the latest equals
> >> > branch. Guess
> >> > what?
>
> >> > No loop/recur bugs.
>
> >> I wouldn't expect anything else, for two reasons:
>
> >> 1) Most clojure code doesn't deal with integers - it deals with
> >>    symbols, strings, and sequences. Hence it won't run into this problem.
> >> 2) The libraries are generally written by experienced users who will
> >>    have tweaked them for performance - meaning they've typed hinted
> >>    them, and thus avoided this problem.
>
> >> > When you guys start postIng your broken code that has this problem
> >> > then people can start believing it is an issue for working code.
>
> >> I guess a perfectly natural expression of a reasonable algorithm that
> >> works under 1.1 and doesn't on the equal branch isn't "broken" because
> >> it's the same function we've been using all along. So here's some new
> >> examples, pulled in sequence from some of my combinatorics code:
>
> >> (defn count-in [value col]
> >>    (loop [value value col col res 0]
> >>       (if (empty? col)
> >>           res
> >>           (recur value (rest col) (if (= (first col) value) (inc res) 
> >> res)
>
> >> (defn ones-n-zeros [vectors]
> >>   (loop [vectors vectors m-zeros 0 m-ones 0]
> >>      (if (empty? vectors)
> >>          [m-zeros m-ones]
> >>          (let [data (first vectors)
> >>                zeros (count-in 0 data)
> >>                ones (count-in 1 data)]
> >>             (recur (rest vectors) (if (> zeros ones) (inc m-zeros) m-zeros)
> >>                                   (if (> ones zeros) (inc m-ones) 
> >> m-ones))
>
> >> No, I haven't verified it fails - I've given up trying to check out
> >> the branch, as hg convert failed, and git (after reinstalling over a
> >> broken version) keeps complaining about "warning: remote HEAD refers
> >> to nonexistent ref, unable to checkout." However, my reading of the
> >> proposal is that the inc's here will cause the same problems as the
> >> *'s in the perfectly reasonable factorial example.
>
> >> Now go ahead and claim that that's not very good code, because an
> >> expert would have type hinted it or written it with map & apply or
> >> some such, or that there's a contrib library somewhere with a faster
> >> implementation of count-in in it. That, after all, is your rhetoric.
>
> >> But that's my point. I want the *obvious* code to work. I'll worry
> >> about making it fast after I've made it right. If you want a read-only
> >> language that requires an expert to get working code in a reasonable
> >> amount of time, you can always write in Perl or C.
>
> >>         >> --
> >> Mike Meyer           http://www.mired.org/consulting.html
> >> Independent Network/Unix/Perforce consultant, email for more information.
>
> >> O< ascii ribbon campaign - stop html mail -www.asciiribbon.org
>
> > --
> > You received this message because you are subscribed to the Google
> > Groups "Clojure" group.
> > To post to this group, send email to clojure@googlegroups.com
> > Note that posts from new members are moderated - please be patient with 
> > your first post.
> > To unsubscribe from this group, send email to
> > clojure+unsubscr...@googlegroups.com
> > For more options, visit this group at
> >http://groups.google.com/group/clojure?hl=en

-- 
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: Enhanced Primitive Support

2010-06-19 Thread Aaron Cohen
I actually believe it will throw an overflow exception if col contains
more than Integer.MAX_VALUE elements. Hard to confirm without getting
bored though.

-- Aaron

On Sat, Jun 19, 2010 at 10:19 PM, Rob Lachlan  wrote:
> Actually, Mike, your two functions work just fine.  (Equal branch).
> Mind you I checked that out over two hours ago, so this information
> might be out of date.
>
> Rob
>
> On Jun 19, 6:59 pm, Mike Meyer  620...@mired.org> wrote:
>> On Sat, 19 Jun 2010 20:40:13 -0400
>>
>> David Nolen  wrote:
>> > Mark and Mike you fail to address my deeper question.
>>
>> Maybe because you've failed to ask in your hurry to claim code is
>> non-idiomatic or calling our example rhetoric.
>>
>> > I've been using
>> > many different Clojure libraries all day long with the latest equals
>> > branch. Guess
>> > what?
>>
>> > No loop/recur bugs.
>>
>> I wouldn't expect anything else, for two reasons:
>>
>> 1) Most clojure code doesn't deal with integers - it deals with
>>    symbols, strings, and sequences. Hence it won't run into this problem.
>> 2) The libraries are generally written by experienced users who will
>>    have tweaked them for performance - meaning they've typed hinted
>>    them, and thus avoided this problem.
>>
>> > When you guys start postIng your broken code that has this problem
>> > then people can start believing it is an issue for working code.
>>
>> I guess a perfectly natural expression of a reasonable algorithm that
>> works under 1.1 and doesn't on the equal branch isn't "broken" because
>> it's the same function we've been using all along. So here's some new
>> examples, pulled in sequence from some of my combinatorics code:
>>
>> (defn count-in [value col]
>>    (loop [value value col col res 0]
>>       (if (empty? col)
>>           res
>>           (recur value (rest col) (if (= (first col) value) (inc res) 
>> res)
>>
>> (defn ones-n-zeros [vectors]
>>   (loop [vectors vectors m-zeros 0 m-ones 0]
>>      (if (empty? vectors)
>>          [m-zeros m-ones]
>>          (let [data (first vectors)
>>                zeros (count-in 0 data)
>>                ones (count-in 1 data)]
>>             (recur (rest vectors) (if (> zeros ones) (inc m-zeros) m-zeros)
>>                                   (if (> ones zeros) (inc m-ones) 
>> m-ones))
>>
>> No, I haven't verified it fails - I've given up trying to check out
>> the branch, as hg convert failed, and git (after reinstalling over a
>> broken version) keeps complaining about "warning: remote HEAD refers
>> to nonexistent ref, unable to checkout." However, my reading of the
>> proposal is that the inc's here will cause the same problems as the
>> *'s in the perfectly reasonable factorial example.
>>
>> Now go ahead and claim that that's not very good code, because an
>> expert would have type hinted it or written it with map & apply or
>> some such, or that there's a contrib library somewhere with a faster
>> implementation of count-in in it. That, after all, is your rhetoric.
>>
>> But that's my point. I want the *obvious* code to work. I'll worry
>> about making it fast after I've made it right. If you want a read-only
>> language that requires an expert to get working code in a reasonable
>> amount of time, you can always write in Perl or C.
>>
>>        > --
>> Mike Meyer           http://www.mired.org/consulting.html
>> Independent Network/Unix/Perforce consultant, email for more information.
>>
>> O< ascii ribbon campaign - stop html mail -www.asciiribbon.org
>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with your 
> first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en

-- 
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: Enhanced Primitive Support

2010-06-19 Thread Michał Marczyk
On 20 June 2010 03:59, Mike Meyer
 wrote:
> So here's some new
> examples, pulled in sequence from some of my combinatorics code:

This works fine as far as arithmetic ops are concerned, though I
suppose it might suffer from issues of = vs. == now (which is a
separate matter).

Sincerely,
Michał

-- 
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: Enhanced Primitive Support

2010-06-19 Thread Rob Lachlan
Actually, Mike, your two functions work just fine.  (Equal branch).
Mind you I checked that out over two hours ago, so this information
might be out of date.

Rob

On Jun 19, 6:59 pm, Mike Meyer  wrote:
> On Sat, 19 Jun 2010 20:40:13 -0400
>
> David Nolen  wrote:
> > Mark and Mike you fail to address my deeper question.
>
> Maybe because you've failed to ask in your hurry to claim code is
> non-idiomatic or calling our example rhetoric.
>
> > I've been using
> > many different Clojure libraries all day long with the latest equals
> > branch. Guess
> > what?
>
> > No loop/recur bugs.
>
> I wouldn't expect anything else, for two reasons:
>
> 1) Most clojure code doesn't deal with integers - it deals with
>    symbols, strings, and sequences. Hence it won't run into this problem.
> 2) The libraries are generally written by experienced users who will
>    have tweaked them for performance - meaning they've typed hinted
>    them, and thus avoided this problem.
>
> > When you guys start postIng your broken code that has this problem
> > then people can start believing it is an issue for working code.
>
> I guess a perfectly natural expression of a reasonable algorithm that
> works under 1.1 and doesn't on the equal branch isn't "broken" because
> it's the same function we've been using all along. So here's some new
> examples, pulled in sequence from some of my combinatorics code:
>
> (defn count-in [value col]
>    (loop [value value col col res 0]
>       (if (empty? col)
>           res
>           (recur value (rest col) (if (= (first col) value) (inc res) res)
>
> (defn ones-n-zeros [vectors]
>   (loop [vectors vectors m-zeros 0 m-ones 0]
>      (if (empty? vectors)
>          [m-zeros m-ones]
>          (let [data (first vectors)
>                zeros (count-in 0 data)
>                ones (count-in 1 data)]
>             (recur (rest vectors) (if (> zeros ones) (inc m-zeros) m-zeros)
>                                   (if (> ones zeros) (inc m-ones) m-ones))
>
> No, I haven't verified it fails - I've given up trying to check out
> the branch, as hg convert failed, and git (after reinstalling over a
> broken version) keeps complaining about "warning: remote HEAD refers
> to nonexistent ref, unable to checkout." However, my reading of the
> proposal is that the inc's here will cause the same problems as the
> *'s in the perfectly reasonable factorial example.
>
> Now go ahead and claim that that's not very good code, because an
> expert would have type hinted it or written it with map & apply or
> some such, or that there's a contrib library somewhere with a faster
> implementation of count-in in it. That, after all, is your rhetoric.
>
> But that's my point. I want the *obvious* code to work. I'll worry
> about making it fast after I've made it right. If you want a read-only
> language that requires an expert to get working code in a reasonable
> amount of time, you can always write in Perl or C.
>
>         --
> Mike Meyer           http://www.mired.org/consulting.html
> Independent Network/Unix/Perforce consultant, email for more information.
>
> O< ascii ribbon campaign - stop html mail -www.asciiribbon.org

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


Re: Enhanced Primitive Support

2010-06-19 Thread Michał Marczyk
On 20 June 2010 02:13, David Nolen  wrote:
> On Sat, Jun 19, 2010 at 4:10 PM, Michał Marczyk
>  wrote:
>> (defn fact [n]
>>  (loop [n n r 1]
>>    (if (zero? n)
>>      r
>>      (recur (dec n) (* r n)
> Huh? That doesn't look like it's going to work at all.
> 1) 1 is primitive, we know that, accept it
> 2) we don't know the type of n, what will (* r n) be?
> 3) BOOM!

Yes, I know what's going on, after reading through this rather lengthy
thread and participating in / listening in on a number of exchanges on
#clojure. I still find the notion that this code "doesn't look like
it's going to work at all" to be fairly surprising. (Also, I'd rather
not refactor a private loop so that it becomes exposed to the outside
world (presumably to be instructed to ignore the binary overload), but
that is beside the point. The (num ...) hint is a simple enough
solution, which incidentally I'd be able to live with if things were
not to go the way I prefer.)

I wanted to address the pre-BOOM points above, though:

1) With the other approach being proposed, this would read something
like "1 is primitive in primitive contexts, but will get boxed if used
as an initialiser for an unhinted local". That's rather a significant
improvement over the stylistically matching description of the
1.2-master (& 1.1) state of affairs (which I'll omit from here while
noting that apparently acceptance was pretty low on that). I'm very
happy to see Clojure moving forward w.r.t. the way in which top
numeric performance can be achieved; that leaves plenty of room for
doubting whether it should be the outright default. So, how about we
address this point...?

2) That is in fact precisely the reason why I find it odd to presume
that we know the desired type of r based on the literal alone.

The question I wanted to pose when posting that factorial example was this:

Should basic arithmetic work with no explicit hints / casts / primed
ops / whatever -- or not necessarily?

This seems like a valid question to me. If the answer is "not
necessarily", I'll probably be able to get used to the idea; if it is
"yes", or at least "hopefully", then perhaps there's something left to
tweak / change etc. Note that if there was a way to have
primitive-by-default arithmetic, yet also have naive arithmetic code
work without hinting, this would be orthogonal to the issue of the
choice of default. (In fact, it could affect my personal preference,
or at least the degree to which I care about it.)

Sincerely,
Michał

-- 
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: Enhanced Primitive Support

2010-06-19 Thread Mike Meyer
On Sat, 19 Jun 2010 20:40:13 -0400
David Nolen  wrote:

> Mark and Mike you fail to address my deeper question.

Maybe because you've failed to ask in your hurry to claim code is
non-idiomatic or calling our example rhetoric.

> I've been using
> many different Clojure libraries all day long with the latest equals
> branch. Guess
> what?
> 
> No loop/recur bugs.

I wouldn't expect anything else, for two reasons:

1) Most clojure code doesn't deal with integers - it deals with
   symbols, strings, and sequences. Hence it won't run into this problem.
2) The libraries are generally written by experienced users who will
   have tweaked them for performance - meaning they've typed hinted
   them, and thus avoided this problem.

> When you guys start postIng your broken code that has this problem
> then people can start believing it is an issue for working code.

I guess a perfectly natural expression of a reasonable algorithm that
works under 1.1 and doesn't on the equal branch isn't "broken" because
it's the same function we've been using all along. So here's some new
examples, pulled in sequence from some of my combinatorics code:

(defn count-in [value col]
   (loop [value value col col res 0]
  (if (empty? col)
  res
  (recur value (rest col) (if (= (first col) value) (inc res) res)

(defn ones-n-zeros [vectors]
  (loop [vectors vectors m-zeros 0 m-ones 0]
 (if (empty? vectors)
 [m-zeros m-ones]
 (let [data (first vectors)
   zeros (count-in 0 data)
   ones (count-in 1 data)]
(recur (rest vectors) (if (> zeros ones) (inc m-zeros) m-zeros)
  (if (> ones zeros) (inc m-ones) m-ones))

No, I haven't verified it fails - I've given up trying to check out
the branch, as hg convert failed, and git (after reinstalling over a
broken version) keeps complaining about "warning: remote HEAD refers
to nonexistent ref, unable to checkout." However, my reading of the
proposal is that the inc's here will cause the same problems as the
*'s in the perfectly reasonable factorial example.

Now go ahead and claim that that's not very good code, because an
expert would have type hinted it or written it with map & apply or
some such, or that there's a contrib library somewhere with a faster
implementation of count-in in it. That, after all, is your rhetoric.

But that's my point. I want the *obvious* code to work. I'll worry
about making it fast after I've made it right. If you want a read-only
language that requires an expert to get working code in a reasonable
amount of time, you can always write in Perl or C.

http://www.mired.org/consulting.html
Independent Network/Unix/Perforce consultant, email for more information.

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

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


Re: need help understanding two issues

2010-06-19 Thread Michał Marczyk
On 19 June 2010 18:59, Albert Cardona  wrote:
> 1. How come APersistentMap$KeySet doesn't implement IPersistentSet?

Beyond what Rob has already written above, keys works with
APersistentMap$KeySeq (note the "q" at the end), not
APersistentMap$KeySet. To get at the latter, use (.keySet {:a 1 :b
2}); you'll get back a java.util.Set of two entries, :a and :b. This
is mainly an interop feature, I believe (meant to make it easier for
non-Clojure code on the JVM to read Clojure data structures directly).

clojure.set/intersection knows how to handle java.util.Set instances,
though in this case, using (comp set keys) -- that is, normally, (set
(keys ...)) -- is the more usual and overall more sensible way to go.

> 2. I can't get clojure.set/project to work.

clojure.set/project is meant to implement the projection operator of
[Relational algebra](http://en.wikipedia.org/wiki/Relational_algebra).

The representation of relations assumed here is a "collection of
tuples", which makes sense: the mathematical definition of a relation
-- the one used in relational algebra -- is "a set of tuples". The
tuples are here represented as maps. Of course in a mathematical
relation all tuples have the same "format"; in Clojure, if some of the
maps happen to be missing some of the keys present in some of the
other maps, the overall semantics are very much (if not exactly) as if
they had those keys bound to nil (as the usual Clojure semantics for
maps would imply).

Now the projection operator takes a relation and throws out some of
its attributes (or some of the columns if you visualise it as a table;
or if you think of a set of tuples, it removes some axes from all the
tuples). The result is still a relation, i.e. a set, meaning in
particular that there are no duplicates:

(clojure.set/project #{{:foo 1 :bar 2} {:foo 1 :bar 3}} [:foo])

returns #{{:foo 1}}, because once we throw out the :bars, the two
tuples from the input relation become indistinguishable on the basis
of the remaining :foo attribute and "blend together" into just one
tuple in the output relation.

An example where the projection is larger:

(clojure.set/project #{{:foo 1 :bar 2} {:foo 2 :quux 3}} [:foo])
; => #{{:foo 1} {:foo 2}}

So, that's how it's supposed to work. Your final example should
perhaps fail more gracefully -- the first argument to
clojure.set/project cannot be a map (which is by definition a
collection of map entries and not of maps, as required here). As
things stand, it gives a weird result due to clojure.set/project using
select-keys, which in turn uses clojure.lang.RT/find, which happens to
return nils when it's called with an argument which makes no sense (in
addition to returning nil when the argument does make sense -- i.e. is
a map -- but the given key is not found).

Sincerely,
Michał

-- 
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: Enhanced Primitive Support

2010-06-19 Thread David Nolen
Mark and Mike you fail to address my deeper question. I've been using
many different Clojure libraries all day long with the latest equals
branch. Guess
what?

No loop/recur bugs.

When you guys start postIng your broken code that has this problem
then people can start believing it is an issue for working code.

Until then this is just theoretical rhetoric.

On Saturday, June 19, 2010, Mark Engelberg  wrote:
> On Sat, Jun 19, 2010 at 5:13 PM, David Nolen  wrote:
>> Huh? That doesn't look like it's going to work at all.
>> 1) 1 is primitive, we know that, accept it
>> 2) we don't know the type of n, what will (* r n) be?
>> 3) BOOM!
>
> Yes David, if you have a deep understanding of how loop/recur
> interacts with primitives, and you understand that n, as an input is
> boxed and that literals are primitives, it is of course possible to do
> the analysis and see why it doesn't work.
>
> But it does look like it *should* work -- in current Clojure it works,
> and the same kind of code in just about any dynamically typed language
> I can think of would work.  It might not work in a statically typed
> language, but the types would be right there in your face, so it would
> be totally obvious what was going on.  The problem is that the
> behavior is dependent on something that is invisible from the code,
> and requires considerable reasoning even for this simple example.
>
>> My suggestion is to stop it with the contrived examples. Start showing some
>> real code, real problems in your real programs. Using loop/recur is already
>> the beginning of code smell for anything that is not performance sensitive.
>
> I think the notion that loop/recur is a code smell for anything that
> isn't performance sensitive is absurd.  It's basically the only
> looping mechanism that Clojure offers - it's in all types of code.
>
>> (defn fact
>>   ([n] (fact n 1))
>>   ([n r] (if (zero? n)
>>           r
>>           (recur (dec n) (* r n)
>> Sleep soundly.
>
> The fact that this refactoring of the fact function fixes the problem
> further bolsters our argument that the newly proposed semantics are
> significantly more inscrutable than they should be.  Without a fair
> amount of thought, it's completely unobvious why this refactoring
> should fix the problem.  (Yes, I know it's because it boxes the 1 when
> it passes it to the two-arg version, but stuff like this really
> shouldn't make such a significant difference in behavior).
>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with your 
> first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en

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


Re: Enhanced Primitive Support

2010-06-19 Thread Rob Lachlan
The main example for recur on the special forms page (http://
clojure.org/special_forms#Special%20Forms--(recur%20exprs*)) is:

(def factorial
  (fn [n]
(loop [cnt n acc 1]
   (if (zero? cnt)
acc
  (recur (dec cnt) (* acc cnt))

I may not be be clojure jedi, but I've been learning the language for
a while.  I've never come across the notion that this is a code
smell.  I thought that the loop recur form was perfectly orthodox.

Also, the fact that the form above doesn't compile in the equal branch
does make me a little uneasy.

Rob

On Jun 19, 5:13 pm, David Nolen  wrote:
> On Sat, Jun 19, 2010 at 4:10 PM, Michał Marczyk
>
>  wrote:
> > (defn fact [n]
> >  (loop [n n r 1]
> >    (if (zero? n)
> >      r
> >      (recur (dec n) (* r n)
>
> Huh? That doesn't look like it's going to work at all.
>
> 1) 1 is primitive, we know that, accept it
> 2) we don't know the type of n, what will (* r n) be?
> 3) BOOM!
>
> My suggestion is to stop it with the contrived examples. Start showing some
> real code, real problems in your real programs. Using loop/recur is already
> the beginning of code smell for anything that is not performance sensitive.
>
> (defn fact
>   ([n] (fact n 1))
>   ([n r] (if (zero? n)
>           r
>           (recur (dec n) (* r n)
>
> Sleep soundly.

-- 
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: Enhanced Primitive Support

2010-06-19 Thread Mike Meyer
On Sat, 19 Jun 2010 20:13:07 -0400
David Nolen  wrote:

> On Sat, Jun 19, 2010 at 4:10 PM, Michał Marczyk
>  wrote:
> > (defn fact [n]
> >  (loop [n n r 1]
> >(if (zero? n)
> >  r
> >  (recur (dec n) (* r n)
> 
> Huh? That doesn't look like it's going to work at all.
> 
> 1) 1 is primitive, we know that, accept it
> 2) we don't know the type of n, what will (* r n) be?
> 3) BOOM!
> 
> My suggestion is to stop it with the contrived examples. Start showing some
> real code, real problems in your real programs. Using loop/recur is already
> the beginning of code smell for anything that is not performance sensitive.

Oh, come on. I didn't write that example, but it's a perfect
reasonable implementation of the factorial loop algorithm.

I'd say that you're calling "using loop/recur" a code smell is itself
a smell, indicating that loop/recur is broken.

http://www.mired.org/consulting.html
Independent Network/Unix/Perforce consultant, email for more information.

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

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


Re: Enhanced Primitive Support

2010-06-19 Thread Mark Engelberg
On Sat, Jun 19, 2010 at 5:13 PM, David Nolen  wrote:
> Huh? That doesn't look like it's going to work at all.
> 1) 1 is primitive, we know that, accept it
> 2) we don't know the type of n, what will (* r n) be?
> 3) BOOM!

Yes David, if you have a deep understanding of how loop/recur
interacts with primitives, and you understand that n, as an input is
boxed and that literals are primitives, it is of course possible to do
the analysis and see why it doesn't work.

But it does look like it *should* work -- in current Clojure it works,
and the same kind of code in just about any dynamically typed language
I can think of would work.  It might not work in a statically typed
language, but the types would be right there in your face, so it would
be totally obvious what was going on.  The problem is that the
behavior is dependent on something that is invisible from the code,
and requires considerable reasoning even for this simple example.

> My suggestion is to stop it with the contrived examples. Start showing some
> real code, real problems in your real programs. Using loop/recur is already
> the beginning of code smell for anything that is not performance sensitive.

I think the notion that loop/recur is a code smell for anything that
isn't performance sensitive is absurd.  It's basically the only
looping mechanism that Clojure offers - it's in all types of code.

> (defn fact
>   ([n] (fact n 1))
>   ([n r] (if (zero? n)
>           r
>           (recur (dec n) (* r n)
> Sleep soundly.

The fact that this refactoring of the fact function fixes the problem
further bolsters our argument that the newly proposed semantics are
significantly more inscrutable than they should be.  Without a fair
amount of thought, it's completely unobvious why this refactoring
should fix the problem.  (Yes, I know it's because it boxes the 1 when
it passes it to the two-arg version, but stuff like this really
shouldn't make such a significant difference in behavior).

-- 
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: Enhanced Primitive Support

2010-06-19 Thread Peter Schuller
> Where can I get jar files of the various branches so I can test for
> myself without having to deploy whatever infrastructure is needed to
> build clojure these days? Or am I likely to be able to build them with
> tools found in the BSD ports tree?

It still seems to build with 'ant' like it always has for me? Install
devel/apache-ant and simply run 'ant' in the clojure checkout.

If you want to get the maven artifact installed in your local
repository for use with leiningen/maven projects, you first want to
install devel/maven2. The complication is that clojure is not built by
maven (normally you would just 'mvn install'), but instead is built
with Ant with it's maven tasks. So, you need to drop in:

   http://www.apache.org/dyn/closer.cgi/maven/binaries/maven-ant-tasks-2.1.0.jar

Into ~/.ant/lib so that ant can pick that up. Afterwards, you should
be able to run:

  ant ci-build

And that should install (although it does so very silently) clojure
into your (user) local maven repository:

  ls -ltr ~/.m2/repository/org/clojure/clojure/1.2.0-master-SNAPSHOT

-- 
/ Peter Schuller

-- 
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: Enhanced Primitive Support

2010-06-19 Thread David Nolen
On Sat, Jun 19, 2010 at 4:10 PM, Michał Marczyk
 wrote:
> (defn fact [n]
>  (loop [n n r 1]
>(if (zero? n)
>  r
>  (recur (dec n) (* r n)

Huh? That doesn't look like it's going to work at all.

1) 1 is primitive, we know that, accept it
2) we don't know the type of n, what will (* r n) be?
3) BOOM!

My suggestion is to stop it with the contrived examples. Start showing some
real code, real problems in your real programs. Using loop/recur is already
the beginning of code smell for anything that is not performance sensitive.

(defn fact
  ([n] (fact n 1))
  ([n r] (if (zero? n)
  r
  (recur (dec n) (* r n)

Sleep soundly.

-- 
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: Enhanced Primitive Support

2010-06-19 Thread Mark Engelberg
On Sat, Jun 19, 2010 at 4:10 PM, Michał Marczyk
 wrote:
> (defn fact [n]
>  (loop [n n r 1]
>    (if (zero? n)
>      r
>      (recur (dec n) (* r n)

Thanks for posting this surprisingly simple example of something that
looks like it should work, but wouldn't under the current proposal.
Really demonstrates how even for straightforward programs you would
have to do a certain amount of "type flow" analysis to verify that it
will compile.

-- 
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: Enhanced Primitive Support

2010-06-19 Thread Michał Marczyk
On 19 June 2010 23:51, Mike Meyer
 wrote:
> In any case, I don't think 10% is enough gain to justify narrowing the
> range for which naive programs are correct. An order of magnitude
> would be. A factor of two is a maybe.

QFT!

Have a look at this:

(defn fact [n]
  (loop [n n r 1]
(if (zero? n)
  r
  (recur (dec n) (* r n)

This doesn't compile. To make it compile, the initial value of r has
to be given as (num 1) *or* the initial binding of the "inner" n has
to be given as (long n). Changing the ops to *' and dec' rules out the
latter option, but the (num ...) hint on r is still required. Not
surprisingly having r start off with (Long. 1) solves makes this
compile too.

The summary is that I'm finding it impossible to write a standard
tail-recursive factorial function without type hints on my literals. I
suppose I can guess what the reason is by now, but I find it
unreasonably confusing. Not sure to which degree this can be ironed
out if boxing were to remain an opt-in rather than -out...?

Oh, just in case votes on this are of interest, I like the idea of
loop' for fast-by-default looping.

Sincerely,
Michał

-- 
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: Enhanced Primitive Support

2010-06-19 Thread Michał Marczyk
On 19 June 2010 16:43, David Nolen  wrote:
> "Most real world programs". You mean like Clojure itself?
> Please look over the implementation of gvec before making statements like
> this:

Surely Clojure's internals are a *very* special case though... I
wouldn't find it particularly worrying if they turned out to require
some hinting.

I suppose even Ruby 1.8 must have its fair share of full-speed C math
under the hood (disclaimer: I'm not a Rubyist though, so I never cared
to check), which has nothing to do with the performance of math in
user programmes, which is what I interpreted Mike's statement to be
referring to.

Sincerely,
Michał

-- 
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: Enhanced Primitive Support

2010-06-19 Thread Mike Meyer
On Sat, 19 Jun 2010 22:27:05 +0100
Nicolas Oury  wrote:

> On Sat, Jun 19, 2010 at 10:15 PM, Mike Meyer  wrote:
> > Pretty much any time I really need integer speed, I also deal with
> > numbers that can get much larger than 10^19th, because I tend to be
> > doing combinatorics or cryptography.
> But you would agree that for this kind of domain, it wouldn't be too bad to
> be explicit about
> wanting bigint. If you write a program that work with XML, you don't ask
> clojure data to be
> encoded in XML.

Yes, I would agree. The real issue is that when I say "gimme bigints",
it happens pretty much everywhere, so I don't have to worry about
overlooking some quantity that might overflow. I suppose this cuts
both ways - when you want primitives, you want them everywhere, so you
don't have to worry about overlooking some heavily used quantity
somewhere.

The difference is, I'm worried about getting the correct answer, but
you're worried about performance. You can profile your code to
identify where the time is going (in fact, you should have already
done that before adding the first annotation) to make sure you don't
overlook anything. The only automated tool I've got for finding
overflows is - well, to run into them. Having to fix them and repeat
the run pretty thoroughly negates any win I might have gotten out of
using primitive arithmetic where I could.

> > True, this represents a small fraction of all programs. The question
> > I'd really like answered is how much difference does this make for
> > non-numeric clojure code, where only a few percent of the calls to
> > core functions are calls to integer ops.
> I tried on some code with 1/2 ops per functions and already quite a dew
> annotations. 10% speed-up in a program that spend 80% in Object.hashCode
> (which does not get accelerated at all).

Not quite what I wanted, for at least one reason (preexisting
annotations) and possibly because you should be comparing the two
variants of the appropriate branch, instead of comparing that branch
with either 1.1 or the current master.

In any case, I don't think 10% is enough gain to justify narrowing the
range for which naive programs are correct. An order of magnitude
would be. A factor of two is a maybe.

> I think that's due to the 1/2 ops + the ops hidden in clojure library code.
> I'd like to see more results like that and bugs in real programs.
> It was a matter of minutes to try.
> - pull the branch with git
> - compile with ant
> - replace your clojure.jar
> - recompile.

Except you have to do it twice, and get correct timings. It would
really help if someone could provide precompiled jars with an
appropriate README.

http://www.mired.org/consulting.html
Independent Network/Unix/Perforce consultant, email for more information.

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

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


Re: Enhanced Primitive Support

2010-06-19 Thread Nicolas Oury
On Sat, Jun 19, 2010 at 10:15 PM, Mike Meyer  wrote:

>
>
> Pretty much any time I really need integer speed, I also deal with
> numbers that can get much larger than 10^19th, because I tend to be
> doing combinatorics or cryptography.
>
> But you would agree that for this kind of domain, it wouldn't be too bad to
be explicit about
wanting bigint. If you write a program that work with XML, you don't ask
clojure data to be
encoded in XML.



> True, this represents a small fraction of all programs. The question
> I'd really like answered is how much difference does this make for
> non-numeric clojure code, where only a few percent of the calls to
> core functions are calls to integer ops.
>
>
I tried on some code with 1/2 ops per functions and already quite a dew
annotations. 10% speed-up in a program that spend 80% in Object.hashCode
(which does not get accelerated at all).
I think that's due to the 1/2 ops + the ops hidden in clojure library code.
I'd like to see more results like that and bugs in real programs.
It was a matter of minutes to try.
- pull the branch with git
- compile with ant
- replace your clojure.jar
- recompile.

-- 
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: Enhanced Primitive Support

2010-06-19 Thread Mike Meyer
On Sat, 19 Jun 2010 20:20:48 +0100
Nicolas Oury  wrote:

> Not "ordinary" code. 10^19 is big.

No, Aleph-2 is big. Any non-infinite number you can name in your
lifetime is small ;-).

Pretty much any time I really need integer speed, I also deal with
numbers that can get much larger than 10^19th, because I tend to be
doing combinatorics or cryptography.

True, this represents a small fraction of all programs. The question
I'd really like answered is how much difference does this make for
non-numeric clojure code, where only a few percent of the calls to
core functions are calls to integer ops.

  http://www.mired.org/consulting.html
Independent Network/Unix/Perforce consultant, email for more information.

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

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


Re: Enhanced Primitive Support

2010-06-19 Thread Mike Meyer
While I generally favor correct over fast (worrying about fast before
you're correct is a good sign that you're engaged in premature
optimization), I'm still trying to figure out the tradeoffs
here. Especially since most LISPs & other dynamic languages don't seem
to run into this issue - or at least the debate that we're seeing
here.

IIUC, the problem is that we've got three "kinds" (not types; which
normally refers to bit lengths) of integer:

primitive, which is what the JVM does it's math with.
boxed, which is the primitive wrapped in a Java object, and what Java
   normally uses.
bigint, which is a clojure-specific kind of integer.

Other numeric types don't have issues because they don't have all
three kinds (is that right? Or could this entire thread be rewritten
in terms of primitive vs. boxed floats?).

And the bottom line is that for some reason we can't get from
primitives (which are required for speed) to bigints (which are
required to maximize the domain for which we get correct answers)
automatically. 

Assuming that that's right, the first question that occurs to me is:
Does clojure really need java's boxed types? Other than for java
interop, of course. 

Again, other languages seem to get by with the platform primitives
(module tweaks to get type information) going to bigints, and to get
reasonable performance by throwing away the dynamic nature of the
language for the hot spots. Could clojure do something similar, or is
this something technical issue with the JVM, similar to the reason we
don't get TCE?

   http://www.mired.org/consulting.html
Independent Network/Unix/Perforce consultant, email for more information.

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

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


Re: Enhanced Primitive Support

2010-06-19 Thread Mike Meyer
On Sat, 19 Jun 2010 10:43:36 -0400
David Nolen  wrote:

> On Sat, Jun 19, 2010 at 5:13 AM, Mike Meyer <
> mwm-keyword-googlegroups.620...@mired.org> wrote:
> >
> >
> > Were those real world programs, or arithmetic benchmarks? Most real world
> > programs I see spend so little of their time doing arithmetic that making
> > the math an order of magnitude slower wouldn't make a noticeable difference
> > in overall runtime.
> >
> 
> "Most real world programs". You mean like Clojure itself?
> 
> Please look over the implementation of gvec before making statements like
> this:

This is actually the what I'm trying to figure out. While *my* code
may have no explicit arithmetic in it, it's not clear without diving
into the guts of clojure how much arithmetic gets done in it's name by
things like gvec.

http://www.mired.org/consulting.html
Independent Network/Unix/Perforce consultant, email for more information.

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

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


Re: Enhanced Primitive Support

2010-06-19 Thread Mike Meyer
On Sat, 19 Jun 2010 11:00:39 +0100
Nicolas Oury  wrote:
>  There is a bit of arithmetic involved everywhere, and around 2-3 double
> operations per function in the part choosing the instance of rule to apply.

That still sounds arithmetic-heavy to me. In looking through my code,
I find three different classes of algorithm:

1) Things that are hard-core number-crunching, which for me is usually
   either combinatorics or crypto, where bigint is either a necessity
   or a major convenience.

2) Searches of various kinds, where most of the code manipulates
   trees/graphs to be searched with no (explicit) arithmetic, and one
   function evaluates a node with maybe a half-dozen arithmetic ops,
   meaning an average of <1 arithmetic op per function.

3) Everything else (web hacks, database stuff, string processing,
   etc.) where there's basically *no* arithmetic.

I guess the real question I should be asking is:

Where can I get jar files of the various branches so I can test for
myself without having to deploy whatever infrastructure is needed to
build clojure these days? Or am I likely to be able to build them with
tools found in the BSD ports tree?

   http://www.mired.org/consulting.html
Independent Network/Unix/Perforce consultant, email for more information.

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

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


Re: Enhanced Primitive Support

2010-06-19 Thread Brian Goslinga
On Jun 19, 2:24 pm, Mark Engelberg  wrote:
> On Sat, Jun 19, 2010 at 12:20 PM, Nicolas Oury  wrote:
> > Not "ordinary" code. 10^19 is big.
>
> Nicolas, I think you misunderstand my point.  I'm talking about
> loop/recur behavior.  If you initialize a loop with the literal 1, and
> then recur with a number 2 that's pulled from a collection (and thus
> boxed), it will break.  That's ordinary code.
What if loop had its current functionality, but if one tries to recur
with a different type, the affected loop variable becomes
automatically boxed (and if *warn-on-reflection* or a similar variable
is set, the compiler emits an note)?  What would be the downside of
this approach?  All of the code that currently works correctly with
the current state of the equal branch remains fast, and all of these
examples of bad behaviour should just work, and the programmer should
be able to ask to know about them.

-- 
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: Enhanced Primitive Support

2010-06-19 Thread Garth Sheldon-Coulson
Do any of the proposals on the table affect floating point math?

Currently, it seems mildly inconsistent to me that Clojure's numeric
operations are auto-promoting and arbitrary-precision for integers but not
for floats unless you specifically request it with the M suffix. This
probably matters only to people doing scientific computing, but it's
something to think about.

To illustrate with a question: If we were to make "fast" the default and
"correct" something you opt into with the primed operators and (num ), then does the question arise whether BigDecimals (as opposed to
doubles) are returned from (num ) and (*'  )?

-- 
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: Enhanced Primitive Support

2010-06-19 Thread Mark Engelberg
On Sat, Jun 19, 2010 at 12:20 PM, Nicolas Oury  wrote:
> Not "ordinary" code. 10^19 is big.

Nicolas, I think you misunderstand my point.  I'm talking about
loop/recur behavior.  If you initialize a loop with the literal 1, and
then recur with a number 2 that's pulled from a collection (and thus
boxed), it will break.  That's ordinary code.

-- 
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: Enhanced Primitive Support

2010-06-19 Thread Jules
On Jun 19, 3:53 pm, Rich Hickey  wrote:
> On Jun 19, 2010, at 6:39 AM, Jules wrote:
>
>
>
>
>
> > I know nothing about the JVM, but I do know that on x86 you can handle
> > fixnum -> bignum promotion fairly cheaply. You compile two versions of
> > the code: one for bignums and one for fixnums. After an arithmetic
> > instruction in the fixnum code you check if it overflowed, and if it
> > did you switch to the bignum code.
>
> > while(n < 10) {
> >  n = n + 1;
> > }
>
> > =>
>
> > while(n #< 10) {
> >   a = n #+ 1;
> >   if(overflow){ n = ToBignum(n); goto foo; }
> >   n = a;
> > }
>
> > while(n.lessthan(10)) {
> > foo:
> >   n = n.add(1);
> > }
>
> > where #< and #+ are the fixnum versions of < and +, and lessthan and
> > add are the bignum versions. Yeah it's slower than ignoring the
> > overflow, but faster than tagged 31-bit fixnums and a whole lot faster
> > than bignums. Can you convince the JVM to produce similar code?
>
> You can do things like that in a closed world of a few operators and  
> types (although it gets unwieldy as the number of variables goes up).  
> And of course, inside the math ops Clojure already does things like  
> that.
>
> But that is not what we are dealing with here. This is an open system,  
> where representational issues of functions, arguments and returns come  
> into play. The 'operators' +, - etc are actually function calls - they  
> are not special to the compiler. And your loop may also contain other  
> function calls:
>
> while(n < 10) {
>   foo(n)
>   n = n + 1;
>
> }
>
> how do I know foo can handle the bigint once I've upgraded?
>
> How about this?
>
> while(n < 10) {
>   n = foo(n)
>
> }
>
> Unless you have a tagged architecture you can't have boxed/unboxed arg/
> return uniformity (and even then you lose some bits of range).
>
> Rich

There are two possibilities: either foo gets inlined and the same
optimization is applied to the inlined code. Or foo is not inlined and
then you pass the general boxed representation to foo (but inside foo
the same optimization will be applied).

Suppose that we have a boxed representation like this:

class Num { ... }
class Small {
  int val;
  Num add(int n){ // argument specialized to int for simplicity of
this example
int sum = val + n;
if(overflow) return val.toBig().add(n);
else return new Small(sum);
  }
  ...
}
class Big {
  BigNum val;
  Num add(int n){ ... }
}

Now the while loop. I use functional notation because the control flow
is hairy and with while loops this leads to a lot of reorganization.
With functional notation it's easier to see that every step is simple
and mechanical.

Here's our while loop and the library function to add two numbers:

loop(n) = if p(n) then n else loop(add(n,1))
add(Small a, int b) = let sum = a.val+b in if overflow then
add(Big(a.val),b) else Small(sum)
add(Big a, int b) = bigAdd(a,b)

Inline add into the loop:

loop(Small n) = if p(n) then n else let sum = n.val+1 in if overflow
then loop(add(Big(n.val),1)) else loop(Small(sum))
loop(Big n) = if p(n) then n else loop(bigAdd(n,1))

Introduce a new name:

loop_small(n) = if p(n) then n else let sum = n.val+1 in if overflow
then loop(add(Big(n.val),1)) else loop(Small(sum))
loop(Small n) = loop_small(n)
loop(Big n) = if p(n) then n else loop(bigAdd(n,1))

Inline loop into loop_small and eliminate dead code, turning
loop(Small(sum)) into loop_small(Small(sum)):

loop_small(n) = if p(n) then n else let sum = n.val+1 in if overflow
then loop(add(Big(n.val),1)) else loop_small(Small(sum))
loop(Small n) = loop_small(n)
loop(Big n) = if p(n) then n else loop(bigAdd(n,1))

Note that we have eliminated the checks (in this case pattern
matching) from the loop_small loop! Inlining + dead code elimination
did the trick. Sure, we are still using a boxed representation in
loop_small, but it's not polymorphic anymore and standard algorithms
can turn the heap allocated Small instances into stack allocated local
int variables (essentially "inlining" the Small class' instance
variables into the local variables, in this case only val).

It's not trivial to build a compiler that does this, but it's not
impossible either. Perhaps the JVM already does some of this. You can
get best of both worlds: speed *and* correctness. The situation is not
"pick one: speed, correctness", it is "pick two: speed, correctness,
simple compiler".

Jules

-- 
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: Enhanced Primitive Support

2010-06-19 Thread Nicolas Oury
Not "ordinary" code. 10^19 is big.

On Sat, Jun 19, 2010 at 8:08 PM, Mark Engelberg wrote:

>
> Agreed, but with a default of boxing, it is possible to write all code
> without ever using an annotation -- it will just be a bit slower than
> it could be.  With a default of primitives, there is ordinary code
> that won't work properly unless you dig deeper into Clojure and learn
> all about explicit boxing and figure out when and where to use it.  I
> prefer the default where I c

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

Re: Enhanced Primitive Support

2010-06-19 Thread Mark Engelberg
On Sat, Jun 19, 2010 at 6:32 AM, Rich Hickey  wrote:
> Really? It seems tedious to me.  Don't you get tired of saying int i = 42 in
> Java, when you know full well the compiler knows 42 is an int? I do, and
> Clojure is competing with languages that infer the right types without the
> redundancy.

In this case, the question isn't so much whether Clojure can figure
out that 42 is a primitive or boxed integer.  The question is whether
the programmer wants to insist that, upon recurrence, the
primitiveness must match the initial binding.  Right now, Clojure
makes the determination about what the recurrence needs to be based on
the initial binding, so it becomes paramount for the programmer to
understand the type of that initial binding.  But conceivably there
are other ways that Clojure could make a determination about what kind
of loop/recur behavior you want other than the type of the initial
binding.  So an alternative way to think about this is to relax the
restriction that a recur must match the primitiveness of the loop
binding, but allow the programmer to somehow control whether they want
this primitive-matching behavior or not.  Ideally, the behavior of
recur should be readily apparent from inspection of the code.
Unfortunately, the type of the initial binding is not always clear,
which suggests to me that another scheme would be preferable.

Sadly, I don't have any idea right now on how to cleanly specify the
desired loop/recur behavior other than something that looks a lot like
type annotations.  But thinking of it in this way opens up the
possibility of other solutions (such as a loop' construct), so maybe
brainstorming along these lines will be useful.  I agree with another
poster that the holy grail would be if loop/recur automagically gave
performance benefits when recurring with a primitive that matched the
initial binding, but if you recur with something else, it just
gracefully rolls over to a boxed version of the whole loop.  Given
that Java has no way of expressing that something can be a primitive
or an Object, this seems unlikely to be possible, but perhaps with
that ideal in mind, some approximation can be found.

> Again, it is a matter of defaults, the non-default is going to have to be
> explicit, and you can just as easily be explicit that you want the loop
> argument to be an Object, either with (loop [^Object i 42] ...), (loop [i
> (num 42)] ...) or your (loop' [i 42] ...) idea.

Agreed, but with a default of boxing, it is possible to write all code
without ever using an annotation -- it will just be a bit slower than
it could be.  With a default of primitives, there is ordinary code
that won't work properly unless you dig deeper into Clojure and learn
all about explicit boxing and figure out when and where to use it.  I
prefer the default where I can ignore tedious type annotations and my
code "just works".

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


Re: Clojure script in the classpath

2010-06-19 Thread Paul Moore
On 19 June 2010 17:22, Chas Emerick  wrote:
> If you're just looking to run a script that happens to be on the classpath,
> you can do so by prepending an '@' character to the classpath-relative path
> to the script.
>
> So, if a directory foo is on your classpath, and a clojure file you'd like
> to run is at foo/bar/script.clj, then you can run it with:
>
> java -cp  clojure.main @/bar/script.clj
>
> FWIW, this is noted in the documentation for clojure here:
>
> http://clojure.org/repl_and_main

Nice! Thanks.
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


Re: Clojure script in the classpath

2010-06-19 Thread Paul Moore
On 19 June 2010 07:24, rzeze...@gmail.com  wrote:
> On Jun 18, 6:15 pm, Paul Moore  wrote:
>> I've just seen a couple of postings which, if I'm not mistaken, imply
>> that it's possible to have a Clojure script in my classspath. Is that
>> right?
>
> Yes, you can have .clj files on your classpath.  In fact, you can
> pretty much have anything on your classpath.  Checkout
> java.lang.ClassLoader 
> http://java.sun.com/j2se/1.5.0/docs/api/java/lang/ClassLoader.html#getResource(java.lang.String)
> .  This is what Clojure uses under the covers.

Thanks! (And thanks for the rest of your comments). I'll look into
this a bit more. I think that my experiments were failing because I
had the namespaces wrong - thanks for the pointer.

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


Re: Basic toolset for non-Java programmer

2010-06-19 Thread Paul Moore
Thanks to Ryan, Rob and Alex for the suggestions. I'll have a deeper
look into all of them.
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


Re: Enhanced Primitive Support

2010-06-19 Thread Daniel
On Jun 19, 11:45 am, Rich Hickey  wrote:
> On Jun 19, 2010, at 4:25 AM, Daniel wrote:
>
>
>
> > Checked out the new prim branch to repeat some tests.
>
> > user=> (defn ^:static fib ^long [^long n]
> >  (if (<= n 1)
> >1
> >(+ (fib (dec n)) (fib (- n 2)
> > #'user/fib
> > user=> (time (fib 38))
> > "Elapsed time: 4383.127343 msecs"
> > 63245986
>
> > That's certainly not what I expected
>
> > user=> (defn fact [n] (loop [n n r 1] (if (zero? n) 1 (recur (dec' n)
> > (*' r n)
> > #'user/fact
> > user=> (fact 40)
> > java.lang.ClassCastException: clojure.lang.Symbol cannot be cast to
> > java.lang.Number (NO_SOURCE_FILE:7)
>
> > Neither is this.  According to the docs "long-and-smaller integers
> > promote in all cases, even when given integer primitives" with the
> > prime ops.
>
> > Something I did wrong?
>
> Yes, you are in the wrong branch. Get the 'equal' branch.
>
> Rich

Cool.  This works correctly now.  Super nice, too :)

user=> (defn ^:static fib ^long [^long n]
  (if (<= n 1)
1
(+ (fib (dec n)) (fib (- n 2)
#'user/fib
user=> (time (fib 38))
"Elapsed time: 601.563589 msecs"
63245986


And this returns the error you specified:

user=> (defn fac [n] (loop [n n r 1] (if (zero? n) 1 (recur (dec' n)
(*' r n)
java.lang.RuntimeException: java.lang.IllegalArgumentException:  recur
arg for primitive local: r is not matching primitive, had:
java.lang.Number, needed: long (NO_SOURCE_FILE:13)


Which is really poor behavior.  Having numeric literals default to
primitive types is great but this behavior does not match the
documentation.  To quote: "long-and-smaller integers promote in all
cases, even when given integer primitives" with the prime ops.  Any
behavior other than that is confusing and essentially means the
programmer cannot have dependable bindings (to be fair, boxing at the
start of the loop fixes it but whatever).  I fully acknowledge that
the reason I don't understand 'primitive-by-default locals' may be
because I'm so new at Clojure (and functional programming), so take
this suggestion with a grain of salt: locals should default to the
type specified in code (which means the prime ops should cause the
rebind to auto-box/upgrade like the documentation dictates) or have
sensible defaults (like literals default to primitives (which is
awesome!)).  At least that makes sense to me in a dynamic context.


> Really? It seems tedious to me.  Don't you get tired of saying int i =
> 42 in Java, when you know full well the compiler knows 42 is an int? I
> do, and Clojure is competing with languages that infer the right types
> without the redundancy.

Agree 100%, which is partly why this silly loop/recur behavior needs
to be fixed.

-- 
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: Enhanced Primitive Support

2010-06-19 Thread Rich Hickey


On Jun 19, 2010, at 1:05 PM, Tim Daly wrote:



(proclaim (speed 3) (safety 0))

is verbose? Telling the compiler in one place that you care
about boxing speed, such as (declare (x unboxed)) seems to
me to be a very direct way to tell the compiler to choose
+' vs + everywhere that 'x' occurs.

This means that "it just works" code does not need additional
unboxing overhead. It also means that "make it fast" code is
marked in a single place.

And the form can be dynamically computed so you can adapt to
the platform.

It has the additional factor that common lispers will "get it".

I understand that it does not fit with your current model of
using inline typing. For a pervasive change like fast numerics
the inline typing or library-based typing is, to my mind, a bit
more cumbersome than 'proclaim' and 'declare' but that's probably
because of my common lisp background. Type hinting feels to me
like using symbol-property machinery in common lisp.



I don't want to get into it here, but the CL model in this area is  
quite cumbersome and opaque, IMO.


What precisely will (proclaim (speed 3) (safety 0)) do?

And of course, that is never enough, this from the CL spec:

(defun often-used-subroutine (x y)
  (declare (optimize (safety 2)))
  (error-check x y)
  (hairy-setup x)
  (do ((i 0 (+ i 1))
   (z x (cdr z)))
  ((null z))
  ;; This inner loop really needs to burn.
  (declare (optimize speed))
  (declare (fixnum i))
  ))

The (declare (fixnum i)) above being pertinent to this discussion vis- 
a-vis verbosity.


Not to mention the wonderful 'the' (this also from the CL spec):

(let ((i 100)) (declare (fixnum i)) (the fixnum (1+ i))) => 101

N.B. that the declaration of the type of i does not cover the result  
of 1+, which needs its own declaration.


Never mind that trading runtime safety for speed is completely not on  
the table for Clojure. It is one of the great lies of CL that it is  
both safe and very fast. It is safe *or* very fast. Clojure code will  
remain verifiable and safe.


The CL model is not something I want to emulate in Clojure.

Point taken about the type hinting. OTOH, metadata type hints flow  
through macros, whereas the decoupled i and its declaration of the CL  
above are extremely difficult to transform together. Metadata flowing  
is really an enormous win, IMO.


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: need help understanding two issues

2010-06-19 Thread Rob Lachlan
I'll take a whack at it.


> 1. How come APersistentMap$KeySet doesn't implement IPersistentSet?

Because keys and vals are designed to return (lazy) sequences.  More
important, these two functions return those two sequences in the same
order.  The laziness avoids having to incur the overhead of creating
the set structure, though if you want that you can just call (set
(keys map)) as in your example.


>
> 2. I can't get clojure.set/project to work. All of the following throw
> an exception:
>
> (clojure.set/project (keys {2 "two" 4 "four"}) #{2 3})
> (clojure.set/project (set (keys {2 "two" 4 "four"})) #{2 3})
>

Yeah, I found the doc confusing as well.  Here's an example:

user> (ns user (:use clojure.set))
nil
user> (project [{1 2, 2 4, 3 6}, {1 3, 2 6}] [1])
#{{1 3} {1 2}}

So project seems to take a collection of maps, and "projects", or
restricts them all on to the values specified in the second argument.

Cheers
Rob

-- 
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: Enhanced Primitive Support

2010-06-19 Thread Tim Daly


(proclaim (speed 3) (safety 0))

is verbose? Telling the compiler in one place that you care
about boxing speed, such as (declare (x unboxed)) seems to
me to be a very direct way to tell the compiler to choose
+' vs + everywhere that 'x' occurs.

This means that "it just works" code does not need additional
unboxing overhead. It also means that "make it fast" code is
marked in a single place.

And the form can be dynamically computed so you can adapt to
the platform.

It has the additional factor that common lispers will "get it".

I understand that it does not fit with your current model of
using inline typing. For a pervasive change like fast numerics
the inline typing or library-based typing is, to my mind, a bit
more cumbersome than 'proclaim' and 'declare' but that's probably
because of my common lisp background. Type hinting feels to me
like using symbol-property machinery in common lisp.

In any case, keep up the good work. I'm impressed with Clojure.

Tim Daly

Rich Hickey wrote:


On Jun 19, 2010, at 2:50 AM, Tim Daly wrote:


Is it possible to follow the Common Lisp convention
of proclaim/declaim/declare in order to specify types?



It would be possible of course, but undesirable. We're trying to avoid 
that kind of verbosity.


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


need help understanding two issues

2010-06-19 Thread Albert Cardona
Hi all,

I have run into the following two issues over the last few days. I
would appreciate insight/help/advice:


1. How come APersistentMap$KeySet doesn't implement IPersistentSet?

(clojure.set/intersection (keys {2 "two" 4 "four"}) #{2 3})

 java.lang.ClassCastException: clojure.lang.APersistentMap$KeySeq
cannot be cast to clojure.lang.IPersistentSet


So one must:

(clojure.set/intersection (set (keys {2 "two" 4 "four"})) #{2 3})

... which is redundant. Is there a better way?


2. I can't get clojure.set/project to work. All of the following throw
an exception:

(clojure.set/project (keys {2 "two" 4 "four"}) #{2 3})
(clojure.set/project (set (keys {2 "two" 4 "four"})) #{2 3})

Caused by: java.lang.ClassCastException: java.lang.Integer cannot be
cast to java.util.Map

... and this one returns a result that I don't understand:

(clojure.set/project {2 "two" 4 "four"} #{2 3})

#{{}}

So perhaps I have misread what "xrel" is supposed to be, in the docs
for clojure.set/project:

clojure.set/project
([xrel ks])
  Returns a rel of the elements of xrel with only the keys in ks

I understand that one should use select-keys to get the submap for a
given set of keys.
But how come the map's key set is not set that plays well with the
rest of clojure sets?



Help very appreciated.

Albert
-- 
http://albert.rierol.net

-- 
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: Enhanced Primitive Support

2010-06-19 Thread Rich Hickey


On Jun 19, 2010, at 4:25 AM, Daniel wrote:


Checked out the new prim branch to repeat some tests.


user=> (defn ^:static fib ^long [^long n]
 (if (<= n 1)
   1
   (+ (fib (dec n)) (fib (- n 2)
#'user/fib
user=> (time (fib 38))
"Elapsed time: 4383.127343 msecs"
63245986

That's certainly not what I expected


user=> (defn fact [n] (loop [n n r 1] (if (zero? n) 1 (recur (dec' n)
(*' r n)
#'user/fact
user=> (fact 40)
java.lang.ClassCastException: clojure.lang.Symbol cannot be cast to
java.lang.Number (NO_SOURCE_FILE:7)


Neither is this.  According to the docs "long-and-smaller integers
promote in all cases, even when given integer primitives" with the
prime ops.

Something I did wrong?


Yes, you are in the wrong branch. Get the 'equal' branch.

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: labrepl isn't a project in netbeans 6.8 - (Ubuntu 10.04)

2010-06-19 Thread kredaxx
Find the Maven plugin in the NB's plugin section and install if you
don't have it. It *might* help. At least that's what fixed it for my
NB installation.

-- 
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: classpath and require

2010-06-19 Thread Mohammad Khan
Yes, exactly it was, also at some point I was trying examples/introduction
(ruby's require like statement) instead of examples.introduction which all
together made me lost. Thanks everybody for your help.

Thanks,
Mohammad


On Sat, Jun 19, 2010 at 11:59 AM, Michael Wood  wrote:

> On 19 June 2010 17:46, Rob Lachlan  wrote:
> > I was wondering whether putting a dot in a directory on the classpath
> > makes a difference.  On OS X, the answer is no.  Unfortunately, I
> > don't have a windows machine, so I can't check for certain what the
> > situation is there.
>
> No, rzezeski found the problem.
>
> Mohammad's CLASSPATH environment variable was correct, but he was
> overriding that by using:
> java -cp clojure-contrib.jar;clojure.jar clojure.main
>
> --
> Michael Wood 
>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with
> your first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en
>

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

Records forget they are records

2010-06-19 Thread Oscar Forero
Hello,

I am working with Clojure for a university project and hit this
problem

http://paste.pocoo.org/show/227239/

I am trying to defines symbols from a map with keywords as keys and X
as value (where X is usually a lambda or a Record), the first example
does that ...

(binder data)

Creates the definitions but the record loose the Record type
information.

Using a macro works but I can not operated on the whole collection,
have tried multiple options including doseq but all hit different
issues.

>From the chat it seems that a record evals to map and is the reason
why the function approach fails (thx AWizzArd). Is this intended or
did I just hit an under construction sign?

Any suggestions?

best regards,

Oscar

-- 
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: Enhanced Primitive Support

2010-06-19 Thread Daniel
Checked out the new prim branch to repeat some tests.


user=> (defn ^:static fib ^long [^long n]
  (if (<= n 1)
1
(+ (fib (dec n)) (fib (- n 2)
#'user/fib
user=> (time (fib 38))
"Elapsed time: 4383.127343 msecs"
63245986

That's certainly not what I expected


user=> (defn fact [n] (loop [n n r 1] (if (zero? n) 1 (recur (dec' n)
(*' r n)
#'user/fact
user=> (fact 40)
java.lang.ClassCastException: clojure.lang.Symbol cannot be cast to
java.lang.Number (NO_SOURCE_FILE:7)


Neither is this.  According to the docs "long-and-smaller integers
promote in all cases, even when given integer primitives" with the
prime ops.

Something I did wrong?

-- 
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: classpath and require

2010-06-19 Thread Mohammad Khan
Correction, it worked..


On Fri, Jun 18, 2010 at 6:19 PM, Mohammad Khan  wrote:

> No, it didn't work.. what else I could be missing..
>
>
> On Fri, Jun 18, 2010 at 5:56 PM, Rob Lachlan wrote:
>
>> Whoops, that should read:
>>
>> java -cp c:\clojure-contrib\clojure-contrib.jar;c:\clojure
>> \clojure.jar;c:
>> \projects.clj clojure.main
>>
>> On Jun 18, 2:51 pm, Rob Lachlan  wrote:
>> > have you tried starting with:
>> >
>> > c:\clojure-contrib\clojure-contrib.jar;c:\clojure\clojure.jar;c:
>> > \projects.clj clojure.main
>> >
>> > On Jun 18, 2:00 pm, Mohammad Khan  wrote:
>> >
>> >
>> >
>> > > C:\Projects.clj>java -cp
>> > > c:\clojure-contrib\clojure-contrib.jar;c:\clojure\clojure.jar
>> clojure.main
>> > > Clojure 1.1.0-alpha-SNAPSHOT
>> > > user=> (require 'examples.introduction)
>> > > java.io.FileNotFoundException: Could not locate
>> > > examples/introduction__init.class or examples/introduction.clj on
>> > > classpath:  (NO_SOURCE_FILE:0)
>> > > user=>
>> >
>> > > C:\Projects.clj>echo %CLASSPATH%
>> > > C:\Projects.clj;C:\clojure;C:\clojure-contrib
>> > > C:\Projects.clj>dir examples\introduction.clj
>> > >  Volume in drive C is xxx
>> > >  Volume Serial Number is -
>> > >  Directory of C:\Projects.clj\examples
>> >
>> > > 06/18/2010  04:52 PM40 introduction.clj
>> > >1 File(s) 40 bytes
>> > >0 Dir(s)  xx,xxx,xxx bytes free
>> >
>> > > C:\Projects.clj>
>>
>> --
>> You received this message because you are subscribed to the Google
>> Groups "Clojure" group.
>> To post to this group, send email to clojure@googlegroups.com
>> Note that posts from new members are moderated - please be patient with
>> your first post.
>> To unsubscribe from this group, send email to
>> clojure+unsubscr...@googlegroups.com
>> For more options, visit this group at
>> http://groups.google.com/group/clojure?hl=en
>>
>
>

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

Re: Clojure script in the classpath

2010-06-19 Thread Chas Emerick
If you're just looking to run a script that happens to be on the  
classpath, you can do so by prepending an '@' character to the  
classpath-relative path to the script.


So, if a directory foo is on your classpath, and a clojure file you'd  
like to run is at foo/bar/script.clj, then you can run it with:


java -cp  clojure.main @/bar/script.clj

FWIW, this is noted in the documentation for clojure here:

http://clojure.org/repl_and_main

Cheers,

- Chas

On Jun 18, 2010, at 6:15 PM, Paul Moore wrote:


I've just seen a couple of postings which, if I'm not mistaken, imply
that it's possible to have a Clojure script in my classspath. Is that
right? I come from a Python background (little or no Java experience)
and the idea that anything other than .class or .jar files (or
directories) could be on the classpath never occurred to me.

Can anyone give me a complete example of how this works? (I probably
need to get the file names and namespaces right, something I'm still
struggling with - again the Java/JVM requirements for filenames that
match classnames is a new concept for me).

Could I have found anything about this on the web? The Java
documentation (http://java.sun.com/javase/6/docs/technotes/tools/windows/classpath.html 
)

didn't mention anything other than classes/jars/zips/directories, and
my Google skills didn't turn up anything clojure-specific.

Thanks,
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


--
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: classpath and require

2010-06-19 Thread Michael Wood
On 19 June 2010 17:46, Rob Lachlan  wrote:
> I was wondering whether putting a dot in a directory on the classpath
> makes a difference.  On OS X, the answer is no.  Unfortunately, I
> don't have a windows machine, so I can't check for certain what the
> situation is there.

No, rzezeski found the problem.

Mohammad's CLASSPATH environment variable was correct, but he was
overriding that by using:
java -cp clojure-contrib.jar;clojure.jar clojure.main

-- 
Michael Wood 

-- 
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: Enhanced Primitive Support

2010-06-19 Thread Rich Hickey

The hard error has been restored:

http://github.com/richhickey/clojure/commit/25165a9ccd1001fa7c4725a8219c4108803ae834

Rich

On Jun 19, 2010, at 2:03 AM, Mark Engelberg wrote:


I'm confused.  In the latest scheme, what is the eventual plan for
handling a recur to a loop element that was initialized with a
primitive?  Are boxed numbers automatically coerced to the primitive?
Would a long be coerced to a double, or double to long?  Under what
scenarios will you get a warning, and when will you get an error?

I think what troubles me the most about this loop/recur issue is that
the semantics of recur depend completely on whether a variable is
assigned a primitive or boxed numeric type.  To know what the recur
will do, you must know the type of the assigned value.  This has
always been the case, but in the current version of Clojure, provided
you aren't using Java interop, it's relatively straightforward to
know.  Unless the variable or literal is explicitly cast to a
primitive, it's not a primitive.  But now, with the advent of static
functions which can return primitives, it becomes more likely to not
easily be able to determine this fact.  If I say (loop [x (foo 2)]...)
I have no way of knowing what's going to happen when I recur.  Yes, I
realize that you can run the function and use warnings/errors to find
out.  But I find it unsettling to have a commonly used code form with
semantics I can't predict just by looking at it.

It's attractive that the current proposal gives speed benefits to
common cases with no additional annotation.  But I personally place a
higher value on being able to understand the semantics of my code when
reading through it.  I would prefer a version where loop requires some
sort of explicit annotation on a variable if you want it to require a
primitive upon recur.  (Ideally, I'd probably want the annotation on
the variable using a syntax that mirrors static functions, rather than
the old technique of typecasting the initializer, since the whole
typecasting system makes less sense now that literals and certain
return values are already primitives.  Unifying the syntax and
semantics of using primitives in loops with the syntax and semantics
of using primitives as inputs to static functions makes a lot of sense
to me.)

--  
You received this message because you are subscribed to the Google

Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient  
with your first post.

To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en


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


Re: classpath and require

2010-06-19 Thread Rob Lachlan
I was wondering whether putting a dot in a directory on the classpath
makes a difference.  On OS X, the answer is no.  Unfortunately, I
don't have a windows machine, so I can't check for certain what the
situation is there.

Another issue: I ignored case-sensitivity in my answer above.  Are
windows paths ever case-sensitive?  (silly question, I know, but I
haven't worked with windows in a while.)  Another question:

If you run:

java -cp "c:\clojure-contrib\clojure-contrib.jar;c:\clojure
\clojure.jar;c:\projects.clj\examples" clojure.main

can you then just do (require 'introduction)

And do try it with quotes around the classpath.  The dot in
projects.clj might be like a space in that it could lead to a parsing
error without quotes.

Good luck
Rob

On Jun 19, 1:58 am, Rasmus Svensson  wrote:
> 2010/6/18 Mohammad Khan 
>
>
>
>
>
> > C:\Projects.clj>java -cp
> > c:\clojure-contrib\clojure-contrib.jar;c:\clojure\clojure.jar clojure.main
> > Clojure 1.1.0-alpha-SNAPSHOT
> > user=> (require 'examples.introduction)
> > java.io.FileNotFoundException: Could not locate
> > examples/introduction__init.class or examples/introduction.clj on
> > classpath:  (NO_SOURCE_FILE:0)
> > user=>
>
> > C:\Projects.clj>echo %CLASSPATH%
> > C:\Projects.clj;C:\clojure;C:\clojure-contrib
> > C:\Projects.clj>dir examples\introduction.clj
> >  Volume in drive C is xxx
> >  Volume Serial Number is -
> >  Directory of C:\Projects.clj\examples
>
> > 06/18/2010  04:52 PM                40 introduction.clj
> >                1 File(s)             40 bytes
> >                0 Dir(s)  xx,xxx,xxx bytes free
>
> > C:\Projects.clj>
>
> Hello!
>
> To me it looks like you have gotten the most things right. As I see you
> understand, you must have clojure, clojure-contrib and the source on the
> class path. However, how these are specified can be a bit tricky. There are
> basically two cases: directories and jar files.
>
> When using jar files, the jar file itself must be in the class path, not the
> directory which contains it. In our case, the entries would be
> c:\clojure\clojure.jar and c:\clojure-contrib\clojure-contrib.jar, just as
> you wrote.
>
> When using folders with clojure source files or ahead-of-time compiled
> classes, the directory that contains the folder that represents the topmost
> component of the namespace. For example, in your case the namespace
> examples.introduction is stored in the file
> C:\Projects.clj\examples\introduction.clj so the directory C:\Projects.clj\
> should be inlcuded in the class path.
>
> When Clojure loads the namespace examples.introduction, it will try to find
> examples\introduction.clj in every directory (or jar file) in the class
> path. The error you got is an indication that no matching file could be
> found.
>
> On windows, the paths are delimited with semicolons, but on most other
> platforms colons are used. That's why most examples will use colons. If the
> paths in the class path contains spaces or other special characters, you
> should enclose the thing in spaces, like this:
>
> java -cp "C:\path one\;C:\path two\" clojure.main
>
> From what I can tell, Rob's example should work. I'm not sure if a trailing
> backslash is required for directories, but you could try with and without it
> to see if it makes any difference. If that doesn't work, try renaming
> projects.clj to something without a dot in it. Also, look carefully for
> typos...
>
> I hope this helps...
>
> // raek

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


what replaces clojure.parallel?

2010-06-19 Thread Albert Cardona
Hi all,

The http://clojure.org/other_libraries web page states that:

"Parallel Processing"
"The parallel library (namespace parallel, in parallel.clj) wraps the
ForkJoin library. This lib is now deprecated."

If the clojure.parallel is deprecated, what replaces it?
Is it pcalls and pvalues in clojure.core?
What other parallel computation constructs exist in clojure 1.2 beyond
pmap, pcalls and pvalues?

Pointers very appreciated.

Albert
-- 
http://albert.rierol.net

-- 
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: Enhanced Primitive Support

2010-06-19 Thread Nicolas Oury
I definitely would like to see more people trying their code with primitive
by default and talk about unexpected bugs and performance improvements.


On Sat, Jun 19, 2010 at 3:43 PM, David Nolen  wrote:

>
> "Most real world programs". You mean like Clojure 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: labrepl isn't a project in netbeans 6.8 - (Ubuntu 10.04)

2010-06-19 Thread Aaron Bedra
Jared,

There was another post about issues with netbeans.  I am looking into why
this is happening.  On another note, labrepl uses clojure 1.2, but that is
all handled via leiningen.

Cheers,

Aaron

On Thu, Jun 17, 2010 at 11:10 PM, Jared  wrote:

> I was following the instructions to get labrepl up and running and hit
> a snag. Netbeans does not recognize Samples/Clojure/Relevance
> LabReplProject as a project. After creating it it does not appear in
> the Projects window. So I go to File -> Open Project and click on
> RelevanceLabRepl and hit Open Project. Instead of opening the project
> it displays the subfolders. Also, when RelevanceLabRepl is selected it
> does not display a name for Project Name:, and the box Open as Main
> Project is grayed out.
>
> I do have a normal clojure project that I can open. I am using clojure
> 1.0 if that matters.
>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with
> your first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en

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

Re: Enhanced Primitive Support

2010-06-19 Thread David Nolen
On Sat, Jun 19, 2010 at 5:13 AM, Mike Meyer <
mwm-keyword-googlegroups.620...@mired.org> wrote:
>
>
> Were those real world programs, or arithmetic benchmarks? Most real world
> programs I see spend so little of their time doing arithmetic that making
> the math an order of magnitude slower wouldn't make a noticeable difference
> in overall runtime.
>

"Most real world programs". You mean like Clojure itself?

Please look over the implementation of gvec before making statements like
this:

  clojure.lang.IPersistentCollection
  (cons [this val]
 (if (< (- cnt (.tailoff this)) (int 32))
  (let [new-tail (.array am (inc (.alength am tail)))]
(System/arraycopy tail 0 new-tail 0 (.alength am tail))
(.aset am new-tail (.alength am tail) val)
(new Vec am (inc cnt) shift root new-tail (meta this)))
  (let [tail-node (VecNode. (.edit root) tail)]
(if (> (bit-shift-right cnt (int 5)) (bit-shift-left (int 1) shift))
;overflow root?
  (let [new-root (VecNode. (.edit root) (object-array 32))]
(doto ^objects (.arr new-root)
  (aset 0 root)
  (aset 1 (.newPath this (.edit root) shift tail-node)))
(new Vec am (inc cnt) (+ shift (int 5)) new-root (let [tl
(.array am 1)] (.aset am  tl 0 val) tl) (meta this)))
  (new Vec am (inc cnt) shift (.pushTail this shift root tail-node)
 (let [tl (.array am 1)] (.aset am  tl 0 val) tl) (meta
this))


David

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

Re: Enhanced Primitive Support

2010-06-19 Thread cageface
Maybe it's only because I'm coming from Ruby, in which number
promotion is automatic and everything is slow, but if I have to choose
between correctness and performance as a *default*, I'll choose
correctness every time. I think there's a good reason that GCC, for
instance, makes you push the compiler harder with compiler flags if
you want to squeeze extra performance out of a program and accept the
corresponding brittleness that it often brings. I also always thought
that the transparent promotion of arithmetic was one of the strongest
selling points of Common Lisp.

My impression has always been that performance of numerics is rarely
the bottleneck in typical code (web stuff, text processing, network
code etc), but that unexpected exceptions in such code are the source
of a lot of programmer heartache. On the other hand, I think 99% of
the cases in which I've had a number exceed a 64 bit value were also
examples of errors that might as well have been exceptions because
they indicated a flaw in the code.

-- 
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: Enhanced Primitive Support

2010-06-19 Thread Rich Hickey


On Jun 19, 2010, at 6:41 AM, Heinz N. Gies wrote:



On Jun 19, 2010, at 4:12 , Rich Hickey wrote:
I have to say I'm in the 'pay for what you use' camp - you need a  
box, you ask for one. If I don't (and neither do any of those  
loops), why should I have to do extra work to avoid it?


- 42

I totally and wholeheartedly disagree, as long as there is a chance  
something goes wrong, and here is a lot of it, the default can not  
be we force people to know more - for example that they explicitly  
need to box things. And it is not even about longs and BigInts,  
doubles and Floats or what the java version means also come into  
play, how often do you mixed calculations because initializing 1 is  
shorter and more used for you then 1.0? This will now break your  
loop, make it crumble into dust and give you odd, unexpected and  
wrong results.


Lets get away from the argument already cast and bring a new one. It  
is an impossible situation that the literal 1 in one place has a  
different meaning and behavior then in another place. This is in  
fact a show stopper, I'm serious, this would be worst then java.


(* 1 0.2) -> works fine

but

(loop [n 1 r 1](if (zero? n) r (recur (dec n) (* r 0.2

does not because the 1 there is not the 1 in the upper example, that  
is so utterly wrong and horrible please think about it and think  
about how you'd sell someone he has to know where a literal means  
what, I can guarantee you this will keep many people from this  
wonderful language :(.


As I told Mark, this was, and will again be, a hard error.

I am telling you though, if you continue with these "show stopper",  
"will keep people from using Clojure" sky-is-falling histrionics, I  
will stop reading your messages.


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: Enhanced Primitive Support

2010-06-19 Thread Rich Hickey


On Jun 19, 2010, at 6:39 AM, Jules wrote:


I know nothing about the JVM, but I do know that on x86 you can handle
fixnum -> bignum promotion fairly cheaply. You compile two versions of
the code: one for bignums and one for fixnums. After an arithmetic
instruction in the fixnum code you check if it overflowed, and if it
did you switch to the bignum code.

while(n < 10) {
 n = n + 1;
}

=>

while(n #< 10) {
  a = n #+ 1;
  if(overflow){ n = ToBignum(n); goto foo; }
  n = a;
}

while(n.lessthan(10)) {
foo:
  n = n.add(1);
}

where #< and #+ are the fixnum versions of < and +, and lessthan and
add are the bignum versions. Yeah it's slower than ignoring the
overflow, but faster than tagged 31-bit fixnums and a whole lot faster
than bignums. Can you convince the JVM to produce similar code?



You can do things like that in a closed world of a few operators and  
types (although it gets unwieldy as the number of variables goes up).  
And of course, inside the math ops Clojure already does things like  
that.


But that is not what we are dealing with here. This is an open system,  
where representational issues of functions, arguments and returns come  
into play. The 'operators' +, - etc are actually function calls - they  
are not special to the compiler. And your loop may also contain other  
function calls:


while(n < 10) {
 foo(n)
 n = n + 1;
}

how do I know foo can handle the bigint once I've upgraded?

How about this?

while(n < 10) {
 n = foo(n)
}

Unless you have a tagged architecture you can't have boxed/unboxed arg/ 
return uniformity (and even then you lose some bits of range).


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: Enhanced Primitive Support

2010-06-19 Thread Rich Hickey


On Jun 19, 2010, at 2:50 AM, Tim Daly wrote:


Is it possible to follow the Common Lisp convention
of proclaim/declaim/declare in order to specify types?



It would be possible of course, but undesirable. We're trying to avoid  
that kind of verbosity.


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: Enhanced Primitive Support

2010-06-19 Thread Rich Hickey


On Jun 19, 2010, at 2:03 AM, Mark Engelberg wrote:


I'm confused.  In the latest scheme, what is the eventual plan for
handling a recur to a loop element that was initialized with a
primitive?  Are boxed numbers automatically coerced to the primitive?
Would a long be coerced to a double, or double to long?  Under what
scenarios will you get a warning, and when will you get an error?

I think what troubles me the most about this loop/recur issue is that
the semantics of recur depend completely on whether a variable is
assigned a primitive or boxed numeric type.  To know what the recur
will do, you must know the type of the assigned value.  This has
always been the case, but in the current version of Clojure, provided
you aren't using Java interop, it's relatively straightforward to
know.  Unless the variable or literal is explicitly cast to a
primitive, it's not a primitive.  But now, with the advent of static
functions which can return primitives, it becomes more likely to not
easily be able to determine this fact.  If I say (loop [x (foo 2)]...)
I have no way of knowing what's going to happen when I recur.  Yes, I
realize that you can run the function and use warnings/errors to find
out.  But I find it unsettling to have a commonly used code form with
semantics I can't predict just by looking at it.



Sorry for the confusion. This is a part of the design subject to  
change. I had temporarily eased the error here in an effort to see the  
usage patterns. The current warning tells you what is going on, since  
the compiler always knows when it is using a primitive local.  
Restoring the error on recur mismatch will cover all of these cases,  
without requiring any sophisticated analysis. If you get it wrong, it  
won't compile, and will tell you quite explicitly why.


The default (auto-primitives or always Objects) will follow the  
default for +, - etc.



It's attractive that the current proposal gives speed benefits to
common cases with no additional annotation.  But I personally place a
higher value on being able to understand the semantics of my code when
reading through it.  I would prefer a version where loop requires some
sort of explicit annotation on a variable if you want it to require a
primitive upon recur.  (Ideally, I'd probably want the annotation on
the variable using a syntax that mirrors static functions, rather than
the old technique of typecasting the initializer, since the whole
typecasting system makes less sense now that literals and certain
return values are already primitives.  Unifying the syntax and
semantics of using primitives in loops with the syntax and semantics
of using primitives as inputs to static functions makes a lot of sense
to me.)



Really? It seems tedious to me.  Don't you get tired of saying int i =  
42 in Java, when you know full well the compiler knows 42 is an int? I  
do, and Clojure is competing with languages that infer the right types  
without the redundancy.


Loops are unlike static function arguments, in many ways. There is no  
context when defining the signature of a static function, and you are  
explicitly creating an interface for callers. By contrast, a loop is  
not an interface for anyone, and all possible context is present.


Again, it is a matter of defaults, the non-default is going to have to  
be explicit, and you can just as easily be explicit that you want the  
loop argument to be an Object, either with (loop [^Object i 42] ...),  
(loop [i (num 42)] ...) or your (loop' [i 42] ...) idea.


Everyone who is advocating for what the other side ought to do should  
be aware that if the default doesn't go their way, the other side will  
be them.


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: Enhanced Primitive Support

2010-06-19 Thread Heinz N. Gies

On Jun 19, 2010, at 14:55 , Rich Hickey wrote:

> 
> Yes, that's a bit Java-ish. All we care about here is returning the canonic 
> boxed representation of the number.

It was suggested before that it is simple to allow automatic promotion, by 
compiling multiple versions. how about doing this? One version with primitives 
and one version with everything object boxed. This would (of cause mean) even 
if only one argument has to get boxed all others will to but it would give use 
speed and correctness.

Would that be possible?

-- 
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: Enhanced Primitive Support

2010-06-19 Thread Rich Hickey


On Jun 18, 2010, at 11:47 PM, dmiller wrote:

Yes, it's easy to imagine a world where people who want efficient  
code
have to jump through hoops to get it. OTOH, you can just say (num  
some-

expr) to force it to be boxed, if you want assurance of an Object
initializer. Which will be the more common need?



From the wiki page "Enhanced Primitive Support":  * Note: this means
that locals initialized with literals will have primitive type, e.g.
(let [x 42] …), and especially: (loop [x 42] …). If you intend to
recur with a non-primitive, init like this, (loop [x (num 42)] …)


I'd like to ask for some consideration on any use of (num x).   On the
CLR side, it is unimplementable as documented, there being no
equivalent in the CLR to Number.  If a proposed use of num can be
satisfied by this definition of num:

(defn num {tag :object} [x] x)

I can manage. I imagine this to be the case, but haven't had time to
read all the new code.

If you really mean to use a type that is a base type for all the
primitive numeric types -- not going to happen on the CLR.



Yes, that's a bit Java-ish. All we care about here is returning the  
canonic boxed representation of the number.


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: Enhanced Primitive Support

2010-06-19 Thread David Powell

> I think if we had them, promoting ops
> should be the primed ones, and they would mostly be used in library

Oops, I had meant the non-primed ops should support promotion. But
tbh, I have mixed feelings about promotion.

I haven't required bitint promotion myself, but having statically
typed numeric vars, where the type of the vars is chosen by Clojure
and it isn't obvious what that type is, seems potentially confusing.

It is the issue of loop initialisers fixing the types of the loop
variable slot that I'm more bothered about though.

-- 
Dave

-- 
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: Enhanced Primitive Support

2010-06-19 Thread Heinz N. Gies

On Jun 19, 2010, at 14:18 , David Powell wrote:
> 
>  (loop [^int n 1 r 1](if (zero? n) r (recur (dec n) (* r 0.2
> 
> 
> Numeric literals would still produce primitives where possible, but
> would get auto-boxed in loop initialisers.
> 
> I think this option wouldn't have any nasty surprises.
> 
+41 (would be 42 if it were ^long since it is the clojure type I think)

This gives the option of make it fast if you know-what-you-are-doing(TM) which 
is great, and I certainly would use that myself :P but it still keeps the 
things simple and working for the default case.

Regards,
Heinz

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

Re: Enhanced Primitive Support

2010-06-19 Thread David Powell


Personally, I have no real interest in bigints, but I'm glad that they
are there, and that arithmetic code supports them polymorphically.

I'm not sure what I think regarding non-promoting numeric operators.
They are ok, but they seem to add complexity to the language, and they
don't look very newbie friendly. I think if we had them, promoting ops
should be the primed ones, and they would mostly be used in library
functions where performance is important.

>  but
> (loop [n 1 r 1](if (zero? n) r (recur (dec n) (* r 0.2
> does not [work]

This seems to be particularly nasty. Clojure is statically typing r on
the assumption that just because the init value of r fits a primitive
int, that it can never be anything else.  Promoting operators do no
good, because the variable slot for the loop var has already been
assumed to be a primitive, so it isn't possible to promote it.

Is there any possibility that loop variables could be assumed to be
boxed numerics, unless type hinted to something else?

So:

  (loop [^int n 1 r 1](if (zero? n) r (recur (dec n) (* r 0.2


Numeric literals would still produce primitives where possible, but
would get auto-boxed in loop initialisers.

I think this option wouldn't have any nasty surprises.


-- 
Dave

-- 
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: Problems with URL params and http-agent

2010-06-19 Thread Michael Wood
On 18 June 2010 23:54, Timothy Washington  wrote:
> That works, thanks. It's a bit weird because I did try just http encoding
> the parameters before. But I obviously encoded the wrong characters, or
> maybe used the wrong character encoding. Hmmm.
>
> Thanks :)

No problem :)

-- 
Michael Wood 

-- 
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: Enhanced Primitive Support

2010-06-19 Thread Michał Marczyk
On 19 June 2010 03:33, Rich Hickey  wrote:
> Turnabout is fair play, so I've produced a version that swaps the
> defaults, still in the 'equal' branch:

The issue of which behaviour should be the default aside, I think that
I'd expect the *, + etc. ops to go with unannotated literals and the
primed variants to go with explicit hinting, whereas now this seems
not to be the case:

(defn fact [n]
  (loop [n (num n) r (num 1)]
  (if (zero? n)
  r
  (recur (dec n) (* r n)

This works for (fact 40), whereas the version with dec' and *' (and
the (num ...) still in place) doesn't; I'd expect this to be reversed.

In general, I'd expect the primed ops to be there for those who know
what they're doing; same goes for explicit hinting.

On 19 June 2010 04:12, Rich Hickey  wrote:
> I have to say I'm in the 'pay for what you use' camp - you need a box, you
> ask for one. If I don't (and neither do any of those loops), why should I
> have to do extra work to avoid it?

The question is which desirable commodity Clojure programmers can
expect to get for free and which is to be obtainable through voluntary
banter: the sturdy boxes or the Potion of Speed +5. I'm used to paying
for the PoS, but a sudden rise in the price of boxes seems unwarranted
to me, especially if it only serves to lower the price of the PoS from
a (prim ...) hint where the local is introduced to zero. I mean, this
is no longer about "the free lunch", it's more about "the free
dessert" which the power number crunchers surely do not need.

I have a hunch that if (num ...) stays in and primitive is the
default, people (I mean just about *everybody*) will only box things
in the face of the first crash or *maybe* after developing a great
intuitive feel for when that might be required. Of course there's
going to be a period of frantic learning about numeric representations
on the JVM etc. in between the crash and the boxing. And, um, whatever
for...?

Interestingly, the introductory materials on Clojure I've read so far
tout the "don't worry about it" quality of Clojure's numerics as a
benefit of the language. (The "don't worry about it" phrasing comes
from "Programming Clojure".) I just mention this because I tend to
think it reasonable to present that as a benefit. The idea of making a
U-turn on this is surprising to me... Which is partly to say that I'm
still evaluating it, though so far my intuition stays pretty firmly on
the "don't worry about it"-is-good side.

TLDR summary: I'm very excited about the latest equal; I'd definitely
want the primed arithmetic ops to go with the hinted locals, whereas
non-primed (basic) variants would do the right thing for the simplest,
unhinted code (so which ops should get the primes in my eyes depends
on whether boxing of locals is the default); my heart is still on the
side of free sturdy boxes while I'm expecting to pay for the Potion of
Speed.

Sincerely,
Michał

-- 
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: scala

2010-06-19 Thread nickikt
For such a young language it has a big momentum. Did Scala have that
after 2 years?

On 18 Jun., 23:56, cageface  wrote:
> Quick disclaimer - there are a lot of things I like in Scala and I
> think Odersky & crew have done some very impressive work bringing
> functional language concepts to the VM and giving Java developers a
> path forward. I also don't think Clojure vs x language battles are
> very productive and don't want to encourage one.
>
> Anyway, I imagine my trajectory as a developer over the last 10  years
> is pretty typical. I started out doing Java stuff but fell in love
> with Ruby and Rails in 2004 and have been working almost entirely in
> Ruby since. The idea that all that heavy, cumbersome Java cruft could
> in many cases be dispensed with was a revelation and the discovery
> that I could build software in a language that offered *no* compile
> time error checking that was still robust was a very pleasant
> surprise.
>
> Like a lot of Ruby hackers though, I also saw some warts in the
> language and also remained curious about other approaches. Also like a
> lot of Ruby hackers, the recent rise of new JVM languages has piqued
> my interest, particularly Scala and Clojure. Scala seemed like a more
> natural step from Ruby and my first experiences with it were
> encouraging. It seemed to offer a lot of the expressiveness of Ruby
> but with potentially much better performance and more robust runtime
> and, intriguingly, static type checking. However, after writing a
> handful of small but non-trivial programs in it the complexity lurking
> under the surface started peeking through and the intricacies of the
> type system and the significant complexity of the language itself
> became more apparent. It started to feel like a step back to the
> rigors of Java and heavyweight syntax and fights with the compiler.
> The predominant Scala web platform, Lift, also seemed to have a very
> heavy, enterprisey sort of "correctness" about it that felt
> overengineered.
>
> So I bounced over to Clojure and its clean, elegant core and minimal,
> flexible syntax seemed very refreshing. It felt much more in the
> liberal, malleable spirit of Ruby. The functional stuff was a bit of a
> stretch but it also seemed built on a simpler set of core concepts
> than the featureful but complex Scala collections.
>
> Unfortunately there seems to be a lot more commercial momentum for
> Scala though. It's still a blip compared to the mainstream languages
> but I'm seeing more and more job posts mentioning it, and hardly any
> for Clojure. I don't think Scala is a bad language overall, but I'm
> not sure I'd dump Ruby for it. On the other hand, I can imagine
> migrating most of my dev work over to Clojure with the right project.
> Has anybody else wrestled with this choice? Any thoughts?

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


Re: Enhanced Primitive Support

2010-06-19 Thread Heinz N. Gies

On Jun 19, 2010, at 4:12 , Rich Hickey wrote:
> I have to say I'm in the 'pay for what you use' camp - you need a box, you 
> ask for one. If I don't (and neither do any of those loops), why should I 
> have to do extra work to avoid it?

- 42

I totally and wholeheartedly disagree, as long as there is a chance something 
goes wrong, and here is a lot of it, the default can not be we force people to 
know more - for example that they explicitly need to box things. And it is not 
even about longs and BigInts, doubles and Floats or what the java version means 
also come into play, how often do you mixed calculations because initializing 1 
is shorter and more used for you then 1.0? This will now break your loop, make 
it crumble into dust and give you odd, unexpected and wrong results.

Lets get away from the argument already cast and bring a new one. It is an 
impossible situation that the literal 1 in one place has a different meaning 
and behavior then in another place. This is in fact a show stopper, I'm 
serious, this would be worst then java.

(* 1 0.2) -> works fine

but

(loop [n 1 r 1](if (zero? n) r (recur (dec n) (* r 0.2

does not because the 1 there is not the 1 in the upper example, that is so 
utterly wrong and horrible please think about it and think about how you'd sell 
someone he has to know where a literal means what, I can guarantee you this 
will keep many people from this wonderful language :(.

The default case for a language has to be the most intuitive version otherwise 
you end up with a mess of complex rules and special cases. It was said before, 
this is premature optimization in it's worst since it is forced on the user if 
they want or not. The priority has to be 'it works' later if it matters we can 
worry about 'it is fast' but this isn't working any more. 

Regards,
Heinz

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


Re: Enhanced Primitive Support

2010-06-19 Thread Jules
I know nothing about the JVM, but I do know that on x86 you can handle
fixnum -> bignum promotion fairly cheaply. You compile two versions of
the code: one for bignums and one for fixnums. After an arithmetic
instruction in the fixnum code you check if it overflowed, and if it
did you switch to the bignum code.

while(n < 10) {
  n = n + 1;
}

=>

while(n #< 10) {
   a = n #+ 1;
   if(overflow){ n = ToBignum(n); goto foo; }
   n = a;
}

while(n.lessthan(10)) {
foo:
   n = n.add(1);
}

where #< and #+ are the fixnum versions of < and +, and lessthan and
add are the bignum versions. Yeah it's slower than ignoring the
overflow, but faster than tagged 31-bit fixnums and a whole lot faster
than bignums. Can you convince the JVM to produce similar code?

Jules

On Jun 19, 4:22 am, Rich Hickey  wrote:
> On Jun 18, 2010, at 10:18 PM, Mark Fredrickson wrote:
>
> > So far most of the action has concerned arithmetic ops (+, -, *, /).
> > Will these new semantics include the bit-shift operators? I vote yes.
> > My use cases for bit ops would benefit from primitive ops.
>
> > On a related note, my use cases call for silent overflow of bit shifts
> > (pseudo random number generators). Will there be a way to disable
> > overflow exceptions (either via a binding or through unchecked-*
> > functions)?
>
> Yes, bit-ops will be made to align with whatever is done here.
>
> Rich
>
>
>
>
>
> > On Jun 18, 8:33 pm, Rich Hickey  wrote:
> >> Turnabout is fair play, so I've produced a version that swaps the
> >> defaults, still in the 'equal' branch:
>
> >> Docs:
>
> >>https://www.assembla.com/wiki/show/b4-TTcvBSr3RAZeJe5aVNr/
> >> Enhanced_Pr...
>
> >> Code:
>
> >>http://github.com/richhickey/clojure/commit/
> >> 310534b8e7e7f28c75bb122b4...
>
> >> You can get the older arbitrary-precision default with this commit:
>
> >>http://github.com/richhickey/clojure/commit/
> >> 7652f7e935684d3c7851fbcad...
>
> >> I've also temporarily enabled a diagnostic (in both) that tells you
> >> when you have a mismatch between a loop initializer and its recur
> >> form. It goes off over a hundred times in Clojure itself, when using
> >> the arbitrary precision default. In each case, the recur value is
> >> needlessly being boxed, every iteration of a loop, for loops that  
> >> will
> >> never be bigints; indexes, counters etc. I expect this will be very
> >> typical of most code. But removing that useless overhead would be a
> >> lot of tedious work.
>
> >> With the defaults swapped, only 2 warnings.
>
> >> Pay for what you use ...
>
> >> Rich
>
> >> On Jun 18, 4:52 pm, Rich Hickey  wrote:
>
> >>> I've revised and enhanced the strategy, based upon the feedback  
> >>> here.
> >>> I think it is a nice compromise.
>
> >>> Docs (see update section at the top)
>
> >>>https://www.assembla.com/wiki/show/b4-TTcvBSr3RAZeJe5aVNr/Enhanced_Pr
> >>> ...
>
> >>> Code:
>
> >>>http://github.com/richhickey/clojure/commit/c79d28775e06b196ae1426f6c
> >>> ...
>
> >>> Thanks to all for the feedback, keep it coming!
>
> >>> Rich
>
> >>> On Jun 17, 2010, at 4:13 PM, Rich Hickey wrote:
>
>  I've been doing some work to enhance the performance, and unify the
>  semantics, of primitives, in three branches. I've started to  
>  document
>  this work here:
>
> https://www.assembla.com/wiki/show/clojure/Enhanced_Primitive_Support
>
>  Feedback welcome,
>
>  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

-- 
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: Enhanced Primitive Support

2010-06-19 Thread Nicolas Oury
yes, when it will be released :-b.
I can describe it though:
it applied a stochastically a set of rewriting rules on trees (represented
by records of records).
To speed up,  the activity of the rules in each subtree is cached in a Java
weak hash table from one step to another.
 There is a bit of arithmetic involved everywhere, and around 2-3 double
operations per function in the part choosing the instance of rule to apply.

On Sat, Jun 19, 2010 at 10:28 AM, Mike Meyer <
mwm-keyword-googlegroups.620...@mired.org> wrote:

>
> "Nicolas Oury"  wrote:
>
> >I tried it on my program. Very few arithmetic, most of it with annotation.
> >10%
>
> Can we see the source?
> --
> Sent from my Android phone with K-9 Mail. Please excuse my brevity.
>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with
> your first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en
>

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

Re: Enhanced Primitive Support

2010-06-19 Thread Mike Meyer

"Nicolas Oury"  wrote:

>I tried it on my program. Very few arithmetic, most of it with annotation.
>10%

Can we see the source?
-- 
Sent from my Android phone with K-9 Mail. Please excuse my brevity.

-- 
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: Enhanced Primitive Support

2010-06-19 Thread Nicolas Oury
I tried it on my program. Very few arithmetic, most of it with annotation.
10%.
On an arithmetic benchmark, it would be in te *10/*20 range.
This 10% is orthogonal to what profiling shows. It just makes a lot of
little improvements spread everywhere.
That's why it couldn't be solved with annotation.


On Sat, Jun 19, 2010 at 10:13 AM, Mike Meyer <
mwm-keyword-googlegroups.620...@mired.org> wrote:

>
> "Nicolas Oury"  wrote:
>
> >On the other hand, having boxed by default is a very significant slowdown
> >(10% on the strange program I tried, that had already a lot of
> annotations,
> >probably 20% or more on most programs), that can never be addressed : you
> >can't write annotations on every single line of your program.
>
> Were those real world programs, or arithmetic benchmarks? Most real world
> programs I see spend so little of their time doing arithmetic that making
> the math an order of magnitude slower wouldn't make a noticeable difference
> in overall runtime.
>
> Which puts making numbers primitives by default squarely in the realm of
> premature optimization.
> --
> Sent from my Android phone with K-9 Mail. Please excuse my brevity.
>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with
> your first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en
>

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

Re: Enhanced Primitive Support

2010-06-19 Thread Mike Meyer

"Nicolas Oury"  wrote:

>On the other hand, having boxed by default is a very significant slowdown
>(10% on the strange program I tried, that had already a lot of annotations,
>probably 20% or more on most programs), that can never be addressed : you
>can't write annotations on every single line of your program.

Were those real world programs, or arithmetic benchmarks? Most real world 
programs I see spend so little of their time doing arithmetic that making the 
math an order of magnitude slower wouldn't make a noticeable difference in 
overall runtime.

Which puts making numbers primitives by default squarely in the realm of 
premature optimization.
-- 
Sent from my Android phone with K-9 Mail. Please excuse my brevity.

-- 
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: classpath and require

2010-06-19 Thread Rasmus Svensson
2010/6/18 Mohammad Khan 

> C:\Projects.clj>java -cp
> c:\clojure-contrib\clojure-contrib.jar;c:\clojure\clojure.jar clojure.main
> Clojure 1.1.0-alpha-SNAPSHOT
> user=> (require 'examples.introduction)
> java.io.FileNotFoundException: Could not locate
> examples/introduction__init.class or examples/introduction.clj on
> classpath:  (NO_SOURCE_FILE:0)
> user=>
>
> C:\Projects.clj>echo %CLASSPATH%
> C:\Projects.clj;C:\clojure;C:\clojure-contrib
> C:\Projects.clj>dir examples\introduction.clj
>  Volume in drive C is xxx
>  Volume Serial Number is -
>  Directory of C:\Projects.clj\examples
>
> 06/18/2010  04:52 PM40 introduction.clj
>1 File(s) 40 bytes
>0 Dir(s)  xx,xxx,xxx bytes free
>
> C:\Projects.clj>
>

Hello!

To me it looks like you have gotten the most things right. As I see you
understand, you must have clojure, clojure-contrib and the source on the
class path. However, how these are specified can be a bit tricky. There are
basically two cases: directories and jar files.

When using jar files, the jar file itself must be in the class path, not the
directory which contains it. In our case, the entries would be
c:\clojure\clojure.jar and c:\clojure-contrib\clojure-contrib.jar, just as
you wrote.

When using folders with clojure source files or ahead-of-time compiled
classes, the directory that contains the folder that represents the topmost
component of the namespace. For example, in your case the namespace
examples.introduction is stored in the file
C:\Projects.clj\examples\introduction.clj so the directory C:\Projects.clj\
should be inlcuded in the class path.

When Clojure loads the namespace examples.introduction, it will try to find
examples\introduction.clj in every directory (or jar file) in the class
path. The error you got is an indication that no matching file could be
found.

On windows, the paths are delimited with semicolons, but on most other
platforms colons are used. That's why most examples will use colons. If the
paths in the class path contains spaces or other special characters, you
should enclose the thing in spaces, like this:

java -cp "C:\path one\;C:\path two\" clojure.main

>From what I can tell, Rob's example should work. I'm not sure if a trailing
backslash is required for directories, but you could try with and without it
to see if it makes any difference. If that doesn't work, try renaming
projects.clj to something without a dot in it. Also, look carefully for
typos...

I hope this helps...

// raek

-- 
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: compiling the instructions of a simple vm into a function

2010-06-19 Thread Nicolas Oury
There is two way to make a domain-specific language with a clojure back-end
:
- if you want the language to be an extension of Clojure, still to be used
in a REPL or by clojure source
   -> you write macros. That's what I call embedded.  There is a lot of
litterature on Embedded Domain Specific Language in functional languages. (A
*lot* in Haskell, for example)
In this situation, eval is most of the time evil.

- you want to read instructions that are very far from Clojure in a file and
execute them. (Your case, not by choice but because of the ICFP  specs).
Then, eval is necessary. But you have to call it only once per compiled
function, ideally, and never while executing the code (for performance).
In your situation, I would write
(defn compile-instruction [instructions] ...)

Then, when reading the instructions
(let [compiled-function (eval (compile-instruction (read-file...)))]
 ...

Then, eval is called once, just after reading and compiling. And
compiled-function is a real Clojure function.

Have fun,

Nicolas.







On Sat, Jun 19, 2010 at 3:39 AM, Eugen Dück  wrote:

> Thanks Nicolas,
>
> your first variant resembles the generated code much closer than my
> initial approach, which is great. I need the eval though, to be able
> to pass in non literals. In my real program I'm reading the
> instructions from a binary file. So if I want to be able to do
> something like this:
>
> (def three-instructions '([+ 2 3] [- 0 1] [+ 1 0]))
> (def compiled (compile-instructions three-instructions))
>
> The macro would have to look like this:
>
> (defmacro compile-instructions
>  [instructions]
>  (let [memory (gensym "memory-")]
>   `(fn [~memory]
>  ~@(map (fn [[op m1 m2]]
> `(aset ~memory ~m1 (~op (aget ~memory ~m1) (aget
> ~memory ~m2
>(eval instructions)
>
> But I like your suggestion to turn it into a function even better:
>
> (defn compile-instructions
>  [instructions]
>  (let [memory (gensym "memory-")]
>(eval
> `(fn [~memory]
>   ~@(map (fn [[op m1 m2]]
>`(aset ~memory ~m1 (~op (aget ~memory ~m1) (aget ~memory
> ~m2
>   instructions)
>
> And
>
> (def compiled (compile-instructions three-instructions)))
>
> just works as before. So I guess macros don't add any value here.
>
> > eval is evil, but eval is not evil is a compiler (you have to evaluate
> the
> > code you read).
> > However eval is evil again in an "embedded compiler", when you use macro
> to
> > extend Clojure.
>
> What do you mean by "embedded compiler"?
>
> Eugen
>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with
> your first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en
>

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

Re: Basic toolset for non-Java programmer

2010-06-19 Thread Alex Ott
Hello

Paul Moore  at "Sat, 19 Jun 2010 00:08:54 +0100" wrote:
 PM> - Build tools: There seem to be things like ant, maven, leiningen. How
 PM> do they relate to each other? Is there an "obvious" best answer or
 PM> should I be expecting to check them all out depending on my needs? In
 PM> that case, are there any good comparisons around?

I use mvn or lein to build clojure code

 PM> - Profilers: Same sort of question - do IDEs offer this, are there
 PM> standalone tools?

I use VisualVM to profile code

 PM> - Testing: I've not really got to the documentation on Clojure's own
 PM> testing tools, so maybe that's all I need, but are there testing
 PM> frameworks I should look at, that sort of thing?

clojure.test provides enough features to test code

 PM> - Deployment: For simple standalone utilities, am I looking at bat
 PM> file wrappers (I'm on Windows mainly) to set classpath and the like?
 PM> Given that there are some annoying limitations with bat files (nasty
 PM> nesting behaviour, ugly console windows for GUI applications), are
 PM> there any commonly used better solutions? For web applications, I
 PM> gather that a servlet container (all that fancy J2EE stuff :-)) and
 PM> something like compojure is a good place to start. For non-web
 PM> long-running services, is it still reasonable to use an application
 PM> server, or should I be looking at something to wrap a Clojure app up
 PM> as a Windows service (something like "Java Service Wrapper"
 PM> (http://wrapper.tanukisoftware.org/doc/english/download.jsp) came up
 PM> for me on a Google search)?

I use procrun from apache commons daemon project to run clojure app on
windows as service. All works fine, except case when you need to load
resources manually.  See ticket #379 in Clojure's Assembly for more details

To build installers I use izpack from maven

-- 
With best wishes, Alex Ott, MBA
http://alexott.blogspot.com/http://alexott.net/
http://alexott-ru.blogspot.com/
Skype: alex.ott

-- 
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: Enhanced Primitive Support

2010-06-19 Thread Nicolas Oury
On Sat, Jun 19, 2010 at 3:12 AM, Rich Hickey  wrote:

>
> I have to say I'm in the 'pay for what you use' camp - you need a box, you
> ask for one. If I don't (and neither do any of those loops), why should I
> have to do extra work to avoid it?
>
> Rich
>
>
> +1.

It is often very easy to spot integers that can grow above 10^18. Again, >
95% of number variables that someone will write in his life never will
attain that because they are somehow referring to a ressource, either in the
computer (counter, indices) or in the real world.

So, except for scientific programming, fact, fib and ackerman, that's not a
problem. (For scientific programming, I argue people should know what to do
with numbers). I still would like to have a real world example were it is
hard to predict and to solve.

On the other hand, having boxed by default is a very significant slowdown
(10% on the strange program I tried, that had already a lot of annotations,
probably 20% or more on most programs), that can never be addressed : you
can't write annotations on every single line of your program.

So, we take a 10/30% speed hit, that won't be solved, mainly because we want
people writing their first Fib or fact function not to have an exception
thrown. I think people can handle this level of complexity.


If boxed is the default, I advocate at least a flag allowing to change that
(and possibly allowing int as a default for embedded stuff).
Most problem with semantic changing flag disappear if the flags have an
order.
It is close to choosing the size of your heap on the command -line, which is
a semantic-changing run-time flag...

-- 
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: Enhanced Primitive Support

2010-06-19 Thread Konrad Hinsen
On 18.06.2010, at 15:31, Nicolas Oury wrote:

> In this situation, I would rather have some kind of toggle 
> *use-bigints-by-default* (defaulted to false) used by the compiler.
> Then, if someone needs big integers, he can switch the toggle and recompile 
> everything.
> You wouldn't have to change the libraries ns. 

I don't think it's a good idea to have a compiler switch change the semantics 
of number handling.

> As for being predictable, if you have numbers that can be bigger than 10^19, 
> you would probably know it in advance.
> (indices, counters and the like don't grow that big)

True, but that's on a variable-by-variable basis.

Konrad.

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


Re: Clojure / Common Lisp Question

2010-06-19 Thread Tim Daly

Clojure is an amazing piece of work.

I'm interested in Clojure for the concurrency.

I'm also interested in the immutable data structure work.
Someone needs to write a paper about the performance
characteristics of immutable structures when the whole
structure changes. That is, what are the performance
comparisons of mutable/immutable for various sorts?

I'm using Clojure as a "console front end" to our
huge Java project. Rather than writing Java programs to
generate test or output I write Clojure.

Rich Hickey's insightful videos have caused me to stop
writing loops whenever possible. For me this is the same
level of "thinking-change" that happened when I moved to
using "Structured Programming" rather than GOTO (in Fortran).
Rich needs to write a paper called
  "Loops considered harmful"

Common lisp, however, gives me precise machine-level to
massive function semantics, e.g. (car ...) is a machine
pointer and (integrate ...) is a huge function but I can
freely mix them in (integrate (car ...)). I don't feel the
same "one-ness" in Clojure/Java.

In general, I'm a common lisp bigot :-)

Tim Daly

rob levy wrote:
As an informal survey of people who use both Clojure and Common Lisp 
for different projects, what do you see as the main determining 
factors behind your choice to use either Clojure or Common Lisp for a 
project,  given the present state of Clojure.  Let's only assume we 
are talking about projects you completely own and have complete 
freedom to do what you want with.


Common lisp:
   Compiled on the processor, fast.
   Reader macros. 
   Quality, not quantity of libraries.
   Multi-paradigm programming with no nudging -- programmer has 
freedom to be insane/bizarre in ways Clojure makes hard (see Let Over 
Lambda for examples)

   Downsides:
 Hard to deploy. -- but not a problem as server side of web app
 Can't run on on GAE. -- need to run a server or rent/maintain 
virtual server.

 Limited to native librares, though they tend to be awesome.

Clojure:
   Neat concurrency stuff.
   Better deployment. 
   Can run on Google App Engine. (maybe ABCL can too, but I wouldn't 
want to use that personally).

   Lots of Java libraries, many more than for CL.
   Increasing a large number of awesome native libraries.
   Downsides:
  As server side of web app in apache, less straigtforward 
requires Tomcat, Java crud.
  Java interop is great-- but Java itself sucks!  There is an 
impedance mismatch of language semantics.
  The nudging of paradigm/idiom makes many things easier in Common 
Lisp.
  Lots of cool benefits of Clojure (such as any/all GUI stuff for 
example) depend on crufty Java nonsense you must contend with.



So, for me at this point, if I don't need interesting concurrent 
stuff, and I do my own hosting, Common Lisp in Hunchentoot or mod lisp 
still seems like a superior web development approach.  On the other 
hand if I am doing desktop apps, applets, want to use GAE, etc, 
Clojure seems better.   I feel like as time goes on we will be more 
abstracted away from the pain of Java.


Any thoughts on how you make your decision for specific projects?

Thanks,
Rob
--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient 
with your first post.

To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en 


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


Re: Enhanced Primitive Support

2010-06-19 Thread Konrad Hinsen
On 18.06.2010, at 15:20, Rich Hickey wrote:

> Which then begs the questions:
> 
> - how will someone 'protect' themselves from libraries written using fastmath?

Using fastmath or not would be part of the library specification. Or, in 
general, of the documentation for each individual function. It may not matter 
at all for the user of some functions, but be very important for others.

> - similar looking code will change semantics when the ns switch is made - 
> seems dangerous as it might violate the presumptions of the original authors.

That is true, but it is true for any strategy to introduce new maths semantics 
into Clojure. As soon as there are two, there is a risk for confusion. And even 
if there is only one but different from the one in the past, there is a risk 
for confusion as well.

Konrad.

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