Why aren't lisp keywords protected?

For example,

(define a 3)
(define define +) #makes define useless
(define a 1) #outputs 4, instead of assigning 1 to a.

Is this flexibility so important? Or even worse:

(define + -)
(+ 1 1) #Output 0.

Where can this be useful, and, can this behavior be blocked? AFAIK, all programming languages have reserved keywords.


In Common Lisp, all symbols in the package COMMON LISP are protected by the standard. It says that redefining the package or the symbols in the package has undefined consequences. Which means, everything can happen: nothing, the change is made, the program crashes, the program might run into an error, ..., or even the sun comes up in the west the next morning.

Real Common Lisp implementations will often warn the user:


CL-USER 1 > (defun defun () 3)

Error: Redefining function DEFUN visible from package COMMON-LISP.
  1 (continue) Redefine it anyway.
  2 (abort) Return to level 0.
  3 Restart top-level loop.


* (defun defun () 3)

debugger invoked on a SYMBOL-PACKAGE-LOCKED-ERROR:
  Lock on package COMMON-LISP violated when proclaiming DEFUN as a function
  while in package COMMON-LISP-USER.
See also:
  The SBCL Manual, Node "Package Locks"
  The ANSI Standard, Section

Type HELP for debugger help, or (SB-EXT:EXIT) to exit from SBCL.

  0: [CONTINUE      ] Ignore the package lock.
  1: [IGNORE-ALL    ] Ignore all package locks in the context of this operation.
  2: [UNLOCK-PACKAGE] Unlock the package.
  3: [ABORT         ] Exit debugger, returning to top level.

Since many Common Lisp implementations are largely programmed in themselves, there needs to be a mechanism to allow changes and then later prevent them.

Some parts of the language even can't be modified by redefining the function or macro. There is no way for the user to change, add or remove special forms (like LET) and special syntax like argument lists and lambda expressions. The syntax for argument lists is hardwired into the language. The syntax for lambda expressions is hardwired. You can't change it. You would need to change the interpreter and/or the compiler.


Symbols are not protected because they don't need to be. Some languages have reserved names because their syntax cannot tolerate having a class named "class", even though technically you could avoid it. Sometimes it is done on purpose to avoid ambiguity in the programmer's mind and truly, redefining - to mean + is the kind of things that really would be disastrous in theory. However, this is part of having a dynamic environment, where this kind of flexibility is useful sometimes.

Those problems vanish when you use different namespaces, so that mypackage:+ is different from yourpackage:+ (unqualified uses of + can be inspected during development to know which symbols is actually used).

By the way, your example is in Scheme (you tagged it as lisp originally), but Common Lisp is a little bit different in that regard.

The 978 symbols in the standardized "COMMON-LISP" package shouldn't be redefined in a portable program (undefined behavior if you do this). An implementation like SBCL provides a way to "lock" packages, to prevent accidental changes. Of course, it gives you a way to unlock them.

This is not a problem in practice because you generally don't want to redefine the standard operators but provide your own operator, defined in your own package.

Packages being first class, you can even modify which symbols are imported in a given package, so that you can sometimes change the semantics of an existing programs without touching its files, just by changing what an unqualified + function means (and recompiling).

This is useful, for example, to perform some kind of instrumentation, like automatic differentiation. You replace a set of operators by your own because you want to compute information about your program, for example.


Why aren't lisp keywords protected?

Because they aren't keywords, they are just library functions like any other.

Where can this be useful,

It means that you, as a user, have the same power as the language designer. Making a change to a language can take several decades and is a massive undertaking. Writing a new library function only takes seconds and can be done by anyone.

AFAIK, all programming languages have reserved keywords.

No, not all. Lisp doesn't, for example. In fact, Lisp doesn't really have syntax at all.

Io has no keywords, neither have Ioke or Seph. Poison and Potion also don't have keywords.

Smalltalk also has only a very small number of keywords: true, false, nil, self, super, and thisContext. Newspeak has almost the same list (true, false, nil, self, super, and outer). In both cases, nil, true, and false could just as easily be method calls instead, leaving only 3 keywords. (Actually, Gilad Bracha, the designer of Newspeak said that all of them could be made method calls, but it wouldn't be worth it.)

  • 3
    What do you mean by "Lisp doesn't really have syntax at all."? So, why is (+ 1 1) a legal expression and () 1 + 1 not? – Quora Feans Sep 8 '16 at 2:51
  • @QuoraFeans Syntax and semantics are different things. FWIW, most lisps do have syntax, but it is relatively minimal ("this is what constitutes a symbol") and in Common Lisp, it is changeable by manipulating the run-time environment. – Vatine Sep 8 '16 at 10:08
  • 1
    That's basically wrong. You confuse the syntax of s-expressions, which is a data format with the syntax of Lisp. READ does not know anything about the programming language Lisp, it reads S-expressions - as data. If you look at LAMBDA expressions. LAMBDA is hardwired into the Lisp syntax. Look: the ANSI CL standard has EBNF forms describing the syntax of lambda expressions. And no, LAMBDA in a lambda expression is not even a function,not a macro, not a special form. Lambda expressions can be used in some places, described by more syntax... – Rainer Joswig Sep 8 '16 at 17:16
  • 1
    The syntax for lambda expressions is not (lambda arglist body). The arglist ist complex and has required args, optional, keywords, defaults .... Then we have a documentation string and declarations with lots of declaration syntax. Then we have a body of expressions. This all is described in the ANSI CL standard by EBNF syntax descriptions, just like you would have them in Pascal. The main difference: the Lisp syntax is defined over Lisp data. But it describes syntactic structure just like in Pascal (where the syntax is described for text). – Rainer Joswig Sep 8 '16 at 17:24
  • 1
    LET has syntax, LAMBDA expressions have syntax, DEFUN has syntax, DEFCLASS has syntax, DO has syntax, ... – Rainer Joswig Sep 8 '16 at 17:28

Your Answer

