Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Defining and using functions in variables in Common Lisp

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?

Scheme 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.

Common Lisp

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.

like image 201
Frank Avatar asked Dec 05 '16 23:12

Frank


People also ask

How do you define a function in a Common Lisp?

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.

How are variables defined in Lisp?

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.

Which types of variable are used in Lisp?

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.

How many functions does a Lisp have?

13 Functions This chapter explains what functions are, how they accept arguments, and how to define them.


1 Answers

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.

like image 167
Nathan Davis Avatar answered Oct 24 '22 01:10

Nathan Davis