[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Issue: UNDEFINED-VARIABLES-AND-FUNCTIONS (Version 1)



I know it's late to be introducing this, but I think everyone will agree
it's an issue people are likely to care about and that we should
probably address.  Since it affects the language glue itself (including
variable access, function calling, and CLOS), I'm sending it to
CL-Cleanup instead of some more specialized list.

However, since this isn't likely to be non-controversial enough to make
Masinter's upcoming mail ballot, please let's not waste a lot of time
discussing this until after the pre-ballot rush. I just wanted to get it
on the books for people to contemplate...
 -kmp

-----
Issue:        UNDEFINED-VARIABLES-AND-FUNCTIONS
References:   5.1.2 Variables (CLtL pp55-56),
	      Slots (88-002R, p1-10)
Category:     CHANGE
Edit history: 29-Nov-88, Version 1 by Pitman
Status:	      For Internal Discussion

Problem Description:

  CLtL does not specify what happens if you attempt to call a named function
  which is in fact undefined. In most implementations, it would be devastating to
  actually jump to code which you had not verified to be a function, so this error
  should be easily caught -- yet, CLtL does not guarantee that an error will be
  signalled even in the safest, least fast OPTIMIZE settings.

  CLtL (p56) specifies that "it is an error to refer to a variable that is unbound."

  CLOS (p1-10) specifies that "when an unbound slot is read, the generic function
  SLOT-UNBOUND is invoked. The system-supplied primary method for SLOT-UNBOUND
  signals an error."

  CLOS and CLtL are not in agreement on their treatment of unbound variables.

  CLtL is very weak in that it guarantees no support for reliably detecting
  and signalling an error when the error situation occurs, even in the safest,
  least fast OPTIMIZE setting.

  CLOS is very strong in that it forces detection of the error in all
  situations -- even in the fastest, least safe OPTIMIZE setting.

  The disparate positions for treatment of variables and slots should be
  reconciled, either by finding a compromise or by justifying the apparent
  inconsistency. The final story should explain function references as well.

Proposal (UNDEFINED-VARIABLES-AND-FUNCTIONS:COMPROMISE):

  Define that reading an undefined function, an unbound variable, or 
  an unbound slot must be detected in the highest safety setting,
  but the effect is undefined in any other safety setting. That is,
   - Reading an undefined function should signal an error.
   - Reading an an unbound variable should signal an error.
   - Reading an unbound slot should invoke the function SLOT-UNBOUND.

  By ``reading an undefined function'' in the above, we mean to 
  include both references to the function using the FUNCTION 
  special form, such as F in (FUNCTION F) and references to the
  function in a call, such as F in (F X).

  For the case of INLINE functions (in implementations where they are
  supported), it is permissible to consider that performing the inlining
  constitutes the read, so that an FBOUNDP check need not be done at
  execution time. Put another way, the effect of FMAKUNBOUND of a function
  on potentially inlined references to that function is undefined.

  Specify that the type of error signalled when an undefined function
  is detected is UNDEFINED-FUNCTION, and that the NAME slot of the
  UNDEFINED-FUNCTION condition is initialized to the name of the
  offending function.

  Specify that the type of error signalled when a unbound variable 
  is detected is UNBOUND-VARIABLE, and that the NAME slot of the
  UNBOUND-VARIABLE condition is initialized to the name of the
  offending variable.

  Introduce a new condition type, UNBOUND-SLOT, which inherits from
  CELL-ERROR. This new type has an additional slot, INSTANCE, which
  can be initialized using the :INSTANCE keyword to MAKE-CONDITION.
  Introdue a new function UNBOUND-SLOT-INSTANCE to access INSTANCE slot.

  Specify that the type of error signalled by the default primary
  method for the SLOT-UNBOUND generic function is UNBOUND-SLOT,
  and that the NAME slot of the UNBOUND-SLOT condition is initialized
  to the name of the offending variable, and that the INSTANCE slot
  of the UNBOUND-SLOT condition is initialized to the offending instance.

Test Case:

  (PROCLAIM '(OPTIMIZE (SAFETY 3) (SPEED 0)))
  (DEFUN FOO () X)
  (FOO)
  >>Error: The variable X is not bound.
  ...

Rationale:

  This makes it easier to treat slots like variables.

  This makes it possible to better rely on an unbound variable error being
  signalled when one has occurred.

  This makes it possible to compile out useless error checking in CLOS
  code where the code is debugged and the checking is redundant.

  For the case of undefined functions, blindly jumping to an undefined
  function is an incredibly dangerous thing to do. Every implementation
  should guarantee at least some way to get error checking of undefined
  functions.

Current Practice:

  Until recently, Symbolics Cloe did not ever signal an error on unbound
  variable, even in the safest case. The excuse was that this was a CLtL
  didn't require it, but it was sometimes an impediment to debugging.

  Some benchmarks for Symbolics Cloe (which currently only claims to
  implement New Flavors, not CLOS) could be faster if checking for unbound
  instance variables could be optimized away.

  Symbolics Genera doesn't care about safety issues in variable access
  because the check can be done by microcode.

Cost to Implementors:

  This change does not force a change to any current implementation, except
  those which do not yet signal unbound variable or undefined function errors
  even in the safest setting.

Cost to Users:

  This checking might slow down some code which is written for the safest
  setting yet does not need this check.

  Any implementation-specific code which depended on these references not
  signalling would be broken. Such code was not portable, of course.

  Any CLOS code which depends on SLOT-UNBOUND being called even in low safety
  settings would be broken. The amount of such code at this point is likely
  to be little or none. If such cases did exist, local or global changes to
  safety settings would correct the problem (at some cost in speed).

Cost of Non-Adoption:

  Some important error checking would not occur.
  Some important optimizations could not be done.
  The language would seem internally less consistent.

Benefits:

  The costs of non-adoption would be avoided.

Aesthetics:

  This would regularize things a little.

Discussion:

  Pitman thinks this would be a good idea.