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

[Gall: Bug Report]

Here are some comments on -portions- of the two long messages from Nick Gall.

    !section  9.1(6)    Nick Gall 85-03-19
    !version  Digital Press 1984
    !topic    Pervasiveness of declarations over FLET and LABELS

	      (defun the-many-function-names-foo (x)
		(declare (inline foo))
		(foo x)			; First call of FOO
		(flet ((foo (y z) (zap z y)))
		  (foo x x))		; Second call of FOO
		(foo x))		; Third call of FOO
    Declarations concerning function names should be treated as
    special variable declarartions are:  references are pervasively
    affected, but not bindings.

Agreed.  There are a number of areas in the language where the
implications of adding FLET and LABELS (thus adding local function
definitions) were not immediately obvious and therefore were not
reflected in other parts of the manual.

    !section  9.1(12)   Nick Gall 85-03-19
    !version  Digital Press 1984
    !topic    Non-Top-Level use of PROCLAIM

    Can PROCLAIM be used, other than at top-level?  Since DEFVAR,
    etc., are proclamations and can be used at other than top-level,
    the answer to this question seems to be `yes'.


    Is PROCLAIM a `declaration', i.e., must it appear only where a
    declaration is allowed?  Since it is allowed at top-level (unlike 
    DECLARE), and it is a function, and since the other proclaiming
    forms (e.g. DEFVAR, etc.) could not be considered declarations
    (since they perform evaluation and assignment), the answer must
    be no.


    Then what is the effect of using PROCLAIM (or one one the other
    proclaiming forms) in the middle of a function?  For example:

	      (defun foo (a) (zap a) (proclaim '(special a)) (zark a))

    Does the first reference to A refer to the local binding?  Does
    the second reference refer to the global?

PROCLAIM is merely a function, and has effect when it is called, not
when a call to it is compiled.  Your example might be rewritten as

  (defun foo (a)
    (zap a)
    (eval-when (compile)
      (proclaim '(special a)))
    (zark a))

were EVAL-WHEN permitted inside a function body (it is not; see p.66).
Of course you could write a macro that evaluates the PROCLAIM at macro
expansion time.  If you did so, you could properly be castigated for
using incomprehensible programming style, and I presume your program
would execute differently in different Common Lisp compilers and

    Some mention of the effects of the non-top-level use of PROCLAIM
    and the other proclaiming forms should be made.

On p.66 it says that DEFVAR is not allowed elsewhere than top-level.
PROCLAIM is the only function (rather than special form) that makes
declarations, and presumably the declarations it makes when it is
called take effect "immediately", but the exact definition of "immediately"
might be implementation-dependent.  For example, it is implementation-
dependent whether PROCLAIM affects interpreted functions that have already
been defined.

    !section  7.5(14)   Nick Gall 85-03-19
    !version  Digital Press 1984
    !topic    Scope and Extent of local function names

    NOTE: See 9.2 (ftype, function, inline).


	      (FUNCALL FOO 'BILL) => ?????

    Question: What does CAR refer to when it is used in the closure
			returned by CREATE-MAKEP?  I.E., What is the scope and
			extent of the binding of a local function name to a
			functional object?

    Section 7.1(1) states that "There are two spaces of variables in
    Common Lisp, in effect: ordinary variables and function names." 
    And the function name binding control structures appear in the
    section entitled "Establishing New Variable Bindings".

Lexical function name bindings and lexical variable name bindings are
treated identically.  This should, of course, be discussed in chapter 3.
See above comment about the implications of FLET and LABELS not having
been fully thought out and reflected in the manual.

    I suggest that Common Lisp go all the way, and allow a
    SPECIAL-FUNCTION-NAME declaration that would be analogous to the
    SPECIAL declaration for "ordinary" variables.

    Such a concept would make the idea of
    ordinary-variable/function-name binding and assignment much more

As I recall this was considered and rejected on the basis that it would
be confusing and wouldn't give any real increase in expressive power
(since FUNCALL of a special variable could be used).  I agree with that
decision, even though our implementation has always had the feature.
The only place where we use it is in a crock that could just as well be
done some other way.

    !section  10.3(9)   Nick Gall 85-03-19
    !version  Digital Press 1984
    !topic    Which  bindings are copied by COPY-SYMBOL?

	      "the initial value and function-definition of the new symbol
    will be the same as those of SYM..."

	      Does this mean that the (dynamic) value of the variable
    referred to by SYM, at the point where COPY-SYMBOL symbol is
    invoked, is copied?   Or, does it mean that the `initial', i.e.
    global value of the special variable named by SYM is copied?
    Although the wording seems to suggest the latter, it should be
    made clearer.

The word "initial" was meant to refer to the new symbol, not the old
symbol, I believe.  Probably no one realized the English could be
regarded as ambiguous.

    The same questions and suggestion applies to the
    function-definition copied by COPY-SYMBOL.

    !section  15.5(8)   Nick Gall 85-03-19
    !version  Digital Press 1984
    !topic    Is (TAILP NIL list) true or false for every list?


By the way, the index entry for TAILP contains a typographical error and
furthermore the function is documented in the wrong section (it's hard
to see a justification for regarding it as an operation on sets).

    "...TAILP is true if (NTHCDR n list) is sublist, for some value
    of N."  According to this definition NIL is a sublist of every
    list, since the (NTHCDR (LENGTH list) list) is NIL for every

Yes, this side comment in the text would better have been omitted.

    !section  20.1(7)   Nick Gall 85-03-19
    !version  Digital Press 1984
    !topic    Is *APPLYHOOK* funcalled for special forms?

    "The variable *APPLYHOOK* ... is used when a function is about to
    be applied to arguments."  Does `function' refer to a functional
    object which is in fact a function (i.e., its args. are evaled
    before it is called), or does it refer to any functional object
    (e.g., `special' functional objects)?

Special forms are excluded.

    Later in the paragraph, it is stated that, 

	      The apply hook function is used only for application of
	ordinary functions within eval.  It is not used for
	applications via apply, or funcall, for applications by such
	functions as map or reduce, or for invocation of
	macro-expansion functions...

    This paragraph does not really address the "application of
    ordinary functions within eval" but rather the "ordinary
    application of functions by eval."  

I disagree (but this may be an ambiguity of English).

					Also it does not clarify the
    action taken for special forms.

Indeed, it ought to say something like "linkage from EVAL to special forms."
Part of the problem is that there is no way, in Common Lisp, to describe
the intercommunication between EVAL and special forms, since it is
implementation-dependent and the language provides no way for the user
to add new special forms.  This is not a deficiency in the language (in
my opinion), just something that makes it hard to fit special forms into
that paragraph of documentation.

    !section  20.1(last-1)        Nick Gall 85-03-19
    !version  Digital Press 1984
    !topic    Is nil declared by defconstant?

	      ...all constant symbols declared by DEFCONSTANT, such as NIL,
	T, and PI.

    If NIL is declared by DEFCONSTANT then it can legally be
    redefined according to section 5.1.2(last):

	      Constant symbols defined by DEFCONSTANT ... may be redefined,
	if necessary, by using DEFCONSTANT again[].

    Is such an interpretation correct?

I do not believe that system-supplied constants can legally be redefined.

    !section  4.8(1)    Nick Gall 85-03-19
    !version  Digital Press 1984
    !topic    The meaning of the word `convert'

    Does coerce `convert' (i.e., change the type bits) and return the
    original object (or the pointer if typed pointers are supported)
    when possible (e.g., coercing a string to an array of
    (unsigned-byte 8) in some implementations); or does coerce ALWAYS
    create and return a new `equivalent' object; or does the Common
    Lisp spec. not define this?

Common Lisp does not specify sharing or non-sharing of storage between
the argument and result of COERCE.  I don't see how it could, since this
is necessarily very implementation-dependent.  But the documentation
could be clearer.

    !section  11.7      Nick Gall 85-03-20
    !version  Digital Press 1984
    !topic    INTERN's effect on an accessible symbol's owner.

	      As a verb, to `intern' a symbol in a package means to
	    cause the symbol to be interned (sic) in the package if
	    it was not already; this function is performed by the
	    function INTERN.  If the symbol was previously unowned,
	    then the package it is being interned in becomes its
	    owner (home package)...
					    CLRM Section 11.0 (pg. 172)

    I interpret this passage in the following way:

    ;; Current package is USER

    * (setf p1 (make-package 'p1 :use '()))
    {printed rep. of p1}

    * (import 'p1::xyzzy)

    * (symbol-package 'xyzzy)
    {printed rep. of p1}

    * (unintern 'xyzzy p1)

    * (symbol-package 'xyzzy)

    * (intern "XYZZY")

    * (symbol-package 'xyzzy)
    {printed rep. of user}

    In other words, INTERN ensures that the symbol that it returns
    as its first value has a home package.

    Is this interpretation correct?

I think the mention of accessible but unowned symbols on page 172 (in the
discussion of home packages) shoots down your example.  The result of the
last call to SYMBOL-PACKAGE is probably undefined.

    !section  11.7      Nick Gall 85-03-20
    !version  Digital Press 1984
    !topic    UNINTERNing a shadowing-symbol

    When uninterning a shadowing symbol (call it foo), UNINTERN
    collects all inherited symbols with the same print-name
    as foo, including foo (assuming foo was inherited).  If the name
    conflict is only between foo and one other symbol, what sense
    does it make to signal a name conflict error and give the user a
    choice between shadow-importing foo and the other symbol.  If the
    user chooses foo, it is no different from aborting from the

    In the above case, shouldn't UNINTERN just automatically
    shadow-import the other symbol?

Surely it is a bad idea to guess the user's intent in this pathological
case, rather than asking.  I suppose it would be legal for a debugger
not to offer the redundant option of shadowing-importing foo again,
although that doesn't seem like a feature of great importance.

I hope someone is listening to comments on unclarities in the manual,
such as Gall's, and that someday a revised and improved manual will
be issued.  The Common Lisp community is hardly in possession of the
same resources as the Ada community, so I don't think we can realistically
expect as precise a specification as Ada enjoys.