[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

RE: another take on hackers and painters



The argument about 1 + "3" and what it should do isn't just a matter of
what to do with "3". There are two different questions to this problem.
One of which is being ignored and making the discussion a lot more
confusing than it needs to be, imo. :)

A) Who provides the interpretation for the operator and the contexts for
the operands?
B) How do you handle the case of coercion to the required context?

In typed languages, B is "you don't". This necessarily provides a lot more
freedom to A. A+B does different things depending upon whether the
operands are integers, strings, or floats. 1+1 returns 2, and "1"+"1"
returns "11". The interpretation of the operand uses the whole type system
to figure out which operand function is the desired one that matches the
operands.

Now, try showing a dynamic typing system to a static typing person, and
they go crazy. "1+"3"? Insane, bugs will proliferate!" To a static-typing
programmer, 1+"3" is as confusing as "1"+"3" is to a dynamic programmer.
The main difference is that in dynamic typed languages, the answer to
question B above allows for type coercion to the types necessary for the
operands.

This dynamic-typed choice isn't free, of course, and imposes additional
restrictions on the interpretation of the operator. "+" now cannot be
multi-methody, and cannot handle both strings and numbers. In these
dynamic languages, a *different* operator is used for numeric addition and
string concatenation (or catenation, if you prefer. ;) In Perl,
concatenation and addition are respectively provided by "." and "+".

I believe other languages mentioned can fit into the above spectrum pretty
easily. Dan's mention of DCL seems to  implement + with an eval-as-numeric
context to the operands. And in Icon, it seems to be just like Perl's
choice, but using "|||" and "+" for concatenation and addition.


Some languages even try to provide both choices for question B, and that's
when things get hairy. Perl, (and I'm assuming other languages as well)
allow you to override the + operator. This then causes the first operand
to interpret the + operator. And then to impose a context on the second
operand when the value is inevitably used in the internals of the addition
function/method. This makes things like func1()+2 do things that are
confusing when you don't know if func1() is returning an object. At the
same time, the overloading can hide much of the complexities of dealing
with complex numbers, or other semi-numeric forms, from the user.

In a further extreme, Perl6 wants to provide for MM-dispatch based upon
the types on both sides of the +. This is because Perl doesn't go far
enough, as func1()+2 and 2+func1() aren't commutative. In a MM-dispatch
scheme, the operands choose the interpretation for the + operator,
dispatching to the correct function. But at the same time, Perl6 wants to
retain the auto-coercion of +'s operands that make it so popular with
dynamic programming folks. At this point, things get confusing.
func1()+func2() does something that depends upon what both functions
return. And without static typing (or informal specifications) to
guarantee the return types, the programmer may go a-hunting. But again, it
does allow BigInteger and ComplexNumber to interact correctly, assuming
someone writes a library which supports the interaction of both, something
not previously possible.

More power to hide implementation from the user, all while making it
harder for the user to find the implementation. And to someone accustomed
to the complete execution knowledge that static typing provides, that can
be extremely scary, for good reason.

Are we really the first to have the dynamic versus static typing argument?
If we're not, then surely we should have realized that there is no single
correct answer, just opinions and preferences. :)

Mike Lambert