In the following loop:
(let ((funs (loop for i upto 3 do (print i) collect #'(lambda () i))))
(loop for fun in funs collect (funcall fun)))
i would intuitively think i would get a list of four closures which return the numbers 0 1 2 and 3 upon being called, but this is what i get:
>> 0
>> 1
>> 2
>> 3
=> (4 4 4 4)
But rebinding the i locally to something else:
(let ((funs (loop for i upto 3 do (print i) collect (let ((x i))
#'(lambda () x)))))
(loop for fun in funs collect (funcall fun)))
works as expected:
>> 0
>> 1
>> 2
>> 3
=> (0 1 2 3)
So each of the functions return 4, why are all return values the same, and why 4?
update
This seems to be a question about lambda actually. See below:
(setq dynamic-var 8
funs ())
(push (lambda () dynamic-var) funs)
(incf dynamic-var)
(push (lambda () dynamic-var) funs)
(mapcar #'funcall funs) ;(9 9)
What does
(let (i ; a counter variable
f) ; a list of functions
(setf i 1)
(push (lambda () i) f)
(setf i 2)
(push (lambda () i) f)
(mapcar #'funcall f))
return?
How about:
(let (i
f)
(setf i 1)
(push (lambda () i) f)
(let (i)
(setf i 2)
(push (lambda () i) f))
(mapcar #'funcall f))
Which is the LOOP model?
See also:
CL-USER 42 > (let (f)
(dotimes (i 10 (mapcar #'funcall (reverse f)))
(push (lambda () i) f)))
(10 10 10 10 10 10 10 10 10 10)
CL-USER 43 > (let (f)
(dotimes (i 10 (mapcar #'funcall (reverse f)))
(push (let ((i i))
(lambda () i))
f)))
(0 1 2 3 4 5 6 7 8 9)
The Common Lisp standard says for DOTIMES:
It is implementation-dependent whether dotimes establishes a new binding of var on each iteration or whether it establishes a binding for var once at the beginning and then assigns it on any subsequent iterations.
you write:
i would intuitively think i would get a list of four closures which return the numbers 0 1 2 and 3 upon being called
This intuition is only partly correct. You get four closures, but in this case they all share one variable binding. Thus they can only see the current binding of this one variable. In Common Lisp this binding is mutable and closures see the current binding, not the one of the initial binding of closure creation time.
Your intuition would be right, when each closure had its own variable binding.
Additional answer: why is this Lisp returning 10 ?
(PROGN
(SETQ I (THE INTEGER (1+ (THE INTEGER I))))
(WHEN (>= (THE INTEGER I)
(THE INTEGER #:|dotimes-count-1075|))
(GO #:|dotimes-end-tag1080|)))
Above is a part of the macro expansion of the dotimes construct. As you can see it first increments the variable and then tests for >=. Thus it exits when I is >= 10. Thus the last value of I is 10. Later after exiting the dotimes you are retrieving the value of I and then it's 10.
Related
I'm learning lisp and and implemented a nested array parses, so that:
"[1,[2,[3,[4,[5,6,7]]]],8,9]" -> '(1 (2 (3 (4 (5 6 7)))) 8 9)
Online Code snippet here
This was my first implementation of parse-line
(defun parse-line (string)
(loop
:for i = 0 :then (1+ j)
:for stack = (list nil)
:as j = (position-if (lambda (c) (member c '(#\[ #\] #\,))) string :start i)
:as n = (parse-integer string :start i :end j :junk-allowed t)
:when n :do (push n (car stack))
:while j
:do (cond
((eql #\[ (aref string j)) (push nil stack))
((eql #\] (aref string j)) (push (nreverse (pop stack)) (car stack))))
:finally (return (car (pop stack))))
))
But it crashes on the stack pop.
;test-case
(print (equal '(1 (2 (3 (4 (5 6 7)))) 8 9) (parse-line "[1,[2,[3,[4,[5,6,7]]]],8,9]")))
The value
NIL
is not of type
CONS
I then brute-forced my way into a solution declaring stack with let outside the loop macro
(defun parse-line (string)
(let ((stack (list nil)))
(loop
:for i = 0 :then (1+ j)
:as j = (position-if (lambda (c) (member c '(#\[ #\] #\,))) string :start i)
:as n = (parse-integer string :start i :end j :junk-allowed t)
:when n :do (push n (car stack))
:while j
:do (cond
((eql #\[ (aref string j)) (push nil stack))
((eql #\] (aref string j)) (push (nreverse (pop stack)) (car stack))))
:finally (return (car (pop stack))))
))
But I can't see why the second implementation works.
I also can't see why I need to initialize stack with (list nil). I thought that initializing stack to nil and removing the final car should be equivalent but it crashes with the same error at the same place, ie:
(defun parse-line (string)
(let (stack)
(loop
:for i = 0 :then (1+ j)
:as j = (position-if (lambda (c) (member c '(#\[ #\] #\,))) string :start i)
:as n = (parse-integer string :start i :end j :junk-allowed t)
:when n :do (push n (car stack))
:while j
:do (cond
((eql #\[ (aref string j)) (push nil stack))
((eql #\] (aref string j)) (push (nreverse (pop stack)) (car stack))))
:finally (return (pop stack)))
))
Look at these two lines in your first implementation:
:for i = 0 :then (1+ j)
:for sack = (list nil)
There is a typo (sack -> stack), but even then it doesn't work, because with each new value of i, you will create a brand new stack, losing all previous values. Add some debug print to see, what's going on:
i:0 j:0 n:NIL stack:(NIL NIL)
i:1 j:2 n:1 stack:((1))
i:3 j:3 n:NIL stack:(NIL NIL)
i:4 j:5 n:2 stack:((2))
i:6 j:6 n:NIL stack:(NIL NIL)
i:7 j:8 n:3 stack:((3))
...
If you don't want to use let to initialize stack, you can use keyword :with:
(defun parse-line (string)
(loop
:with stack = (list nil)
:for i = 0 :then (1+ j)
:as j = (position-if (lambda (c) (member c '(#\[ #\] #\,))) string :start i)
:as n = (parse-integer string :start i :end j :junk-allowed t)
:when n :do (push n (car stack))
:while j
:do (cond
((eql #\[ (aref string j)) (push nil stack))
((eql #\] (aref string j)) (push (nreverse (pop stack)) (car stack))))
:finally (return (car (pop stack)))))
You can use a similar debug print to see, why your code crashes with stack initialized to nil. This error can be reproduced with:
> (let ((stack '((9 8 (2 (3 (4 (5 6 7)))) 1))))
(push (nreverse (pop stack)) (car stack)))
Error: NIL (of type NULL) is not of type CONS.
You can find some explanation for this behaviour here: Why I can't (push 3 '()) in Common Lisp's REPL?
I would recommend using a Lisp compiler and using its warnings. SBCL gives this warning on your first form:
; in: DEFUN PARSE-LINE
; (PUSH N (CAR STACK))
;
; caught WARNING:
; undefined variable: COMMON-LISP-USER::STACK
;
; compilation unit finished
; Undefined variable:
; STACK
; caught 1 WARNING condition
That would lead you to investigate why that is: why is STACK undefined?
I am starting to use log4cl and am facing a weird issue when using it inside an iterate loop. While working does show the name of the method it is empty for not-working.
Do I miss something obvious here? Or is there a bug in the combination of iterate and log4cl?
(ql:quickload "iterate")
(ql:quickload "log4cl")
(defpackage :minimal
(:use #:cl #:iterate))
(in-package :minimal)
(defclass test ()
((a :documentation "test-a"
:initform (make-array '(3 3)
:element-type 'integer
:initial-element 0)
:initarg :a)))
(defvar *a* (make-instance 'test))
(defmethod not-working ((test test))
(with-slots (a) test
(iter
(for i below 3)
(iter
(for j below 3)
(unless (= 10 (aref a i j))
(log:info "R: ~D C: ~D" i j))))))
(defmethod working ((test test))
(with-slots (a) test
(loop
for i below 3
do (loop
for j below 3
unless (= 10 (aref a i j))
do (log:info "I: ~D J: ~D" i j)))))
(not-working *a*)
(working *a*)
EDIT
I see the issue only on sbcl. Using cclthe method name is displayed correctly. Furthermore, omitting the (are...) statement inside unless leads to a working version:
(defmethod also-working ((test test))
(with-slots (a) test
(iter
(for i below 3)
(iter
(for j below 3)
(unless (= 10 j)
(log:info "R: ~D C: ~D" i j))))))
i wrote this function but i have been told i can't use the loop inside of it, i have no idea how to modify it in order to remove the loop.
any suggestion?
(defun function (P VariableValues)
(let* ((M (mono P))
(VariableNames (variables P))
(VariableDict (loop for x in VariableNames for y in VariableValues collect (cons x y)))
(Valorizzati (mapcar (lambda (x) (applica-valori VariableDict x)) M))
)
(if Valorizzati
(+ (car Valorizzati) (recursive-sum (cdr Valorizzati)))
0)))
You can use mapcar for that:
(mapcar #'cons '(a b c) '(1 2 3))
;; ==> ((a . 1) (b . 2) (c . 3))
I am trying to implement a while loop using recursion with lambda, but I just don't understand how to do it.
I am supposed to start with this lambda expression:
((lambda (x) (x x)) (lambda (x) (x x))
My first question is why does this cause 'eternal' recursion? I try to understand how it works, but I just can't grasp it.
I also have this code to go after:
((lambda (x) (x x))
(lambda (x)
(if (not (= i 0))
(begin
(display i)
(set! i (- i 1))
(x x))
)))
This code causes a loop that prints from i = n to i = 0, but I don't understand this either. If someone would care to explain the use of lambda here I would be grateful :)
Edit: I have to use this lambda expression as my 'starting point', and I don't want to use macros (it's a voluntary excercise which I try to understand, so I want to follow the guidelines :))
To see what happens when ((lambda (x) (x x)) (lambda (x) (x x)) is evaluated use the stepper in DrRacket. It can show you the steps an evaluation takes.
Write your expression in the definition window of DrRacket.
Then choose the teaching language "Intermediate Student with lambda". Then click the stepper button (the green triangle followed by a bar).
You will see something that looks like the image (which uses a different program):
Update:
Try this program:
(define i 5)
((lambda (x) (x x))
(lambda (x)
(if (not (= i 0))
(x x)
'ignore)))
Update:
(define i 5)
(define f
(lambda (x)
(if (not (= i 0))
(begin
(display i)
(set! i (- i 1))
(x x))
'done)))
(f f)
Or without any defines at all:
((lambda (f) (f f))
(lambda (x)
(if (not (= i 0))
(begin
(display i)
(set! i (- i 1))
(x x))
'done)))
And here without an external variable:
((lambda (f i) (f f i))
(lambda (x i)
(if (not (= i 0))
(begin
(display i)
(x x (- i 1)))
'done))
5)
Using a while function:
(define (while body . args)
(apply body body args))
(while (lambda (loop i)
(if (not (= i 0))
(begin
(display i)
(loop loop (- i 1)))
'done))
5)
I'm writing a small interpreter for a C-like language in Scheme (R5RS) and trying to convert something like:
for (i = 0; i < 100; i++)
{
if (isprime(i)) continue;
else /* do something with i */
}
to valid Scheme (the isprime function is just an example and not important).
However, after trying for some time, I have not been able to find an efficient/simple way to add the equivalent of a continue statement to a do loop in Scheme. What would be even better would be a "for" macro which allows "continue" and "break" to be used.
I'm considering switching to Common Lisp. Would this sort of thing be any easier in CL?
We can write FOR as a macro. The Common Lisp version:
(defmacro for ((var start end) &body body)
(let ((block-name (gensym "BLOCK")))
`(loop for ,var from ,start below ,end
do (block ,block-name
(flet ((continue ()
(return-from ,block-name)))
,#body)))))
CL-USER 2 > (for (i 10 20)
(if (evenp i) (continue))
(print i))
11
13
15
17
19
CL's tagbody is a convenient target:
(let (i)
(tagbody
(setf i 0)
body
(if (isprime i)
(go increment))
(do-something-with i)
increment
(setf i (1+ i))
(if (< i 100)
(go body))))
I'd go for continuations like in this pseudo-scheme example.
Just store the current point of execution in a continuation and call it when appropriate.
(call/cc (lambda break ; jump outside the for
(for 0 100 (lambda i
(call/cc (lambda continue ; jump to the next iteration
(if (isprime i)
(continue)
(break))))))))
I know this is 8 years late, but I thought it might help someone.
Using the iterate construct in Common Lisp, you could use the next-iteration clause:
(iter (for i from 0 to 100)
(if (isprime i)
(next-iteration)
(do-something-else)))
The straightforward Scheme way to achieve this is just to restructure your code:
for (i = 0; i < 100; i++)
{
if (isprime(i)) continue;
if (is_bad(i)) break;
else /* do something with i */
}
is
(let loop ((i 0))
(cond
((isprime i) ;; continue the loop
(loop (+ i 1)))
((is_bad i)
#f) ;; break from the loop
(else ;; do something with i
....... ;; and then continue the loop
(loop (+ i 1)))))
If your loop body is tangled and you want to (continue) or (break) from deep inside its nested structure, either have your compiler restructure it in the above way, or you could set up exit points with call/cc as e.g.
(call/cc (lambda (break)
(let loop ((i 0))
(call/cc (lambda (continue)
;; your loop logic here,
;; potentially using
;; (continue A) ;; A is ignored
;; or
;; (break B) ;; B is immediately returned as
;; ;; the overall loop's result
))
;; (continue _) continues here:
(loop (+ i 1)))))
Racket has delimited continuations which should be more efficient.
To implement this particular code sample in Scheme, you don't need continue, break or call/cc:
(let loop ((i 0))
(when (< i 100)
(if (prime? i)
(loop (add1 i)))
(do-something-else)))
I think Vijay's answer can be extended in a way that works (sorry for answering my own question, but can't figure out how to format code in a comment):
(let loop ((i 0))
(define (next)
(loop (+ i 1)))
(call/cc
(lambda (break)
(if (< i 100)
(begin
(if (isprime i)
(next)
(begin
(if (isbad i)
(break break))
(do-something)
(next))))))))
It's not a macro, but doubtlessly leads to one that's general enough. I'd be interested to see any improvements. I'm pretty new to Scheme.
You can use throw and catch as well (elisp):
(let ((j 0))
(while (< j 10)
(catch 'continue
(setq j (1+ j))
(if (= j 3) (throw 'continue t))
(prin1 j))))
1245678910nil