So basically this code's purpose is to simply print out the first n even numbers.
for (i = 0; i <=n; i+= 2)
{
print i;
}
Thing is though, I don't understand Scheme at all. So, help please.
There are several ways to convert the code in the question to Scheme. The first one I can think of:
(define (print-even n)
(let loop ((i 0))
(if (<= i n)
(begin
(print i)
(newline)
(loop (+ i 2))))))
Notice this:
The solution is written as a recursive procedure
Instead of a for loop, I'm using a construct called a named let, which permits the initialization of some iteration variables (i in this case, initialized to 0) and the repeated execution of a recursive procedure (loop in this case), producing an effect similar to a for, even in performance
The stop condition in the "loop" is handled with essentially the same expression: repeat the body of the iteration as long as (<= i n), when that condition becomes false, the iteration ends
The begin surrounds the body of the "loop", just as the curly braces {} do in the original code
The print procedure performs the expected operation; for readability I added a new line after printing each number
The increment part of the original loop i += 2 is handled by the expression (+ i 2), inside the recursive call
So you see, the process being executed is essentially the same, only the way to write it (the syntax!) is different. Give it a try, type this:
(print-even 6)
... And the following will get printed on the screen:
0
2
4
6
Another possible way to implement the procedure, more similar to the original code, although (this is completely subjective) less idiomatic than the previous one:
(define (print-even n)
(do ((i 0 (+ i 2))) ((> i n))
(print i)
(newline)))
Finally, if you're using Racket this will seem even more familiar to you:
#lang racket
(define (print-even n)
(for ((i (in-range 0 (+ n 1) 2)))
(print i)
(newline)))
The first big difference between Scheme and other languages is this: In Scheme, you do (almost) everything recursively.
To implement a simple loop, for instance, you would define a recursive function. This function would first check to see whether it's time to break out of the loop; if is is, it would return the final value. (There is no final value in this case, so it would just return something like (void) or '().) Otherwise, the function would do whatever it's supposed to do, then call itself again.
Any loop variables (such as i) become arguments to the function.
Hopefully this helps you understand how to do this.
The Scheme way to do something like this is using a recursive function like the one below.
(define (doit value n)
(if (<= value n)
(begin
;;...perform loop body with x...
(display value)(newline)
(doit (+ value 2) n))))
To call this function you call (doit 2 n) where n is your n in the for loop.
With regards to learning Scheme, I recommend the first two links below.
For additional information on Scheme see
SICP
How to Design Programs
Schemers
Related Stackoverflow Question
Scheme Cookbook Looping Constructs
Related
I implemented a solution to a Project Euler problem using an approach loosely based on the meet-in-the-middle algorithm for the knapsack problem. However, SBCL--and only SBCL--won't compile my solution.
The relevant chunk of code is:
(loop with upper-half = <list in descending order>
and lower-half = <list in ascending order>
for i in lower-half maximize (loop for j on upper-half
for prod = (* (car j) i)
when (> upper-limit prod)
return (prog1 prod (setf upper-half j))))
The numbers on upper-half and lower-half are such that the inner loop never reaches the end of upper-half and the inner loop never returns Nil.
While this does run on Lispworks, SBCL emits the following error:
warning:
Constant NIL conflicts with its asserted type REAL.
See also:
SBCL Manual, Handling of Types [:node]
--> BLOCK LET LET SB-LOOP::WITH-MINIMAX-VALUE LET SB-LOOP::LOOP-BODY
--> TAGBODY SB-LOOP::LOOP-ACCUMULATE-MINIMAX-VALUE PROGN SETQ
==>
(THE REAL
(LOOP FOR J ON UPPER-HALF
FOR PROD = (* (CAR J) I)
WHEN (> UPPER-LIMIT PROD) ...))
Compilation failed.
It seems that the compiler assumed that the inner loop returns Nil (but it only returns integers; I tested this substituting collect for maximize). The SBCL Manual goes on and on about type handling, but doesn't explain how to turn this pesky check off. And alas, I couldn't even figure out whether this is a bug or a feature. Well, how do I get this to work?
Any input is appreciated.
SBCL does a bit more of static type checking than some other implementations (which is one of the reasons that its compiler is significantly slower than, say, CCL's). The maximize needs the return value of your inner loop to be a real, but if the when condition is never met, it may return nil, which is not a real. It doesn't know (cannot prove) that the input you actually give it never reaches this case, which, if you think about it, would be quite a feat for a general purpose compiler.
Other implementations might not check this. Even on SBCL, it is just a warning, however, so if you insist on doing it this way, you can ignore it, it still compiles.
You could wrap your inner loop in an (or … 0) to satisfy the compiler. Maybe you can also decrease the safety optimization knob to skip this check, but this may have other effects, too.
You can extract the inner loop and define another function, as follows:
(defun foo (upper-half upper-limit i)
(loop
for j on upper-half
for prod = (* (car j) i)
when (> upper-limit prod)
return (prog1 prod (setf upper-half j))))
Its behaviour is different than before, since side-effects are only local. For example, upper-half is a local variable whereas in the original code it was a free variable in the copied expression. This is however not important for type analysis.
After compilation the function will have the following type (as shown by describe):
(FUNCTION (T T T) (VALUES (OR NULL SINGLE-FLOAT DOUBLE-FLOAT RATIONAL) &OPTIONAL))
Remark (values t1 ... tn &optional) is a way to be explicit about the number of return values of a function (e.g. it must return exactly n types). See VALUES:
[The &optional and &rest markers] indicate the parameter list of a function that, when given to multiple-value-call along with the values, would correctly receive those values.
In other words, the returned type of FOO is either NULL or REAL, given that REAL above is expanded in terms of its possible subtypes.
The NULL type originates from the NIL value that can happen when the loop terminates normally.
Now, you don't want to have a NULL type in the type union for the resulting type. In other words, you want the loop to never terminate normally. That is easily achieved by signaling an error at the end of the loop:
(defun bar (upper-half upper-limit i)
(loop
for j on upper-half
for prod = (* (car j) i)
when (> upper-limit prod)
return (prog1 prod (setf upper-half j))
finally (error "Impossible")))
In the modified function, the normal execution path of the loop eventually reaches a call to error, whose return type is NIL (a.k.a. the bottom type): it never successfully returns any value. The NIL types represents an empty domain and is, as one would expect, a neutral element for the type union.
The inferred type is thus (OR NIL REAL), which is simply REAL, the type shown when describing the modified function:
(FUNCTION (T T T) (VALUES REAL &OPTIONAL))
I am supposed to write a function called (nth-filtered f n), where f is a function of one variable and n is a natural number, which evaluates to the nth natural number such that f applied to that number is #t.
If we called
(nth-filtered even? 1) we would get 2
(nth-filtered prime? 10) we would get 29
How do I make it so that it works for any sequential function? What should I think about when approaching this type of problem?
A variable is a variable and + is also a variable. The main difference between a function and some other data type is that you can wrap a function name in parentheses with arguments and it will become a new value.
eg.
(define (double fun)
(lambda (value)
(fun (fun value))))
(define (add1 v)
(+ 1 v))
(define add2 (double add1))
(add2 1) ; ==> 3
Now the contract doesn't say so you deduct by looking that you do (fun ...) that fun needs to be a function. Imagine this:
(define test (double 5)) ; probably works OK
(test 1)
The last one fails since you get application: 5 is not a procedure or something similar. The error message is not standardized.
How to attack your task is by making a helper that has the same arguments as your function but in addition the current number that I guess starts at 1. As I demonstrated you use the function variable as a function and recurse by always increasing the number and reducing n when the f call was #t. The actual function will just use the helper by passing all the parameters in addition to your state variable.
Your problem requires a fold, which is the standard way to iterate other a list while keeping a record of things done so far.
Here a very rackety method using for/fold:
(define (nth-filtered predicate index)
(for/fold ([count 0]
[current #f] #:result current)
([n (in-naturals 1)]) ; we start at 1 but we could start at 0
#:break (= count index)
(values (if (predicate n) (add1 count) count)
n)))
for/fold takes a list of initial state. Here we define count as the number of times the given predicate returned #t and current as the currently tested value.
Then it takes a list of iterators, in this case we only iterate infinitely over (in-naturals).
To make it stop, we provide a #:break condition, which is "when the number of truthy predicates (count) is equal to the requested amount (index)".
for/fold requests that it's body finishes with a list of values for each "state" variable, in order to update them for the next iteration. Here we provide two values: one is the new count, the other is just the current n.
You can try it out, it works as you requested:
> (nth-filtered even? 1)
2
> (require math/number-theory)
> (nth-filtered prime? 10)
29
> (nth-filtered prime? 5)
11
so i am trying to understand this piece of code, and after staring at it for far too long i decided to ask here if anyone could help me understand how and why it works
(define knock-knock
(letrec ([dig (lambda (i)
(cons (* i (list-ref knock-knock (- i 1)))
(dig (+ i 1))))])
(cons 1 (dig 1))))
the function is then called by name with the value:
(list-ref knock-knock 5)
So my main problem is that i can not see where the letrec would end. the other thing is that i am not given a list, so what is the 4th element in the list that i am supposed to reference in line 3?
First, a note: this is not normal Scheme, as it requires lazy evaluation.
In lazy evaluation, values are only computed when they are needed. So, for defining knock-knock, we can just do
(cons 1 <thunk: (dig 1)>)
i.e., we generate a pair, but we don't need the second element, so we defer its evaluation until later.
When we actually want to evaluate the second element, we will already have knock-knock defined, so we can reference it.
The next element is computed by taking the previous (i-1-st) element, and multiplies it by i. So this will generate the series {n!}: 1,1,2,6,24,...
A straightforward translation of this code to the (normally lazy) Haskell language goes like this:
knock :: [Int]
knock = 1 : dig 1
where dig i = (i * knock !! (i-1)) : dig (i+1)
hy everyone, for school i have to make a function where lambda is used as a parameter
like so : (string (lambda ...) 5 40) where we have to fill in the dots
this is the function we had to reinvent, the regular string version
(define (string decoration n r) >string decoration is a function that creates a string with either fish or pumpkins hanging on the string
(define (decorations k) >decorations is the recursive function which hangs all the decorations together
(if (= k 1)
(decoration r 10) > here decoration is to be replaced with either a pumpkin or a fish as stated in the parameters
(ht-append (decoration r 10) > ht-append is a function that appends 2 figures Horizontally at the Top
(decorations (- k 1)))))
(hang-by-thread (decorations n))) > hang by thread is a function that hangs all the decorations at a string
all the names should be self-explanatory, the function takes a decoration , either a fish or a pumpkin and hangs it by a thread. But the fish has 3 parameters and the pumpkin has 2 which caused an error. So in a previous exercise we had to make an extra definition called fish-square which uses only 2 parameters to make a fish. Now we have to implement this same squared fish but with a lambda. Any help is greatly appreciated
(define (fish-square wh l) > this is the fish square functio which makes a fish but with 2 times the same parameter so it looks like a square
(vc-append (filled-rectangle 2 l) (fish wh wh))) > the l is the length of the string that attaches the fish to the string at the top
the fish function is just (fish x y) x makes it longer, y makes it taller.
the pumpkin function is just (pumpkin x y) same story
so my question is, how do rewrite the given code , but with lambda as a parameter.
i would upload an image, but my repuation isn't high enough :s
The string procedure as it is already receiving a procedure as a parameter (you don't have to rewrite it!), decoration can be any two-argument function used for decorating. Now when you call it you can pass a named procedure, for example:
(define (decoration r n)
<body>)
(string decoration
5
40)
... Or just as easily, you can pass the same procedure in-line as a lambda, and if I understood correctly, this is what you're supposed to do:
(string (lambda (r n)
<body>)
5
40)
Just replace <body> with the actual body of the decoration you want to use. In othre words: the change you're expected to do is in the way you pass the parameters to the function at invocation time, but you're not expected to change the function itself.
Imagine you have the procedure +. It could be any really. It takes several arguments but you need a different procedure that takes one and adds that to an already constant value 3.
Thus you want to pass + with the extra information that it should add 3.
A full definition of such procedure would be
(define (add3 n)
(+ 3 n))
which is the short form of the full define
(define add3
(lambda (n)
(+ 3 n)))
Now when passing a procedure 3+ you could actually just pass it's definition. These two does the same:
(do-computation add3 data)
(do-computation (lambda (n) (+ 3 n)) data)
I have see the following code... The first call of (next-num) returns 1, and the second returns 2.
(define next-num
(let ((num 0))
(lambda () (set! num (+ num 1)) num)))
(next-num) ; 1
(next-num) ; 2
What I can not understand is... num is created by let inside next-num, it is kind of a local variable... How does scheme know that each time next-num is called, the value of num is not erased by let ((num 0)); How does scheme know that it is always the same num that we modify whenever next-num is called?
It seems that num is both local and static... How can we define a local variable, but not static?
This is "lexical closure" and you're right that num, the "closed-over variable" is similar to a static variable, in C for example: it's only visible to code within the let form (its "lexical scope"), but it persists across the whole program run, rather than being re-initialized with each call to the function.
I think the part you're confused on is this: "num is created by let inside next-num, it is kind of a local variable". This isn't true because the let block isn't part of the next-num function: it's actually an expression which creates and returns the function which is then bound to next-num. (This is very different, e.g., from C, where functions can only be created at compile-time and by defining them at top-level. In Scheme, functions are values like integers or lists, which any expression can return).
Here's another way to write (almost) the same thing which makes it clearer that the define is just associating next-num to the value of a function-returning expression:
(define next-num #f) ; dummy value
(let ((num 0))
(set! next-num
(lambda () (set! num (+ num 1)) num)))
It's important to note the difference between
(define (some-var args ...) expression expression ...)
which makes some-var a function which executes all the expressions when called, and
(define some-var expression)
which binds some-var to the value of expression, evaluated then and there. Strictly speaking, the former version is unnecessary, because it's equivalent to
(define some-var
(lambda (args ...) expression expression ...))
Your code is almost the same as this, with the addition of the lexically scoped variable, num, around the lambda form.
Finally, here's a key difference between closed-over variables and static variables, which makes closures much more powerful. If you had written the following instead:
(define make-next-num
(lambda (num)
(lambda () (set! num (+ num 1)) num)))
then each call to make-next-num would create an anonymous function with a new, distinct num variable, which is private to that function:
(define f (make-next-num 7))
(define g (make-next-num 2))
(f) ; => 8
(g) ; => 3
(f) ; => 9
This is a really cool and powerful trick which accounts for a lot of the power of languages with lexical closures.
Edited to add: You ask how Scheme "knows" which num to modify when next-num is called. In outline, if not in implementation, this is actually pretty simple. Every expression in Scheme is evaluated in the context of an environment (a lookup table) of variable bindings, which are associations of names to places which can hold values. Each evaluation of a let form or a function call creates a new environment by extending the current environment with new bindings. To arrange to have lambda forms behave as closures, the implementation represents them as a structure consisting of the function itself plus the environment in which it was defined. Calls to that function are then evaluated by extending the binding environment in which the function was defined -- not the environment in which it was called.
Older Lisps (including Emacs Lisp until recently) had lambda, but not lexical scope, so although you could create anonymous functions, calls to them would be evaluated in the calling environment rather than the definition environment, and so there were no closures. I believe Scheme was the first language to get this right. Sussman and Steele's original Lambda Papers on the implementation of Scheme make great mind-expanding reading for anyone who wants to understand scoping, among many other things.