On Sat, Jan 15, 2011 at 1:06 PM, Stuart Halloway
<stuart.hallo...@gmail.com> wrote:
> We have thought about this quite a bit, and an argument from one axis only 
> (e.g safe/unsafe) that doesn't even mention some of  the other axes is not 
> likely to be persuasive. Would be more interesting to see a new axis we 
> haven't thought of...

Here's an axis that hasn't gotten much discussion:  How evident is the
behavior of Clojure code, and what features help and hinder this
clarity?

Clojure is a dynamically typed language, which means that generally
speaking, it is not obvious what the type of a given variable is,
since there aren't annotations immediately prior to the variable
telling you what it must be.  Similarly, a Clojure IDE does not offer
any way to to "hover" over a variable and see what the type is.  There
is a lot of freedom that comes with this, but the cost is that a
dynamic programmer must be careful to document in some way what kinds
of things are acceptable inputs, and what kinds of promises are made
of the outputs.  The compiler can't check this, so it's up to the
programmer.  As Clojure programmers, we take on the responsibility of
tracking a certain amount of "unseen information" that isn't readily
evident from the code itself, but there's a limit to how much
responsibility programmers can take on before programs become brittle,
so new features should take this "axis" into account.

Primitives are especially problematic because there is no good way to
determine whether something is a primitive or not.  Consider the
following interactions in the 1.1 REPL:
user> (type 1)
java.lang.Integer
user> (type (int 1))
java.lang.Integer
Any features involving primitives should be assessed from the
standpoint that it is extremely difficult to know from looking at code
whether something is a primitive or not.  Many of the new features
(e.g., static functions can now return primitives, literals are
primitives, but numbers that get stored in collections or cross
certain kinds of function boundaries are not), means that you'll
frequently end up with a mixture of primitives and non-primitives, and
it won't always be obvious which is which.

When designing math operators that behave one way for longs and
another for bigints, one question that needs to be asked is: "How
apparent will it be whether a variable represents a long or a bigint?
If it's not apparent, how will the programmer know which behavior to
expect?  Is there any tooling that can help make this more
discoverable?"  One possibility is that Clojure programmers will need
to evolve ways to track this information, perhaps by explicitly
commenting in code whether a function can gracefully handle both longs
and bigints.  On the other hand, there's already a history in Clojure
and similar languages of just documenting certain vars as "numbers"
without needing to get more precise than that, so this could be a
painful transition for many programmers who are not used to thinking
about specifying their numeric types in greater detail than that.

Because it's difficult to do "typeflow analysis" within a
dynamically-typed language as Clojure, this clarity axis also comes
into play when thinking about what sorts of burdens are going to be
placed on library developers.  As a case in point, I developed the
expt function in clojure.contrib.math because I was surprised when I
first came to Clojure that no generic exponentiation operator existed
in the language.  The expt in contrib handles all of Clojure's numeric
types seamlessly.  But what am I supposed to do with expt in Clojure
1.3?  New expectations are being created with the new model -- some
people will expect expt with primitives to return primitives; some
will expect computation with longs to return bigints when necessary,
since exponentiation frequently overflows.  Do I need to provide an
expt and expt' function to make both camps happy?  (For that matter,
is there even a way to overload expt for both primitive longs and
primitive doubles, or do I need to make separate expt-long and
expt-double functions?)  Are we going to see a proliferation of
variations for all mathematical functions once we start going down
this road?

This is an axis I think about a lot, and I hope this is something that
the Clojure dev team is carefully considering as well.

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

Reply via email to