For what I know in functional languages is common to use lambda for referring to anonymous functions, but I do not see to be really useful to use:
(define square
(lambda (x) (* x x)))
instead of
(define (square x)
(* x x))
why is the first form used in almost all documents that I found regarding Scheme?
Thanks
I always use this syntax because it is explicit. lambda defines a function. Functions have no name. Then you assign this function to a variable. Variables have names. The form (define (f x) ...) is merely syntactic sugar for a very common case, but obscures the fact that scheme is a lisp-1.
Related
Ok, this is a fairly basic question: I am following the SICP videos, and I am a bit confused about the differences between define, let and set!.
1) According to Sussman in the video, define is allowed to attach a value to avariable only once (except when in the REPL), in particular two defines in line are not allowed. Yet Guile happily runs this code
(define a 1)
(define a 2)
(write a)
and outputs 2, as expected. Things are a little bit more complicated because if I try to do this (EDIT: after the above definitions)
(define a (1+ a))
I get an error, while
(set! a (1+ a))
is allowed. Still I don't think that this the only difference between set! and define: what is that I am missing?
2) The difference between define and let puzzles me even more. I know in theory let is used to bind variables in local scope. Still, it seems to me that this works the same with define, for instance I can replace
(define (f x)
(let ((a 1))
(+ a x)))
with
(define (g x)
(define a 1)
(+ a x))
and f and g work the same: in particular the variable a is unbound outside g as well.
The only way I can see this useful is that let may have a shorter scope that the whole function definition. Still it seems to me that one can always add an anonymous function to create the necessary scope, and invoke it right away, much like one does in javascript. So, what is the real advantage of let?
Your confusion is reasonable: 'let' and 'define' both create new bindings. One advantage to 'let' is that its meaning is extraordinarily well-defined; there's absolutely no disagreement between various Scheme systems (incl. Racket) about what plain-old 'let' means.
The 'define' form is a different kettle of fish. Unlike 'let', it doesn't surround the body (region where the binding is valid) with parentheses. Also, it can mean different things at the top level and internally. Different Scheme systems have dramatically different meanings for 'define'. In fact, Racket has recently changed the meaning of 'define' by adding new contexts in which it can occur.
On the other hand, people like 'define'; it has less indentation, and it usually has a "do-what-I-mean" level of scoping allowing natural definitions of recursive and mutually recursive procedures. In fact, I got bitten by this just the other day :).
Finally, 'set!'; like 'let', 'set!' is pretty straightforward: it mutates an existing binding.
FWIW, one way to understand these scopes in DrRacket (if you're using it) is to use the "Check Syntax" button, and then hover over various identifiers to see where they're bound.
Do you mean (+ 1 a) instead of (1+ a) ? The latter is not syntactically valid.
Scope of variables defined by let are bound to the latter, thus
(define (f x)
(let ((a 1))
(+ a x)))
is syntactically possible, while
(define (f x)
(let ((a 1)))
(+ a x))
is not.
All variables have to be defined in the beginning of the function, thus the following code is possible:
(define (g x)
(define a 1)
(+ a x))
while this code will generate an error:
(define (g x)
(define a 1)
(display (+ a x))
(define b 2)
(+ a x))
because the first expression after the definition implies that there are no other definitions.
set! doesn't define the variable, rather it is used to assign the variable a new value. Therefore these definitions are meaningless:
(define (f x)
(set! ((a 1))
(+ a x)))
(define (g x)
(set! a 1)
(+ a x))
Valid use for set! is as follows:
(define x 12)
> (set! x (add1 x))
> x
13
Though it's discouraged, as Scheme is a functional language.
John Clements answer is good. In some cases, you can see what the defines become in each version of Scheme, which might help you understand what's going on.
For example, in Chez Scheme 8.0 (which has its own define quirks, esp. wrt R6RS!):
> (expand '(define (g x)
(define a 1)
(+ a x)))
(begin
(set! g (lambda (x) (letrec* ([a 1]) (#2%+ a x))))
(#2%void))
You see that the "top-level" define becomes a set! (although just expanding define in some cases will change things!), but the internal define (that is, a define inside another block) becomes a letrec*. Different Schemes will expand that expression into different things.
MzScheme v4.2.4:
> (expand '(define (g x)
(define a 1)
(+ a x)))
(define-values
(g)
(lambda (x)
(letrec-values (((a) '1)) (#%app + a x))))
You may be able to use define more than once but it's not
idiomatic: define implies that you are adding a definition to the
environment and set! implies you are mutating some variable.
I'm not sure about Guile and why it would allow (set! a (+1 a)) but
if a isn't defined yet that shouldn't work. Usually one would use
define to introduce a new variable and only mutate it with set!
later.
You can use an anonymous function application instead of let, in
fact that's usually exactly what let expands into, it's almost
always a macro. These are equivalent:
(let ((a 1) (b 2))
(+ a b))
((lambda (a b)
(+ a b))
1 2)
The reason you'd use let is that it's clearer: the variable names are right next to the values.
In the case of internal defines, I'm not sure that Yasir is
correct. At least on my machine, running Racket in R5RS-mode and in
regular mode allowed internal defines to appear in the middle of the
function definition, but I'm not sure what the standard says. In any
case, much later in SICP, the trickiness that internal defines pose is
discussed in depth. In Chapter 4, how to implement mutually recursive
internal defines is explored and what it means for the implementation
of the metacircular interpreter.
So stick with it! SICP is a brilliant book and the video lectures are wonderful.
Take this example:
(define sqrt (lambda (x) (* 2 (sqrt x))))
(sqrt 2)
2.828427 ...
How can I call the original built-in sqrt procedure without restarting my interpreter (or undefine the shadowing define)?
Actually, what happens internally when we do this? Does the built-in get overwritten, or do two procedures coexist in different namespaces?
Your definition of sqrt will actually cause a stack overflow, because it recurses into itself, not the built-in sqrt. :-P
Anyway, in Racket, your definition of sqrt will affect your current module only. It is possible to reimport the built-in sqrt under a different name, and call that from your module-specific sqrt:
(require (rename-in racket/base [sqrt racket-sqrt]))
(define sqrt (lambda (x) (* 2 (racket-sqrt x))))
Note that your code won't affect other modules that don't import your module's sqrt definition; they will continue to use the built-in sqrt.
I'm trying to add a pattern matching function to an existing scheme meta circular evaluator (this is homework) and I'm a bit lost on the wording of the instructions. I was hoping someone more skilled in this regard could help me interpret this.
The syntax for match should look like the following: (match a ((p1 v1) (p2 v2) (p3 v3)))
And it could be used to find length like so:
(define length (lambda (x)
(match x (('() 0)
(('cons a b) (+ 1 (length b))))))
The pattern language in the function should contain numeric constants, quoted constants, variables, and cons. If patterns are exhausted without finding a match, an error should be thrown.
I thought I understood the concept of pattern matching but implementing it in a function this way has me a bit thrown off. Would anyone be willing to explain what the above syntax is doing (specifically, how match is used in length above) so I can get a better understanding of what this function should do?
(match x (('() 0)
(('cons a b) (+ 1 (length b)))))
It may be most helpful to consider what this code would need to expand into. For each pattern, you'd need a test to determine whether the object you're trying to match matches, and you'd need code to figure out how to bind variables to its subparts. In this case, you'd want an expansion roughly like:
(if (equal? '() x)
0
(if (pair? x)
(let ((a (car x))
(b (cdr x)))
(+ 1 (length b)))
;; indicate failure to match
'NO-MATCH))
You could write that with a cond, too, of course, but if you have to procedurally expand this, it might be easier to use nested if forms.
If you're actually implementing this as a function (and not as a macro (i.e., source transformation), then you'll need to specify exactly how you can work with environments, etc.
I suggest you read the chapter four, Structured Types and the Semantics of Pattern Matching, from The Implementation of Functional Languages. The chapter is written by Simon L. Peyton Jones and Philip Wadler.
I've been learning Scheme through the Little Schemer book and it strikes me as odd that a file in Scheme / Lisp isn't a list of statements. I mean, everything is supposed to be a list in Lisp, but a file full of statements doesn't look like a list to me. Is it represented as a list underneath? Seems odd that it isn't a list in the file.
For instance...
#lang scheme
(define atom?
(lambda (x)
(and (not (pair? x)) (not (null? x)))))
(define sub1
(lambda (x y)
(- x y)))
(define add1
(lambda (x y)
(+ x y)))
(define zero?
(lambda (x)
(= x 0)))
Each define statement is a list, but there is no list of define statements.
It is not, because there is no practical reasons for it. In fact, series of define statements change internal state of the language. Information about the state can be accessible via functions. For example , you can ask Lisp if some symbol is bound to a function.
There is no practical benefit in traversing all entered forms (for example, define forms). I suppose that this approach (all statements are elements of a list) would lead to code that would be hard to read.
Also, I think it not quite correct to think that "everything is supposed to be a list in Lisp", since there are also some atomic types, which are quite self-sufficient.
When you evaluate a form, if the form defines something, that definition is added to the environment, and that environment is (or can be) a single list. You can build a program without using files, by just typing definitions into the REPL. In Lisp as in any language, the program “lives” in the run-time environment, not the source files.
(define a 42)
(set! 'a 10)
(define a 42)
(define (symbol) 'a)
(set! (symbol) 10)
(define a (cons 1 2))
(set! (car a) 10)
I tried running them in DrScheme and they don't work. Why?
Think of set! is a special form like define which does not evaluate its first operand. You are telling the scheme interpreter to set that variable exactly how you write it. In your example, it will not evaluate the expression 'a to the word a. Instead, it will look for a variable binding named "'a" (or depending on your interpreter might just break before then since I think 'a is not a valid binding).
For the last set of expressions, if you want to set the car of a pair, use the function (set-car! pair val) which works just like any scheme function in that it evaluates all of its operands. It takes in two values, a pair and some scheme value, and mutates the pair so that the car is now pointing to the scheme value.
So for example.
>(define pair (cons 1 2))
>pair
(1 . 2)
>(set-car! pair 3)
(3 . 2)
Because the first argument of set! is a variable name, not an "lvalue", so to speak.
For the last case, use (set-car! a 10).
The issue is with (set! 'a 10), as you shouldn't be quoting the symbol a.
It sounds like you're trying to learn Scheme, and you don't know Lisp, yes? If so, I strongly recommend trying Clojure as an easier to learn Lisp. I failed to grasp the interaction between the reader, evaluation, symbols, special forms, macros, and so forth in both Common Lisp and Scheme because those things all seemed to interact in tangled ways, but I finally really understand them in Clojure. Even though it's new, I found Clojure documentation is actually clearer than anything I found for Scheme or CL. Start with the videos at http://clojure.blip.tv/ and then read the docs at clojure.org.