this is a followup to my previous message. If you did not like that,

simply skip this, since you will not like it ;-)

Im just working on a simple minded Dylan implementation, and since

Im

just arrived at the subject of types, I would like to make some

suggestions and

receive feedback/comments.

First Id like to introduce a new function "partial" that is thought

to create

new Dylan types, i. e. (indirect) instances of <type>.:

I wonder whether the concept of singleton and union types can be

extended in a reasonable way.

Consider this:

define method fak(n :: <integer>)

n * fak(n - 1);

end;

define method fak(n :: singleton(0))

1;

end;

What does "n :: <integer>" stand for? It means: take an object, name

it "n" and if it

is an integer then consider the enclosing method as applicable.

Similarly "singleton(0)" stands for compare n with 0 (==!) and use

this method if true.

To put it another way, there is a conceptual "decision predicate" that

rules

whether the method is applicable.

In the first case this would be "instance?(n, <integer>)", and in the

second "n == 0".

Now introduce the generic concept:

One could define new types on base of an arbitrary predicate function:

define constant >odd-integer< :: <type> = partial(method(i ::

<integer>) i.odd? end);

the instance? test for any <integer> is clear:

instance?(n, >odd-integer<) <=> (method(i :: <integer>) i.odd?

end)(n)

The subtype? test is somewhat trickier:

the base type of >odd-integer< would be <integer>, since the predicate

is

defined on this type. An optional #key argument "base: :: <type>"

could

override this assumption. One could infer the base type by

"function-specializers(predicate)[0]".

The obvious constraints would apply to the number of specializers

of the predicate and its result type (<boolean>) and to the

permitted "base:" argument.

Now lett play with that somewhat:

define method erasthotenes(i :: >odd-integer<)

// just sieve i here ;-)

end method;

define constant >eras< = partial(erasthotenes); // I cannot recall

whether this is

// the mathematical definition

// of pseudo-primes?

// (have a look into van der Waerden)

or:

define constant >unit< = partial(method(c :: <complex>) c.abs = 1

end);

even nicer version of >odd-integer< is:

define constant >odd-integer< :: <type> = partial(odd?);

since odd? takes <integer>s.

You get the message, what is going on here is the Dylan analogy to

the mathematical subset notation:

{c ? C | |c| = 1} (sorry for the special font but I dont think

TeX is more readable :-)

Now its time to refine the concept:

Imagine this:

define constant >colleagues< = partial(method(h)

member?(h, #(#"martin", #"jens", #"claus", #"dodo"))

end);

Quote:

>colleagues< would be equivalent to

type-union(singleton(#"martin"), singleton(#"jens"),

singleton(#"claus"), singleton(#"dodo"))

A better notation would be:

partial(#(#"martin", #"jens", #"claus", #"dodo"))

with a collection as first argument.

This way one could expressively write down explicit sets.

The compiler could infer the equivalence of the above three types,

since

"singleton", "partial", "type-union", "member?" and "=="

are all functions completely known at compile-time

and their arguments are literal constants.

Subsumming the above, the declaration of partial (with proposed syntax

from previous message) would be:

partial(pred :: limited(<function>, specializers: 1, results:

#(<boolean>))

#key base :: <type>) => part :: <type>

partial(set :: <collection>, #key comp :: <function> = \==)

=> part :: <type>

Just thinking...

Gabor

P.S.: A better name for "partial" is welcome.