Article View: comp.lang.misc
Article #3428Re: Dynamic typing (part 3)
From: Benjamin Chase
Date: Mon, 08 Apr 1991 16:55
Date: Mon, 08 Apr 1991 16:55
111 lines
5347 bytes
5347 bytes
gudeman@cs.arizona.edu (David Gudeman) writes:
> OK, try this. In mathematics you don't have to describe the types
> of objects unless the type is important. In statically typed
> languages, you have to declare the type whether it has any relevance
> or not (or fix it at compile time whether it is really knowable or
> not).
As we shall see below, delaring the type may not be quite as painful
as you suggest.
> In mathematics or dynamically typed languages you can describe the
> concept of a set or a sequence, and operations over those data
> structures, without refering to the "type" of elements. For example
> in math you could say
> If f is a function and s is a sequence, then map(f,s) is the
> sequence t such that for all i . t[i] = f(s[i]).
> In a Icon (a dynamically typed language) you could define
> procedure map(f,s)
> local t,i
> t := list(*s)
> every i := 1 to *s do t[i] := f(s[i])
> return t
> end
> Try to write this function in a statically typed language so that it
> has all the generality of the math and Icon versions.
I think you can write "map" in Russell, which is statically typed.
My Russell is a little rusty, so I could be wrong. There might be a
hitch with the declaring the result type of "map"; I'm not really
certain either way. This works by using a different notion of types
and polymorphism than you were probably expecting...
The type declarations for "map" look sort of parameterized in Russell.
Informally, they'd run something like
map(f:S->T; s:list of S) : list of T;
S has {V} /* value of (ie. rvalue of an lvalue, basically) */
T has {V,:=} /* value of, assignment operator */
{
}
I'm certain that I've got the syntax wrong. Anyhow, the gist is that
I require the types S (type of elements of s) and T (types of elements
of t) to support certain operations. This definitely has an o-o feel
to it, yes, and it might be helpful for purposes of your comprehension
to rephrase it as "classes S and T must support certain methods, named
V and :=".
> ... Furthermore, when you do use something like a type declaration
> in mathematics, it is to disambiguate or add clarify, and the nature
> of the declarations reflects that. In statically typed programming
> languages the purpose of the types is to let the compiler generate
> better code, and the nature of the declarations reflects that.
Such an efficiency-minded purpose is not so apparent in Russell. I
found the feel of type declarations for a polymorphic function to be
more of a flavor of "to use the function, your argument types must
support the following operations: ...". That seemed like a very
natural requirement to me, one that would hold for most languages,
either at compile time or at run time. I liked it from a
software-engineering aspect, too.
> I only have to show one example of "dynamic typing" in mathematics
> to show that mathematics is not "statically typed" in the universal
> sense of statically typed programming languages (and I did so
> above).
Careful. You may have instead shown a narrow view of what is actually
possible.
Now, having said all this, I will say that I am not an unflagging fan
of static typing nor of Russell. There are hard problems in Russell
regarding arrays, to which I never quite found a good solution. I
recall it being difficult to write a completely general-purpose matrix
math package, without having explicit (ie. run-time) checks that the
sizes of arrays matched appropriately. In particular, if you want to
code up a matrix multiply operation:
mult(A: array[m,n] of T;
B: array[o,p] of T) : array [m,p] of T
...
{
/* Ooops, need to basically do a run-time type check */
if (n != o) {
print("Hey, these arrays can't be multiplied!");
print("Their sizes don't match!");
}
}
(Of course, Russell's polymorphism over the element type T does work
like a champ. Oh, yeah, and it supports operator overloading and
precendence, so the above function was actually called "*", and you'd
say "A*B", like you'd want.)
So, I guess I'd like something like Russell, but maybe with a
dynamically typed loophole. I'd tell the compiler what I know, or
what I care to let it know, about my code. It would figure out what
it can (and perhaps informs me of what is left unchecked), and then
puts off the rest of the checking until run-time. I wish there had
been a way for the above run-time array size check to be done
automagically (I suppose you'd declare the arrays mxn and nxp then,
and unify the two n's?), and for the handling of such an error to be
done in some standard fashion (Modula-3 style raises/exceptions?).
--
Ben Chase <bbc@rice.edu>, Rice University, Houston, Texas
Technical Details
Message-ID:
<BBC.91Apr8115505@sicilia.rice.edu>Path:
arc1-ca.pugleaf.net!utzoo!utgpu!news-server.csri.toronto.edu!rpi!usc!cs.utexas.edu!bcm!rice!bbcReferences:
<1593@optima.cs.arizona.edu>Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!utzoo!utgpu!news-server.csri.toronto.edu!rpi!usc!cs.utexas.edu!bcm!rice!bbc From: bbc@rice.edu (Benjamin Chase) Newsgroups: comp.lang.misc Subject: Re: Dynamic typing (part 3) Message-ID: <BBC.91Apr8115505@sicilia.rice.edu> Date: 8 Apr 91 16:55:05 GMT References: <1593@optima.cs.arizona.edu> Sender: news@rice.edu (News) Reply-To: Benjamin Chase <bbc@rice.edu> Distribution: na Organization: Center for Research on Parallel Computations Lines: 111 In-Reply-To: gudeman@cs.arizona.edu's message of 8 Apr 91 00:41:22 GMT