For loop 在方案中定义For循环
注意:这似乎是笨拙的方案版本0.9.3.3。For loop 在方案中定义For循环,for-loop,scheme,lisp,define-syntax,For Loop,Scheme,Lisp,Define Syntax,注意:这似乎是笨拙的方案版本0.9.3.3。 我似乎无法理解这些Lisp语言:/ 我试图在Scheme中定义for循环语法。我不确定递归函数是否可行(我想是的),但现在我真的想让定义语法工作起来 我可以使用以下代码让循环运行一次(然后它看起来会终止): (define-syntax forloop (syntax-rules () ((forloop start stop exps) (letrec ((aloop (lambda (astart astop aexps)
我似乎无法理解这些Lisp语言:/ 我试图在Scheme中定义for循环语法。我不确定递归函数是否可行(我想是的),但现在我真的想让
定义语法工作起来
我可以使用以下代码让循环运行一次(然后它看起来会终止):
(define-syntax forloop
(syntax-rules ()
((forloop start stop exps)
(letrec ((aloop (lambda (astart astop aexps)
(if (<= astart astop) (begin aexps (aloop (+ astart 1) astop aexps))))))
(aloop start stop exps)))))
我做错了什么?我已经成功地实现了一个when
语句(我自己做的,但是有几十个例子,我已经看过很多了)。我想我想做的事情的递归性和省略号把我搞糊涂了 宏是在编译时展开的,因此类似于(begin exps…(forloop(+start 1)stop exps…)
的东西将一次又一次地展开forloop
,而不管(+start 1)
的值是多少(在运行时计算)
至少使用语法规则
,您能做的最好的事情可能是使用宏仅捕获要运行的表达式,并使用非宏代码处理循环:
(define-syntax forloop
(syntax-rules ()
((forloop start stop exps ...)
(let ((j stop))
(let loop ((i start))
(when (<= i j)
exps ...
(loop (+ i 1))))))))
谢谢,这是可行的,编译时和运行时是有道理的,但是我没有看到您的第一个示例与我的第一个示例有什么本质上的不同。。。你的行得通,我的不行。根本的区别是,我的版本中的循环不是宏。letrec是在创建宏吗?或者是兰姆达?我不认为这是一个宏。哦,我在看你的最后一个例子,不是第一个。与第一个示例的根本区别在于,我没有将表达式传递到递归调用中。@milies使用第一个代码将(forloop a b c)
转换为(letrec((aloop)(lambda(x y z)(if(
(define-syntax forloop
(syntax-rules ()
((forloop start stop exps ...)
(if (<= start stop)
(begin exps ... (forloop (+ start 1) stop exps ...))))))
(forloop 6 8 (display "g"))
(define-syntax forloop
(syntax-rules ()
((forloop start stop exps ...)
(let ((j stop))
(let loop ((i start))
(when (<= i j)
exps ...
(loop (+ i 1))))))))
(define-syntax forloop
(syntax-rules ()
((forloop start stop exps ...)
(let ((j stop))
(do ((i start (+ i 1)))
((> i j))
exps ...)))))