Path: utzoo!utgpu!watserv1!watmath!att!rutgers!usc!sdd.hp.com!uakari.primate.wisc.edu!aplcen!aplcomm!uunet!mcsun!ukc!edcastle!aiai!jeff From: jeff@aiai.ed.ac.uk (Jeff Dalton) Newsgroups: comp.lang.lisp Subject: Re: Common Lisp Package System Considered Harmful Message-ID: <3620@skye.ed.ac.uk> Date: 23 Oct 90 18:17:55 GMT References: <271E0D40.451E@wilbur.coyote.trw.com> <388@shrike.AUSTIN.LOCKHEED.COM> Reply-To: jeff@aiai.UUCP (Jeff Dalton) Organization: AIAI, University of Edinburgh, Scotland Lines: 96 In article kers@hplb.hpl.hp.com (Chris Dollin) writes: >(c) packageing seems to be done in the wrong place - as part of the lexical >and syntactic analysis, not in the compiler [*2]. >[*2] Or interpreter. For these purposes the difference is irrelevant. Continuing in my current role as Defender of Common Lisp... Packages are handled by the reader. Thus they apply to data as well as code. This approach has some disadvantages (see one of my earlier articles for an example), but it also has advantages. There are several ways in which data structures can end up being interpreted as code: 1. A symbol that has a global function definition can be used as a function. 2. A list, symbol, or other object can be given to EVAL. 3. A list, symbol, or other object can result from macro expansion. Let's look at the first example. If the package information were not part of the symbol, and the symbol were given as a function to MAPCAR, MAPCAR would have no way to determine which package held the function definition. [Why doesn't MAPCAR know? The symbol doesn't say, and the compiler can't find all calls to MAPCAR and stick the information in at the point of call. The reason the compiler can't find all calls is that some might be done via FUNCALL or APPLY or some function that calls FUNCALL or APPLY. Not to mention EVAL. Moreover, for user-defined functions, the compiler might not be able to determine which arguments were functions (and so needed package information inserted at the call).] Similar problems occur if a list containing function names is given to EVAL or returned as the result of macro expansion. There are several solutions that might be applied to these problems: S-1. Eliminate the offending parts of the language. S-2. Adopt a convention such as: always use the current package. S-3. Have the user explicitly specify the package. S-4. Invent a zowie new mechanism that makes (almost) everything work as we (ought to) expect. Some people favor (S-1) for (1) and (2). That is, eliminate the ability to use symbols as functions and eliminate EVAL. Some people would apply it to (3) as well: no macros. That seems a rather large price to pay. As for S-2, it's difficult to come up with a convention that works in enough cases. On the other hand, it might be argued that we should eliminate (1) and that "use the current package" is good enough for (2) and (3). I think it isn't good enough for (3) [or for (1)]. That is, I should be able to write a macro like this one: (defmacro mac (x) `(some-package:some-function ,x)) or one like this: (defmacro mac (x) `(some-function ,x)) where I expect package information to stick to SOME-FUNCTION. [N.B. I haven't said what "current package" means. I don't think it works well enough to use either the current value of *package* or the current "compilation" package: ie, the package in which the code being compiled is defined. Not does it work to always use the package in which the macro was defined.] S-3 is often used for EVAL: give EVAL an extra "environment" argument. It would be a pain to use it for (1), giving an extra argument to MAPCAR and all the rest. Moreover, it's hard to see how it would work for (3). So that leaves S-4. It is clearly the best solution, but rather difficult to devise. The Scheme world will eventually do it for modules and macros in Scheme. Scheme won't support symbols as functions, and it won't have EVAL. Scheme, then, will offer a reasonable set of solutions. But (a) some regard it as a high price to pay, and (b) the Common Lisp solution, imperfect as it is, is available now and, moreover, was available back when people were writing whatever applications we're using now. -- Jeff