I agree with Nicolas. An overflow says "you did math that doesn't work
with basic numbers" and pretty much everybody coming to computers via
any path may encounter that from time to time. It's basic stuff.
There's a distinction between knowing that something can occur, and
expecting to have to handle it in user code. (Particularly without
something like checked exceptions to tell you about it.)
If you're coming from Python, or Common Lisp, or any one of a hundred
other languages, you know that numeric overflow can occur... and you
expect your programming language to automatically promote on your
behalf.
>>> math.factorial(50) + 1
30414093201713378043612608166064768844377641568960512000000000001L
We similarly expect our PL and OS stack to handle virtual memory
paging, garbage collection, and so on, even though that's "basic
stuff" that everyone knows.
The question here is whether Clojure is a "primitive" language, where
numbers are machine numbers by default, or a "modern" language, where
getting primitive math might require input from the programmer, but by
default all operations are promoting and conceal the limitations of
the hardware. (The big trick is that there are limitations imposed by
the JVM.)
My personal feeling is that one should be able to write non-hinted
code and have it work without exceptions for all input ranges, and
that the compiler should (a) do static analysis to optimize code when
enough info is available, and (b) provide rich compiler messages to
allow hints when it's not.
I am now firmly in
the camp that would prefer performance by default and fewer surprises
for folks new to Clojure.
This is interesting.
One set of folks considers non-machine-number performance to be
surprising, and wants to avoid it.
Another set of folks considers the possibility of arithmetic
exceptions for certain combinations of input to be surprising, and
wants to avoid them.
Nobody likes surprises, but discounts the other folks' surprise as
less important :)
That's probably colored by my background where most of the languages I
grew up with that shaped my experience gave you overflow exceptions
from fact( someLargeNumber ) but they calculated fact(
reasonableNumber ) very fast :)
I'm used to languages where the compiler gives you both, and if it
can't it can tell you why...
http://www.franz.com/support/documentation/8.2/doc/compiler-explanations.htm#explain-1
;Tgen1:Examined a call to +_2op with arguments:
;Targ2: symeval x type in fixnum range (integer 0 64)
;Tinf1: variable-information: lexical: ((type (integer 0 64)))
;Targ3: constant 1 type in fixnum range (integer 1 1)
;Tres1: which returns a value in fixnum range of type (integer 0 64)
versus
;Call1:Generated a non-inline call to /_2op:
;Tgen1:Examined a call to /_2op with arguments:
;Targ2: symeval sum type in fixnum range (integer -536870912 536870911)
;Tinf1: variable-information: lexical: ((type
(integer -536870912
536870911)))
;Targ3: constant 4096 type in fixnum range (integer 4096 4096)
;Tres1: which returns a value of type (rational * *)
--
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