tgd@orstcs.CS.ORST.EDU (Tom Dietterich) (12/13/87)
I too love Sedit in the Xerox lisp environment. However, there is a bad interaction between structure editors and packages. Every symbol typed to a structure editor is interned in the current package. This is generally too soon in my experience. I would like to type in a function and then decide which package to put it in. With a text-editor development environment, you can do this sort of thing, because you haven't committeed yet. But in a structure editor, you must be committed immediately. The only way to fix it in the Xerox environment is to write out your file in its package (so that no prefixes get written) and then load it into a different package (using a special keyword option on LOAD). This is a pain and rarely works right for me. Maybe the structure editor could be changed so that it could "move" all of the symbols in my function to a different package with one command. I haven't thought too carefully about this, but my experience with the package system is that everything is trickier than it looks. Maybe this just indicates that the real problem is with the package system... --Tom Dietterich tgd@cs.orst.edu
pds@quintus.UUCP (Peter Schachte) (12/15/87)
In article <1487@orstcs.CS.ORST.EDU>, tgd@orstcs.CS.ORST.EDU (Tom Dietterich) writes: > Maybe this just indicates that the real problem is with the > package system... Packages are certainly one aspect of CommonLisp that make incore development painful, if not impossible. Why do they put all SYMBOLS in packages? It's much more natural to think of individual DEFINITIONS as being in packages. That would make it much easier to move them around. The CommonLisp book talks about trying to maintain Write/Read consistency, but doesn't mention that CommonLisp fails to do this because of packages. I won't belabor the point with an example: I'm sure you've all seen them before. -- -Peter Schachte pds@quintus.uucp ...!sun!quintus!pds
jeff@aiva.ed.ac.uk (Jeff Dalton) (12/20/87)
In article <464@cresswell.quintus.UUCP> pds@quintus.UUCP (Peter Schachte) writes: >The CommonLisp book talks about trying to maintain Write/Read >consistency, but doesn't mention that CommonLisp fails to do this >because of packages. I won't belabor the point with an example: I'm >sure you've all seen them before. 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. So I have to disagree with the claim that CLtL doesn't mention the consistency problems caused by packages. 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
pds@quintus.UUCP (Peter Schachte) (12/23/87)
In article <215@aiva.ed.ac.uk>, jeff@aiva.ed.ac.uk (Jeff Dalton) writes: > In article <464@cresswell.quintus.UUCP> pds@quintus.UUCP (Peter Schachte) writes: > >The CommonLisp book talks about trying to maintain Write/Read > >consistency, but doesn't mention that CommonLisp fails to do this > >because of packages. > > 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. > > So I have to disagree with the claim that CLtL doesn't mention the > consistency problems caused by packages. 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. 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. Yes, of course, I shouldn't do this. But it's so EASY to do without knowing it. 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. This is not a purely academic or theoretical argument. This type of problem has cost me many hours and caused me many problems. -- -Peter Schachte pds@quintus.uucp ...!sun!quintus!pds
barmar@think.COM (Barry Margolin) (12/23/87)
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. 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. --- Barry Margolin Thinking Machines Corp. barmar@think.com seismo!think!barmar
jeff@aiva.ed.ac.uk (Jeff Dalton) (01/19/88)
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
shebs%defun.utah.edu.uucp@utah-cs.UUCP (Stanley T. Shebs) (01/21/88)
In article <464@cresswell.quintus.UUCP> pds@quintus.UUCP (Peter Schachte) writes: >Packages are certainly one aspect of CommonLisp that make incore >development painful, if not impossible. Why do they put all SYMBOLS in >packages? The truly cynical explanation is that somebody came up with that idea while working on the MIT Lisp Machine almost a decade ago, and it got enshrined in CL because the designers were too tired arguing about everything else to do anything but take the design verbatim. A less cynical explanation is that providing lexical environments with export/import operations etc is not as easy as it sounds, and no one has produced a universally satisfactory solution as of yet. stan shebs