Reputation: 21615
numberp
is a predicate in Lisp, and (numberp 1)
returns T as expected. But if I only type numberp
in the console, it prompts that the variable name is undefined.
What's the difference between these 2?
Upvotes: 4
Views: 1416
Reputation: 3200
One of the differences between Scheme (one Lisp dialect, so to speak) and Common Lisp is that in Scheme, there is one namespace for variables and functions, whereas in CL, there are two separate namespaces. Thus, in Scheme, "define" sets this one-and-only name-to-value assoc, whereas in CL, there is "define" for the value and "defun" for the function association.
So, in CL you can:
(define foo ...something...)
(defun foo ...somethingElse...)
to confuse the reader.
In Scheme, there is only one:
(define foo something)
If this is good or bad has been an almost religious dispute in the past...
Upvotes: 0
Reputation: 139251
The question is slightly wrong already.
We are talking about different things in Common Lisp:
In Common Lisp the symbol can have both a value and a function (or macro).
There are top-level variables defined by DEFVAR and DEFPARAMETER. There are also local variables defined by LAMBDA, DEFUN, LET, LET* and others.
(defun foo (i-am-a-variable) ...)
(defparameter *i-am-a-global-variable* ...)
Example:
(defun i-am-a-function (foo) ...)
(flet ((i-am-a-function (foo) ...)) ...)
To further complication function names and variable names are symbols in the source code.
Example:
(type-of (second '(defun foo () nil))) --> SYMBOL
Let's look at functions and variables:
(defun foo ()
(let ((some-name 100))
(flet ((some-name (bar) (+ bar 200)))
(+ some-name (some-name some-name)))))
Above code uses a variable and a function with the same symbol in the source code. Since functions and variables have their own namespace, there is no collision.
(+ some-name (some-name some-name))
Above then means we add the variable to the result of the function call on the variable.
This has the practical effect that you can do something like this:
(defun parent (person) ...)
(defun do-something (parent)
(parent parent))
You don't have to fear that your local variable names will shadow a global (or local) function. They simply are in different namespaces.
In Scheme there is only one namespace and we have to write
(define (foo lst) (list 'a lst 'n))
where in Common Lisp we can write:
(defun foo (list) (list 'a list 'n))
In Common Lisp there is no need to write lst
instead of list
- because there is no clash between the local variable list
and the global function list
.
Accessing the other namespace
To get a function object stored in a variable you can use FUNCTION
.
(let ((my-function (function numberp)))
(funcall my-function 10))
(function foo)
can be written shorter as #'foo
.
FUNCALL
calls a function object.
OTOH, if you want to store a function object from a variable in the function namespace, there is only one way:
(setf (symbol-function 'foo) my-function)
It is also necessary that the object is really a function and not something else (a number, a string, ...). Otherwise you'll see an error.
The side effect of this is that a Common Lisp never has to check if in (foo bar)
the FOO is really a function. There is no possibility that it can be other than a function or undefined.
Upvotes: 12
Reputation: 370112
Functions and variables live in different namespaces in Common Lisp.
So when you use a name in a position where a function is expected (i.e. at the head of a list that is being evaluated), it looks for a function (or macro) with that name. If you use the same name at a position where a variable is expected, it looks for a variable with that name.
In your case there is a function named numberp, but not variable named numberp, so the second case causes an error.
Upvotes: 8