The Department of Computer Science & Engineering
cse@buffalo

CSE202: Programming in Lisp

Course
Grades
Email

Welcome

Policies
    Grades
    Inc
    Intgrty

Preface
Part I
  Chap 1
  Chap 2
  Chap 3
  XEmacs
  Chap 4
  Chap 5
  Chap 6
  Chap 7
  Chap 8
  Chap 9
Part II
  Chap 10
  Chap 11
  Chap 12
  Chap 13
  Chap 14
  Chap 15
  Chap 16
  Chap 17
  Chap 18
  Chap 19
  Chap 20
  Chap 21
  Chap 22
  Chap 23
Part III
  Chap 24
  Chap 25
  Chap 26
  Chap 27
  Chap 28
  Chap 29
  Chap 30
  Chap 31
  Chap 32
CHAPTER 7: PACKAGES
Corrections
Read Chapter 7, and refer to these Corrections as you come to the appropriate pages. Try all the interactions for yourself as you read about them, especially because there may be small differences in the output. It is extremely important to change packages when directed by the interactions in the book, or else the later interactions won't work correctly.

Footnotes 1 and 2 on page 44 speak of a "new Common Lisp standard". This standard is now in effect, and versions of Common Lisp that abide by it are called "ANSI Common Lisp". The ACL we are using is an ANSI Common Lisp. This will not make much of a difference in the version of the text you are using, nor in this course. However, it does make a difference in the use of packages, which will mostly be felt in this chapter and in Chapter 12.

  • page 45, line 3: Change (in-package 'lisp) to (in-package lisp). That is, the quote mark is no longer to be used.

    However, it's even more convenient to use the acl top-level listener command :pa as in

    USER(61): :pa lisp
    CL(62): 
    
    (CL is a "nickname" of the common-lisp package.)
    From now on, when the book tells you to use the function in-package use the :pa command instead and, save some typing!

  • page 45, line 14, 15: When the book says to type user::frank you can continue to do so, even though the package is now officially named common-lisp-user because user is a nickname of the common-lisp-user package. Similarly lisp, along with cl, is a nickname of the common-lisp package.

  • page 46, line -7: export, unlike in-package, still needs its argument quoted, so follow the book here, and enter (export 'frank)

  • page 47, line 13: It is no longer correct that "The in-package function will create a new package if necessary." New packages must be defined by using defpackage. So, you need to do
    
    USER(77): (defpackage test)
    #<The TEST package>
    > :pa test
    TEST(79):
    

  • page 48, line 8: import, like export, still needs its argument quoted.

  • page 49, line -2 - page 50, line 2: find-package can also take the same symbol used by in-package, but it has to be quoted:
    TEST(92): (find-package 'test)
    #<The TEST package>
    

  • page 50, lines 5-10: make-package still exists, but let's get used to using defpackage. So change
    Packages may be created by in-package, as we have seen. A package may also be created by the function make-package. The difference is that in-package also changes the package we are in, whereas make-package doesn't.
    > (make-package "foo")
    #>Package foo 12760773>
    
    to
    Recall that packages are created by defpackage, but that defpackage does not change the package we are in.
    TEST(94): (defpackage "foo")
    #<The foo package>
    

  • page 50, line -12: Change
    The functions in-package, make-package, and find-package"
    to
    The functions in-package, defpackage, and find-package"

Notes
  1. By now, you should have tried all the interactions of Chapter 7, as requested by Exercise 7.1. Be sure to return to the common-lisp-user package before going on to the other exercises.

  2. Exercise 7.3
    When you try to import user:bill into the test package, you should get the following response:
    Error: Importing these symbols into the TEST package causes a name conflict:
    (COMMON-LISP-USER:BILL)
      [condition type: PACKAGE-ERROR]
    
    Restart actions (select using :continue):
     0: Import these symbols with Shadowing-Import.
     1: Return to Top Level (an "abort" restart)
     2: Abort #
    [1c] TEST(101): 
    
    Your choices are now to enter one of the following:
    • :cont 0 to have user:bill "shadow" test::bill so that user:bill is available in the test package, the old test::bill disappears, and now test::bill is eql to user:bill.
    • cont: 1 to abort the attempted import and return to the top-level listener. (Equivalent to entering :res)
    • :cont 2 to kill the ACL process entirely.
    Either enter :cont 0, :cont 1, or :res Do not kill the ACL process, because you want to continue right on to Exercise 7.4 in the current environment.

  3. For Exercise 7.4, you should be in the test package and do the following:
    1. evaluate (describe 'pi)

    2. evaluate (shadow 'pi)

    3. evaluate (describe 'pi) again

    4. describe the pi in the common-lisp package without leaving the test package.

    The technique shown in this exercise is the way to "shadow" a symbol in one package that would normally be available from another package, so that you can introduce a symbol in this package with the same name. You will use this technique extensively in the rest of this course, so that you can define your own version of Common Lisp functions.

  4. In fact, try this, as Exercise 7.4.5:

    While still in the test package do (shadow 'length)
    Now try to evaluate (length "abc")
    You should get an error message.
    The symbol length you typed is test::length, which is not the name of a function. Notice that you are given an opportunity to use COMMON-LISP:LENGTH instead. Take this option by entering :cont 1
    You should see the result (3) and another top-level prompt.
    Using C-c C-p put your form (length "abc") into the current line of the Lisp listener, and edit it so that it is a call to lisp:length instead, and try that. It should work.

  5. Do Exercise 7.5 immediately after doing Exercise 7.4.5, and exactly as instructed. Students in the past have found this exercise very confusing. Here is the situation:

    • After exporting test::pi there are two symbols named "PI": test::pi and common-lisp:pi

    • Since every new package inherits the external symbols of the common-lisp package, when you change into the foo package, the pi that's available is lisp:pi

    • However, when you do (shadowing-import 'test:pi) the pi that's available in the foo package is test:pi and lisp:pi is shadowed.

    • Nevertheless, lisp:pi may still be used in the foo package by using its full qualified name---lisp:pi

  6. Now, create a file named ch7.cl, and paste into it the interactions you have been having with the Lisp listener as you worked on Exercises 7.3, 7.4, 7.4.5, and 7.5. Submit this file, and go on to Chapter 8. You shouldn't find that as confusing as this chapter may have been.

Next

Copyright © 1999, 2000 by Stuart C. Shapiro. All rights reserved.

Stuart C. Shapiro <shapiro@cse.buffalo.edu>