Aaron
--
Cheers,
Aaron Bedra
--
Clojure/core
http://clojure.com
In the early discussions of this new feature, it was pointed out that
people who want overflow capability can use the special "prime"
operators, but that the preferred way to do things would be to write
functions in such a way that you can pass in bigints if you want
overflow.
But it was also pointed out that passing in bigints to ensure overflow
would be a huge performance hit over 1.2 for cases where overflow only
happens sometimes, because this forces bigint math to happen all the
time, which is substantially slower than Clojure's existing strategy
of doing math on longs and only switching to slower bigint math when
overflow actually occurs.
To resolve this, it was proposed that Clojure would use its own BigInt
class rather than Java's built-in. It would start off as a stub that
forwarded everything to Java's implementation, but would eventually be
converted to a more intelligent interpretation that works more like
Clojure's existing system -- numbers small enough to be represented as
Ints or Longs would be represented that way and benefit from faster
computation.
As far as I know, the stub class was indeed implemented to preserve
the option to make these optimizations, but no one has actually
refined the BigInt class. I propose that these optimizations should
be done before Clojure 1.3 goes final, because this is a really
important part of ensuring good numeric performance for applications
that were previously taking advantage of Clojure's ability to handle
overflows. If this isn't done by Clojure 1.3 final, we're going to
end up with a body of code that, by necessity, uses the prime
operators, because the preferred strategy of passing in bigints will
be impractically slow. If we want to get people to use the idiom of
using non-prime operators and passing in bigints, we need to make sure
this approach performs well for the final release.
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clo...@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+u...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en
--
Howard M. Lewis Ship
Creator of Apache Tapestry
The source for Tapestry training, mentoring and support. Contact me to
learn how I can get you up and productive in Tapestry fast!
It's probably worth pointing out that various existing 3rd party
libraries that depend on contrib 1.2 will also fail on Clojure 1.3 - I
ran into this recently with CongoMongo. I went thru pretty much
exactly the same process Stuart described for getting CongoMongo to
run on Clojure 1.3 and now it runs on both 1.2 and 1.3 by depending
only on "new" contrib libraries.
You can read about that process here:
http://groups.google.com/group/congomongo-dev/browse_thread/thread/65e8981711d87f62
If you're interested in code, you can see the five commits containing
the necessary changes, ending at this commit and following the parent
chain back: https://github.com/aboekhoff/congomongo/commit/c1d143d7be3c2436017948efad2e668bd80ea191
--
Sean A Corfield -- (904) 302-SEAN
An Architect's View -- http://corfield.org/
World Singles, LLC. -- http://worldsingles.com/
Railo Technologies, Inc. -- http://www.getrailo.com/
"Perfection is the enemy of the good."
-- Gustave Flaubert, French realist novelist (1821-1880)
> So, if you are currently using Clojure 1.2, your upgrade path might look
> something like this:
>
> 1. Find the "new" contrib library you need
I am wondering how best to handle current contrib functionality, such as
clojure.contrib.reflect, that is being absorbed into 1.3 and does not have
a standalone contrib equivalent. Any suggestions?
I'm not sure how many of these there are. At least in the case of
clojure.contrib.reflect, the code is both short and standalone, so could
easily be copied to a project specific namespace.
--
Hugo Duncan
On 06/24/2011 11:31 PM, Alan Malloy wrote:
> What about juxt? Can we get rid of the "Alpha - name subject to
> change" in the docstring there?
http://dev.clojure.org/display/design/Contrib+Library+Names
--
Cheers,
Aaron Bedra
--
Clojure/core
http://clojure.com
A few weeks ago, I updated my contrib libraries for 1.3 (math,
combinatorics, priority-map). I would love to see one last snapshot
of all the old contrib libraries that work under 1.3.
As I discussed with Stuart offline, I was surprised to realize that
all contrib libraries that aren't explicitly ported by a volunteer to
the new structure will be going away. I had thought that anything
that worked under 1.3 would automatically get moved over, and was
disappointed to find out that was not the case.
I have a bit of time this weekend to move my contrib libraries over.
Can someone please explain to me what needs to be done?
Thanks,
Mark
Sure, let me elaborate on what I mean with a short but somewhat
contrived example.
Consider the following definition of factorial:
(defn fact [n]
(loop [n n result 1]
(if (zero? n) result
(recur (dec n) (* result n)))))
factorial overflows as soon as you get to (fact 21). Now, let's say
you don't know exactly at what point factorial overflows. So to be on
the safe side, the recommended procedure is to pass a bigint to the
factorial function and rely on contagion to make this work, i.e.:
(fact 21N)
The problem is that (fact 21N) in 1.3 is slower than (fact 21) in 1.2.
We're paying a big performance by relying on contagion.
Here's why:
In Clojure 1.2, the first 20 multiplications are done with longs, and
only when it overflows then the last multiplication is done with
bigints.
In Clojure 1.3, all the multiplications are done with bigints which are slow.
When this issue was first raised back when Rich floated the idea of
primitive ops with bigint contagion, he created the stub class saying
that eventually the plan would be to come up with a better version of
bigint than Java's BigInteger class in the sense that it would reduce
and compute with longs (and maybe ints) when in that range.
Now, factorial is contrived because overflow happens fairly early in
the process, yet the difference is still measurable. For many of the
statistics I compute in my work project, a substantial number of the
computations happen within the long range, but sometimes they
overflow. 1.3 kills performance for me if I try to leverage
contagion; I must convert everything to the overflow ' operators.
I was thinking about this recently because I was rewriting my
clojure.contrib.math to support 1.3. One of the things I had to think
about was how the expt function should behave. It would be most
compatible with 1.3's "outlook" if
(expt primitive-long primitive-long) returned a primitive-long or
generated an overflow error. But to implement expt in this way, I
also have to think about the fact that for many cases, exponentiation
will overflow. So what should users do? One option is I could also
provide a expt' function. But I ruled this out because then I get
caught up in a proliferation of two versions (regular and ') of nearly
every math function. It might be feasible to provide a single version
of expt that supports primitive math and then allow users to use
contagion (e.g., (expt 2N 100)), but this contagion will hurt
performance. So the only viable option I see is to implement expt
with boxed numbers and the *' operator, maintaining the same
performance profile as 1.2, but missing out on the possibility of
making the primitive math people happy.
Does this explanation help?
Thanks for your help.
Cheers,
Aaron Bedra
--
Clojure/core
http://clojure.com