Why does this not evaluate in Scheme? - functional-programming

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!

Related

Racket - Closure / Currying, where is the difference?

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.

How do I evaluate an expression with given arguments?

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.

Mapping curry to a list of parameters

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.

What does the following function do in Scheme programming language

(define (unknown (lambda (x y)
(cond
((null? y) y)
((x (car y)) (unknown x (cdr y))))
(else (cons (car y) (unknown x (cdr y)))))))
I'm a newbie when it comes to scheme and wanted to know the purpose of this function which I came across in a textbook. My main doubt lies as to what ((x (car y)) does. How does this expression get executed without any operators and yet I don't come across any errors while compiling. Although I'm unable to run the program because the values I input for x are apparently not applicable for the function. Please help.
Scheme functions can take functions as arguments, and can return functions. Your code makes sense if you pass in a function as an argument.
If you call the code like this:
(unknown even? '(1 2 3 4 5))
then it should return the list (1 3 5). This is a filtering function that returns members of y where the result of applying the function x to the member is false.

Destructive operations in scheme environments

I'm confused about destructive operations in Scheme. Let's say I have a list and some destructive procedures defined in the global environment:
(define a '(a b c))
(define (mutate-obj x)
(set! x '(mutated)))
(define (mutate-car! x)
(set-car! x 'mutated))
(define (mutate-cdr! x)
(set-cdr! x 'mutated))
Then we have the following expression evaulation:
(mutate-obj! a) a => (a b c)
(mutate-car! a) a => (mutated b c)
(mutate-cdr! a) a => (mutated . mutated)
Why isn't set! having an effect on a outside its procedure when both set-car! and set-cdr! have? Why isn't the expression on the first line evaluating to (mutated)? How does all of this really work?
The first example isn't working as you imagined. Although both the x parameter and the a global variable are pointing to the same list, when you execute (set! x '(mutated)) you simply set x (a parameter local to the procedure) to point to a different list, and a remains unchanged. It'd be different if you wrote this:
(define (mutate-obj)
(set! a '(mutated)))
Now a gets mutated inside the procedure. The second and third procedures are modifying the contents of the a list, also pointed by x, so the change gets reflected "outside" once the procedure returns.

Resources