Let as syntactic sugar for lambda - scheme

Is the following how a let statement resolves in terms of lambda?
(let((a 4)(b 5)) (+ a b))
-->
((lambda (a b) (+ a b)) 4 5)
Is the general form something along the lines of:
(lambda (key1 key2 ...) <body> (val1 val2 ...))
-->
(let ((key1 val1) (key2 val2) ...) <body>)
What's the advantage of using the let syntax? Is it just the easier readability placing the key/value pair next to each other?

(lambda (key1 key2 ...) <body> (val1 val2 ...))
-->
(let ((key1 val1) (key2 val2) ...) <body>)
The first pattern is actually like this:
((lambda (par1 par2 ...) <body>) arg1 arg2 ...)
-->
(let ((par1 arg1) (par2 arg2) ...) <body>)
The function has parameters. Common Lisp has positional, optional, rest and keyword parameters.
The function form has argument forms. Each argument form gets evaluated and the function then gets called with the arguments values. The parameters (local variables) get bound to the arguments values and the body gets executed.
The main benefit of a let is a question of easier seeing which parameter has which argument form and how many arguments (and possibly which) one has to provide.
Imagine:
((lambda (a b c d e f)
<long body> ; and yes the body can get long
)
1 2 3 4 5 5)
Be warned, there is a lot of code where the body is longer than five lines.
The let moves the argument forms to the top and it is easier to see what the environment is in which the body gets evaluated:
(let ((a 1)
(b 2)
(c 3)
(d 4)
(e 5)
(d 6))
<long body>
)
or even
(let ((a 1) (b 2) (c 3) (d 4) (e 5) (d 6))
<long body>
)

Not only easier readability; it is easier to write code using let than it is to write code that uses lambda to express let. Consider:
(let ((x 2)
(y 3))
(let ((u (+ x y))
(v (* x y)))
(display "let version:\n")
(for-each display (list x ", " y "\n" u ", " v "\n"))))
let version:
2, 3
5, 6
And a lambda version of the same construct:
((lambda (x y)
((lambda (u v)
(display "lambda version:\n")
(for-each display (list x ", " y "\n" u ", " v "\n")))
(+ x y) (* x y))) 2 3)
lambda version:
2, 3
5, 6
Both versions work, but the let version expresses intent through use of an appropriate syntax. The lambda version expresses intent only through the semantics of its construction. If you are unaware if the idiom that allows the expression of the idea of let binding, or if you can't piece together what is happening by analyzing the code, the meaning of the lambda version is opaque. But the let version clearly states its intent by using syntax dedicated to let binding.
Further, as let binding scenarios get more complex, using let offloads a substantial portion of that complexity to the syntax. The above example is a simple nested let, and it is already easy to make mistakes in the lambda version. You have to be sure that the parentheses are placed correctly (I actually managed to get one out of place when writing the example code), and the final version places all of the variable identifiers at the beginning of the construction, with all of the bound values at the end. This means that to understand the lambda version you must keep referencing the beginning and the end to understand what is happening in the body.
Generally speaking, lambda expresses a very general idea, but let expresses a more specific idea that is often needed. The advantage of let syntax is that it allows you to express the more specific idea easily, concisely, and readably in a way that is less error-prone than always expressing the specific idea by implementing it in terms of the more general idea.

Related

What is the purpose of Closures in Scheme/Racket?

