I am still new in racket language.
I am implementing a switch case in racket but it is not working.
So, I shift into using the equal and condition. I want to know how can i call a function that takes input. for example: factorial(n) function
I want to call it in :
(if (= c 1) (factorial (n))
There are two syntax problems with this snippet:
(if (= c 1) (factorial (n)))
For starters, an if expression in Racket needs three parts:
(if <condition> <consequent> <alternative>)
The first thing to fix would be to provide an expression that will be executed when c equals 1, and another that will run if c is not equal to 1. Say, something like this:
(if (= c 1) 1 (factorial (n)))
Now the second problem: in Scheme, when you surround a symbol with parentheses it means that you're trying to execute a function. So if you write (n), the interpreter believes that n is a function with no arguments and that you're trying to call it. To fix this, simply remove the () around n:
(if (= c 1) 1 (factorial n))
Now that the syntax problems are out of the way, let's examine the logic. In Scheme, we normally use recursion to express solutions, but a recursion has to advance at some point, so it will eventually end. If you keep passing the same parameter to the recursion, without modifying it, you'll get caught in an infinite loop. Here's the proper way to write a recursive factorial procedure:
(define (factorial n)
(if (<= n 0) ; base case: if n <= 0
1 ; then return 1
(* n (factorial (- n 1))))) ; otherwise multiply and advance recursion
Notice how we decrement n at each step, to make sure that it will eventually reach zero, ending the recursion. Once you get comfortable with this solution, we can think of making it better. Read about tail recursion, see how the compiler will optimize our loops as long as we write them in such a way that the last thing done on each execution path is the recursive call, with nothing left to do after it. For instance, the previous code can be written more efficiently as follows, and see how we pass the accumulated answer in a parameter:
(define (factorial n)
(let loop ([n n] [acc 1])
(if (<= n 0)
acc
(loop (- n 1) (* n acc)))))
UPDATE
After taking a look at the comments, I see that you want to implement a switchcase procedure. Once again, there are problems with the way you're declaring functions. This is wrong:
(define fact(x)
The correct way is this:
(define (fact x)
And for actually implementing switchcase, it's possible to use nested ifs as you attempted, but that's not the best way. Learn how to use the cond expression or the case expression, either one will make your solution simpler. And anyway you have to provide an additional condition, in case c is neither 1 nor 2. Also, you're confounding the parameter name - is it c or x? With all the recommendations in place, here's how your code should look:
(define (switchcase c)
(cond ((= c 1) (fact c))
((= c 2) (triple c))
(else (error "unknown value" c))))
In racket-lang, conditionals with if has syntax:
(if <expr> <expr> <expr>)
So in your case, you have to provide another <expr>.
(define (factorial n)
(if (= n 1) 1 (* n (factorial (- n 1)))))
;^exp ^exp ^exp
(factorial 3)
The results would be 6
Update:
(define (factorial n)
(if (= n 1) 1 (* n (factorial (- n 1)))))
(define (triple x)
(* 3 x))
(define (switchcase c)
(if (= c 1)
(factorial c)
(if(= c 2)
(triple c) "c is not 1 or 2")))
(switchcase 2)
If you want something a lot closer to a switch case given you can return procedures.
(define (switch input cases)
(let ((lookup (assoc input cases)))
(if lookup
(cdr lookup)
(error "Undefined case on " input " in " cases))))
(define (this-switch c)
(let ((cases (list (cons 1 triple)
(cons 2 factorial))))
((switch c cases) c)))
Related
I'm trying to get the hang of recursion in scheme. I put together a Fibinachi function and it keeps returning unspecified instead of a number. How do I make this function return a number and to unspecified?
(define (F n)
(if (= n 0)
0)
(if (= n 1)
1)
(if (< n 2)
(+
(F (- n 1))
(F (- n 2)))))
(display (F 5))
(newline)
The function returns
#<unspecified>
I'm using guile (GNU Guile) 2.0.13.
The issue here is that your code is:
(begin
(if a 1)
(if b 2)
(if c 3))
What is wrong with this? The value of that will be unspecified except if c is true.
Why? The value of each if is unspecified when the condition is false. The begin returns the value of the last expression.
Where did the begin come from you might ask as it didn't appear in my code? To make it easier every lambda and define contains an implicit begin which is why your code was even accepted for execution.
You should use either nested ifs or a cond form:
(if a 1
(if b 2
(if c 3)))
(cond (a 1)
(b 2)
(c 3))
Ok, I'm been learning COMMON LISP programming and I'm working on a very simple program to calculate a factorial of a given integer. Simple, right?
Here's the code so far:
(write-line "Please enter a number...")
(setq x (read))
(defun factorial(n)
(if (= n 1)
(setq a 1)
)
(if (> n 1)
(setq a (* n (factorial (- n 1))))
)
(format t "~D! is ~D" n a)
)
(factorial x)
Problem is, when I run this on either CodeChef or Rexter.com, I get a similar error: "NIL is NOT a number."
I've tried using cond instead of an if to no avail.
As a side note, and most bewildering of all, I've seen a lot of places write the code like this:
(defun fact(n)
(if (= n 1)
1
(* n (fact (- n 1)))))
Which doesn't even make sense to me, what with the 1 just floating out there with no parentheses around it. However, with a little tinkering (writing additional lines outside the function) I can get it to execute (equally bewildering!).
But that's not what I want! I'd like the factorial function to print/return the values without having to execute additional code outside it.
What am I doing wrong?
One actually needs to flush the I/O buffers in portable code with FINISH-OUTPUT - otherwise the Lisp may want to read something and the prompt hasn't yet been printed. You better replace SETQ with LET, as SETQ does not introduce a variable, it just sets it.
(defun factorial (n)
(if (= n 1)
1
(* n (factorial (- n 1)))))
(write-line "Please enter a number...")
(finish-output) ; this makes sure the text is printed now
(let ((x (read)))
(format t "~D! is ~D" x (factorial x)))
Before answering your question, I would like to tell you some basic things about Lisp. (Neat fix to your solution at the end)
In Lisp, the output of every function is the "last line executed in the function". Unless you use some syntax manipulation like "return" or "return-from", which is not the Lisp-way.
The (format t "your string") will always return 'NIL as its output. But before returning the output, this function "prints" the string as well.
But the output of format function is 'NIL.
Now, the issue with your code is the output of your function. Again, the output would be the last line which in your case is:
(format t "~D! is ~D" n a)
This will return 'NIL.
To convince yourself, run the following as per your defined function:
(equal (factorial 1) 'nil)
This returns:
1! is 1
T
So it "prints" your string and then outputs T. Hence the output of your function is indeed 'NIL.
So when you input any number greater than 1, the recursive call runs and reaches the end as input 1 and returns 'NIL.
and then tries to execute this:
(setq a (* n (factorial (- n 1))))
Where the second argument to * is 'NIL and hence the error.
A quick fix to your solution is to add the last line as the output:
(write-line "Please enter a number...")
(setq x (read))
(defun factorial(n)
(if (= n 1)
(setq a 1)
)
(if (> n 1)
(setq a (* n (factorial (- n 1))))
)
(format t "~D! is ~D" n a)
a ;; Now this is the last line, so this will work
)
(factorial x)
Neater code (with Lisp-like indentation)
(defun factorial (n)
(if (= n 1)
1
(* n (factorial (- n 1)))))
(write-line "Please enter a number...")
(setq x (read))
(format t "~D! is ~D" x (factorial x))
Common Lisp is designed to be compiled. Therefore if you want global or local variables you need to define them before you set them.
On line 2 you give x a value but have not declared the existence of a variable by that name. You can do so as (defvar x), although the name x is considered unidiomatic. Many implementations will give a warning and automatically create a global variable when you try to set something which hasn’t been defined.
In your factorial function you try to set a. This is a treated either as an error or a global variable. Note that in your recursive call you are changing the value of a, although this wouldn’t actually have too much of an effect of the rest of your function were right. Your function is also not reentrant and there is no reason for this. You can introduce a local variable using let. Alternatively you could add it to your lambda list as (n &aux a). Secondarily your factorial function does not return a useful value as format does not return a useful value. In Common Lisp in an (implicit) progn, the value of the final expression is returned. You could fix this by adding a in the line below your format.
For tracing execution you could do (trace factorial) to have proper tracing information automatically printed. Then you could get rid of your format statement.
Finally it is worth noting that the whole function is quite unidiomatic. Your syntax is not normal. Common Lisp implementations come with a pretty printer. Emacs does too (bound to M-q). One does not normally do lots of reading and setting of global variables (except occasionally at the repl). Lisp isn’t really used for scripts in this style and has much better mechanisms for controlling scope. Secondarily one wouldn’t normally use so much mutating of state in a function like this. Here is a different way of doing factorial:
(defun factorial (n)
(if (< n 2)
1
(* n (factorial (1- n)))))
And tail recursively:
(defun factorial (n &optional (a 1))
(if (< n 2) a (factorial (1- n) (* a n))))
And iteratively (with printing):
(defun factorial (n)
(loop for i from 1 to n
with a = 1
do (setf a (* a i))
(format t “~a! = ~a~%” i a)
finally (return a)))
You can split it up into parts, something like this:
(defun prompt (prompt-str)
(write-line prompt-str *query-io*)
(finish-output)
(read *query-io*))
(defun factorial (n)
(cond ((= n 1) 1)
(t (* n
(factorial (decf n)))))
(defun factorial-driver ()
(let* ((n (prompt "Enter a number: "))
(result (factorial n)))
(format *query-io* "The factorial of ~A is ~A~%" n result)))
And then run the whole thing as (factorial-driver).
Sample interaction:
CL-USER 54 > (factorial-driver)
Enter a number:
4
The factorial of 4 is 24
The function is supposed to be tail-recursive and count from 1 to the specified number. I think I'm fairly close. Here's what I have:
(define (countup l)
(if (= 1 l)
(list l)
(list
(countup (- l 1))
l
)
)
)
However, this obviously returns a list with nested lists. I've attempted to use the append function instead of the second list to no avail. Any guidance?
Here's an incorrect solution:
(define (countup n)
(define (help i)
(if (<= i n)
(cons i (help (+ i 1)))
'()))
(help 1))
This solution:
uses a helper function
recurses over the numbers from 1 to n, cons-ing them onto an ever-growing list
Why is this wrong? It's not really tail-recursive, because it creates a big long line of cons calls which can't be evaluated immediately. This would cause a stack overflow for large enough values of n.
Here's a better way to approach this problem:
(define (countup n)
(define (help i nums)
(if (> i 0)
(help (- i 1)
(cons i nums))
nums)))
(help n '()))
Things to note:
this solution is better because the calls to cons can be evaluated immediately, so this function is a candidate for tail-recursion optimization (TCO), in which case stack space won't be a problem.
help recurses over the numbers backwards, thus avoiding the need to use append, which can be quite expensive
You should use an auxiliar function for implementing a tail-recursive solution for this problem (a "loop" function), and use an extra parameter for accumulating the answer. Something like this:
(define (countup n)
(loop n '()))
(define (loop i acc)
(if (zero? i)
acc
(loop (sub1 i) (cons i acc))))
Alternatively, you could use a named let. Either way, the solution is tail-recursive and a parameter is used for accumulating values, notice that the recursion advances backwards, starting at n and counting back to 0, consing each value in turn at the beginning of the list:
(define (countup n)
(let loop ((i n)
(acc '()))
(if (zero? i)
acc
(loop (sub1 i) (cons i acc)))))
Here a working version of your code that returns a list in the proper order (I replaced l by n):
(define (countup n)
(if (= 1 n)
(list n)
(append (countup (- n 1)) (list n))))
Sadly, there is a problem with this piece of code: it is not tail-recursive. The reason is that the recursive call to countup is not in a tail position. It is not in tail position because I'm doing an append of the result of (countup (- l 1)), so the tail call is append (or list when n = 1) and not countup. This means this piece of code is a normal recusrive function but to a tail-recursive function.
Check this link from Wikipedia for a better example on why it is not tail-recusrive.
To make it tail-recursive, you would need to have an accumulator responsible of accumulating the counted values. This way, you would be able to put the recursive function call in a tail position. See the difference in the link I gave you.
Don't hesitate to reply if you need further details.
Assuming this is for a learning exercise and you want this kind of behaviour:
(countup 5) => (list 1 2 3 4 5)
Here's a hint - in a tail-recursive function, the call in tail position should be to itself (unless it is the edge case).
Since countup doesn't take a list of numbers, you will need an accumulator function that takes a number and a list, and returns a list.
Here is a template:
;; countup : number -> (listof number)
(define (countup l)
;; countup-acc : number, (listof number) -> (listof number)
(define (countup-acc c ls)
(if ...
...
(countup-acc ... ...)))
(countup-acc l null))
In the inner call to countup-acc, you will need to alter the argument that is checked for in the edge case to get it closer to that edge case, and you will need to alter the other argument to get it closer to what you want to return in the end.
I'm unsure of how to turn count-forwards into a tail-recursive program. It takes a non-negative number, n, and returns the list of integers from 0 to n (including n).
Edit: Okay, I finally got this one to work. The problem wasn't that my current program was recursive and I needed to make it tail-recursive- It was just plain wrong. The actual answer is really short and clean. So if anyone else is stuck on this and is also a total programming noob, here's a few hints that might help:
1) Your helper program is designed to keep track of the list so far.
2) Its base case is.. If x = 0.. what do you do? add 0 onto.. something.
3) Recur on x - 1, and then add x onto your list so far.
4) When you get to your actual program, count-forwards, all you need is the helper. But remember that it takes two arguments!
The only recursive function here is list-reverse. It is tail-recursive, because the call to itself is the last operation in the function body.
Your function for generating a nondecreasing sequence from zero to m, which contains the successive results of adding 1 to the previous element, would look something like:
(define (my-reverse lst)
(define (rev-do xs ys)
(if (empty? xs)
ys
(rev-do (cdr xs) (cons (car xs) ys))))
(rev-do lst empty))
(define (seq m n)
(seq-do m n (list m)))
(define (seq-do m n xs)
(if (= m n)
(my-reverse xs)
(let ((next (add1 m)))
(seq-do next n (cons next xs)))))
(define (seq-from-zero m)
(seq 0 m))
Test:
> (seq-from-zero 10)
(0 1 2 3 4 5 6 7 8 9 10)
seq-do is a general function for generating nondecreasing sequences from m to n; it is tail-recursive, because the last operation is the call to itself.
I've also implemented reverse from scratch, so that you can use it in your homework problems.
My solution to exercise 1.11 of SICP is:
(define (f n)
(if (< n 3)
n
(+ (f (- n 1)) (* 2 (f (- n 2))) (* 3 (f (- n 3))))
))
As expected, a evaluation such as (f 100) takes a long time. I was wondering if there was a way to improve this code (without foregoing the recursion), and/or take advantage of multi-core box. I am using 'mit-scheme'.
The exercise tells you to write two functions, one that computes f "by means of a recursive process", and another that computes f "by means of an iterative process". You did the recursive one. Since this function is very similar to the fib function given in the examples of the section you linked to, you should be able to figure this out by looking at the recursive and iterative examples of the fib function:
; Recursive
(define (fib n)
(cond ((= n 0) 0)
((= n 1) 1)
(else (+ (fib (- n 1))
(fib (- n 2))))))
; Iterative
(define (fib n)
(fib-iter 1 0 n))
(define (fib-iter a b count)
(if (= count 0)
b
(fib-iter (+ a b) a (- count 1))))
In this case you would define an f-iter function which would take a, b, and c arguments as well as a count argument.
Here is the f-iter function. Notice the similarity to fib-iter:
(define (f-iter a b c count)
(if (= count 0)
c
(f-iter (+ a (* 2 b) (* 3 c)) a b (- count 1))))
And through a little trial and error, I found that a, b, and c should be initialized to 2, 1, and 0 respectively, which also follows the pattern of the fib function initializing a and b to 1 and 0. So f looks like this:
(define (f n)
(f-iter 2 1 0 n))
Note: f-iter is still a recursive function but because of the way Scheme works, it runs as an iterative process and runs in O(n) time and O(1) space, unlike your code which is not only a recursive function but a recursive process. I believe this is what the author of Exercise 1.1 was looking for.
I'm not sure how best to code it in Scheme, but a common technique to improve speed on something like this would be to use memoization. In a nutshell, the idea is to cache the result of f(p) (possibly for every p seen, or possibly the last n values) so that next time you call f(p), the saved result is returned, rather than being recalculated. In general, the cache would be a map from a tuple (representing the input arguments) to the return type.
Well, if you ask me, think like a mathematician. I can't read scheme, but if you're coding a Fibonacci function, instead of defining it recursively, solve the recurrence and define it with a closed form. For the Fibonacci sequence, the closed form can be found here for example. That'll be MUCH faster.
edit: oops, didn't see that you said forgoing getting rid of the recursion. In that case, your options are much more limited.
See this article for a good tutorial on developing a fast Fibonacci function with functional programming. It uses Common LISP, which is slightly different from Scheme in some aspects, but you should be able to get by with it. Your implementation is equivalent to the bogo-fig function near the top of the file.
To put it another way:
To get tail recursion, the recursive call has to be the very last thing the procedure does.
Your recursive calls are embedded within the * and + expressions, so they are not tail calls (since the * and + are evaluated after the recursive call.)
Jeremy Ruten's version of f-iter is tail-recursive rather than iterative (i.e. it looks like a recursive procedure but is as efficient as the iterative equivalent.)
However you can make the iteration explicit:
(define (f n)
(let iter
((a 2) (b 1) (c 0) (count n))
(if (<= count 0)
c
(iter (+ a (* 2 b) (* 3 c)) a b (- count 1)))))
or
(define (f n)
(do
((a 2 (+ a (* 2 b) (* 3 c)))
(b 1 a)
(c 0 b)
(count n (- count 1)))
((<= count 0) c)))
That particular exercise can be solved by using tail recursion - instead of waiting for each recursive call to return (as is the case in the straightforward solution you present), you can accumulate the answer in a parameter, in such a way that the recursion behaves exactly the same as an iteration in terms of the space it consumes. For instance:
(define (f n)
(define (iter a b c count)
(if (zero? count)
c
(iter (+ a (* 2 b) (* 3 c))
a
b
(- count 1))))
(if (< n 3)
n
(iter 2 1 0 n)))