phimvt@... wrote:
> 3. Type checking
> In static languages all or almost all typechecking can be done
> at compile time (= as the program is being read). In dynamic languages
> this is not possible, and hence either programs are not checked at
> all, or are checked at run time. In Joy this means, in the case
> of the addition operator + :
> 1. Do we have two parameters?
> 2. Is the top an integer?
> 3. Is the second an integer?
> 4. Add them!
> Tests 2. and 3. are done by looking at a (one byte) field of the
> stack nodes. These fields are in addition to the value fields of the
> nodes (and the "next-link" fields of the nodes).
> Often the checks are unnecessary. Consider
> foo == + 10 *
> This will add two (hopefully) numbers and multiply the sum by 10.
> At compile time it will not be known whether the two parameters
> really are numbers, so the usual dynamically typechecked version
> of + has to be compiled. On the other hand, the sum is an integer,
> 10 is an integer, and so the compiler knows that the multiplication
> will receive correct arguments, and a stripped down version of
> multiplication is all that is needed.
> Again, you already know my views on premature optimisation.
> It would be of considerable interest to examine what kind of
> subset of Joy could be (easily) statically typechecked.
I'm very interested in a (mostly) static Joy too. Since you mentioned
the subject I'd like to give some brief examples of what my system can
do [I indicated some time back on the list that I was going to document
my type system fully but that is taking longer than expected due to some
niggling issues that remain to be resolved].
I won't say its "easy" but a static type system could do things that a
dynamic one can't. In particular, the runtime type passing model is (I
believe) impractical for polymorphism on return values or on implicit
context. Consider:
area-of-circle == dup * pi *
depending on whether the radius value on the top of stack is (say) a
floating point or a rational, we'd want the type of pi to be selected
accordingly. But since the pi function takes no arguments, the type
passing model has no way to disambiguate it. In my system,
pi (float) == 3.1416
pi (double) == 3.1415926535
pi (rational) == #314159/10000
... etc
and the system infers the correct selection based on the dataflow
context the function is instantiated into.
In graphics work its common to permit some tolerance when comparing
values:
=.approx == - abs epsilon <
(for now treat '=.approx' as if it were a single name)
this function expects two like values on top, subtracts them, converts
the result to an absolute value and finally checks to see if this is
below some threshold (denoted here by 'epsilon'). The precise value of
epsilon will depend on the types involved (eg. are we comparing floats
or doubles or ...) and also can vary depending on the intentions of the
programmer. For example, during curved surface intersection the
calculations tend to be quite complex and therefore precision may be
lower, hence a larger epsilon value could be desired. In my system you
can specify whatever cases are needed:
epsilon.small (float) = 1e-30
epsilon.big (float) = 1e-28
epsilon.small (double) = 1e-70
epsilon.big (double) = 1e-68
... etc
Then use explicit context refinement to indicate intention:
foo == (=/approx) (epsilon/small) = swap = and
The (../..) are context refinements. In this case, we're saying that we
want the 'approx' notion of equality and the 'small' notion of epsilon
(the refinements stay in place for the scope of the function).
Explicit context refinement also allows polymorphism on global
properties like the target operating system, build configuration, cpu,
etc. For example:
main ==
(os/linux)
(build.fileformat/gif.jpg.bmp.pcx)
(build.type/ELF)
(cpu/alpha)
do-stuff
then within the program you can distinguish cases like:
foo.alpha == ... do foo in an alpha specific way
foo.x86.linux == ... do foo in an intel & linux specific way
foo.x86.windows == ... do foo in an intel & windows specific way
... etc but can then use it everywhere simply as 'foo'
I've left out _lots_ of detail in these explanations but I hope that the
basic ideas come across. Overall, you can do some interesting things
statically.
--
Louis.