for/继续方案/lisp
我正在Scheme(R5RS)中为类C语言编写一个小型解释器,并尝试将以下内容转换
for (i = 0; i < 100; i++)
{
if (isprime(i)) continue;
else /* do something with i */
}
为有效的Scheme(isprime函数只是一个示例,并不重要)。
然而,经过一段时间的尝试,我一直无法找到一种有效/简单的方法来将 continue 语句的等效项添加到 Scheme 中的 do 循环中。更好的是“for”宏,它允许使用“继续”和“中断”。
我正在考虑转向 Common Lisp。在 CL 中这种事情会更容易吗?
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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
我们可以将 FOR 写成宏。 Common Lisp 版本:
We can write FOR as a macro. The Common Lisp version:
CL 的
tagbody
是一个方便的目标:CL's
tagbody
is a convenient target:我会选择延续,就像这个伪方案示例一样。
只需将当前执行点存储在延续中,并在适当的时候调用它即可。
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.
我知道这已经晚了 8 年,但我认为这可能会对某人有所帮助。
使用 Common Lisp 中的
iterate
构造,您可以使用 next-iteration 子句: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:实现这一点的简单的方案方法就是重构你的代码:
如果
你的循环体是混乱的,并且你想从其内部深处
(继续)
或(break)
嵌套结构,要么让编译器以上述方式重组它,要么您可以使用 call/cc 设置退出点,例如Racket 具有分隔的延续,这应该更有效。
The straightforward Scheme way to achieve this is just to restructure your code:
is
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 withcall/cc
as e.g.Racket has delimited continuations which should be more efficient.
要在Scheme中实现这个特定的代码示例,您不需要
continue
、break
或call/cc
:To implement this particular code sample in Scheme, you don't need
continue
,break
orcall/cc
:我认为维杰的答案可以以一种有效的方式扩展(很抱歉回答我自己的问题,但无法弄清楚如何在评论中格式化代码):
它不是一个宏,但无疑会导致一个足够通用的宏。我很想看到任何改进。我对计划还很陌生。
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):
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.
您也可以使用 throw 和 catch (elisp):
You can use throw and catch as well (elisp):