Subject: Re: (package-name "not a name") -> type-error or package-error?
From: Erik Naggum <erik@naggum.no>
Date: 02 Nov 2002 14:33:59 +0000
Newsgroups: comp.lang.lisp
Message-ID: <3245236439620140@naggum.no>

* Sam Steingold <sds@gnu.org>
| what error should
| 
| (progn (ignore-errors (delete-package "not a name"))
|        (package-name "not a name"))
| 
| signal?

  As usual, you have conflated several issues and made yourself a knot.
  There are several independent questions here:

  When (find-package foo) returns nil for some foo, what should
  (package-name foo) return or signal?

  When a package has been deleted, should the name still hang around
  somehow?

  When a package designator is not a name, what signal should package
  functions signal?

  From this confusing mess, let me assume that you really want to ask what
  (package-name foo) should do when (find-package foo) returns nil because
  foo is a string and not a package.

| CLHS says that it should be type-error when the argument is not a package
| designator,

  This means that if you give any package-function something other than a
  string or a package, you get a type error.  Since you give the function a
  string, you have given it a package designator and /this/ particular
  reason to signal a type error is therefore not invoked.

| ("object that denotes a package" as opposed to "object that _CAN_ denote
| a package")

  No other designators "can" denote anything, so this is one of those cases
  where a reader has to invent something in order to make a clear text
  confusing.  The designator is a type convention, not a value convention,
  which it seems you want it to be and which confuses you greatly.

| appears to imply that "CL" _IS_ a package designator because "CL" is a
| nickname for the "COMMON-LISP" package, while "not a name" may or may not
| be a package designator depending on the state of the system (i.e.,
| whether "not a name" has been made the name or a nickname of a valid
| package).

  This is simply horribly confused.

| What do people think?

  I think you should think more /clearly/ about what you want to know.

  In this case, I /assume/ we have a question of what to do when a package
  designator does not resolve to a package.  That is (find-package foo)
  returns nil, and foo is "not a name", which is at horribly stupid string
  to use in an example because it confuses semantic levels.  It /is/ a name
  by virtue of being a string.  It is not the name of an existing package,
  but that does not mean it is not a name.  This confusion just adds to
  your problems.

  So, what should (package-name (find-package foo)) do when the inner
  function returns nil?  Do we have to go through another step to make this
  clear in this horrible confusion?  Well, let me do that, just in case.

  A designator has a means to resolve into the desired type, let us call
  that the designator-resolver function.  A call to a function that accepts
  a designator for a type foo that is of type bar, will therefore have the
  form (function-call bar-value) which is in effect the same as the much
  less convenient (function-call (designator-resolver bar-value)).  We do,
  in fact, have to assume that the function calls designator-resolver when
  given a designator.

  Now, the points of departure should finally be pretty obvious.

  Should the designator-resolver for package designators return a
  type-error if it receives a designator for a package that does not exist
  or is deleted?  My answer is a resounding "no".  The reason for this is
  that package designators are used when /creating/ packages, too.

  Should the expression (package-name foo) be /identical/ to the similar
  expression (package-name (find-package foo)) in all possible respects?
  My answer is a resounding "yes".  The reason for this is that the cases
  where it is not would be horribly confusing and messy.¹

  Now, please note the exceptionally beautiful nature of designator-resolver
  functions such as find-package: they actually take the same type they are
  intended to return.  (find-package (find-package "CL")) not only works,
  it is /intended/ to work, just as (string (string #\a)) does.

  So, if we for the moment ignore package designators, what should
  (package-name nil) do?  This is not an error with the package because
  there is no package, this is an error with the type of the argument, a
  type-error.

  I assumed that you do not want to confuse this issue with the spurious
  delete-package, but that this redundant form was only to ensure that
  (find-package "not a name") would return nil.  I have also assumed that
  "not a name" is just a string like every other string and not some random
  noise that is not a string.  If these assumptions are incorrect, please
  clarify your question and remove superfluous redundancies.

-------
¹ There /is/ one such case that makes things needlessly messy, though.
  (defpackage "NIL") and have fun.

-- 
Erik Naggum, Oslo, Norway

Act from reason, and failure makes you rethink and study harder.
Act from faith, and failure makes you blame someone and push harder.