[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?
Exactly.
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
time.
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:
<http://www.functionalobjects.com/>
[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
<http://www.gwydiondylan.org/>
<http://www.cafepress.com/chrispage>