Operator overloading [was: Re: Does my ideal language exist?] 
Author Message
 Operator overloading [was: Re: Does my ideal language exist?]

[Background for those joining the thread in comp.lang.dylan ...  This
sub-thread (here newly renamed) is discussing the tensions between
operator overloading being a good thing -- because it's used in maths and
it seems to work pretty well there to simplify communication -- and a bad
thing -- because it increases the potential for programmer confusion,
particularly when user-defined types are involved and/or your language has
implicit type coercion (e.g., C, C++, Java, JavaScript, ...).

Disclaimer: I'm a Dylan fan :-)]


Quote:


> > These languages are badly designed.  This is not the same
> > type of situation as combining various types of numbers,
> > vectors, and matrices, or even elements of more general
> > linear spaces or algebraic systems or sets.

> OK, let's 'add' scalars and vectors.

>    3 + (1 2 3 4 5)

> Could be: [... various plausible answers ...]

> You need to take a step beyond overloading into objects, then you can
> create appropriate behaviour:

>    3 + (accumulator 1 2 3 4 5) -> (accumulator 4 5 6 7 8)
>    3 + (orderedlist 1 2 3 4 5) -> (orderedlist 3 1 2 3 4 5)
>    3 + (set 1 2 3 4 5) -> (set 1 2 3 4 5)

> and so on.

> > >Either provide a complete object hierarchy, in whch case you gain the
> > >ability to provide type semantics (so that (3 inches) plus (10 feet) is
> > >(123 inches), and (3 inches) plus (10 pounds) is an error or raises an
> > >exception) and get something that's actually an approximation to
> > >physics or engineering, or don't even try.

Dylan does this: everything inherits from class <object>.  In addition,
there are NO implicit conversions.  (I'm pretty sure of that -- see the
Dylan Reference manual at < http://www.*-*-*.com/ ;.  I'm
not 100% sure how the type of numeric literals is decided -- e.g., "smallest
type that fits"? -- but they still aren't implicitly promoted etc.)

If you want a <double-float> from a <single-float> you have to convert with
the function "as".  However, you don't have to explicitly convert all the
time because functions like "\+" are defined to cover all combinations of
the built-in concrete classes.  If you try to, say, add two objects for
which no applicable method can be found, you'll get either a runtime
exception or a compile-time error, depending on when there's enough type
information.

Initially I though explicit conversion would be irritating but in (about 3
years of) practice it hasn't been.  Then again, I haven't done that much
heavily numerical programming in Dylan (and maybe I've just got used to it
:-).

Another way in Dylan to approach operators meaning different things in
different contexts is to use the renaming facility of Dylan's module system.  
Renaming is mostly just used to avoid name clashes but you can use it to
rename and hence "wrap" or outright replace standard functions (or from any
library), including the numeric operators.  The "big-integers" library in
Functional Developer (at < http://www.*-*-*.com/ > -- shameless
plug ends ;-) renames various operators and classes to give you 64-bit
(well, 61-bit I think -- see below) integers.  The neat thing here is that
you only have to change a module definition in your library to import/rename
differently -- all the rest of the code "in" that module just magically uses
the new objects via the original names.

However, both <number> and <array> are abstract, open classes in Dylan, so
you probably don't need to do this for the matrix multiplication examples
quoted earlier in this thread.  (BTW, don't worry: there are concrete,
non-extensible subclasses for the typical cases, so things can stay
efficient. :-)

Quote:
> > Again, this is for the user to do, not the compiler writer.

> It's certainly possible to write object-oriented code in classic
> procedural languages, but I'd recommend using a language that's designed
> for the job.

In particular, in the presence of implicit coercions (user extensible via
copy constructors in C++), the language may require more effort on your part
(e.g., the "explicit" modifer for said C++ constructors) just to prevent
things you didn't intend (and probably didn't want) from happening
automatically.

You may or may not be willing to trade this "riskiness" for some other
benefits a particular language provides.  In Dylan part of the trade-off is
that the default <integer> class, for example, is only guaranteed to provide
28 bits of precision, not 32 (although that's not related directly to
overloading etc.).  In practice this is okay, too: often you just want a
loop index to be "big enough" and you can find out what the
"$maximum-integer" is; when you do need 32 bits, a particular implementation
may provide a way to get them.

Quote:
> > >And, again, I have had painful experiences with overloaded operators
> > >changing the meaning of expressions in surprising and dangerous ways.

From my experience, I can certainly sympathise in terms of numeric type
promotions/truncations etc. in C/C++.

Hugh



Sun, 24 Nov 2002 03:00:00 GMT  
 Operator overloading [was: Re: Does my ideal language exist?]

Quote:

>If you want a <double-float> from a <single-float> you have to convert with
>the function "as".  However, you don't have to explicitly convert all the
>time because functions like "\+" are defined to cover all combinations of
>the built-in concrete classes.  If you try to, say, add two objects for
>which no applicable method can be found, you'll get either a runtime
>exception or a compile-time error, depending on when there's enough type
>information.

Algol 68 has strong typing. An integer of mode INT has a specific
number of bits, but if it has mode LONG INT it may have more,
depending on the implementation.

Operators for LONG INT operands exist in the standard library
(standard prelude) for all the usual arithmetic operators (+, -, *,
/, **) and can be defined for any other operator. The same applies to
REAL and LONG REAL. Any integer of mode INT cannot be automatically
converted to an integer of mode LONG INT: you have to use the LENG
operator. Similarly with SHORT SHORT INT to SHORT INT. There is
another operator SHORTEN which goes the other way around.

Operator overloading in Algol 68 is possible (and typical) because
the context of an operand is `firm' which means that integers cannot
be `widened' to real or complex numbers, nor converted into arrays
(`multiples' in Algol 68).

Quote:
>Initially I though explicit conversion would be irritating but in (about 3
>years of) practice it hasn't been.  Then again, I haven't done that much
>heavily numerical programming in Dylan (and maybe I've just got used to it
>:-).

Algol 68 is very good with numerical programming.

Quote:
>> It's certainly possible to write object-oriented code in classic
>> procedural languages, but I'd recommend using a language that's designed
>> for the job.

>In particular, in the presence of implicit coercions (user extensible via
>copy constructors in C++), the language may require more effort on your part
>(e.g., the "explicit" modifer for said C++ constructors) just to prevent
>things you didn't intend (and probably didn't want) from happening
>automatically.

The `automatic' conversions in Algol 68 are known as `coercions' and
are well-defined. Every context has a strength which is also
well-defined. At any point, a cast can ensure that a particular
construct will yield the mode required, but not like C.

Quote:
>You may or may not be willing to trade this "riskiness" for some other
>benefits a particular language provides.  In Dylan part of the trade-off is
>that the default <integer> class, for example, is only guaranteed to provide
>28 bits of precision, not 32 (although that's not related directly to
>overloading etc.).  In practice this is okay, too: often you just want a
>loop index to be "big enough" and you can find out what the
>"$maximum-integer" is; when you do need 32 bits, a particular implementation
>may provide a way to get them.

In Algol 68, environment enquiries will provide the programmer the
necessary information to determine the size of any particular
precision. For example, the value `int lengths' (of mode INT) is 2 if
both modes INT and LONG INT exist. This doesn't just mean that you
can write

        LONG INT li = LONG 36

but also that `max int' has a different value from `long max int'.
Any Algol 68 compiler should allow you to write

        LONG LONG LONG LONG REAL r = LONG LONG LONG LONG 2.0

but there is no guarantee that that precision is distinguishable from
the next precision down. Again, the value `real lengths' will tell
you what is available. There are other values which enable the
programmer to determine the exact precision (particularly important
for numerical calculations).

Quote:
>> > >And, again, I have had painful experiences with overloaded operators
>> > >changing the meaning of expressions in surprising and dangerous ways.

>From my experience, I can certainly sympathise in terms of numeric type
>promotions/truncations etc. in C/C++.

Just doesn't happen in Algol 68!

Regards
--
Sian Leitch (Software Engineer specialising in Algol 68)
Algol 68 for Linux will be available from me.



Sat, 07 Dec 2002 03:00:00 GMT  
 Operator overloading [was: Re: Does my ideal language exist?]


Quote:
> ...
> Operator overloading in Algol 68 is possible (and typical) because
> the context of an operand is `firm' which means that integers cannot
> be `widened' to real or complex numbers, nor converted into arrays
> (`multiples' in Algol 68).

i don't have access to algol68 material any more, but i am pretty sure
that in most contexts automatic widening did happen, while narrowing
had to be explicitely requested by in the source code.  the rational i
remember was that widening is always safe (in terms of value
preservation), while narrowing (i think that was the term they used)
usually implied a potential inaccuracy or value loss, so for most
narrowing operations there were several operators providing different
types of narrowing (like round / truncate / floor / ceiling)

Quote:
> ...

--

Hartmann Schaffer



Sat, 07 Dec 2002 03:00:00 GMT  
 
 [ 3 post ] 

 Relevant Pages 

1. Does my ideal language exist?

2. Finding Bugs(was: Does my ideal language exist)

3. Does my ideal language exist?

4. Does my ideal language exist?

5. Does my ideal language exist?

6. Does my ideal language exist?

7. Does my ideal language exist?

8. Overloading Operators: Extension to Language

9. Numerical programming (was: Overloading Operators: Extension to Language)

10. operator overloading and user definable operators.

11. Overloading logical operators and bitwise operators

12. Operator overload of base operator and compiler diagnostic

 

 
Powered by phpBB® Forum Software