Somewhere earlier in this thread I said:
> > I would like proper typed variables in poplog. Yes, truly.
This has sparked some discussion, e.g. the latest item I've seen
in from Robin Popplestone. Amongst other things he says:
>Is "strong" the right adjective. Don't we mean "static"? I'd say that
(snip)
Although the discussion has moved on beyond this, I'd like to
go back and clarify what I originally meant. I said "typed
variables". Not strongly typed (indeed, I specifically made
that clear, I think). Also, I didn't say "statically typed".
Some static type checking may be desirable, but isn't what I said.
A type system in which you had everything you had now, plus the
option of typed variables, would not prevent anyone doing anything
they already do. Nor would it break any existing code.
One use I would like to make, of typed variables, is the following.
vars foo = [a list with 5 items];
integer n;
foo(4) -> n; ;;; this is ok
foo(2) -> n; ;;; this causes an error;
...
m * n * k => ;;;otherwise you don't find the error until here,
;;;and even then you may not know which variable
;;;has a non-numeric value.
I suspect the above behaviour would be difficult to achieve with
static typing, but would be easy with run-time type checking. (It
could also be emulated already, using active variables, but this
would nearly always be vastly less efficient than a built-in
typed-variable mechanism.)
Another, different, use of the "integer n" declaration would be
so that the compiler could use fast procedures for things like:
3 * n -> n;
It's strictly analogous to the use of procedure variables: type
checking is done on assignment, and subsequently you can use the
value of the variable without checking it. This is an efficiency
gain whenever you use a variable more times than you assign to
it. It is only an efficiency loss if you assign to it more than
you use it. And if you assign to a variable but never use its
value, possibly there are some other issues to think about. Like
whether you need the assignment in the first place.[Note 1, see
end of message.]
Also, an assignment like the above example does not require
any type checking when "*" is a constant procedure guaranteed to
return an integer if fed two integers. (There is an issue
here about arithmetic overflow, but I'm explaining a point,
not writing a detailed specification.)
This kind of type-checking on assignment is particularly
useful when you have complicated data structures, (or nested
lists) whose components can vary a lot. If you could declare
a variable as "list of list" then you can do;
list of list custard;
rhubarb(data) -> custard; ;;;type check performed automatically here
...
if hd(tl(custard)) == "bucolic" then ;;;no risk of "List needed" here
And in answer to a couple of other points earlier in the thread
(from different people):
Declaring several different temporary variables, because they
are different types, need not cause unnecessary code bloat, or
create more temporary variables in the compiled code. A
smart compiler can use register colouring techniques,
and will generate the same code as if you had used one
temporary variable if that's all you need. But, either at
compile or run time, you get additional checks and hence less
risk of bugs.
And, yes, the source code is longer (another point someone made),
but that is a Good Thing, for the same reason that code containing
(useful) comments is better than uncommented code.
Jonathan
[Note 1] There may be some situations where you do assign
to a variable more often than you check it. For example, initialising
a boolean flag before entering a loop, and setting the flag inside
the loop if some condition occurs, then checking the flag after
the loop, e.g.
boolean flag = false;
for x in list do
if something(x) then
action();
true -> flag;
endif
endfor;
if flag then
it_happened();
endif
Arguably, in this case, it would be more efficient to declare -flag-
as an untyped variable because it would need fewer run-time type
checks. Except that in this case -true- is constant, so the type
check can be static. I leave it as an exercise for the reader to
construct an example where type-checking on assignment is more
expensive than type-checking on use.
Jonathan
|