For / continued in / lisp schema

I am writing a small interpreter for a C-like language in Scheme (R5RS) and am trying to convert something like:

for (i = 0; i < 100; i++) { if (isprime(i)) continue; else /* do something with i */ } 

into a valid circuit (the isprime function is just an example and does not matter).

However, after some time, I could not find an efficient / easy way to add the equivalent of the continue statement to the do loop in Scheme. What would be even better for the for macro, which allows you to use continue and split.

I am considering switching to Common Lisp. Will it be easier in CL?

+5
source share
6 answers

We can write FOR as a macro. General version of Lisp:

 (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 
+4
source

I would go on to continue , as in this pseudo-scheme example.

Just save the current execution point in the sequel and call it when necessary.

 (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)))))))) 
+1
source

CL 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)))) 
+1
source

To implement this specific code example in a Schema, you do not need continue , break or call/cc :

 (let loop ((i 0)) (when (< i 100) (if (prime? i) (loop (add1 i))) (do-something-else))) 
0
source

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 the 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)))))))) 

This is not a macro, but it certainly leads to something common enough. I would be interested to see any improvements. I am new to Scheme.

0
source

I know that this is 8 years later, but I thought it could help someone.

Using the iterate construct in Common Lisp, you can use the next-iteration clause:

 (iter (for i from 0 to 100) (if (isprime i) (next-iteration) (do-something-else))) 
0
source

Source: https://habr.com/ru/post/1334070/


All Articles