Consider the following Scheme definition:
(define f (lambda () (procedure? f)))
Strangely, when I evaluate (f) I get #t. The question is: why does this evaluation terminate? I was expecting it to loop indefinitely. What does the inner lambda evaluate to, given that f hasn't yet been defined?
There is no recursion involved here.
When you execute this code, a procedure f is defined (not executed):
> (define f (lambda () (procedure? f)))
> f
#<procedure:f>
When you then execute it, it checks if there is a procedure associated with the symbol f, which is true at that point in time, so it returns #t:
> (f)
#t
To be recursive, the procedure would have to call itself using (f).
Related
So from my personal research, it seems that closures / currying seem to be more or less the exact same thing, which can't be obviously correct. So where is the difference?
So here is an example of a closure in Racket:
(define (make-an-adder x)
(lambda (y)
(+ y x)))
(define add3 (make-an-adder 3))
(add3 5)
will give back
8
So where is the difference to currying? Because if i look up documentations and other examples, it seems that they do the exact same thing as i showed for the closure?
Thanks in advance everyone!
So they are different concepts, but both are related to nested lambdas.
A Closure can be created by a lambda that refers to a variable defined outside itself, and is most important when the lambda escapes from the context where that outside variable is defined. The Closure's job is to make sure that variable is preserved when the lambda escapes that context.
A Curried function is a function that can take its arguments in multiple steps, or multiple different function-applications. This normally means there are lambdas nested within lambdas.
Curried functions aren't always closures, though they often are
Most useful curried functions need to use closures, but if the inner lambdas ignore the outer arguments, they aren't closures. A simple example:
(define (curried-ignore-first ignored)
(lambda (y) y))
This is not a closure because the inner lambda (lambda (y) y) is already closed: it doesn't refer to any variables outside itself.
A curried function doesn't always need to ignore the outer arguments... it just needs to be done processing them before it returns the inner lambda, so that the inner lambda doesn't refer to the outer argument. A simple example of this is a curried choose function. The "normal" definition of choose does indeed use a closure:
(define (choose b)
(lambda (x y)
(if b x y))) ; inner lambda refers to `b`, so it needs a closure
However, if the if b is put outside the outer lambda, we can avoid making closures:
(define (choose b)
(if b
(lambda (x y) x) ; not closures, just nested lambdas
(lambda (x y) y)))
Closures aren't always from curried functions
A closure is needed when a inner lambda refers to a variable in an outer context and might escape that context. That outer context is often a function or a lambda, but it doesn't have to be. It can be a let:
(define closure-with-let
(let ([outer "outer"])
(lambda (ignored) outer))) ; closure because it refers to `outer`
This is a closure, but not an example of currying.
Turning a Curried-function-producing-a-closure into one without a closure
The example in the original question is a curried function that produces a closure
(define (make-an-adder x)
(lambda (y)
(+ y x)))
If you wanted to make a version that's still a curried function with the same behavior, but without needing a closure over x in some special cases, you can branch on those before the lambda:
(define (make-an-adder x)
(match x
[0 identity]
[1 add1]
[-1 sub1]
[2 (lambda (y) (+ y 2))]
[3 (lambda (y) (+ y 3))]
[_ (lambda (y) (+ y x))]))
This avoids producing a closure for the cases of x being an exact integer -1 through 3, but still produces a closure in all other cases of x. If you restricted the domain of x to a finite set, you could turn it into a function that didn't need closures, just by enumerating all the cases.
If you don't want a closure over x, but you're fine with a closure over other things, you can use recursion and composition to construct an output function that doesn't close over x:
(define (make-an-adder x)
(cond [(zero? x) identity]
[(positive-integer? x)
(compose add1 (make-an-adder (sub1 x)))]
[(negative-integer? x)
(compose sub1 (make-an-adder (add1 x)))]))
Note that this still produces closures (since compose creates closures over its arguments), but the function it produces does not close over x. Once this version of make-an-adder produces its result, it's "done" processing x and doesn't need to close over it anymore.
I'm currently trying make a function with following signature:
(define (point-app F x))
Which calculates F(x). My goal is to be able to evaluate the function F with x as argument.
So if I have:
(point-app '(+(* x x) 4) 2) <==> F(2) = (2^2)+4
the expected output would be 8.
I've tried using eval, by following drracket's docs:
(define (point-fixe f x)
(eval `(let ([number x]),f)))
But I cannot attach the variable x to number. As far as I know it's because eval dynamically loads the expressions? I've searched through common threads, but didn't find anything that would help me. Any aid would be gratefully appreciated.
The way you express a function in lambda calculus is λx.e where e is some expression probably involving x. This translates directly into Racket as (λ (x) e) where again e is some expression.
So your function simply needs to call its first argument, a function, on its second, some value:
(define (point-app F x)
(F x))
If you want to express your functions as literal data (lists, say), then you can use eval to turn those into functions:
(define (source->function function-form)
(eval function-form))
So now:
> (point-app (source->function '(λ (x) (+ (* x x) 4))) 2)
8
If you don't want to use the underlying mechanism of the language, then you need to write an evaluator. That's not very hard and there are a lot of examples out there I am sure.
I am using the DrRacket environment to try out the Scheme language.
I defined sum+1 as follows:
(define sum+1 '(+ x y 1))
I was wondering why the following expression does not evaluate:
(let ([x 1] [y 2]) (eval sum+1))
whereas doing this returns the correct value:
(define x 1)
(define y 2)
(eval sum+1)
eval does not work with lexical variables at all unless the lexical variable was created in the same expression:
#!r7rs
(import (scheme base)
(scheme eval))
(define env (environment '(scheme base)))
(let ((x 10))
(eval 'x env)) ; ERROR! `x` is not defined
You can think of it as eval always happening top level with the global bindings of the environment you pass to the second argument. You can perhaps trick it by passing values from your lexical environment like this:
(eval '(let ((x 10))
x)
env) ; ==> 10
(let ((x 10))
(eval `(let ((x ,x))
x)
env) ; ==> 10
By the time most Scheme implementations run code local variables are usually stack allocated. Thus something imagine this code:
(define (test v)
(display v)
(newline)
(eval 'v))
Might turn into this at runtime:
(define (test 1 #f) ; indicates 1 argument, no rest
(display (ref 0)) ; fetches first argument from stack
(newline)
(eval 'v)) ; but what is v?, certainly not the first argument
Also you can make corner cases. What happens if you mutate?
(define (test v)
(eval '(set! v 10))
v)
The structure to eval might come from user input so it's not obvious that v gets mutated, also many compiling Scheme implementations need to treat variables that mutate differently so it needs to know before the code runs that v needs special treatment, but it is not decidable because the (set! v 10) might come from the database or user input. Thus by not including local bindings you save yourself a lot of trouble and the language gets easier to optimize and compile.
There are lisp languages that can only be interpreted since it allows for passing macros as first class objects. These languages are impossible to reason about at compile time.
The reason that the command with let does not work is that let creates local variables. This means that the variables it creates can NOT be accessed from just anywhere - only from within let's body argument.
In your example, you defined:
(define sum+1 '(+ x y 1))
Then you commanded this:
(let ([x 1] [y 2]) (eval sum+1))
This doesn't work because x and y are only being defined in the eval statement, not within the procedure sum+1. This may seem counter-intuitive, but it prevents many errors with other inputs.
Your second example was:
(define x 1)
(define y 2)
(eval sum+1)
This does works because x and y are defined globally. This means that they CAN be accessed anywhere, and by anything. They are then applied to the sum+1 definition and are able to be printed. Please respond with any questions or feedback you have!
I'm doing some exercises in Racket, and ran into a problem I couldn't seem to query the docs for.
I want to generate the following curries of modulo for a list of divisors:
(define multlist '[3 5])
(define modfuncs (map (lambda x ;# make some modulos
(curry modulo x)) multlist))
This produces a list of curried procedures, which sounds promising, but when I try to test one of them, I get the following error:
-> (car modfuncs)
#<procedure:curried>
-> ((car modfuncs) 3)
; modulo: contract violation
; expected: integer?
; given: '(3)
; argument position: 1st
; [,bt for context]
Assuming this isn't a terrible way to do this, how do I unquote the values of multlist passed to the curry/map call so these functions will evaluate correctly?
You're actually doing this correctly, albeit with a tiny mistake:
(lambda x (curry modulo x))
This doesn't do what you think it does. What you actually want is this:
(lambda (x) (curry modulo x))
See the difference? In the former, x is not within an arguments list, so it will actually be passed a list of all arguments passed to the function, not a single argument.
You can see this behavior for yourself with the following simple program:
((lambda x x) 1 2 3)
; => '(1 2 3)
Therefore, your curry function is receiving a list of one number for x, not an actual integer.
So perhaps the more satisfying answer is: why does Racket do this? Well, this is actually a result of Racket/Scheme's rest parameter syntax. Inserting a dot before the last argument of a lambda makes that parameter a rest parameter, which becomes a list that holds all additional parameters passed to the function.
((lambda (a b . rest) rest) 1 2 3 4 5)
; => '(3 4 5)
However, this isn't actually just a special syntax. The dot notation actually has to do with how Racket's reader reads lists and pairs in syntax. The above parameter list actually becomes an "improper" list made up of the following cons sequence:
(cons 'a (cons 'b 'rest))
The same function without the rest parameter would have a proper list as its argument declaration, which would look like this instead:
(cons 'a (cons 'b null))
So then, what about the original x just standing alone? Well, that's an improper list with no preceding arguments! Doing ( . rest) wouldn't make any sense—it would be a syntax error—because you'd be trying to create a pair with no car element. The equivalent is just dropping the pair syntax entirely.
I am currently reading ANSI Common Lisp by Paul Graham, and I have a question about writing lambda expressions.
Do we need to prefix a lambda expression with #'?. If I write something like this in REPL, it will work fine
> ((lambda (x) (+ x 1)) 1)
2
so will this
> (mapcar (lambda (x) (+ x x)) '(1 2 3 4))
(2 4 6 8)
I understand that #' denotes a function. So my question is, is it some sort of convention or recommended practice? Can anything go wrong if I don't prefix lambdas with #', is it implementation dependent?
The LAMBDA expression
(lambda ...) is considered to be a lambda expression only in certain places, like the function form or as the head of a function call. Lambda expressions are not evaluated.
(function ; special operator FUNCTION
(lambda () 'foobar)) ; <- this is a lambda expression
( ; a function call
(lambda (foo) foo) ; <- this is a lambda expression
'bar ; argument
)
But here (lambda ...) is a macro form and not a lambda expression:
(funcall ; calling a function via funcall
(lambda (foo) foo) ; this is not a lambda expressions, but the macro lambda
; as all arguments to FUNCALL it will be
; macro expanded and evaluated
; it expands to (function (lambda (foo) foo))
'bar) ; argument
The LAMBDA macro
LAMBDA is a macro. It expands (lambda ...) to (function (lambda ...)), which is the equivalent of #'(lambda ...)).
CL-USER > (macroexpand '(lambda (foo) foo))
(FUNCTION (LAMBDA (FOO) FOO))
The macro saves you a bit of writing/reading, that's all. In the first version of Common Lisp (CLtL1) there was no LAMBDA macro. It has been added later and is now a part of ANSI Common Lisp,
The FUNCTION special operator
FUNCTION is a special operator. It expects a function name or a lambda expression. Thus the name or the lambda expression are not evaluated. In fact lambda expressions can't be evaluated at all. Inside FUNCTION, the lambda expression is not a macro form and thus will not be expanded again. The purpose of FUNCTION is to return the corresponding function object which is denoted by the name or by the lambda expression. It returns the function object as a value. With this special operator one can access the function object from global functions and lexical functions.
The FUNCTION operator is necessary in Common Lisp, because it has separate namespaces for values, functions and a few other things. It as a so-called Lisp-2 or even Lisp-n, with two or more namespaces.
Lambda expressions in function position in a function form
((lambda (foo) foo) 10) is supported by built-in syntax for Common Lisp. See Lambda Forms.
Confusing
This is all logical, but confusing. Don't worry you are not alone, but in practice it's not a big deal.