Following on from Chris's comments about "vals" and "vars".
> [Quickly scanning the Pepper code to hand, I see more than 750 ``val''s
> and less than 250 ``var''s. These figures are distored in favour of
> ``var'' [deleted]
Even this is an underestimate in the ratio between val/var, which I reckon
is probably more like 10:1 rather than the noted 3:1, because Chris omitted
to mention that all input locals and loop variables are declared as val
by default.
My own experience of the val/var distinction is extremely positive. Here's
a (elderly) example drawn from $popautolib (the comments are my own).
define global countitem(file) -> x; ;;; global is soon to be obsolete
lvars c white = false, file x = 0; ;;; obsolete syntax.
discin(file) -> file;
until (file() ->> c) == termin do
if strmember(c, '\s\t\n\r') then
unless white then
x fi_+ 1 -> x; ;;; not safe for v. large files
true -> white ;;; (greater than 1Gb)
endunless;
else
false -> white
endif;
enduntil
enddefine;
In the above code, it is not obvious what variables are playing the role
of state variables and which are just placeholders for intermediate
quantities. Here's the same code in a "Pepper" style.
define countitem( file ) -> var x; ;;; The var declaration makes
0 -> x; ;;; dubious practice stand
false -> var white; ;;; out.
for c from_repeater discin( file ) do ;;; Here, c is a -val- !
if strmember( c, '\s\t\n\r' ) then
unless white then
x + 1 -> x;
true -> white
endunless;
else
false -> white
endif
enduntil
enddefine;
Note how the 2 var declarations pin-point the genuinely changing variables.
Also note that the assignment ``discin( file ) -> file'' has been removed
using the new loop syntax for repeaters. (This is just a more modern
phrasing of the same idiom.) The val/var annotations, to my mind,
really enhance the look of the procedure for the reader, provide useful
protection for the writer, and even make the compiler writer's job
slightly easier.
In this example there is a high proportion of 'var-types' (2 of 4) because the
problem chosen deals with state change. This reflects the coding style.
More commonly, we find libraries such as flatten, gensym, pipein/out,
which, as it happens, contain no variables that need to be var-type.
I've become a convert to the Pepper style of declarations. I believe
that once people try them, they'll all be clamoring for them!
Steve
|