I'm trying to write a recursive function that prints to the screen a list (each number in a new line) of elements of the Fibonacci series for the given parameter n. I need to use the display function to print those numbers and use a helper method as well.
Example:
(fibo 5)
1
1
2
3
5
Can anyone help me please? Thanks!!
Simply call your procedure inside a looping function, taking care of printing the elements in the right order and breaking with new lines. Notice that the point where we call the recursion is very important to obtain the desired behavior! (to see this, move the recursive call after the line break - the printing order will change).
(define print-fibo
(lambda (n)
(cond ((> n 0) ; keep iterating if we haven't reached zero
(print-fibo (- n 1)) ; advance the recursion
(display (fibo n)) ; display current value of fibo
(newline))))) ; print a new line
For example:
(print-fibo 5)
1
1
2
3
5
Related
I am experimenting with clojure's lazy sequences. In order to see when the evaluation of an item would occur, I created a function called square that prints the result before returning it. I then apply this function to a vector using map.
(defn square [x]
(let [result (* x x)]
(println "printing " result)
result))
(def s (map square [1 2 3 4 5])) ; outputs nothing
Here in my declaration of s, the REPL does not output anything. This signals that the computation has not started yet. This appears to be correct. I then do:
(first s)
The function "first" takes only the first item. So I expect that only 1 will be evaluated. My expectation is the REPL will output the following:
printing 1
1
However, the REPL outputted the following instead.
printing 1
printing 4
printing 9
printing 16
printing 25
1
So rather than evaluating only the first item, it seems it evaluates all items, even though I am accessing just the first item.
If the state of a lazy sequence can only be either all values computed and no values computed, then how can it gain the advantages of lazy evaluation? I came from a scheme background and I was expecting more like the behavior of streams. Looks like I am mistaken. Can anyone explain what is going on?
Laziness isn't all-or-nothing, but some implementations of seq operate on 'chunks' of the input sequence (see here for an explanation). This is the case for vector which you can test for with chunked-seq?:
(chunked-seq? (seq [1 2 3 4 5]))
When given a collection map checks to see if the underlying sequence is chunked, and if so evaluates the result on a per-chunk basis instead of an element at a time.
The chunk size is usually 32 so you can see this behaviour by comparing the result of
(first (map square (vec (range 35))))
This should only display a message for the first 32 items and not the entire sequence.
I need to remove the last two elements from a list in common list, but I can remove only one. What's the way?
(defun my-butlast (list)
(loop for l on list
while (rest l)
collect (first l)))
Simple: reverse, pop, pop, reverse ;-) 1
More efficiently, the following works too:
(let ((list '(a b c d)))
(loop
for x in list
for y in (cddr list)
collect x))
This can also be written, for some arbitrary L and N:
(mapcar #'values L (nthcdr N L))
It works because iteration over multiple lists is bounded by the shortest one. What matters here is the length of the second list (we don't care about its values), which is the length of the original list minus N, which must be a non-negative integer. Notice that NTHCDR conveniently works with sizes greater than the length of the list given in argument.
With the second example, I use the VALUES function as a generalized identity function; MAPCAR only uses the primary value of the computed values, so this works as desired.
The behavior is consistent with the actual BUTLAST2 function, which returns nil for N larger than the number of elements in the list. The actual BUTLAST function can also deal with improper (dotted) lists, but the above version cannot.
1. (alexandria:compose #'nreverse #'cddr #'reverse)
2. BUTLAST is specified as being equivalent to (ldiff list (last list n)). I completely forgot about the existence of LDIFF !
There's a function in the standard for this: butlast, or if you're willing to modify the input list, nbutlast.
butlast returns a copy of list from which the last n conses have been omitted. If n is not supplied, its value is 1. If there are fewer than n conses in list, nil is returned and, in the case of nbutlast, list is not modified.
nbutlast is like butlast, but nbutlast may modify list. It changes the cdr of the cons n+1 from the end of the list to nil.
Examples:
CL-USER> (butlast '(1 2 3 4 5) 2)
(1 2 3)
CL-USER> (nbutlast (list 6 7 8 9 10) 2)
(6 7 8)
The fact that you called your function my-butlast suggests that you might know about this function, but you didn't mention wanting to not use this function, so I assume it's still fair game. Wrapping it up is easy:
CL-USER> (defun my-butlast (list)
(butlast list 2))
MY-BUTLAST
CL-USER> (my-butlast (list 1 2 3 4))
(1 2)
The function receives a number and returns the number of bits that would have been
required to be “on” in order to represent the input number in binary base.
For example, the number 5 is represented as 101 in binary and therefore requires two bits to be “on”. I need to know if the function I wrote is tail recursion. If not, how can I turn it to tail recursion? Thanks!
My function:
(define (numOfBitsOn number)
(define (numOfBitsOn-2 number acc)
(if (> number 0)
(if (odd? number)
(numOfBitsOn-2(/(- number 1) 2) (+ acc (modulo number 2)))
(numOfBitsOn-2 (/ number 2) acc))
acc))
(numOfBitsOn-2 number 0))
DrRacket can help you determine whether a call is in tail position or not. Click the "Syntax Check" button. Then move the mouse pointer to the left parenthesis of the expression in question. In an example I get this:
The purple arrow shows that the expression is in tail-position.
From the manual:
Tail Calls: Any sub-expression that is (syntactically) in
tail-position with respect to its enclosing context is annotated by
drawing a light purple arrow from the tail expression to its
surrounding expression.
This is an example from the book I am reading:
1 (define (length items)
2 (define (length-iter a count)
3 (if (null? a)
4 count
5 (length-iter (cdr a)(+ 1 count))))
6 (length-iter items 0))
What I am not understanding is how can length-iter know about count? The first time this
procedure is called with a list, it will in turn define another procedure with two argumenets, I get that much. But how does it know that a is the list items? It hasnt reached line 6 yet, where items is passed to length-iter as the argument a. Somehow though it already knows this and is able to make the computation. Any help in clarifying this a bit is appreciated!
There are two parts in the length function:
Definition of the inner function length-iter;
Invocation of the inner function length-iter.
In the invocation, i.e., line 6, you pass the original items list to the inner function as an argument. This is where the inner function gets called. Previously, you are just defining the function, not calling it:
(length-iter items 0)
Thus, items will be bound to a, and 0 to count. You can think of the inner function as a separate function:
(define (length-iter a count)
(if (null? a)
count
(length-iter (cdr a)(+ 1 count))))
And then, think of your length function as if it just delegated all the work to the length-iter function:
(define (length items)
(length-iter items 0))
That's what's being done in your function. The difference, is that the length-iter function is only known to length.
If I understand correctly Clojure can return lists (as in other Lisps) but also vectors and sets.
What I don't really get is why there's not always a collection that is returned.
For example if I take the following code:
(loop [x 128]
(when (> x 1)
(println x)
(recur (/ x 2))))
It does print 128 64 32 16 8 4 2. But that's only because println is called and println has the side-effect (?) of printing something.
So I tried replacing it with this (removing the println):
(loop [x 128]
(when (> x 1)
x
(recur (/ x 2))))
And I was expecting to get some collecting (supposedly a list), like this:
(128 64 32 16 8 4 2)
but instead I'm getting nil.
I don't understand which determines what creates a collection and what doesn't and how you switch from one to the other. Also, seen that Clojure somehow encourages a "functional" way of programming, aren't you supposed to nearly always return collections?
Why are so many functions that apparently do not return any collection? And what would be an idiomatic way to make these return collections?
For example, how would I solve the above problem by first constructing a collection and then iterating (?) in an idiomatic way other the resulting list/vector?
First I don't know how to transform the loop so that it produces something else than nil and then I tried the following:
(reduce println '(1 2 3))
But it prints "1 2nil 3nil" instead of the "1 2 3nil" I was expecting.
I realize this is basic stuff but I'm just starting and I'm obviously missing basic stuff here.
(P.S.: retag appropriately, I don't know which terms I should use here)
A few other comments have pointed out that when doesn't really work like if - but I don't think that's really your question.
The loop and recur forms create an iteration - like a for loop in other languages. In this case, when you are printing, it is indeed just for the side effects. If you want to return a sequence, then you'll need to build one:
(loop [x 128
acc []]
(if (< x 1)
acc
(recur (/ x 2)
(cons x acc))))
=> (1 2 4 8 16 32 64 128)
In this case, I replaced the spot where you were calling printf with a recur and a form that adds x to the front of that accumulator. In the case that x is less than 1, the code returns the accumulator - and thus a sequence. If you want to add to the end of the vector instead of the front, change it to conj:
(loop [x 128
acc []]
(if (< x 1)
acc
(recur (/ x 2)
(conj acc x))))
=> [128 64 32 16 8 4 2 1]
You were getting nil because that was the result of your expression -- what the final println returned.
Does all this make sense?
reduce is not quite the same thing -- it is used to reduce a list by repeatedly applying a binary function (a function that takes 2 arguments) to either an initial value and the first element of a sequence, or the first two elements of the sequence for the first iteration, then subsequent iterations are passed the result of the previous iteration and the next value from the sequence. Some examples may help:
(reduce + [1 2 3 4])
10
This executes the following:
(+ 1 2) => 3
(+ 3 3) => 6
(+ 6 4) => 10
Reduce will result in whatever the final result is from the binary function being executed -- in this case we're reducing the numbers in the sequence into the sum of all the elements.
You can also supply an initial value:
(reduce + 5 [1 2 3 4])
15
Which executes the following:
(+ 5 1) => 6
(+ 6 2) => 8
(+ 8 3) => 11
(+ 11 4) => 15
HTH,
Kyle
The generalized abstraction over collection is called a sequence in Clojure and many data structure implement this abstraction so that you can use all sequence related operations on those data structure without thinking about which data structure is being passed to your function(s).
As far as the sample code is concerned - the loop, recur is for recursion - so basically any problem that you want to solve using recursion can be solved using it, classic example being factorial. Although you can create a vector/list using loop - by using the accumulator as a vector and keep appending items to it and in the exist condition of recursion returning the accumulated vector - but you can use reductions and take-while functions to do so as shown below. This will return a lazy sequence.
Ex:
(take-while #(> % 1) (reductions (fn [s _] (/ s 2)) 128 (range)))