lisp: lambda scope - lisp

I want to implement filter function that would filter a list based on a condition
(defun filter (func xs)
(mapcan
(lambda (x)
(when (func x) (list x))) xs ))
but I get an error:
*** - EVAL: undefined function FUNC
I thought that lambda should see func. How to pass func to lambda correctly?
I use CLISP.

You want
(when (funcall func x) (list x))
instead of
(when (func x) (list x))
More information about function vs. variable namespace:
http://en.wikipedia.org/wiki/Lisp-1_vs._Lisp-2#The_function_namespace
http://c2.com/cgi/wiki?SingleNamespaceLisp
Why do we need funcall in lisp

Related

How to call a referenced lambda?

I'm trying to call a function (lambda) stored within an alist. Below is a small snippet that demonstrates what I'm trying to do:
(defvar *db* '((:add (lambda (a b)
(+ a b)))
(:sub (lambda (a b)
(- a b)))))
(defun perform-operation-on-numbers (operation a b)
"Performs specified operation on the supplied numbers."
(let ((func (second (find operation
*db*
:key #'car))))
;; TODO: Call `func` on `a` and `b`
(print func)))
(perform-operation-on-numbers :add 1 2)
No matter what I do, not even funcall is able to let me call the lambda stored against :add. How should I reference the retrieved lambda as a lambda?
Your use of quote lead to your inability to use funcall.
Look:
(setf *mydb* '((:add #'+)
(:sub #'-)))
;; ((:ADD #'+) (:SUB #'-))
I can't use funcall. But:
(setf *mydb* (list (cons :add #'+)
(cons :sub #'-)))
;; ((:ADD . #<FUNCTION +>) (:SUB . #<FUNCTION ->))
;;
;; ^^^^ "FUNCTION" ? That's better! <----------
;;
I can (funcall (cdr (first *MYDB*)) 2)
Then the succinct notation is with back-quote and comma.
As pointed out by other answers, you are manipulating code as data, where the forms below (lambda ...) are unevaluated. But even with your data:
(defvar *db* '((:add (lambda (a b)
(+ a b)))
(:sub (lambda (a b)
(- a b)))))
You can use funcall or apply, if you first use COERCE:
If the result-type is function, and object is a lambda expression, then the result is a closure of object in the null lexical environment.
For example, let's access the form associated with :add:
CL-USER> (second (assoc :add *db*))
(LAMBDA (A B) (+ A B))
The value is an unevaluated form.
You can coerce it to a function:
CL-USER> (coerce (second (assoc :add *db*)) 'function)
#<FUNCTION (LAMBDA (A B)) {536B988B}>
Maybe you want to walk the terms to check that the lambda are only using a restricted set of operations, in which case it makes sense to keep them as data. But at some point you'll want to turn these code snippets to actual functions, and you can do that with coerce:
CL-USER> (defvar *db-fns*
(loop
for (n c) in *db*
collect (list n (coerce c 'function))))
*DB-FNS*
Here you compute the functions once, and can reuse them later instead of calling coerce each time.
CL-USER> *db-fns*
((:ADD #<FUNCTION (LAMBDA (A B)) {536B9B5B}>)
(:SUB #<FUNCTION (LAMBDA (A B)) {536B9C0B}>))
(it is equivalent to calling eval on the lambda form)
That's not a function: it's a list beginning (lambda ...). If you want a function have a function, for instance by
(defvar *db* `((:add ,(lambda (a b)
(+ a b)))
(:sub ,(lambda (a b)
(- a b)))))
or, better, don't wrap the thing in some useless baggage:
(defvar *db* `((:add ,#'+
(:sub ,#'-))

Elisp lambdas, quoting, and lexical-let

I'm trying to understand the following two snippets of code:
(defun make-adder1 (n) `(lambda (x) (+ ,n x)))
(defun make-adder2 (n) (lexical-let ((n n)) (lambda (x) (+ n x))))
These both seem to produce callables:
(funcall (make-adder1 3) 5) ;; returns 8
(funcall (make-adder2 3) 5) ;; returns 8
These both work. I have two main questions:
1) I don't understand the disparity in "quoting level" between the two approaches. In the first case, the lambda expression is quoted, which means the "symbol itself" is returned instead of the value. In the second case, it seems like the statement with the lambda will get evaluated, so the value of the lambda will be returned. Yet, these both work with funcall. When using funcall on a defun'ed function, it has to be quoted. Is lexical-let doing some kind of quoting automatically? Isn't this, kind of surprising?
2) Reading other posts on this topic, I'm given to understand that the first approach will break down under certain circumstances and deviate from what one would expect from working with lambdas and higher order functions in other languages, because elisp has dynamic scoping by default. Can someone give a concrete example of code that makes this difference apparent and explain it?
In the first example there is no variable n in the resulting function, which is just (lambda (x) (+ 3 x)). It does not need lexical binding because there is no free variable in the lambda, i.e., no variable that needs to be kept in a binding of a closure. If you don't need the variable n to be available, as a variable in uses of the function, i.e., if its value at function definition time (=3) is all you need, then the first example is all you need.
(fset 'ad1 (make-adder1 3))
(symbol-function 'ad1)
returns:
(lambda (x) (+ 3 x))
The second example creates what is, in effect, a function that creates and applies a complicated closure.
(fset 'ad2 (make-adder2 3))
(symbol-function 'ad2)
returns
(lambda (&rest --cl-rest--)
(apply (quote (closure ((--cl-n-- . --n--) (n . 3) t)
(G69710 x)
(+ (symbol-value G69710) x)))
(quote --n--)
--cl-rest--))
A third option is to use a lexical-binding file-local variable and use the most straightforward definition. This creates a simple closure.
;;; foo.el --- toto -*- lexical-binding: t -*-
(defun make-adder3 (n) (lambda (x) (+ n x)))
(fset 'ad3 (make-adder3 3))
(symbol-function 'ad3)
returns:
(closure ((n . 3) t) (x) (+ n x))
(symbol-function 'make-adder1)
returns:
(lambda (n)
(list (quote lambda)
(quote (x))
(cons (quote +) (cons n (quote (x))))))
(symbol-function 'make-adder2)
returns:
(closure (t)
(n)
(let ((--cl-n-- (make-symbol "--n--")))
(let* ((v --cl-n--)) (set v n))
(list (quote lambda)
(quote (&rest --cl-rest--))
(list (quote apply)
(list (quote quote)
(function
(lambda (G69709 x)
(+ (symbol-value G69709) x))))
(list (quote quote) --cl-n--)
(quote --cl-rest--)))))
(symbol-function 'make-adder3)
returns
(closure (t) (n) (function (lambda (x) (+ n x))))

Is it possible to write the following lisp macro as a function?

I'm reading Paul Graham's ANSI Common Lisp. In the chapter about macros he shows the following example:
(defmacro in (obj &rest choices)
(let ((insym (gensym)))
`(let ((,insym ,obj))
(or ,#(mapcar #'(lambda (c) `(eql ,insym ,c))
choices)))))
(Returns true if the first argument is equal to any of the other arguments)
He holds that it can't be written as a function. Wouldn't this function have the same functionality?
(defun in (obj &rest choices)
(reduce (lambda (x y)
(or x (eql y obj)))
choices
:initial-value nil))
The difference I see is that the macro will only evaluate arguments till it finds an eql argument. Is that it?
The point is, that the macro version evaluates the arguments lazily (it expands into an OR) stopping if a match is found. This cannot be achieved with a function, since a funcall will always evaluate all arguments first.
> (macroexpand '(in 42
(long-computation-1)
(long-computation-2)
(long-computation-3)))
(LET ((#:G799 42))
(OR (EQL #:G799 (LONG-COMPUTATION-1))
(EQL #:G799 (LONG-COMPUTATION-2))
(EQL #:G799 (LONG-COMPUTATION-3))))
To get the same effect you would need to write:
(defun in (obj &rest choices)
(reduce (lambda (x y)
(or x (eql (funcall y) obj)))
choices
:initial-value nil))
and use it this way:
(in 42
(function long-computation-1)
(function long-computation-2)
(function long-computation-3))

Renaming lambda in Common Lisp

I started learning Common Lisp recently, and (just for fun) decided to rename the lambda macro.
My attempt was this:
> (defmacro λ (args &body body) `(lambda ,args ,#body))
It seems to expand correctly when by itself:
> (macroexpand-1 '(λ (x) (* x x)))
(LAMBDA (X) (* X X))
But when it's nested inside an expression, execution fails:
> ((λ (x) (* x x)) 2)
(Λ (X) (* X X)) is not a function name; try using a symbol instead
I am probably missing something obvious about macro expansion, but couldn't find out what it is.
Maybe you can help me out?
edit:
It does work with lambda:
> ((lambda (x) (* x x)) 2)
4
edit 2:
One way to make it work (as suggested by Rainer):
> (set-macro-character #\λ (lambda (stream char) (quote lambda)))
(tested in Clozure CL)
In Common Lisp LAMBDA is two different things: a macro and a symbol which can be used in a LAMBDA expression.
The LAMBDA expression:
(function (lambda (x) (foo x)))
shorter written as
#'(lambda (x) (foo x))
An applied lambda expression is also valid:
((lambda (x) (+ x x)) 4)
Above both forms are part of the core syntax of Common Lisp.
Late in the definition of Common Lisp a macro called LAMBDA has been added. Confusingly enough, but with good intentions. ;-) It is documented as Macro LAMBDA.
(lambda (x) (+ x x))
expands into
(function (lambda (x) (+ x x))
It makes Common Lisp code look slightly more like Scheme code and then it is not necessary to write
(mapcar #'(lambda (x) (+ x x)) some-list)
With the LAMBDA macro we can write
(mapcar (lambda (x) (+ x x)) some-list)
Your example fails because
((my-lambda (x) (* x x)) 2)
is not valid Common Lisp syntax.
Common Lisp expects either
a data object
a variable
a function call in the form (function args...)
a function call in the form ((lambda (arglist ...) body) args...)
a macro form like (macro-name forms...)
a special form using one of the built-in special operators like FUNCTION, LET, ...
defined in the list of special operators in Common Lisp
As you can see a syntax of
((macro-name forms...) forms...)
is not a part of Common Lisp.
It is possible to read the character λ as LAMBDA:
(defun λ-reader (stream char)
(declare (ignore char stream))
'LAMBDA)
(set-macro-character #\λ #'λ-reader)
Example:
CL-USER 1 > ((λ (x) (* x x)) 3)
9
CL-USER 2 > '(λ (x) (* x x))
(LAMBDA (X) (* X X))
You might also think of LAMBDA as an operator which, given a term and a list of free variables, returns a function. This p.o.v. takes LAMBDA out of the family of basic functions and elementary macros -- at least as far as the interpreter is concerned.
(defun lambda-char (stream char)
"A lambda with only ONE arg _"
(declare (ignore char))
(let ((codes (read stream nil)))
`(lambda (_) ,codes)))
(set-macro-character #\λ #'lambda-char t)
λ(+ 1 2 _) ; => (lambda (_) (+ 1 2 _))
Maybe this is more concise, with ONLY ONE arg of _

Emacs Lisp: difference between (function (lambda ...)) and (lambda ...)?

What is the difference between
(function (lambda ...))
and
(lambda ...)
and
'(lambda ...)
?
It seems three are interchangeable in a lot of cases.
They are pretty interchangeable. The answer is that function enables the lambda to be byte compiled, whereas the other two do not (and are equivalent). Note: this does not mean that function actually byte compile the lambda.
How might one figure that out? A little Emacs lisp introspection provides some clues. To start: C-h f function RET:
function is a special form in 'C
source code'.
(function arg)
Like 'quote', but preferred for
objects which are functions. In byte
compilation, 'function' causes its
argument to be compiled. 'quote'
cannot do that.
Ok, so that's the difference between (function (lambda ...)) and '(lambda ...), the first tells the byte compiler that it may safely compile the expression. Whereas the 'ed expressions may not necessarily be compiled (for they might just be a list of numbers.
What about just the bare (lambda ...)? C-h f lambda RET shows:
lambda is a Lisp macro in `subr.el'.
(lambda args [docstring] [interactive]
body)
Return a lambda expression. A call of
the form (lambda args docstring
interactive body) is self-quoting; the
result of evaluating the lambda
expression is the expression itself.
The lambda expression may then be
treated as a function, i.e., stored as
the function value of a symbol, passed
to 'funcall' or 'mapcar', etc.
Therefore, (lambda ...) and '(lambda ...) are equivalent.
Also, there is the notation #'(lambda ...), which is syntactic sugar for (function (lambda ...)).
For more information on functions in Emacs lisp, read the Functions info pages.
Just to check all this, you can type the following into the *scratch* buffer and evaluate the expressions:
(caddr '(lambda (x) (+ x x)))
(+ x x)
(caddr (lambda (x) (+ x x)))
(+ x x)
(caddr (function (lambda (x) (+ x x))))
(+ x x)
(equal '(lambda (x) (+ x x))
(function (lambda (x) (+ x x))))
t
(equal '(lambda (x) (+ x x))
(lambda (x) (+ x x)))
t
So, all three variants of using lambda just build up lists that may be used as functions (one of which may be byte compiled).
Well (quote (lambda...)) and (lambda...) are not equivalent (when byte compiling). Quoted lambdas are not byte compiled whereas everything else is.
For example:
(defun foo (a)
(byte-code-function-p a))
(defun bar ()
(foo '(lambda () (ignore 'me))))
(defun bar2 ()
(foo (lambda () (ignore 'me))))
(defun bar3 ()
(foo (function (lambda () (ignore 'me)))))
(defun bar4 ()
(foo #'(lambda () (ignore 'me))))
(byte-compile 'bar)
(byte-compile 'bar2)
(byte-compile 'bar3)
(byte-compile 'bar4)
(bar) ; -> nil
(bar2) ; -> t
(bar3) ; -> t
(bar4) ; -> t
You usually don't want to quote a lambda unless the function you are going to pass the lambda to is doing something else with it than just funcall it.