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

Conservation of nits

Fahlman's Law of Package Systems: Nits can neither be created nor
destroyed.  It is occasionally possible to smash big ones into a whole
lot of little ones.

    I'd suggest
    that duplicate package name be an error for MAKE-PACKAGE, a primitive, but
    not for IN-PACKAGE, since you'd like to be able to load a program twice
    (presumably after changing it to fix something).

OK.  That's the way I had it originally, before our go-round about
IN-PACKAGE augmenting the externals of the package in question.

    I hope you realize that IN-PACKAGE is incompatible with incremental
    re-compilation of portions of files (after editing them), a Lisp machine
    productivity feature that users are uniformly enthusiastic about.  I
    would think that this would be something that Spice Lisp would definitely
    want, too, once you have a compiler that runs natively in your Lisp.
    I'm not sure yet whether we will strongly discourage people from using
    IN-PACKAGE, or whether we will provide a kludgey way for the editor to
    know that it must parse the beginning of the file looking for IN-PACKAGE
    in order to determine in what package to read forms from the file.

I don't completely understand this.  I looked for incremental
compilation in the Confederate edition of the Chine Nual and couldn't
find anything about it.  What exactly do you folks do?  I would have
assumed that if you do incremental re-compilation on an ASCII file, you
take some notice of the -*-Package:foo-*- business, no?  IN-PACKAGE
would have the same set of problems as that.  I would hate to have you
tell users not to use IN-PACKAGE.  Do you have a specific proposal?

    Say somewhere that the accessor function for the home package of a symbol


    It isn't clear from the description whether SHADOWING-IMPORT will call
    UNINTERN if the symbol being shadowed is directly in the package (rather
    than inherited with USE-PACKAGE).  Surely this must be what was intended.
    Also SHADOWING-IMPORT should be in the list of functions that should be
    used at top level.


    The writeup doesn't say why certain functions should be used at top
    level.  One reason is that if changes are being made to *package* with
    the expectation that they will affect how forms later in the file are
    read, then those changes had better happen at compile time before
    further forms are read from the file.  The other reason is that in many
    implementations the output from the compiler is designed so that the
    loader can look symbols up once, rather having to call INTERN every time
    a symbol is referenced.  This means that the compiler must know when the
    package state is changing (i.e. the read-read consistency rule doesn't
    apply).  It would probably be best to include an Implementation Note
    pointing out the restrictions this places on the compiler/loader
    implementation: the compiler may not read the whole file before compiling
    any of it (as the Lisp machine used to do in order to improve virtual
    memory locality); the loader may not do all its INTERNs before evaling
    any of the top-level forms (as Multics Maclisp does).

    The writeup should say explicitly which functions get an automatic
    (eval-when (compile) ...) wrapped around them when they are seen at
    top level by the compiler.  The example at the end is assuming this

Well, both of the above comments assume that the compiler represents
symbols and their packages internally just by reading them into the
right package.  Certainly the compiler has to keep track of what
packages the various symbols want to end up in, but this might be done
by some more complex mechanism if the compiler wanted to keep its guts
somewhat separate from the stuff it is reading.  I'll see if I can say
something sufficient about this without over-specifying the mechanism.

    I can find no justification in the previous discussion for the suddenly
    introduced restriction that EXPORT and UNEXPORT are not allowed in
    packages that have been USE-PACKAGE'd, unless this is a Solomonian
    attempt to resolve the copy vs reference issue.  If this is trying to
    deal with the case of exporting a symbol too late, after someone who
    thought they were getting it via USE-PACKAGE made an internal symbol
    instead, the naming conflict checks I suggested earlier detect this and
    are able to tell you exactly what happened.  If this is trying to deal
    with the case where exporting a new symbol, that people using
    USE-PACKAGE didn't expect to see exported, causes what was expected to
    be two distinct symbols, internal in different packages, to become one
    (external) symbol, it doesn't deal with it.  That can just as well
    happen if all the EXPORTs are done before all the USE-PACKAGEs, and is
    basically indetectable.  This screw case is really a lot like someone
    changing what a function does without telling everyone who uses it.

I was just trying to do something simple and safe that might end the
debate.	 I figured that I could get this "package locking" rule right on
the first try, and that some tricky rule to signal an error only in the
case of a conflict with some symbol in the inferior package that is not
on that package's shadow list would lead to N more rounds of revision.

You seem to understand this better than I do.  How about if you propose
the exact wording for the error-checking rule you would like to see here
(both for EXPORT and for UNEXPORT)?  That would be the quickest way to
converge, I think.

    The writeup says that SHADOW and SHADOWING-IMPORT "can produce confusing
    situations that violate the consistency rules."  This is misleading.
    They are a change of package state, just like setting *PACKAGE*, so there
    isn't consistency between the world before calling SHADOW and the world
    after calling it.  But the world after calling SHADOW is consistent with

OK, good point, sloppy wording.

    The &optional package argument to USE-PACKAGE and UNUSE-PACKAGE is missing.


    Why does it say init files are not usually compiled?  This is a
    non-sequitur where it appears, and also is untrue in some
    implementations, ours for instance.

Weinreb and Greenberg sent me a message pointing out that Newton's init
file would not work if compiled, and that it needed some (eval-when
(compile ..)) stuff added.  Since this was supposed to the simple part
of the example (the sort of interaction that naive users might have with
the package system), I didn't want to hair it up that way, so I just
mentioned that you don't want to compile these things.  Actually, I
guess with the recent changes, and if we put in the comment about
implicit EVAL-WHENs, we don't need to worry about this.

Just out of curiosity, why in the world would anyone compile an INIT

    Why do two of the modules in Newton's init file have ".lsp" in their names?

OOPS, again.

I'll try to get this fixed up tomorrow.

-- Scott