> It was the stackmark that _really_ annoyed me. The fact that the vestor
> version was different just rubbed it in. I think it's gross to have
> such a thing as a genuine item that gets popped off the stack. I'd
> rather have something that was transparent to popping. Then the
> semantics of % .. % would be something like "collect together
> everything that is put on the stack as a result of doing this
> and put it into the appropriate structure".
Well... a desirable property of semantics is that some predictions about
the behaviour of a program can be made automatically. A useful semantic view
of POP procedures is that they -parse- the stack for their arguments, and
-generate- their result. This can potentially support a rich type structure,
which is simply grammatical. However the question arises, what grammars are
appropriate for characterising this parsing. Clearly doing an arbitrary
computation is too general, so that from this point of view, procedures
that compute the number of arguments are -bad-. However the stackmark approach
works nicely, for the type of sysconslist is
<object_seq> <stackmark> => <list>
where
<object_seq> -> <object>
<object_seq> -> <object> <object_seq>
[Note that pushing something on the stack corresponds to pre-pending]
(here ARGS => RESULTS means "parse the stack for the arguments and generate
the results). With this concept of type,
[a], [% hd() %] =>
fails to typecheck, since the stack-grammar at the call of hd is
<stackmark> <list>,
and the type of hd is
<list> => <object>
The main problem with this approach to types in POP is that a kind of
quotient operation on grammars is required, which is theoretically well
understood, but of an uncomfortable complexity class.
This kind of scheme could probably be extended to deal with structured
argument counting (e.g. #|...|# brackets). And no doubt to parametric
polymorphism, so
<list('a)> => <'a>
would be a more precise characterisation of hd.
Robin Popplestone
|