How would you use set! in a simple procedure f such that evaluating (+ (f 0) (f 1)) will return 0 if the arguments to + are evaluated from left to right but will return 1 if the arguments are evaluated from right to left?
Easiest approach is probably to store some external state and have the implementation of f affect it's contents.
(define x 0)
(define (f n) (let ((tmp x)) (set! x n) tmp))
Thus, x is initially 0 and each call to f will return the current value of x and save the argument as the new value of x. Thus (f 0) followed by (f 1) will both return 0, leaving the final x value of 1. While evaluating (f 1) followed by (f 0) will yield 0 then 1, with a final x of 0.
With call/cc.
(define (f)
(call/cc
(lambda (c) (+ (c 0) (c 1)))))
(write (f))
Invoking c within either argument to + causes f to return immediately, yielding 0 or 1 depending which argument is evaluated first.
But I suspect it will always evaluate left-to-right and thus return 0.
Related
(define ZERO (lambda (f x) x))
(define ONE (lambda (f x) (f x)))
(define SUCC (lambda (n) (lambda (f x) (f (n f x)))))
(display (ZERO 1 0))
(display (ONE 1 0))
(display ((SUCC ZERO) 1 0))
The ZERO function works fine. When I run this code, I get an error,
ERROR: invalid application: (1 0)
for ONE, SUCC function.
How can I fix my code to make it work?
This is the Church encoding of numbers; the number K is represented by K applications of a function f to some argument x.
(The identities of the function and that argument are, surprisingly enough, irrelevant - you can build all of mathematics without caring.)
You can make it make a bit of sense with suitable choices of f and x - try, for instance, 0 and
(define (inc x) (+ x 1))
so the number K is represented by adding 1, K times, to 0.
> (ZERO inc 0)
0
> (ONE inc 0)
1
> ((SUCC ONE) inc 0)
2
You can also add some convenience with an evaluation function:
> (define (number n) (n inc 0))
> (number ZERO)
0
> (number ONE)
1
> (number (SUCC (SUCC (SUCC (SUCC ONE)))))
5
This is the code to calculate the failure function (how many steps we have to go back) in Scheme, when we use the Knuth-Morris-Pratt algorithm:
(define (compute-failure-function p)
(define n-p (string-length p))
(define sigma-table (make-vector n-p 0))
(let loop
((i-p 2)
(k 0))
(cond
((>= i-p n-p)
(vector-set! sigma-table (- n-p 1) k))
((eq? (string-ref p k)
(string-ref p (- i-p 1)))
(vector-set! sigma-table i-p (+ k 1))
(loop (+ i-p 1) (+ k 1)))
((> k 0)
(loop i-p (vector-ref sigma-table k)))
(else ; k=0
(vector-set! sigma-table i-p 0)
(loop (+ i-p 1) k))))
(vector-set! sigma-table 0 -1)
(lambda (q)
(vector-ref sigma-table q)))
But I do not understand the part when k > 0. Can someone explain it please?
I see you're confused with the syntax of a named let. This post does a good job explaining how it works, but perhaps an example with more familiar syntax will make things clearer. Take this code in Python, it adds all integers from 1 to 10:
sum = 0
n = 1
while n <= 10:
sum += n
n += 1
print(sum)
=> 55
Now let's try to write it in a recursive fashion, I'll call my function loop. This is completely equivalent:
def loop(n, sum):
if n > 10:
return sum
else:
return loop(n + 1, n + sum)
loop(1, 0)
=> 55
In the above example, the loop function implements an iteration, the parameter n is used to keep track of the current position, and the parameter sum accumulates the answer. Now let's write the exact same code, but in Scheme:
(let loop ((n 1) (sum 0))
(cond ((> n 10) sum)
(else (loop (+ n 1) (+ n sum)))))
=> 55
Now we've defined a local procedure called loop which is then automatically called with the initial values 1 and 0 for its parameters n and sum. When the base case of the recursion is reached, we return sum, otherwise we keep calling this procedure, passing updated values for the parameters. It's exactly the same as in the Python code! Don't be confused by the syntax.
In your algorithm, i-p and k are the iteration variables, which are initialized to 2 and 0 respectively. Depending on which condition is true, the iteration continues when we call loop again with updated values for i-p and k, or it ends when the case (>= i-p n-p) is reached, at this point the loop exits and the computed value is in the variable sigma-table. The procedure ends by returning a new function, referred to as the "failure function".
How do I return a function using conditionals in scheme? What I want to do is to return the product of 2 numbers (when r = 0), or the sum (when r=1) or the difference (when r=2) or 0 (otherwise) depending on the value of r.
What I tried is below, but the return value is always 0. How do I fix that?
(define (f r)( lambda (x y)
(cond (equal? r 0)
((* x y))
( (equal? r 1)
( (+ x y)))
( (equal? r 2))
( (- x y))
(else
0 ))))
(( f 0) 2 3)
I would expect 6, but I get 0. Thanks in advance.
cond works like this:
(cond (test-expr then-body)
(test-expr2 then-body2)
(else then-body3))
The test-exprs are tested one by one, and the first test-expr that returns a non-false value causes its corresponding then-body to be executed. The last value in the executed then-body is the value of the whole cond.
To know why you got 0 (and not 6), look carefully at your first cond clause: (cond (equal? r 0) ...). equal? is the test-expr, and since equal? itself is not false, its then-body is executed (i.e. r and 0 are executed). Since 0 is the last value in the then-body, 0 is the value of the whole cond. That's why you got 0.
Note that nearly all lines in your cond have parentheses that have been incorrectly placed. Here's a fixed version:
(define (f r)
(lambda (x y)
(cond ((equal? r 0) ; <- Parentheses fixed.
(* x y)) ; <- Parentheses fixed.
((equal? r 1) ; <- Parentheses fixed.
(+ x y)) ; <- Parentheses fixed.
((equal? r 2) ; <- Parentheses fixed.
(- x y)) ; <- Parentheses fixed.
(else 0))))
Here's an arguably better way to define the same function:
(define (f r)
(cond ((= r 0) *)
((= r 1) +)
((= r 2) -)
(else (lambda _ 0))))
For example:
((f 0) 2 3)
;; '(f 0)' returns '*', so this reduces to: (* 2 3)
;; Answer:
6
This version is technically better as it is not restricted to taking only two arguments. For example, you can now do this: ((f 1) 1 2 3 4 5 6) (reduces to (+ 1 2 3 4 5 6)).
The cond expression in your code has some syntax errors:
There are brackets missing in each condition
You must not surround a procedure application with double brackets, this is a mistake: ((* x y))
Notice that you require to return an arithmetic procedure and, for example, we can simply return + which is similar to returning (lambda (x y) (+ x y)) (except that it'll work for more than two parameters, but that's a win!).
Bear in mind that in Racket the solution can be written in a more concise way: for example, by using case to simplify the conditions and const for the last case, when we want to return a procedure that returns 0 no matter what are the parameters. Here's how:
(define (f r)
(case r
((0) *)
((1) +)
((2) -)
(else (const 0))))
It works as expected, by returning a procedure that you can apply to the given arguments:
((f 0) 6 7)
=> 42
((f 3) 2 3)
=> 0
I'm having problems implementing one generator called fib in a function.
I want the function to return me a generator that generates the first n Fibonacci numbers.
;THIS IS MY GENERATOR
(define fib
(let ((a 0) (b 1))
(lambda ()
(let ((return a))
(set! a b)
(set! b (+ b return)
)return))))
;THIS IS MY FUNCTION
(define (take n g)
(define fib
(let ((a 0) (b 1) (cont 1))
(lambda ()
(if (>= cont n) #f
(let ((return a))
(set! cont (+ cont 1))
(set! a b)
(set! b (+ b return)
)(return)))))))
I expect a generator to return the Fibonacci numbers up to N (delivered to the function). But the actual output is :
begin (possibly implicit): no expression after a sequence of internal definitions in:
(begin
(define fib
(let ((a 0) (b 1) (cont 1))
(lambda ()
(if (>= cont n) #f
(let ((return a))
(set! cont (+ cont 1))
(set! a b)
(set! b (+ b return))
(return)))))))
Just as the error says, you have no expressions in your function's definition except for some internal definition (which, evidently, is put into an implicit begin). Having defined it, what is a function to do?
More importantly, there's problems with your solution's overall design.
When writing a function's definition, write down its sample calls right away, so you see how it is supposed / intended / to be called. In particular,
(define (take n g)
suggests you intend to call it like (take 10 fib), so that inside take's definition g will get the value of fib.
But fib is one global generator. It's not restartable in any way between different calls to it. That's why you started copying its source, but then realized perhaps, why have the g parameter, then? Something doesn't fit quite right, there.
You need instead a way to create a new, fresh Fibonacci generator when you need to:
(define (mk-fib)
(let ((a 0) (b 1))
(lambda ()
(let ((ret a))
(set! a b)
(set! b (+ ret b))
ret)))) ;; ..... as before .....
Now each (mk-fib) call will create and return a new, fresh Fibonacci numbers generator, so it now can be used as an argument to a take call:
(define (taking n g) ;; (define q (taking 4 (mk-fib)))
Now there's no need to be defining a new, local copy of the same global fib generator, as you were trying to do before. We just have whatever's specific to the take itself:
(let ((i 1))
(lambda () ; a generator interface is a function call
(if (> i n) ; not so good: what if #f
#f ; is a legitimately produced value?
(begin
(set! i (+ i 1))
(g)))))) ; a generator interface is a function call
Now we can define
> (define q (taking 4 (mk-fib)))
> (q)
0
> (q)
1
> (q)
1
> (q)
2
> (q)
#f
> (q)
#f
>
I can't figure out why my lambda is wrong. It should create a make-exp.
(define (exp b n)
(if (n = 0)
1
(* b (exp b (- n 1)))))
(define make-exp (lambda(n) (lambda(b)(exp b n ))))
(define square (make-exp 2))
(square 3)
Error: 2 is not a function [square, exp, (anon)]
(n = 0)
This calls the function n with the arguments = and 0, except n is 2 and not a function, so this does not work. Presumably you meant (= n 0).