In article <49poaf$bj6@percy.cs.bham.ac.uk>,
sfk@com.hp.hpl.hplb (Steve Knight) wrote:
>Jonathan writes:
>> Actually, if you want a fast prototyping language, I don't understand why
>> you should have to declare any local variables at all
(snip)
>
>Duh. I think this is just poorly worded. Here's my spin on
Um, no. I think I meant what I said. I'm implying that you have to
declare _non-local_ variables. I see declarations as a way to distinguish
kinds of variable. In most languages, a major use for this (i.e. a
major difference between variables) is the type information.
In pop11, most variables are untyped, so declarations are mostly used
to indicate scope (lexical, dynamic etc.) and access (constant, protected
etc.) and also (unusual in most languages) syntactic type (macro, syntax
etc.).
In all cases, in pop11, there are defaults. So absence of a declaration
used to mean "global scope (not the same as a 'global' declaration :-(),
identifier syntactic type, full access (i.e. not constant), untyped".
I'm suggesting that it would be more sensible to make all the defaults
the safest, most common case. Unfortunately, there is a conflict of
interest between "safest" and "most common'. For variables in
the body of a procedure, the most common case (as Aaron pointed out)
is for calling globally scoped procedures. If we exclude these somehow,
then the most common case is, IMO, lexically scoped locals.
I expanded on this in a different posting.
>this issue and, I suspect, something similar to Jonathan's
>view.
>
>There are certain syntactic contexts (input/output locals, loop
>variables) which name variables that, almost always, are declared
>the same way, as a lexical local. For example, in the code fragments
>below, the variable "x" is almost always going to be declared
>as an "lvars".
>
> define foo( x ); ...
> for x in ....
> ... fmatches [ ... ?x ... ] ...
>
>If these contexts were to be considered to be implicit declarations of
>the usual type, the number of explicit declarations would be significantly
>reduced and the code would be less error-prone and easier to understand.
>I think that Jonathan is saying that with the appropriate default
>declarations and appropriate syntactic constructs, the need for explicit
>local declarations disappears - and that is quite right.
That wasn't what I was saying - although I might wish it had been :-).
Certainly it would go some way towards what I was suggesting. In essence,
I see this as identifying many more cases - micro-contexts - where
variables are used, and making the default for variables in these
micro-contexts be appropriate. And the most appropriate is to make
them lexically scoped locals.
But there is still the issue of what to do about free variables. A
common lisp compile will usually give a warning unless such a variable
has been declared "special" globally. Pop-11 used to give such a
warning only once, and then implicitly carried out the declaration, thus
suppressing subsequent warnings.
At present, the requirement that you declare some attributes of an
identifier, but not others, seems to me to be inconsistent, although
I can see the reasons for it.
>
(snip)
>
>Firstly, I think that for loops should implicitly declare the
>loop variables. (And to make this work, we need explicit "free"
>declarations as Jonathan suggests.) Secondly, the for-loop
>syntax should be rationalised to eliminate the completely pointless
>exceptions. Thirdly, all block constructs (especially loops and
>if expressions) should introduce lexical blocks. And fourth, and
>most important of all, implicitly declared variables should be
>made non-assignable. The missing category of contant-lexical
>variables is sorely missed in Pop11. (N.B. lconstant is
>an entirely different concept, despite the name.)
>
I agree with all these suggestions as improvements to the existing
pop-11.
But, if I designed a completely new language, at risk of complete
verbosity, I would look very seriously at eliminating all "declarations"
completely, and requiring such information at every place[1] a variable
is used. Actually, I would only want this in a "production" language,
I would prefer to be lazy in a "prototyping" language, but there is no
reason why they shouldn't be the same language (with strict v. lax
compilation modes)[2].
A very long time ago, in Fortran, (unless you naughtily
overrode it) variables beginning I-N were integers, all others were
real (floats).
Nowadays, there is a common convention for C programmers to use a
simple prefix notation (called Hungarian or something - I forget)
to indicate the type of a variable. For example, you might declare
a boolean flag as
int bHappy;
The variable "bHappy" is actually an integer, but the b prefix indicates
to anyone reading the code that it is being used as a boolean flag.
Similarly, if you encounter a variable called "pfSize" you expect that
it is a "pointer to a float" etc.
In lisp, there is a syntactic construct for adding this information to
expressions, e.g.
(the integer foo)
(the (complex rational) (* z 3))
I could go on, but this is drifting off topic.
Jonathan
[1]I'm not sure whether a place would be each use, or a statement; but
probably not as large as a block - and certainly not as large as a
whole procedure.
[2]And then, when you got a mystery bug, you could put in all the
missing declarations, turn on "strict" mode, and get the system to
tell you what caused your bug, instead of having to do any debugging :-).
|