Why is lambda not a function - functional-programming

For Racket programming language, why is lambda not considered a function?
For example, it can't be defined as a higher order function like this.
(define (my-lambda args body)
(lambda args body))

There's a key distinction that your question is missing:
lambda is syntax.
Procedures are values.
A lambda form is a form of expression whose value is a procedure. The question whether "lambda is a function" starts off with a type error, so to speak, because lambdas and procedures don't live in the same world.
But let's set that aside. The other way to look at this is by thinking of it in terms of evaluation rules. The default Scheme evaluation rule, for the application of a procedure to arguments, can be expressed in pseudo-code like this:
(define (eval-application expr env)
(let ((values
;; Evaluate each subexpression in the same environment as the
;; enclosing expression, and collect the result values.
(map (lambda (subexpr) (eval subexpr env))
expr)))
;; Apply the first value (which must be a procedure) to the
;; other ones in the results.
(apply (car values) (cdr values))))
In English:
Evaluate all of the subexpressions in the same environment as the "parent".
apply the first result (which must have evaluated to a procedure) to the list of the rest.
And now, another reason lambda can't be a procedure is that this evaluation rule doesn't work for lambda expressions. In particular, the point of lambda is to not evaluate its body right away! This, in particular, is what afflicts your my-lambda—if you try to use it this way:
(my-lambda (x) (+ x x))
...the (x) in the middle must be immediately evaluated as an invocation of a procedure named x in the environment where the whole expression appears. The (+ x x) must also be immediately evaluated.
So lambda requires its own evaluation rule. As Basile's answer points out, this is normally implemented as a primitive in the Scheme system implementation, but we can sketch it in pseudocode with something like this:
;;;
;;; Evaluate an expression of this form, returning a procedure:
;;;
;;; (lambda <formals> <body> ...)
;;;
(define (eval-lambda expr env)
(let ((formals (second expr))
(body (cddr expr)))
;; We don't evaluate `body` right away, we return a procedure.
(lambda args
;; `formals` is never evaluated, since it's not really an
;; expression on its own, but rather a subpart that cannot
;; be severed from its enclosing `lambda`. Or if we want to
;; say it all fancy, the `formals` is *syncategorematic*...
(let ((bindings (make-bindings formals args)))
;; When the procedure we return is called, *then* we evaluate
;; the `body`--but in an extended environment that binds its
;; formal parameters to the arguments supplied in that call.
(eval `(begin ,#body) (extend-environment env bindings))))))
;;;
;;; "Tie" each formal parameter of the procedure to the corresponding
;;; argument values supplied in a given call. Returns the bindings
;;; as an association list.
;;;
(define (make-bindings formals args)
(cond ((symbol? formals)
`((,formals . args)))
((pair? formals)
`((,(car formals) . ,(car args))
,#(make-bindings (cdr formals) (cdr args))))))
To understand this pseudocode, the time-tested thing is to study one of the many Scheme books that demonstrate how to build a meta-circular interpreter (a Scheme interpreter written in Scheme). See for example this section of Structure and Interpretation of Computer programs.

lambda needs to be a core language feature (like if, let, define are) in Scheme because it is constructing a closure so needs to manage the set of closed or free variables (and somehow put their binding in the closure).
For example:
(define (translate d) (lambda (x) (+ d x)))
When you invoke or evaluate (translate 3) the d is 3 so the dynamically constructed closure should remember that d is bound to 3. BTW, you generally want the result of (translate 3) and of (translate 7) be two different closures sharing some common code (but having different bindings for d).
Read also about λ-calculus.
Explaining that all in details requires an entire book. Fortunately, C. Queinnec has written it, so read his Lisp In Small Pieces book.
(If you read French, you could read the latest French version of that book)
See also the Kernel programming language.
Read also wikipage about evaluation strategy.
PS. You could, and some Lisp implementations (notably MELT and probably SBCL) do that, define lambda as some macro -e.g. which would expand to building some closure in an implementation specific way (but lambda cannot be defined as a function).

A function call (e0 e1 e2) is evaluated like this
e0 is evaluated, the result is (hopefully) a function f
e1 is evaluated, the result is a value v1
e2 is evaluated, the result is a value v2
The function body of f is evaluated in an environment in which
the formal parameters are bound to the values v1 and v2.
Note that all expressions e0, e1, and, e2 are evaluated before the body of the function is activated.
This means that a function call like (foo #t 2 (/ 3 0)) will result in an error when (/ 3 0) is evaluated - before control is handed over to the body of foo.
Now consider the special form lambda. In (lambda (x) (+ x 1)) this creates a function of one variable x which when called with a value v will compute (+ v 1).
If in contrast lambda were a function, then the expressions (x) and (+ x 1) are evaluated before the body of lambda is activated. And now (x) will most likely produce an error - since (x) means call the function x with no arguments.
In short: Function calls will always evaluate all arguments, before the control is passed to the function body. If some expressions are not to be evaluated a special form is needed.
Here lambda is a form, that don't evaluate all subforms - so lambda needs to be a special form.

In Scheme lingo we use the term procedure instead of function throughout the standard report. Thus since this is about scheme dialects I'll use the term procedure.
In eager languages like standard #!racket and #!r6rs procedures get their arguments evaluated before the body is evaluated with the new lexical environment. Thus since if and lambda has special evaluation rules than for procedures special forms and macros are the way to introduce new syntax.
In a lazy language like #!lazy racket evaluation is by need and thus many forms that are implemented as macros/special forms in an eager language can be implemented as procedure. eg. you can make if as a procedure using cond but you cannot make cond using if because the terms themselves would be evaluated as forms on access and eg (cond (#t 'true-value)) would fail since #t is not a procedure. lambda has similar issue with the argument list.

Related

Why mutating the list to be only its first element with this approach does not work in Common Lisp?

I am trying to learn Common Lisp with the book Common Lisp: A gentle introduction to Symbolic Computation. In addition, I am using SBCL, Emacs, and Slime.
By the end of chapter 10, on the advanced section there is this question:
10.9. Write a destructive function CHOP that shortens any non-NIL list to a list of one element. (CHOP '(FEE FIE FOE FUM)) should return
(FEE).
This is the answer-sheet solution:
(defun chop (x)
(if (consp x) (setf (cdr x) nil))
x)
I understand this solution. However, before checking out the official solution I tried:
(defun chop (xs)
(cond ((null xs) xs)
(t (setf xs (list (car xs))))))
Using this as a global variable for tests:
(defparameter teste-chop '(a b c d))
I tried on the REPL:
CL-USER> (chop teste-chop)
(A)
As you can see, the function returns the expected result.
Unfortunately, the side-effect to mutate the original list does not happen:
CL-USER> teste-chop
(A B C D)
Why it did not change?
Since I was setting the field (setf) of the whole list to be only its car wrapped as a new list, I was expecting the cdr of the original list to be vanished.
Apparently, the pointers are not automatically removed.
Since I have very strong gaps in low-level stuff (like pointers) I thought that some answer to this question could educate me on why this happens.
The point is about how parameters to functions are passed in Common Lisp. They are passed by value. This means that, when a function is called, all arguments are evaluated, and their values are assigned to new, local variables, the parameters of the function. So, consider your function:
(defun chop (xs)
(cond ((null xs) xs)
(t (setf xs (list (car xs))))))
When you call it with:
(chop teste-chop)
the value of teste-chop, that is the list (a b c d) is assigned to the function parameter xs. In the last line of the body of function, by using setf, you are assigning a new value, (list (car xs)) to xs, that is you are assigning the list (a) to this local variable.
Since this is the last expression of the function, such value is also returned by the function, so that the evaluation of (chop test-chop) returns the value (a).
In this process, as you can see, the special variable teste-chop is not concerned in any way, apart from calculating its value at the beginning of the evaluation of the function call. And for this reason its value is not changed.
Other forms of parameter passing are used in other languages, like for instance by name, so that the behaviour of function call could be different.
Note that instead, in the first function, with (setf (cdr x) nil) a data structure is modified, that is a part of a cons cell. Since the global variable is bound to that cell, also the global variable will appear modified (even if, in a certain sense, it is not modified, since it remains bound to the same cons cell).
As a final remark, in Common Lisp it is better not to modify constant data structures (like those obtained by evaluating '(a b c d)), since it could produce an undefined behaviour, depending on the implementation. So, if some structure should be modifiable, it should be built with the usual operators like cons or list (e.g. (list 'a 'b 'c 'd)).

Why is cond a special form in Scheme, rather than a function?

(defun triangle-using-cond (number)
(cond
((<= number 0) 0) ; 1st
((= number 1) 1) ; 2nd
((> number 1) ; 3rd
;; 4th
(+ number
(triangle-using-cond (1- number))))))
Things that I know about Cond
It allows multiple test and alternative expressions
It has pre-specified evaluation order. For instance, the first condition will always evaluated whether it is right or not
One thing that I cannot distinguish is that what makes cond different from a function!
A function call (e0 e1 e2) is evaluated like this
1. e0 is evaluated, the result is (hopefully) a function f
2. e1 is evaluated, the result is a value v1
3. e2 is evaluated, the result is a value v2
4. The function body of `f` is evaluated in an environment in which
the formal parameters are bound to the values `v1` and `v2`.
Note that all expressions e0, e1, and, e2 are evaluated before the body of the function is activated.
This means that a function call like (foo #t 2 (/ 3 0)) will result in an error when (/ 3 0) is evaluated - before control is handed over to the body of foo.
Now consider the special form if. In (if #t 2 (/ 3 0)) the expressions #t is evaluated and since the value non-false, the second expression 2 is evaluated and the resulting value is 2. Here (/ 3 0) is never evaluated.
If in contrast if were a function, then the expressions #t, 2, and, (/ 3 0) are evaluated before the body of is activated. And now (/ 3 0) will produce an error - even though the value of that expressions is not needed.
In short: Function calls will always evaluate all arguments, before the control is passed to the function body. If some expressions are not to be evaluated a special form is needed.
Here if and cond are examples of forms, that don't evaluate all subexpressions - so they they need to be special forms.
If cond were not a special form then the expression:
((> number 1) ;;3rd
(+ number (triangle-using-cond (1- number))))
would cause either:
an infinite loop because triangle-using-cond would keep calling itself recursively via the tail call (triangle-using-cond (1- number)).
or, the last expression would try to apply the value #f or #t as a function (which in a type-2 Lisp such as ANSI Common Lisp is possible, but not possible in a type-1 Lisp such as Racket or Scheme) and produce an error.
What makes cond a special form is that its arguments are evaluated lazily whereas functions in Scheme or Common Lisp evaluate their arguments eagerly.
As already answered, all arguments to a call to some function f are evaluated before the result of applying f is computed. Does it however mean that cond, or if, or both should be special forms?
Well, first, if you have if, you can easily simulate a cond with nested tests. Conversely, if is just a degenerate form of cond. So you can say that it is sufficient to have one of them a special form. Let's choose if because it is simpler to specify.
So shall if be special?
It doesn't really need to...
If the underlying question is "is if expressible in terms of a smaller set of special forms?", then the answers is yes: just implement if in terms of functions:
(define true-fn (lambda (then else) (then)))
(define false-fn (lambda (then else) (else)))
Whenever you can return a boolean, you return one of the above function instead.
You could for example decide to bind #t and #f to those functions.
Notice how they call one of the two input parameters.
((pair? x) ;; returns either true-fn or false-fn
(lambda () (+ x 1))
(lambda () x))
...but why code in lambda calculus?
Evaluating code conditionally is really a fundamental operation of computing. Trying to find a minimal special forms where you cannot express that directly leads to a poorer programming language from the perspective of the programmer, however "clean" the core language is.
From a certain point of view, the if form (or cond) is necessary because without them it becomes really hard to express conditional execution in a way that a compiler/interpreter can handle efficiently.
This document referenced by uselpa discuss using closures to implement if, and concludes:
However, the syntactic inconvenience would be so great that even
Scheme defines if as a special form.

not sure about the definition of a macro in a sample of OnLisp

Here are some sample codes from text of OnLisp.
My question is that why it bothers to use a lambda function,
`(funcall (alrec ,rec #'(lambda () ,base)) ,#lsts))
as second argument to alrec in the definition of on-cdrs?
What is the difference if I just define it without using lambda?
`(funcall (alrec ,rec ,base) ,#lsts))
(defun lrec (rec &optional base)
(labels ((self (lst)
(if (null lst)
(if (functionp base)
(funcall base)
base)
(funcall rec (car lst)
#'(lambda ()
(self (cdr lst)))))))
#'self))
(defmacro alrec (rec &optional base)
"cltl2 version"
(let ((gfn (gensym)))
`(lrec #'(lambda (it ,gfn)
(symbol-macrolet ((rec (funcall ,gfn)))
,rec))
,base)))
(defmacro on-cdrs (rec base &rest lsts)
`(funcall (alrec ,rec #'(lambda () ,base)) ,#lsts))
You don't say how this is intended to be called and this code is a bit of a tangle so at a quick glance I couldn't say how it's supposed to work. However, I can answer your question.
First, let me say that
(if (functionp base) (funcall base) base)
is terrible programming style. This effectively puts a whole in your semantic space, creating a completely different handling of functions as objects than other things as objects. In Common Lisp, a function is supposed to be an object you can choose to pass around. If you want to call it, you should do so, but you shouldn't just say to someone "if I give you a function you should call it and otherwise you should not." (Why this matters will be seen as you read on.)
Second, as Barmar notes, if you write ,base you are basically saying "take the code and insert it for evaluation here". If you write
#'(lambda () ,base)
you are saying put the code inside a function so that its execution is delayed. Now, you're passing it to a function that when it receives the function is going to call it. And, moreover, calling it will evaluate it in the lexical environment of the caller, and there is no intervening change in dynamic state. So you'd think this would be the same thing as just evaluating it at the call site (other than just a little more overhead). However, there is a case where it's different.
If the thing you put in the base argument position is a variable (let's say X) or a number (let's say 3), then you'll either be doing (lrec ... X) or (lrec 3) or else you'll be doing
(lrec ... #'(lambda () X))
or
(lref ... #'(lambda () 3))
So far so good. If it gets to the caller, it's going to say "Oh, you just meant the value of X (or of 3)." But there's more...
If you say instead an expression that yields a function in the base argument position of your call to on-cdrs or your call to alrec, you're going to get different results depending on whether you wrote ,base or #'(lambda () ,base). For example, you might have put
#'f
or
#'(lambda () x)
or, even worse,
#'(lambda (x) x)
in the base argument position. In that case, if you had used ,base, then that expression would be immediately evaluated before passing the argument to lrec, and then lrec would receive a function. And then it would be called a second time (which is probably not what the macro user expects unless the documentation is very clear about this inelegance and the user of the macro has cared enough to read the documentation in detail). In the first case, it will return 3, in the second case, the value of x, and in the third case an error situation will occur because it will be called with the wrong number of arguments.
If instead you implemented it with
#'(lambda () ,base)
then lrec will receive as an argument the result of evaluating one of
#'(lambda () #'f)
or
#'(lambda () #'(lambda () 3))
or
#'(lambda () #'(lambda (x) x))
depending on what you gave it as an argument from our examples above. But in any case what lrec gets is a function of one argument that, when evaluated, will return the result of evaluating its body, that is, will return a function.
The important takeaways are these:
The comma is dropping in a piece of evaluable code, and wrapping the comma'd experession with a lambda (or wrapping any expression with a lambda) delays evaluation.
The conditional in the lrec definition should either expect that the value is already evaluated or not, and should not take a conditional effect because it can't know whether you already evaluated something based purely on type unless it basically makes a mess of functions as first-class data.
I hope that helps you see the difference. It's subtle, but it's real.
So using
#'(lambda () ,base)
protects the macro from double-evaluation of a base that might yield a function, but on the other hand the bad style is something that shouldn't (in my view) happen. My recommendation is to remove the conditional function call to base and make it either always or never call the base as a function. If you make it never call the function, the caller should definitely use ,base. If you make it always call the function, the caller should definitely include the lambda wrapper. That would make the number of evaluations deterministic.
Also, as a purely practical matter, I think it's more in the style of Common Lisp just to use ,base and not bother with the closure unless the expression is going to do something more than travel across a function call boundary to be immediately called. It's a waste of time and effort and perhaps extra consing to have the function where it's really not serving any interesting purpose. This is especially true if the only purpose of the lrec function is to support this facility. If lrec has an independent reason to have the contract that it does, that's another matter and maybe you'd write your macro to accommodate.
It's more common in a functional language like Scheme, which has a different aesthetic, to have a regular function as an alternative to any macro, and to have that function take such a zero-argument function as an argument just in case some user doesn't like working with macros. But mostly Common Lisp programmers don't bother, and your question was about Common Lisp, so I've biased the majority of my writing here to that dialect.

When to use #' (function) in front of lambda expressions?

I understand that, because there are separate namespaces in Common Lisp for functions and variables, you can do this:
((lambda (x) (* 2 x)) 3)
and you can also do this:
(funcall #'(lambda (x) (* 2 x)) 3)
When should we use #' as opposed to not using it? I read in another StackOverflow question that #' was only kept around for historic reasons and shouldn't be used anymore. Is this true? My question is not a duplicate, I am asking about when I would use these in my code.
It's not an issue of lisp-2 versus lisp-1. With lambda expressions in a position where a function value is needed, it's simply a stylistic choice. Some people like the visual marker of #' and some don't. The lambda macro already expands into the function form for which #' provides an abbreviation:
Macro LAMBDA
(lambda lambda-list [[declaration* | documentation]] form*)
== (function (lambda lambda-list [[declaration* | documentation]] form*))
== #'(lambda lambda-list [[declaration* | documentation]] form*)
#'x is just syntactic sugar for (function x), and the function special operator provides "the functional value of name in the current lexical environment." T
Special Operator FUNCTION
The value of function is the functional value of name in the current
lexical environment.
If name is a function name, the functional definition of that name is
that established by the innermost lexically enclosing flet, labels, or
macrolet form, if there is one. Otherwise the global functional
definition of the function name is returned.
While (lambda ...) is the name of a function, it's not a name that could ever be established by a flet, label, or macrolet form, so you're always getting "the global definition of the function name", which is just the lambda function. Since (lambda ...) expands to (function (lambda ...)), there's no difference. It's just a matter of style.
However, it is important to note that in the first case that you talked about,
((lambda (x) (* x 2)) 3)
you could not do:
(#'(lambda (x) (* x 2)) 3) ; or
((function (lambda (x) (* x 2))) 3)
The support for ((lambda ...) ...) is part of the language, unrelated to the fact that there's a definition of lambda as a macro. It's a particular type of compound form, namely a lambda form, which is described in the HyperSpec:
3.1.2.1.2.4 Lambda Forms
A lambda form is similar to a function form, except that the function
name is replaced by a lambda expression.
A lambda form is equivalent to using funcall of a lexical closure of
the lambda expression on the given arguments. (In practice, some
compilers are more likely to produce inline code for a lambda form
than for an arbitrary named function that has been declared inline;
however, such a difference is not semantic.)
For further information, see Section 3.1.3 (Lambda Expressions).

Using delay/force to implement control structures in the absence of macros?

Using Scheme the programming language, how would one use delay/force to implement control structures without resorting to using macro facilities?
Thank you.
Most programming languages support control-flow structures that don't evaluate arguments redundantly.
so (and (expression_1) ... (expression_N)) would return #f as soon as the first false expression is found.
If and were simply a function in Scheme, all of it's parameters would have been evaluated before getting to the body of and's implementation. There's no way you could implement it to get around this.
Macros don't evaluate their arguments, they just rewrite terms before they get evaluated. You can take advantage of that to create control structures like if/cond/or/and as long as you have one of them to work with already. In fact, because a lambda body isn't evaluated until called, all you really need for lazily evaluated control flow statements are lambda and macros.
Now, if you don't want to use macros, then your arguments will be evaluated. You have to wrap them up in lambdas, or you can use delay/force. But then you aren't passing expressions into your control structure. You're passing in expressions wrapped in something. It gets kinda ugly.
Here is a contrived example using lambdas.
(define bool1
(lambda ()
(display "evaluating bool1\n")
#t))
(define bool2
(lambda ()
(display "evaluating bool2\n")
#t))
(define (_or b1 b2)
(if (b1) #t
(if (b2) #t #f)))
(define (_and b1 b2)
(if (b1) (if (b2) #t #f) #f))
usage:
> (_and bool1 bool2)
evaluating bool1
evaluating bool2
#t
> (_or bool1 bool2)
evaluating bool1
#t
>

Resources