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

Re: the forward method [dynamic vs. static typing]

On Dec 9, 2003, at 14:43, Tom Lord wrote:

> Rather than DT vs. ST being a polarizing dichotomy, isn't it more like 
> DT is some core around which we want to facilitate an open-ended range 
> of static declarations of various sorts?


Having programmed extensively in Dylan[1], I don't see much of a 
distinction between "static typing" and "dynamic typing". I see them as 
regions on a continuous, sliding scale. Similarly, I think of "compile 
time" vs. "runtime" as a range along the axis of time.

Speaking loosely, programs are nothing but dynamic behavior[2]. They do 
things. They compute. They perform I/O. They generate entropy when 
evaluated by a computer. In that regard, all programs are "dynamic" to 
one degree or another. On the other hand, "static behavior" is 
effectively an oxymoron. However, we can statically analyze those parts 
of a program that are bounded to one degree or another. For example, 
the behavior of the "if" statement with respect to boolean values is 
usually fixed for all time, but the behavior of a particular "if" 
statement usually depends upon some amount of information known only at 
runtime--or more generally, during some range of time, which can be 
before, during, or after "compile time". The amount of information 
available at a particular point in time determines the amount of static 
analysis possible at that time. One of those times is compile time[3].

The degree to which a program is "statically typed" is dependent upon 
the amount, kind, and precision of the information known about the 
behavior of each region of code in that program at a particular point 
in time.

But enough abstractions.

Type declarations in Dylan (which are optional, by the way) put limits 
on the amount of change that can occur at runtime[4], and therefore 
allow more or less static analysis. You can define a program such that 
it is possible to completely analyze it statically, or disallow most 
such analysis, or anywhere in between.

For example, I can write a function that handles any object, which we 
might say is "completely dynamic". In this case, the language 
definition provides all the information we need and static analysis is 
trivial: By definition, this function can never be called with an 
invalid value. (Although such analysis doesn't really tell us much 
about the program we didn't already know.)

Or I can use a type declaration to limit a function to accept only 
numbers. Static analysis can then tell me if a particular call site 
will, won't, or may call that function with something other than a 
number. We might call this "partially static" or "partially dynamic", I 
suppose. If I'm writing a math function that's valid for all kinds of 
numbers, such a type declaration is "precise" (or "static") in the 
sense that it exactly describes the values for which this function is 
valid, but it's also "imprecise" (or "dynamic") in that the exact value 
at any given point in time varies.

If I really want to ratchet things down, I can declare that function to 
only accept integers of a particular size. Assuming such a class has no 
subclasses, this is "completely static". But, really, it's still only 
"static" to a degree.

We can go even further. Dylan supports range types, for example. We can 
say our function accepts only integers in the range 1..10. This could 
be considered "more static" than the last case in the sense that there 
are fewer possible values at runtime. Static analysis can be more 
precise in this case.

Finally, perhaps, there are no "completely static" programs because 
language definitions can, ultimately, change. Rather, it's perhaps best 
to say that a given program is static in particular ways, to particular 
degrees, over some specific range of time, and that "compile time" is 
merely one particular point in time, and the act of "compiling" 
captures a certain set of information about a program at that point in 

In summary: Dylan's type system and type declarations show there is no 
fundamental distinction between "static" and "dynamic" typing. When 
discussing language design, we should instead consider where we wish to 
place the boundaries of change, and to what degree and in which ways we 
wish to enable static analysis.

[1] I programmed exclusively in Dylan for two years while working on 
the Harlequin Dylan IDE, now known as Functional Developer:


[2] Yes, from a purely functional perspective, programs can be 
described "statically", but the reality is that programs are performed 
by computers and physically alter the universe. More importantly, human 
beings inherently experience a dynamically-changing world, and all 
programs--even purely functional ones--describe some dynamic process 
from the human perspective. Which is perhaps another way to say that 
computers are dynamic machines that simulate "static" functions. [If 
you want to use this as a launching point for discussing the nature of 
reality, please change the subject line. ;-)]

[3] In fact, there are several interesting ways to capture program 
information at runtime to improve safety or performance, for example.

[4] There are many sources of such information. For example, Dylan lets 
you say specifically whether a class or generic function may be 
extended or altered at runtime, via "sealing" declarations. And, of 
course, as with any language, the language definition itself provides 
the foundation of static analysis.

Chris Page - Software Wrangler - palmOne, Inc.

   Dylan + You = Code