I am learning Scheme and just came across Closures. The following example provided, demonstrating the use of Closures:
(define (create-closure x)
(lambda () x))
(define val (create-closure 10))
From what I understand, when the above code is evaluated, val will equal to 10. I realize this is just an example, but I don't understand just how a closure would be helpful. What are the advantages and what would a scenario where such a concept would be needed?
val is not 10 but a closure. If you call it like (val) it returns the value of x. x is a closure variable that still exists since it's still in use. A better example is this:
(define (larger-than-predicate n)
(lambda (v) (> v n )))
(filter (larger-than-predicate 5) '(1 2 3 4 5 6 7 8 9 10))
; ==> (6 7 8 9 10)
So the predicate compares the argument with v which is a variable that still holds 5. In a dynamic bound lisp this is not possible to do because n will not exist when the comparison happens.
Lecical scoping was introduces in Algol and Scheme. JavaScript, PHP amd C# are all algol dialects and have inherited it from there. Scheme was the first lisp to get it and Common Lisp followed. It's actually the most common scoping.
From this example you can see that the closure allows the functions local environment to remain accessible after being called.
(define count
(let ((next 0))
(lambda ()
(let ((v next))
(set! next (+ next 1))
v))))
(count)
(count)
(count)
0..1..2
I believe in the example you give, val will NOT equal to 10, instead, a lambda object (lambda () 10) will be assigned to val. So (val) equals to 10.
In the world of Scheme, there are two different concepts sharing the same term "closure". See this post for a brief introduction to both of these terms. In your case, I believe by "closure" you mean "lexical closure". In your code example, the parameter x is a free variable to the returned lambda and is referred to by that returned lambda, so a lexical closure is kept to store the value of x. I believe this post will give you a good explanation on what (lexical) closure is.
Totally agree with Lifu Huang's answer.
In addition, I'd like to highlight the most obvious use of closures, namely callbacks.
For instance, in JavaScript, I might write
function setup(){
var presses = 0;
function handleKeyPress(evt){
presses = presses + 1;
return mainHandler(evt);
}
installKeyHandler(handleKeyPress);
}
In this case, it's important to me that the function that I'm installing as the key handler "knows about" the binding for the presses variable. That binding is stored in the closure. Put differently, the function is "closed over" the binding for presses.
Similar things occur in nearly every http GET or POST call made in JS. It crops up in many many other places as well.
Btw, create-closure from your question is known by some as the Kestrel combinator, from the family of Combinator Birds. It is also known as True in Church encoding, which encodes booleans (and everything else) using lambdas (closures).
(define (kestrel a)
(lambda (b) a))
(define (create-list size proc)
(let loop ((x 0))
(if (= x size)
empty
(cons (proc x)
(loop (add1 x))))))
(create-list 5 identity)
; '(0 1 2 3 4)
(create-list 5 (kestrel 'a))
; '(a a a a a)
In Racket (I'm unsure about Scheme), this procedure is known as const -
(create-list 5 (const 'a))
; '(a a a a a)

Lisp: IF condition using AND operator

I making this function.
(f 3 4) (sum = 7)
(f 'a 'b) (not num!)
My problem is how can I make if condition using and operator.
I try....
(IF (and (typep a 'integer) (typep b 'integer)) (1) (0))
(IF (and ((typep a 'integer)) ((typep b 'integer))) (1) (0))
(IF ((and ((typep a 'integer)) ((typep b 'integer)))) (1) (0))
But it doesn't work.
(1) (0) is I set it temporarily.
Could I get some lisp syntax help?
The most important thing you need to learn about Lisp at this moment is that parens matter.
In C you can write 1+3, (1)+3, (((1+3))) and they all mean the same thing. In lisp they are very very different:
a means "the value of the variable named a".
(a) means "the return value of the function named a called without any arguments".
((a)) is a syntax error (but see PPS)
So, every version with ((...)) is outright wrong.
Since there is no function named 1, the first version is no good either.
What you need is:
(if (and (typep a 'integer)
(typep b 'integer))
1
0)
Note formatting and indentation.
Lispers read code by indentation, not parens, so proper indentation is critical.
Note that Emacs (and maybe some other Lisp-specific IDEs) will indent lisp code for you.
PS. The description of what you are trying to accomplish is unclear, but it might be that the easiest way is to use generic functions:
(defgeneric f (a b)
(:method ((a integer) (b integer))
(+ a b)))
(f 1 2)
==> 3
(f 1 'a)
*** - NO-APPLICABLE-METHOD: When calling #<STANDARD-GENERIC-FUNCTION F> with
arguments (1 A), no method is applicable.
PPS. Eventually you will see legitimate ((...) ...), e.g., cond:
(defun foo (a)
(cond ((= a 1) "one")
((= a 2) "two")
(t "many")))
(foo 1)
==> "one"
(foo 3)
==> "many"
or lambda forms:
((lambda (x) (+ x 4)) 5)
==> 9
but you do not need to worry about those yet.

Unusual way of parameter passing in Scheme

I'm trying to implement a function in scheme that splits the given list with the function that is also given as parameter to function. To exemplify:
(splitby '("a" "b" "cc" "ab" "abc" "a" "b")
(lambda (x y) (= (string-length x) (string-length y))))
should return (("a" "b") ("cc "ab") ("abc") ("a" "b"))
I'm pretty beginner in Scheme so it is really hard to understand how this 'function like' parameter works, and while implementing such a function what should I do?
In Scheme, functions are objects like numbers, strings, etc. So in this case, your example is equivalent to this:
(define (equal-length x y)
(= (string-length x) (string-length y)))
(splitby '("a" "b" "cc" "ab" "abc" "a" "b") equal-length)
The use of the function is to allow the splitting criterion to be customised. In this case, items are in the same group for as long as the given function returns a true value; otherwise a new group is created.
To get started, write a group-equal function, that groups equal elements together:
(define (group-equal lst)
...)
where, for example,
(group-equal '(1 2 2 3 3 3 4))
returns
((1) (2 2) (3 3 3) (4))
If you successfully implement that, then it's identical to your splitby function, except that you use the given function (equal-length, for example) instead of equal? (as group-equal might use).
Firstly, in Scheme, everything is inside parentheses. So If you want to apply the function f to values x and y, you write:
(f x y)
So you simply need to put splitby inside the first set of parens.
Secondly, functions can be passed as values into other functions, just like data is passed.
So if I have a functions:
(define (double x)
(* x 2))
I can write another function which takes double as an argument:
(define (change_result f x)
(f (+ 3 x)))
; (change_result double 6) returns 18
I can also do this the same way, if I use a lambda (anonymous) function:
(change_result (lambda (x) (* 3 x)) 10)

Using let in Scheme

I want to write a program to find the roots of the quadratic equation in Scheme. I used LET for certain bindings.
(define roots-with-let
(λ (a b c)
(let ((4ac (* 4 a c))
(2a (* 2 a))
(discriminant (sqrt ( - (* b b) (4ac)))))
(cons ( / ( + (- b) discriminant) 2a)
( / ( - (- b) discriminant) 2a)))))
I defined the discriminant with 4ac since I did not want (* 4 a c). Even though I have defined (4ac (* 4 a c)), it is giving me this error:
expand: unbound identifier in module in: 4ac.
My question is how is let evaluated (what order)? And if i want 4ac in my let should i write another inner let? Is there a better way to do this?
Use let* instead of let.
The difference between let and let* is the following:
let* binds variables from left to right. Earlier bindings can be used in new binding further to the right (or down).
let on the other hand can be thought of as syntactic sugar (or macro) for simple lambda abstraction:
(let ((a exp1)
(b exp2))
exp)
is equivalent to
((lambda (a b)
exp)
exp1 exp2)
4ac is a variable with a numeric value, so (4ac) is not meaningful.
LET binds all variables, but the variables can't be used in the computations for the values.
This does not work:
(let ((a 1) (b 1) (c (* a b)))
c)
Use:
(let ((a 1) (b 1))
(let ((c (* a b)))
c))
Above introduces A and B with the first LET. In the second LET both A and B now can be used to compute C.
Or:
(let* ((a 1) (b 1) (c (* a b)))
c)
You'll need a special let-construct (let*) here since the variables inside the let-definition refer to each other.
It's rather a problem of defining a scope than of evaluating an expression (In usual let-definitions, the order of evaluation doesn't matter since the values may not use each other)
When you use let, the bindings are not visible in any of the bodies. Use let* instead and see the RNRS docs for details.

Beginner: Curried functions in Scheme

I'm using the SICP lectures and text to learn about Scheme on my own. I am looking at an exercise that says "An application of an expression E is an expression of the form (E E1,...En). This includes the case n=0, corresponding to an expression (E). A Curried application of E is either an application of E or an application of a Curried application of E."
(Edit: I corrected the above quote ... I'd originally misquoted the definition.)
The task is to define a Curried application of the procedure which evaluates to 3 for
(define foo1
(lambda (x)
(* x x)))
I really don't understand the idea here, and reading the Wikipedia entry on Curriying didn't really help.
Can anyone help with a more lucid explanation of what's being asked for here?
Actually even giving me the answer to this problem would be helpful, since there are five more to solve after this one. ... I just am not getting the basic idea.
Addition: Even after Brian Campbell's lengthy explanation, I'm still somewhat lost.
Is (foo1 (sqrt 3))) considered an application of foo, and therefore a curried application of foo?
Seems too simple, but maybe...
Typing (((foo1 2 )) 2) into DrScheme gives the following error (which I kind of expected)
procedure application: expected procedure, given: 4 (no arguments)
After re-reading What is Currying? I understand I can also re-define foo1 to be:
(define (foo1 a)
(lambda (b)
(* a b)))
So then I can type
((foo1 3 ) 4)
12
But this doesn't really get me any closer to producing 3 as an output, and it seems like this isn't really currying the original foo1, it's just re-defining it.
Damn, 20 years of C programming hasn't prepared me for this. :-) :-)
Hm, this problem is fairly confusingly phrased, compared to the usually much more clear style of the books. Actually, it looks like you might be misquoting the problem set, if you're getting the problem set from here; that could be contributing to your confusion.
I'll break the definition down for you, with some examples that might help you figure out what's going on.
An application of an expression E is an expression of the form (E E1 ... En).
Here's an example of an application:
(foo 1 2) ; This is an application of foo
(bar 1) ; This is an application of bar
This includes the case n=0, corresponding to an expression (E).
(baz) ; This is an application of baz
A Curried application of E is either an application of E or an application of a Curried application of E?...........
This is the one that you misquoted; above is the definition from the problem set that I found online.
There are two halves to this definition. Starting with the first:
A Curried application of E is either an application of E
(foo 1 2) ; (1) A Curried application of foo, since it is an application of foo
(bar 1) ; (2) A Curried application of bar, since it is an application of bar
(baz) ; (3) A Curried application of baz, since it is an application of baz
or an application of a Curried application of E
((foo 1 2) 3) ; (4) A Curried application of foo, since it is an application of (1)
((bar 1)) ; (5) A Curried application of bar, since it is an application of (2)
((baz) 1 2) ; (6) A Curried application of baz, since it is an application of (3)
(((foo 1 2) 3)) ; A Curried application of foo, since it is an application of (4)
(((bar 1)) 2) ; A Curried application of bar, since it is an application of (5)
; etc...
Does that give you the help you need to get started?
edit: Yes, (foo1 (sqrt 3)) is a Curried application of foo1; it is that simple. This is not a very good question, since in many implementations you'll actually get 2.9999999999999996 or something like that; it's not possible to have a value that will return exactly 3, unless your Scheme has some sort of representation of exact algebraic numbers.
Your second example is indeed an error. foo1 returns an integer, which is not valid to apply. It is only some of the later examples for which the recursive case, of an application of an application of the function, are valid. Take a look at foo3, for example.
edit 2: I just checked in SICP, and it looks like the concepts here aren't explained until section 1.3, while this assignment only mentions section 1.1. I would recommend trying to read through section 1.3 if you haven't yet.
See What is 'Currying'?
Currying takes a function and provides
a new function accepting a single
argument, and returning the specified
function with its first argument set
to that argument.
Most of the answers you've gotten are examples of 'partial evaluation'. To do true currying in Scheme you need syntactic help. Like such:
(define-syntax curry
(syntax-rules ()
((_ (a) body ...)
(lambda (a) body ...))
((_ (a b ...) body ...)
(lambda (a) (curry (b ...) body ...)))))
Which you then use as:
> (define adding-n3 (curry (a b c) (+ a b c)))
> (define adding-n2-to-100 (adding-n3 100))
> ((adding-n2-to-100) 1) 10)
111
> (adding-n3 1)
#<procedure>
> ((adding-n3 1) 10)
#<procedure>
I don't think James' curry function is correct - there's a syntax error when I try it in my scheme interpreter.
Here's an implementation of "curry" that I use all the time:
> (define curry (lambda (f . c) (lambda x (apply f (append c x)))))
> ((curry list 5 4) 3 2)
(5 4 3 2)
Notice, it also works for currying more than one argument to a function.
There's also a macro someone has written that let's you write functions that implicitly curry for you when you call them with insufficient arguments: http://www.engr.uconn.edu/~jeffm/Papers/curry.html
I think you are confusing yourself too much. Currying a function takes a function of type F(a1,a2,...aN) and turns it into F(a1) which returns a function that takes a2, (which returns a function that takes a3 ... etc.)
So if you have:
(define F (lambda (a b) (+ a b)))
(F 1 2) ;; ==> 3
you can curry it to make something that acts like the following:
(define F (lambda (a) (lambda (b) (+ a b))))
((F 1) 2) ;; ==> 3
in the case of your specific question, it seems very confusing.
(foo1 (sqrt 3))
seems to be suitable. I would recommend leaving it for now and reading more of the book.
you can actually make a function that does a simple curry for you:
(define (curry f x) (lambda (y) (apply f (cons x y))))
(curry = 0) ;; a function that returns true if input is zero
Depending on your Scheme implementation, there might be some utilities to be able to recover from errors/exceptions, for example, in Chicken Scheme, there is condition-case.
(condition-case (func)
((exn) (print "error")))
We can define a function which take a function of an arbitrary number of elements and return the curryed form :
(define curry
(lambda (func . args)
(condition-case (apply func args)
((exn)
(lambda plus
(apply curry func (append args plus)))))]))))
This is a bit ugly, because if you use too many argument one time, you'll never get the final result, but this turn any function into the curryed form.

Resources