[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Another ballot

Ballot A:

This is a follow-up to the Memorial Day ballot, raising some issues that
came up since the earlier ballot went out.  Please respond by Saturday
evening.  (My apologies to those of you who don't work on weekends, if
any such exist.  You've still got all day Friday.)  With some luck and a
lot of hard work, we may be able to wrap this whole process up by early
next week, and get an final manual out (minus proofreading and some work
on the index).

There are still some unresolved issues relating to the file-name stuff,
so there may be a supplementary ballot making some proposals in that

A1. Proposed that we add BSG's PARSE-INTEGER function in place of the

[I am mildly in favor.  It is easy to implement, and useful in writing
user interfaces.]
A2. Propose that PROCLAIM, the replacement for top-level DECLARE, will
evaluate its arguments as a normal function.  Note that PROCLAIM must be
wrapped in an implicit (EVAL-WHEN (COMPILE LOAD EVAL)...) in order to
work, so whatever the args are, they must be evaluable at compile time.

[Several people, most notably Moon, proposed this in their response to
the earlier ballot.  One advantage is that you can now easily include
constants declared earlier in the file in the body of a proclamation.
The disadvantages are that you have to quote each proclamation in the
usual case, and that it's a little harder to convert old DECLARE forms.
I'm in favor or the proposal.]
A3. Indicate which of the following you could live with, and which you

a. The old scheme in which package names retain their case, but are
matched in a case-insensitive way.  We would have to outlaw :, \, |,
other readmacro characters, and whitespace in package names.

b. My proposal to treat the package name part of a qualified symbol
EXACTLY like the symbol part, except that no symbol is created.  This
would allow things like |fOo|:|BaR|.  It has the disadvantage that |
can no longer be a macro returning a symbol but must be treated as a
sort of escape character.  This complicates the reader.  It also means
that when the package name is entered as a string, you have to be
careful of case.

c. A proposal by Moon to allow slashes (and therefore any character) in
package names, but not vertical bars.  Also to do symbol-like case
conversion on package names (so that they can be read with a subset of
the symbol-reading machinery) but case-insensitive lookup, so that users
don't have to worry about case when typing in package names as strings.
This would mean that two distinct packages could not have names that
differ only in case.  The effect is just like (a) above, except that you
can get the weird characters in using the \ convention.

[ I could live with any of these and have in fact oscillated between B
and C.  Right now I favor B.  As KMP points out, people find it totally
intuitive, and it's not THAT much extra work for the implementor.]
A4. Moon has pointed out that VECTOR-PUSH and VECTOR-PUSH-EXTEND take
their arguments in an order that is inconsistent with PUSH.  Propose to
fix this.

[In favor, of course.]
A5. Add KMP's (NTH-VALUE n form) for picking up one value from a form
that returns multiple values.

[I am mildly opposed to this.  As Moon points out, this would have to be
0-based and would be non-intuitive for that reason.  In addition, it is
rare to want some single value other than the first.]
A6. Propose to add GSB's proposal for a set of primitives to create
named structures.  (This was in recent mail -- I don;t want to repeat
the whole thing here.)

[I oppose this.  A nearly portable DEFSTRUCT package can be created now that
contains implementation-dependent forms in about three places.  That
doesn't seem like a sufficient maintenance headache to justify adding a
whole new level of user-visible standardized machinery.]
A7. EAK has asked that we vote on this:  Propose to eliminate SET and
FSET from Common Lisp in favor of (SETF (SYMBOL-VALUE ...) ...) and

[I strongly oppose this.  I just don't want to type that much stuff in
order to get this job done.]
A8. EAK has also asked that we vote on this: Propose that in Common Lisp
it is an error to do (apply '(lambda ...) ...).

[I am not sure of all the implications of this.  My inclination is to
leave this the way it is right now.]
A9. Propose that we reinstate VREF.  This is a fairly useless synonym
for AREF with one index, but people keep expecting to find it there,
even some who have not been through all the oscillation on this.

[Mildly in favor.]
A10. Add an optional integer seed to MAKE-RANDOM-STATE.  A given seed in
a given implementation always creates a random state object that
generates the same sequence of "random" numbers, but different seeds
create random states that are <mumble, handwave> unrelated.  As it now
stands, the only way to create distinct but repeatable random states is
to start from copies of the same state and run RANDOM for (very) different
numbers of cycles.

[I am in favor, unless there are implementation problems of which I am
A11. Propose that we adopt the APPLYHOOK feture, as specified by Moon.

[I am in favor of this.  It makes possible more refined forms of
single-stepping, at the cost of some minor extra hassle for the
implementor.  (Our lexical EVAL does not actually do a real APPLY, but
could arrange to if *APPLYHOOK* were non-null.) ]

When stepping through an interpreted program, it is desirable to be able
to pause before each evaluation, to pause after each evaluation so that
the value can be examined or changed.  These operations can be done with
the evalhook feature.  It is also desirable to pause before invoking
a function (whether a user function or a system function), so that the
values of the arguments may be examined or modified.  This requires the
applyhook feature, or else requires duplicating an unnecessarily large
part of the EVAL function.

The applyhook feature catches only APPLY operations done by EVAL.  It
does not catch APPLY done in other parts of the interpreter (i.e. by
special forms: CATCH-ALL and UNWIND-ALL are the only ones in Table 5-1
that would do an APPLY), nor does it catch APPLY or FUNCALL operations
done by functions (MAPCAR for instance).  Stepping through APPLY
operations done by a function such as MAPCAR are best done by
intercepting the call to MAPCAR, using the apply hook, and substituting
a different first argument.

The writeups for APPLYHOOK and *APPLYHOOK* should be largely copied
from the writeups for EVALHOOK and *EVALHOOK*.  I have not made any
attempt to do this, but have just indicated the differences.

New variable *APPLYHOOK*:			(analogous to *EVALHOOK*)
When non-NIL, EVAL behaves in a special way.  Whenever it is about to
apply a function to the values of the function's arguments, which have
already been evaluated, instead it calls the value of *APPLYHOOK* with
two arguments: the function and its list of arguments.  Whatever values
the hook function returns are taken as the results.
The list of arguments is just like an &rest argument in its volatility.
If the hook function just calls APPLY on its first two arguments, EVAL
would behave in its normal way except a little slower.  (Of course the
preceding sentence isn't true in a lexical interpreter, where the
internal environment-taking APPLY isn't accessible to the user except
through the APPLYHOOK function, below.)

The apply hook function gets additional "env" arguments just like the
eval hook function.

EVAL binds both *EVALHOOK* and *APPLYHOOK* to NIL around calls to either of them.

EVALHOOK takes an extra argument:
*APPLYHOOK* is bound to the third argument (before the "&rest env"), a function
or NIL.

New function APPLYHOOK:				(analogous to EVALHOOK)
The arguments are function, arglist, evalhook, applyhook (&rest env).
This function is completely analogous to EVALHOOK and is to be called by
*APPLYHOOK* functions in the same way that EVALHOOK is to be called by
*EVALHOOK* functions, to "jump back into the interpreter".

Macros and special forms:
*APPLYHOOK* does not affect the invocation of a macro expansion function.

*APPLYHOOK* has no effect on the evaluation of special forms.
A12. Add a simple form of destructuring LET macro.  DLET would allow
arbitrary list or tree structures in place of the LET variables.  The
leaves would be symbols, the variables to bind.  The LET values would be
picked apart according to these patterns and the pieces assigned to the

[ I propose this with some trepidation.  I am in favor of destructuring
if it goes just this far, but every time we've brought this up someone
pops up with a proposal to destructure vectors, arrays, structures,
character objects, bignums, and the family cat, and to let destructuring
creep into all parts of the language.  Can we vote on the proposal above
and let people who want more complex destructuring do it as a
non-standard extension or wait till the seond edition? ]
A13. A modification to INTERN and FIND-SYMBOL, suggested by Moon:
Both of these functions return two values.  The first is the symbol that
was found or created.  (FIND-SYMBOL does not create a new symbol, but
returns NIL for the first value if no existing symbol was found.)  The
second argument is NIL if no existing symbol was found and takes on one
of three values if a symbol was found:
  :INHERITED (implies internal).
We can now flush FIND-EXTERNAL-SYMBOL.  If you want this, call
FIND-SYMBOL and see if the second value is :EXTERNAL.

[I am in favor of this.]
A14: Proposed by KMP that we rename MULTIPLE-VALUE to MULTIPLE-VALUE-SETQ.

[ Yes!!!  Long overdue.  We don't want users to favor this over
MULTIPLE-VALUE-BIND just because the name seems to imply that this is
the canonical MV function. ]
A15: Steele propose the following:

There has been a lot of flak about the decision that every
implementation must support arrays of rank up to 63.  There are similar
problems with numbers of arguments, and Moon has raised an objection
concerning the equating of valid array dimensions with fixnums.

I propose that we recant a bit, and set no hard limits, but realize that
programs may not be portable by reason of pushing on those limits.  So
that programs may probe the environment, introduce these constants:

ARRAY-RANK-LIMIT	As before, the implementation only supports arrays
			of rank less than this constant.
ARRAY-DIMENSION-LIMIT	Limit on each array dimension.
ARRAY-TOTAL-SIZE-LIMIT	Limit on total size of an array.
CALL-ARGUMENTS-LIMIT	Limit on number of arguments in a function call.
CALL-VALUES-LIMIT	Limit on number of multiple values a call can

We may think of other implementation parameters to make available as
well.  The intent is that no hard limit is set, but that each
implementation should make these numbers as large as practicable.

[ I'm in favor. ]
A16. Guy proposes that we get rid of MACRO, which is a trap for
unsuspecting users who ought to be enjoying the benfits of DEFMACRO.
We need something for DEFMACRO to expand into.  Guy proposes a function
named SET-MACRO that takes two evaluated arguments: the symbol that is
to be defined as a macro and the expansion function.  So if we want to
define a macro named FOO and its expansion function is
(LAMBDA (CALLFORM) ...), we (or rather defmacro) would use
(SET-MACRO 'FOO #'(lambda (callform) ...))

In effect, SET-MACRO does whatr one might express as
	      (make-a-macro-object #'(LAMBDA (CALLFORM) ...)))
except that SET-MACRO hides the existence of this odd macro-object
(if indeed that is the way it is implemented internally).

[ I'm in favor. ]
A17. Per EAK's suggestion, require (integerp 4/2) to be true and also
require (integerp (complex 4 0)) to be true.  That is, rationals always
reduce to canonical form, and so do Gaussian rationals.  More specifically,
any attempt to create a rational whose value is integral will in fact
result in an integer; and any attempt to create a complex number whose
real part is rational and whose imaginary part is the integer zero will
result in a rational, namely the real part.  If either part of a complex
number is floating-point then the complex number must remain complex.
Thus all Gaussian rationals have a unique canonical representation,
while (totally or partially) floating-point numbers maintain their
data type more distinctly (which is important for numerical reasons:
in IEEE arithmetic it is very important to distinguish 1.0, 1.0+0.0i,
and 1.0-0.0i !).

[ Guy supports this.  I'm indifferent. ]