I have started to learn Common Lisp a few days ago reading the book from Peter Seibel. I have downloaded the lispbox-0.7 for Windows and tried out some of the concepts in the SLIME REPL.
Now I'm at chapter 7. Macros and Standard Control Structures / Loops and I found this intressting do expression for the 11th Fibonacci number
(do ((n 0 (1+ n))
(cur 0 next)
(next 1 (+ cur next)))
((= 10 n) cur))
I defined following function
(defun fib (n) (do ((i 1 (1+ i)) (cur 0 next) (next 1 (+ cur next))) ((= n i) cur)))
The function does what I expected and returns the nth Fibonacci number. Now for curiosity i tried summing the first 10 fibonacci numbers using a dotimes loop
(let ((sum 0)) (dotimes (k 10) (setf sum (+ sum (fib k)))) sum)
But this expression runs indefinitly and i don't understand why. Maybe here is another concept I don't know. I tried a simpler example like
(dotimes (k 10) (fib k))
which should return NIL. But this also runs indefinitly. Can someone explain to me what I am missing?
Thx
Ok, nevermind, was not carefull enougth. the code tries to evaluate fib 0, but the test condition in do cannot be fulfilled. Thats why it runs indefinitly
fixing it by (fib (+ k 1))
Related
I'm using a for-loop macro in clojure:
(defmacro for-loop [[sym initial check-exp post-exp] & steps]
`(loop [~sym ~initial]
(if ~check-exp
(do
~#steps
(recur ~post-exp)))))
I want to write a simple function to find the sum of n numbers like:
for(int i=1; i<n; i++)
sum=sum+i;
How can I do this in clojure using the for-loop macro?
First of all, there is no need to use a macro here. Second, your use of do with the final call to recur will prevent the macro from ever returning a value other than nil as discussed in Lee's answer. That you should use when instead of if when you're not really providing an else case is only a slight matter, but hints at a possible better solution: Use the else case to return the result. For this to work you need to introduce an accumulator into the equation.
(defmacro for-loop [[sym initial result initial-result check-exp post-exp] & steps]
`(loop [~sym ~initial
~result ~initial-result]
(if ~check-exp
(do
~#steps
(recur ~#post-exp))
~result)))
This is still pretty ugly, but allows you to solve your summing task like this, actually not requiring any intermediate steps:
(for-loop [i 0 r 0 (< i n) ((inc i) (+ r i))] nil)
If you macro-expand this, it's easier to see that is going on:
(pprint (macroexpand-1 '(for-loop [i 0 r 0 (< i n) ((inc i) (+ r i))] nil)))
==> (clojure.core/loop [i 0 r 0]
(if (< i n)
(do nil
(recur (inc i) (+ r i)))
r))
It would be nice if one would not have to explicitly name and use the accumulator but just use the results from the steps, but as the steps will likely need to refer to any intermediate values build up so far as in this example, there is no way around it.
(def sum (atom 0))
(def n 100)
(for-loop [i 0 (< i n) (inc i)] (swap! sum #(+ % i)))
I've been attempting to learn programming with the book "Structures and Interpretation of Computer Programs. To do the exercises I've been using DrRacket (I couldn't find a scheme interpreter for Windows 7, and DrRacket seems pretty good), and haven't had any problems so far. But while doing exercise 1.22 I've ran into an issue. I've wrote a procedure that gives a given number (n) of prime numbers larger than a:
(define (search-for-primes a n)
(define (sfp-iter a n counter)
(cond ((and (prime? a) (= counter n))
((newline) (display "end")))
((prime? a)
((newline)
(display a)
(sfp-iter (+ a 1) n (+ counter 1))))
(else (sfp-iter (+ a 1) n counter))))
(sfp-iter a n 0))
The procedure works as intended, displaying all that it should, but after displaying end it shows the following error message:
application: not a procedure;
expected a procedure that can be applied to arguments
given: #
arguments...:
#
And highlights the following line of code:
((newline) (display "end"))
What is the problem?
(I apologize for any mistakes in spelling and so, English isn't my native language, I also apologize for any error in formatting or tagging, I'm new here)
You have a couple of parenthesis problems, this fixes it:
(define (search-for-primes a n)
(define (sfp-iter a n counter)
(cond ((and (prime? a) (= counter n))
(newline) (display "end"))
((prime? a)
(newline)
(display a)
(sfp-iter (+ a 1) n (+ counter 1)))
(else (sfp-iter (+ a 1) n counter))))
(sfp-iter a n 0))
In the first and second conditions of the cond, you were incorrectly surrounding the code with (). That's unnecessary, in a cond clause all the expressions that come after the condition are implicitly surrounded by a (begin ...) form, so there's no need to group them together.
(defun fact (n)
(do
((i 1 (+ 1 i))
(prod 1 (* i prod)))
((equal i n) prod)))
I have done the code above and when i try, fact(4), it give me ans is 6. I am not sure what is going wrong. Can anyone help me?
Change to
(defun fact (n)
(do
((i 1 (+ 1 i))
(prod 1 (* i prod)))
((equal i (+ n 1)) prod)))
Basically, you were doing one iteration less than necessary.
Mihai has already given the answer.
I would write it as:
(defun fact (n)
(do ((i 1 (+ 1 i))
(prod 1 (* i prod)))
((> i n) prod)))
Common Lisp has all the usual arithmetic predicates which work for numbers: =, <, >, ...
I need to make something like this but in ACL2:
for (i=1; i<10; i++) {
print i;
}
It uses COMMON LISP, but I haven't any idea how to do this task...
We can't use standard Common Lisp constructions such as LOOP, DO. Just recursion.
I have some links, but I find it very difficult to understand:
Gentle Intro to ACL2 Programming
The section "Visiting all the natural numbers from n to 0" in A Gentle Introduction to ACL2 Programming explains how to do it.
In your case you want to visit numbers in ascending order, so your code should look something like this:
(defun visit (n max ...)
(cond ((> n max) ...) ; N exceeds MAX: nothing to do.
(t . ; N less than or equal to MAX:
. n ; do something with N, and
.
(visit (+ n 1) max ...) ; visit the numbers above it.
.
.
.)))
A solution that uses recursion:
> (defun for-loop (from to fn)
(if (<= from to)
(progn
(funcall fn from)
(for-loop (+ from 1) to fn))))
;; Test
> (for-loop 1 10 #'(lambda (i) (format t "~a~%" i)))
1
2
3
4
5
6
7
8
9
10
NIL
(defun foo-loop (n)
(cond ((zp n) "done")
(t (prog2$ (cw "~x0" n)
(foo-loop (1- n)))))
(foo-loop 10)
You can redo the termination condition and the recursion to mimic going from 1 to 10.
I have some code which collects points (consed integers) from a loop which looks something like this:
(loop
for x from 1 to 100
for y from 100 downto 1
collect `(,x . ,y))
My question is, is it correct to use `(,x . ,y) in this situation?
Edit: This sample is not about generating a table of 100x100 items, the code here just illustrate the use of two loop variables and the consing of their values. I have edited the loop to make this clear. The actual loop I use depends on several other functions (and is part of one itself) so it made more sense to replace the calls with literal integers and to pull the loop out of the function.
It would be much 'better' to just do (cons x y).
But to answer the question, there is nothing wrong with doing that :) (except making it a tad slower).
I think the answer here is resource utilization (following from This post)
for example in clisp:
[1]> (time
(progn
(loop
for x from 1 to 100000
for y from 1 to 100000 do
collect (cons x y))
()))
WARNING: LOOP: missing forms after DO: permitted by CLtL2, forbidden by ANSI
CL.
Real time: 0.469 sec.
Run time: 0.468 sec.
Space: 1609084 Bytes
GC: 1, GC time: 0.015 sec.
NIL
[2]> (time
(progn
(loop
for x from 1 to 100000
for y from 1 to 100000 do
collect `(,x . ,y)) ;`
()))
WARNING: LOOP: missing forms after DO: permitted by CLtL2, forbidden by ANSI
CL.
Real time: 0.969 sec.
Run time: 0.969 sec.
Space: 10409084 Bytes
GC: 15, GC time: 0.172 sec.
NIL
[3]>
dsm: there are a couple of odd things about your code here. Note that
(loop for x from 1 to 100000
for y from 1 to 100000 do
collect `(,x . ,y))
is equivalent to:
(loop for x from 1 to 100
collecting (cons x x))
which probably isn't quite what you intended. Note three things: First, the way you've written it, x and y have the same role. You probably meant to nest loops. Second, your do after the y is incorrect, as there is not lisp form following it. Thirdly, you're right that you could use the backtick approach here but it makes your code harder to read and not idiomatic for no gain, so best avoided.
Guessing at what you actually intended, you might do something like this (using loop):
(loop for x from 1 to 100 appending
(loop for y from 1 to 100 collecting (cons x y)))
If you don't like the loop macro (like Kyle), you can use another iteration construct like
(let ((list nil))
(dotimes (n 100) ;; 0 based count, you will have to add 1 to get 1 .. 100
(dotimes (m 100)
(push (cons n m) list)))
(nreverse list))
If you find yourself doing this sort of thing a lot, you should probably write a more general function for crossing lists, then pass it these lists of integers
If you really have a problem with iteration, not just loop, you can do this sort of thing recursively (but note, this isn't scheme, your implementation may not guaranteed TCO). The function "genint" shown by Kyle here is a variant of a common (but not standard) function iota. However, appending to the list is a bad idea. An equivalent implementation like this:
(defun iota (n &optional (start 0))
(let ((end (+ n start)))
(labels ((next (n)
(when (< n end)
(cons n (next (1+ n))))))
(next start))))
should be much more efficient, but still is not a tail call. Note I've set this up for the more usual 0-based, but given you an optional parameter to start at 1 or any other integer. Of course the above can be written something like:
(defun iota (n &optional (start 0))
(loop repeat n
for i from start collecting i))
Which has the advantage of not blowing the stack for large arguments. If your implementation supports tail call elimination, you can also avoid the recursion running out of place by doing something like this:
(defun iota (n &optional (start 0))
(labels ((next (i list)
(if (>= i (+ n start))
nil
(next (1+ i) (cons i list)))))
(next start nil)))
Hope that helps!
Why not just
(cons x y)
By the way, I tried to run your code in CLISP and it didn't work as expected. Since I'm not a big fan of the loop macro here's how you might accomplish the same thing recursively:
(defun genint (stop)
(if (= stop 1) '(1)
(append (genint (- stop 1)) (list stop))))
(defun genpairs (x y)
(let ((row (mapcar #'(lambda (y)
(cons x y))
(genint y))))
(if (= x 0) row
(append (genpairs (- x 1) y)
row))))
(genpairs 100 100)