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

Problems with packages



    Date: Fri,  2 May 86 07:42:12 EDT
    From: "George J. Carrette" <GJC@MC.LCS.MIT.EDU>
    Subject:  Problems with packages: work arounds.
    
    If you still have the (MACSYMA-MODULE <name>) as the first form in
    every file you can do what I do for DOE-MACSYMA, 
     (macsyma-module <name>) => (eval-when (eval compile load)
				 (or (find-package "MACSYMA") (error "bad news"))
				 ... etc ...)

The issue is not finding a work-around. Obviously I know how to achieve the
computational effect. The issue is that:
 (a) no one should put their shadowed symbols list in more than one file
     because it just sets them up to lose by getting the various lists
     out of alignment with each other.
 (b) everyone who uses files that do IN-PACKAGE for a complicated package
     like the one I'm describing should probably want to do the same workaround.
One purpose of language design is to make sure that idioms get names.
Another is to make it convenient to get the appropriate error checking for those
who may be too lazy to write the error conditional long-hand. Why should everyone
have to invent a MACSYMA-MODULE routine? Introducing an IN-EXISTING-PACKAGE 
primitive would be good for everyone.

By the way, another potential problem with the MACSYMA-MODULE scheme you outline 
is that you can't be sure on what package the MACSYMA-MODULE form will be read.
As such, unless you are sure MACSYMA-MODULE is defined in all possible packages,
the call to IN-PACKAGE must preceed the call to MACSYMA-MODULE so that 
MACSYMA-MODULE will get interned in the correct package, which defeats the 
purpose. Yes, it's possible to make the MACSYMA-MODULE thing work, but I don't
think very portably and I don't think that when it fails it will fail gracefully.
Yes, it's possible to make IN-PACKAGE work, but again when it fails it is not
going to fail gracefully. I think the language should provide minimal support
for common situations like this where the system could and should be doing
error checking.

It's only -very- rarely going to be the case that the person writes IN-PACKAGE
and doesn't know whether he means IN-PACKAGE or IN-EXISTING-PACKAGE. That being
the case, we should allow the person to say which he means and get the benefit
that should come from such clarity of expression.

    Date: Fri, 2 May 1986  10:16 EDT
    From: Rob MacLachlan <RAM@C.CS.CMU.EDU>

	Date: Thursday, 1 May 1986  22:53-EDT
	From: Kent M Pitman <KMP at SCRC-STONY-BROOK.ARPA>
	To:   Common-Lisp at SU-AI.ARPA
	Re:   Problems with packages
	...
	What happened was that I hit a bad timing window and it tried to resolve 
	the `FOO' package at the instant the package was created but before the
	special stuff (like shadowing, importing, etc.) had been done.  ...
    
    Sounds like an environment issue to me :-)
    
Linguistic issues which make it impossible to construct correct environments are
within our charter. I claim this is such an issue.

	While I'm on the subject of packages, I have a few other gripes to
	air...
    
	I'm really bothered that I have to say symbols as arguments to
	shadow. The 3600 implementation allows me to use strings, which CL
	doesn't define. CL should -require- strings as arguments to this
	function and should not allow symbols.  Giving symbols as
	arguments to this function forces things to get created wrong and
	then hopes that things will get cleaned up correctly afterward.
	This reduces the ability to error-check if the symbol to be
	shadowed had already been interned for some reason other than the
	call to shadow.

    I don't quite follow what you are saying about "things getting created
    wrong."  If the call to shadow is read in the package which them
    symbols are to be shadowed in, then:
     1] The symbols get created as internal symbols in the package, in
	which case shadow does nothing but update the shadowing symbols
	list. 
     2] The symbols were already directly present in the package, in which
	case both reading and shadowing do nothing but update the
	shadowing symbols list.
     3] The symbols are inherited from somewhere, in which case the
	"wrong" symbol is read, but nothing is "created wrong", since the
	symbol already existed.

    It is a bit odd that SHADOW takes a list of symbols and then just uses
    the names, but it doesn't have any bad side-effects that I can see.  I
    would guess that consistency was the motivation for using symbols
    everywhere.  Using symbols also lets those of us who dislike uppercase
    type the names of the arguments in lowercase.
    
I may have been a bit vague in my original exposition, so let me give a sample
of a problemsome situation. Suppose you put the following in a file:

 (IN-PACKAGE 'FOO)
 (SHADOW '(CAR))

Then suppose you type Suspend (or Control-B or whatever your asynchronous
interrupt is for getting a Lisp breakpoint ...) while the file is loading and
you (unknowingly) end up between the IN-PACKAGE and the SHADOW. You can verify
that the FOO package exists, but might not think to verify that BAR has not
yet been shadowed. Suppose you type (DEFUN FOO:CAR () 3) while in the breakpoint.
The problem is that FOO:CAR will resolve to LISP:CAR because the shadowing has
not yet been done. This is analagous to what happened to me in the 
multiprocessing situation the other day. Also, when
 (SHADOW '(CAR))
gets done, it will not know that you had previously interned FOO:CAR (in the
breakpoint) because it thinks the reason it finds FOO:CAR interned locally.

Also, if the implementation caches the results of doing 
(INTERN inherited-symbol-name package) for faster lookup later and remembers
that FOO:CAR used to resolve to LISP:CAR, it can signal an error if it later
changes. If shadow takes a symbol argument, the implementation can't reliably
tell that you're doing something nasty because it can't tell if the only previous
use of FOO:CAR (which resolved to LISP:CAR) was the one in the call to shadow
or whether there were other, more substantial, uses of LISP:CAR which you might
want to be warned about.

Even leaving aside issues of asynchronous interrupts, there's no guaranteeing
that someone else hasn't done:
 (IN-PACKAGE 'FOO)
and then just worked in FOO for a while before you loaded a package that
did
 (IN-PACKAGE 'FOO)
 (SHADOW '(CAR))
In that case, you can't appropriately flag any prior uses of CAR because 
the form which calls SHADOW has basically destroyed any debugging information
that might have been around.