1

I have made a simple implementation of LISP using SICP metacircular evaluator as a reference, but even though I know and see the code I don't quite understand something about it. In the apply function that applies a closure to its arguments there is a piece of code that calls eval on each of it's arguments. If I quote an argument, then eval of that argument will give the raw form of that argument.

For clarity of the nature of the question and to present my current understanding of what is happening I will walk through an example.

(define f (lambda (x) (print x)))
(define g (lambda (x) (f x)))

; prints "bar" into the console
(g (quote bar))

First we call g with (quote bar) as the first parameter. The argument to g is evaluated to a symbol bar.

When g is evaluated, it passes it should evaluate it's argument and pass it to function f. But evaluating a symbol will cause a lookup from the environment, which doesn't seem to happen (if it did I should have printed an error, or something like that).

So what I want to know is why does the code print bar and not an error.

bumbread
  • 460
  • 2
  • 11
  • 1
    "When g is evaluated, it passes it should evaluate it's argument and pass it to function f" Well, no. When the *form* `(g (quote bar))` is evaluated, then the argument is evaluated (to the symbol `bar`), and this *value* is then passed to `f`, which then also passes it to `print` and so on. Evaluation and *bindings* are two different concepts, and you seem to be confused by this. – Numbra May 17 '22 at 10:53

1 Answers1

1

I walked through the code with the debugger and now I believe I understand. When g was called, a new environment was created with x associated with the symbol bar. And when a function is executed it's parameters are being evaluated to the things that are stored in the environment. So it's not bar that got evaluated, it's x that got evaluated to bar. And after x is evaluated there's no second-time evaluation.

The reason why quoted things appear to stay quoted is because they actually do get unquoted, but they don't get evaluated as arguments (they only get evaluated once you explicitly call eval on them).

bumbread
  • 460
  • 2
  • 11
  • Things don't stay quoted. `(quote bar)` evaluates to the symbol `bar`. This symbol object is then what is passed around. Thus the symbol when passed isn't quoted, it's just passed as itself. – Rainer Joswig May 17 '22 at 12:57
  • I shall edit my answer to clarify the logic – bumbread May 17 '22 at 13:02