Normative Rule: Single-Cell Symbol Binding (Lisp-1)

← Prev | ↑ Chapter | Next → | Index | Symbols

Normative Rule: Single-Cell Symbol Binding (Lisp-1)

Statement

Each AutoLISP symbol carries exactly one binding cell. setq and defun both write to that single cell; either operation overwrites whatever the other wrote previously. There is no separate function cell distinct from the variable cell. In every position — value position or function-call position — the evaluator dispatches on the same stored value.

This places AutoLISP / Visual LISP in the Lisp-1 family (a single namespace shared by variables and functions, like Scheme), not the Lisp-2 family (separate cells per role, like Common Lisp).

Concrete Consequences

  • After (setq foo 42) followed by (defun foo (x) (+ 1 x)), evaluating the bare symbol foo returns the function object — not 42. The setq-supplied integer is gone.
  • After (defun bar (x) ...) followed by (setq bar 42), calling (bar 5) raises no function definition — the function is gone.
  • (setq myfunc eq) followed by (myfunc "1" "1") must succeed: the variable's stored value (the eq subroutine) is dispatched as the call's function. Bricsys logged this as defect SR44723 and shipped the fix accordingly.
  • defun-q obeys the same single-cell rule, with the additional property that the function value remains list-accessible through defun-q-list-ref / defun-q-list-set.
  • A (defun ... (/ x ...) ...) local — i.e. a name appearing after the slash in a lambda list — establishes a dynamic shadowing of the same single cell during the call's extent, then restores the prior binding on exit. Local declarations therefore work uniformly for symbols whose outer binding is a value, a function, or both successively.

Vendor Evidence

  • BricsCAD V26 release-note defect SR44723 explicitly documents the expected behaviour: (setq myfunc eq) followed by (myfunc "1" "1") must run the eq implementation. The fix landed in mainline V25 and is preserved through V26.
  • BricsCAD V26 / macOS direct probe (this repository, results/bricscad/macos/20260426T155521Z-namespace/):
    • TEST1: (setq probe-foo 42) then (defun probe-foo (x) (+ 1 x)) — evaluating the bare symbol probe-foo returns #<<FUNCTION> ...>, not 42. (probe-foo 5) returns 6.
    • TEST2: after (setq probe-bar 42) on a previously defun'd symbol, calling (probe-bar 5) raises no function definition <PROBE-BAR>; expected FUNCTION at [eval]. The function value was overwritten by the integer.
  • Autodesk reference, About Using Defun to Define a Function: "Never use the name of a built-in function or symbol for the sym argument to defun, as this overwrites the original definition and makes the built-in function or symbol inaccessible." The wording does not distinguish a function role from a value role; it speaks of a single overridable definition.
  • Autodesk reference, About Local and Global Variables: "If a variable name is added to the local variables list of a function, the global variable with the same name is ignored." This describes single-cell dynamic shadowing.

Strict / Lax Policy

The single-cell rule is strict in every supported dialect (strict, autocad-2026, bricscad-v26). No host product is known to expose Lisp-2 semantics; the conformance contract treats any Lisp-2-style behaviour as a regression.

Cross-references

  • Special Form Entry: SETQ (chapter 3) — assigns a value to the single binding cell.
  • Special Form Entry: DEFUN (chapter 3) — assigns a function value to the single binding cell.
  • Special Form Entry: DEFUN-Q (chapter 3) — single-cell write plus list-accessible compatibility metadata.
  • Special Form Entry: LAMBDA, FUNCTION (chapter 3) — produce function values that participate in the same cell.
  • Function Entry: VL-SYMBOL-VALUE (this chapter) — returns the single cell's value.
  • Function Entry: BOUNDP (this chapter) — predicates the single cell's bound state.

Source Notes