Path: utzoo!utgpu!water!watmath!clyde!rutgers!mit-eddie!husc6!think!ames!pasteur!ucbvax!sdcsvax!ucsdhub!esosun!seismo!uunet!mcvax!ukc!its63b!aiva!jeff From: jeff@aiva.ed.ac.uk (Jeff Dalton) Newsgroups: comp.lang.lisp Subject: Re: Structure editors in common lisp Message-ID: <230@aiva.ed.ac.uk> Date: 18 Jan 88 21:17:04 GMT References: <1487@orstcs.CS.ORST.EDU> <464@cresswell.quintus.UUCP> <215@aiva.ed.ac.uk> <14165@think.UUCP> Reply-To: jeff@uk.ac.ed.aiva (Jeff Dalton) Organization: Dept. of AI, Univ. of Edinburgh, UK Lines: 111 In article <14165@think.UUCP> barmar@sauron.think.com.UUCP (Barry Margolin) writes: ] In article <215@aiva.ed.ac.uk> jeff@uk.ac.ed.aiva (Jeff Dalton) writes: ]] The book discusses the consistencey rules on page 173. You will note ]] that it specifies the conditions under which these rules remain true ]] and the sorts of "explicit action" that can cause them to become false. ] Unfortunately, these rules only exist when *PACKAGE* doesn't change. As Barry (and Peter Schachte) have pointed out, I may have overstated the case for Common Lisp. But I still think earlier messages had gone too far the other way. Does this balance out? I don't know, but at least we now have a more precise description of the problem. I'm not entirely happy with the examples, as I'll explain below, but I don't deny there are problems with packages. The one that gets me most often is that I call a function (F, say, which I'm supposed to inherit from package "P") without remembering to do the USE-PACKAGE. Now I have a local symbol (USER::F) as well as the one in the package (P:F) and so I can't do the USE-PACKAGE without a conflict. So my problem is because of the consistency rules, if you will, rather than a violation of them. But it's read-time modularity (i.e., packages) that makes the problem possible. So I would agree that environment-based schemes (e.g., T's locales) have advantages. ] This means that you can't maintain consistency if you use IN-PACKAGE. ] And if you can't use IN-PACKAGE much of the value of the package ] system is lost. ] Here's an example. ] file1 contains: ] (in-package "p1") ] (export 's1) ] file2 contains: ] (in-package "p2" :use '("p1")) ] (setq s1 t) ] CLtL says that the order of loading files shouldn't matter, but the ] effect of the SETQ in file2 depends on whether file1 was loaded before ] or after it. If file1 is loaded first then it sets p1::s1; if file2 ] is loaded without loading file1 it sets p2::s1, and if file1 is later ] loaded the EXPORT will signal an error because it would create a name ] conflict. Here's why I don't like this example. When I try it in Sun Common Lisp, I get an error if I try to load file2 first because the package "p1" doesn't exist yet. I like this error and would expect it to be signalled in most Common Lisps. So you have to take out the :USE, and then it starts to be less convincing. Nonetheless, I'd agree that the consistency conditions (page 173) are more restrictive than they may first appear. But I would expect the order of loading not to matter only in a rather restricted sense in any case. You can't in general load files in any order and expect to get identical results, because you can't evaluate expressions in any order and get the same results. In <490@cresswell.quintus.UUCP>, pds@quintus.UUCP (Peter Schachte) says: ] You're right, it does mention consistency on page 173. But it fails to ] mention some simple, natural ways you call loose print/read consistency ] without using any of the "dangerous" functions mentioned. Here's an ] example: ] You have packages FOO and BAR. FOO USEs BAR. BAR exports a symbol SYM. ] BAR is defined on file BAR.LSP, and FOO in FOO.LSP. Ok, you write out a ] file SYM.LSP containing the symbol BAR:SYM with *PACKAGE* set to FOO. ] Next day, you start up a fresh Lisp, load FOO.LSP, SYM.LSP, and ] BAR.LSP, in that order. Now the occurrance of SYM on SYM.LSP turned ] into FOO:SYM, rather than BAR:SYM. This is certainly a problem. Developing in-core, though, I'd think you'd write files in which everything was fully qualified. After all, you don't care what's in the files so they don't have to look nice. ] I didn't have to call any of the "dangerous" functions to shoot myself ] in the foot, all I had to do was not have EXACTLY the same environment ] when the file was read as I had when it was written. Starting a new Lisp process is much like doing lots of calls to UNINTERN, UNUSE-PACKAGE, etc. -- the things that invalidate the consistency rules. I didn't say, and didn't mean to imply, that living with these rules was always easy. And CLtL would have done better to say something more about how easy it was to get into trouble. ] The only ] way to be really safe is to set *PACKAGE* to LISP before writing out a ] file. Then, as long as you don't change LISP (which you shouldn't do), ] you're safe. All the symbols not in the LISP package will be explicitly ] package qualified in the file. But that really defeats the purpose of ] packages: to give you a way to have long names without having to write ] and read them all the time. It's clear that you must be careful when writing files. I don't know that you have be so careful that you qualify everything not in the Lisp package. Suppose you always wrote such files with respect to a package, P. Output a call to IN-PACKAGE at the start. (You might also want to call SHADOW.) After that, qualify every symbol that's not in LISP or P. All of the symbols inherited via USE-PACKAGE would then be qualified, but the local symbols would not. Would something along these lines work well enough? I'm not suggesting this is adequate to support in-code development, but if you're doing that you don't always care what the files look like. Jeff Dalton, JANET: J.Dalton@uk.ac.ed AI Applications Institute, ARPA: J.Dalton%uk.ac.ed@nss.cs.ucl.ac.uk Edinburgh University. UUCP: ...!ukc!ed.ac.uk!J.Dalton