#3 Forward Polymorphic vs. Backward Polymorphic

Well, the Solve code was meant only as an example of a more or
less working approach. There is a use for something "more
polymorphic" and "less polluting", IMHO.

Glad to see the interesting discussion.

About the C++ - like approach, where the operators are a part of
the class definition:

I think, it is not the best possible:

1) The basic types of the language (even in C++) are handled
differently - if you want to find out everything about Integer!,
you should look at the descriptions of the Core functions handling
Integer! values.
2) The C++ approach is "backward polymorphic" in a sense, as
opposed to "forward polymorphic" (the difference can be described
as a difference between the first Solve wording and the second
one). If I forget to define the division for the complex numbers,
then there is no other way, than to rewrite the definition of
Complex!, if it must contain all operators handling Complex!
values. Are you sure, that you can tell all the operators needed
for the complex values not only now, but in the future?

#4 Types

As you could have seen, when I tried the polymorphic approach, I
had to adjust the type system accordingly (cf. Complex?). Was it
Rebol-like? I think not. The difference is as follows:

1) Weak Type Checking vs. Strong Type Checking

complex? make object! quaternion! [
    re: im: jm: km: 0
]

the result is true, which may sometimes be not exactly the right
thing. From that point of view I would call Complex? Weak Type
Checking as opposed to Strong Type Checking used in Rebol.

2) Type vs. Internal representation:

>> same? 1 1.0
== true
>> type? 1
== integer!
>> type? 1.0
== decimal!
>> for i 1 10.0 1 [print i]
** Script Error: for expected end argument of type: integer.
** Where: for i 1 10 1

, so Rebol even for the same values distinguishes between their
internal representation - Rebol natural types (not pseudotypes)
are the names for the internal representation, not for the set of
all possible values, otherwise could be Decimal? 1 True and the
Integer! datatype could have been a subtype of the Decimal!
datatype.

3) Predicate Types vs. Pseudotypes

Pseudotypes are something added for the sake of conciseness, I
think.They can be simulated through Predicate Types as follows:

num?: func [x [any-type!]] [
    any [integer? x decimal? x]
]

Predicate types are normally weak, as can be seen here from 1),
but you can have predicate types like:

nonzero?: func [x [any-type!]] [
    all [number? x not zero? x]
]

, which may be of some use.

So, to finish this part: the Rebol typesystem is strong, the
organic approach should take that into account together with the
stress on the internal representation.

Bye 4 now

Reply via email to