I stumbled upon this article explaining the Y Combinator. The code is in Scheme, but I'm trying to work through it using Common Lisp.
However, I'm having trouble doing the translation from Scheme to Common Lisp. Scheme uses a single namespace for both functions and (other) variables, but Common Lisp uses different namespaces for functions and variables. How can I resolve this difference, to get working Common Lisp code?
Here's some Scheme code from the tutorial.
In the beginning the author defines the factorial function:
(define (factorial n)
if (= n 0)
1
(* n (factorial (- n 1)))))
and translates it into this:
(define factorial
(lambda (n)
(if (= n 0)
1
(* n (factorial (- n 1))))))
Because (according to the author) that's what Scheme does:
Scheme simply translates the first definition into the second one before evaluating it. So all functions in Scheme are really lambda expressions.
I tried to rewrite both the above snippets in Common Lisp to imitate this transition from the first form to the second. But there is no define
in CL, neither has it a single name space. So I tried to cheat my way around it.
Rewriting the first Scheme definition in Common Lisp was easy:
(defun factorial (n)
(if (= n 0)
1
(* n (factorial (- n 1)))))
But (to me) translating this into the second definition was a bit trickier. I translated it like this:
(setf (symbol-function 'factorial)
(lambda (n)
(if (= n 0)
1
(* n (factorial (- n 1))))))
Is this a bad way to do this (or is there a better way)? It seems to work but the compiler gives me a style warning: undefined function: factorial.
Use defun to define your own functions in LISP. Defun requires you to provide three things. The first is the name of the function, the second is a list of parameters for the function, and the third is the body of the function -- i.e. LISP instructions that tell the interpreter what to do when the function is called.
In LISP, each variable is represented by a symbol. The variable's name is the name of the symbol and it is stored in the storage cell of the symbol.
These types include integer, float, cons, symbol, string, vector, hash-table, subr, byte-code function, and record, plus several special types, such as buffer, that are related to editing.
13 Functions This chapter explains what functions are, how they accept arguments, and how to define them.
If I understand correctly, the main thrust of your question deals with translating between a "Lisp-1" and a "Lisp-2".
Scheme is a "Lisp-1" -- it has a single namespace for both functions and variables. Common Lisp, on the other hand, is a "Lisp-2" -- it has separate namespaces for functions and variables.
In scheme, you can write
(define foo (lambda (...) ...))
and then call foo
like:
(foo ...)
We can define foo
in exactly the same way in Common Lisp as well, but if we try to call foo
using that syntax, your program will crash. This is because foo
is in the variable namespace, not the function namespace.
We can work around this by using funcall
to invoke foo
:
(funcall foo ...)
That's a brief introduction. The Common Lisp Cookbook's page on Functions provides additional details you might find useful.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With