问题标签 [lisp-macros]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
1 回答
182 浏览

macros - 如何在方案中编写带有双准引号的 LISP 宏

我需要在方案中编写 lisp 宏(请参阅卫生宏和语法规则等),它将函数调用和 Alist 作为参数

我希望调用该函数的函数和宏具有如下语法:

或不带引号的宏。

我的最后一个代码正在运行,但不确定这是否是你想像这样编写函数/宏的方式。看来我需要双反引号,但不知道怎么写。(我现在正在阅读 Paul Graham 的 On Lips,他说双反引号非常困难,只有定义宏的宏才需要,但似乎这就是我需要的)。

这是pair-map的定义

(string->symbol "quasiquote")我不能使用双反引号,这可以用双反引号/准引号写吗?这应该是什么样子?

我在问这是否可以用不同的方式编写,这样我就可以在我自己的 lisp 解释器中解决一些问题(不确定是否工作正常,但似乎这个最终版本在 guile 中的工作方式相同)。

0 投票
1 回答
250 浏览

macros - 这个反引号“语法”如何在 lisp 中工作?

这是 Paul Graham 的 On Lisp 一书中的简化示例(类似于语法的方案)。

我知道,,@y应该如何工作,但不确定,',z应该如何工作,首先应该评估什么以及以什么顺序。(我知道它应该评估为符号 foo 因为它(10 (foo 1 2 3))以诡计返回,但我不确定确切的步骤是什么)。

我在 JavaScript 中的 lisp 中需要这个,我得到了结果:

因为它只是从左到右评估它(我只处理特殊,,和更多的逗号)。你应该如何评估这个表达式。

书中也有这样的例子:

应该如何',',评价?这种情况下的步骤是什么?

是否还有其他带有反引号/准引号的奇怪边缘情况?您能否展示这些示例以及应如何评估它们以及以什么顺序进行评估?

0 投票
2 回答
82 浏览

common-lisp - 引用宏定义宏

我正在尝试编写一个宏来定义数组结构数据结构的一些帮助程序(基于代码段)。在该宏中,我定义了另一个宏,它有助于遍历 struct 中的所有槽值。问题是我无法使双重取消引用正常工作。这是代码:

因此,例如(defcomponent buzz x y)宏扩展为

这有点工作,但我想访问components内部with-buzz宏的参数,即像这样

我怎么可能做到这一点?我已经尝试了很多的组合,,@无济于事。

0 投票
3 回答
686 浏览

macros - lisp 宏来构建表达式列表及其评估

我正在尝试在 Common Lisp 中编写一个宏,它接受任意数量的表达式并构建一个列表,其中包含每个表达式,然后在一行中对其进行评估。例如,如果我将宏命名为

我跑

我希望它返回:

到目前为止,我能做的最好的事情是使用代码获取表达式列表

0 投票
2 回答
158 浏览

clojure - clojurescript 中的宏 - 无法正确展开

我在clojure中创建了一个宏

在 clojure repl 中它按预期工作

所以我创建了一个这样的 clojurescript 模块来尝试使用它:

当我在repl中尝试时,我得到了这个

同时回到clojure,有一个线索为什么这可能是

我可以创建以'(而不是(list. 但是,我希望在构建时扩展地图。

到底是怎么回事?我该怎么做才能获得以下内容:

或者我应该怎么做才能在 clojurescript 中使用这个宏?

0 投票
1 回答
103 浏览

scheme - 在 Scheme 中处理 lisp 宏中引用符号的标准方法

对于我正在工作的一些代码,我需要在宏中处理'x。处理这些值的标准方法是什么?

我有这样的代码:

这是应该如何处理的,还是只是在宏中你不使用带引号的符号?

注意:我不是在问卫生宏(我问的是真正的 lisp 宏),所以请不要回答卫生宏。

编辑

我的宏在 Guile 和 BiwaScheme 以及我自己的方案(如 JavaScript 中的 lisp)中正常工作。这是更好的例子:

问题不是关于display,而是关于(cadr x)

EDIT2:你已经问过了,我的宏:

该宏在我的方案中使用,如 JavaScript 中的 lisp,如文档字符串建议:

我要支持:

该代码可以在线测试:https ://jcubic.github.io/lips/ (您需要复制/粘贴代码,因为当前版本只允许方法调用)。

要获得扩展,您可以使用

如果它不起作用(不要扩展),则意味着宏以某种方式损坏。

dot 是内置函数,可获取对象和..宏的属性:

可用于获取嵌套属性,例如(.. document.body.innerHTML)

0 投票
1 回答
53 浏览

common-lisp - 如何在 Lisp 的宏中修复“X 不是数字”

我开始学习 lisps,目前正在为学校开发宏。我在一个名为 decrement.txt 的 txt 文件中创建了一个名为“-=”的简单宏

所以传递的参数是 numericValue(将被递减的值)和 decrementValue(numericValue 将被递减的数量)

当我在 CLISP(即 GNU CLISP 2.49)中运行代码时,我运行它如下...

“X不是数字”是什么意思,这与宏如何不知道变量的实际值有关吗?因为当我输入USE-VALUE并输入 5(X 应该是这个值)时,它运行得非常好,即使我(print x)将 x 显示为 4,因为它在函数中被递减了。所以值会发生应有的变化,但是当我最初运行该“-=”函数时,它会给出该错误,我该如何解决?

0 投票
1 回答
581 浏览

scheme - Scheme中的letrec-syntax和let-syntax有什么区别?

有类似的问题,但没有语法宏,但我认为不同之处在于一个宏看不到另一个,如 letrec 和 let 函数。

但这与 letrec-syntax 和 let-syntax 相同

你能展示这两个宏/语法不同的代码示例吗?

编辑:

发现这个:

不适用,let-syntax它适用于letrec-syntax,但这有什么好处?如果那些局部变量不能是函数(输出是(bar x)),那么 的目的是let-syntax什么?我需要可以在代码中使用它的示例,在不需要的地方letrec-syntax,它就足够了let-syntax

0 投票
2 回答
161 浏览

macros - 同名的 Common Lisp 局部阴影函数

我以前不止一次有过这个问题。

一般问题

是否可以使用同名的包装器透明地在本地隐藏一个函数ff

即,如何在本地将 (f Wrapped-args...) 扩展为 (f args...)?

Flet 似乎让我们这样做,但有局限性,即生成的包装器不是可设置的。是否有可能在不诉诸弗莱特的情况下做到这一点?

理想情况下,会有一个宏让我们编写“包装”f调用,并将代码扩展为原始“非包装”f调用。

起初我认为macrolet 可能是这样,因为它在文档中说它首先扩展宏,然后在扩展的表单上应用 setf,但我无法使用它(请继续阅读下文)。

动机

这在某些参数是隐式的并且不应该一遍又一遍地重复的上下文中很有用,以获得更多的 DRY 代码。

我之前的问题(let-curry)中有一个特殊的例子。尝试“自动”分配函数的一些参数(let-curry)。

弗莱特的注意事项

我在那里得到了一些很好的答案,但是,我遇到了一些限制。通过使用 flet 来完成函数名到其上的包装器的这种局部“阴影”,这种包装器是不可设置的,因此,这种包装器不能像原始函数那样灵活地使用,只能读取值,而不是写入.

具体问题

通过上面的链接,如何编写宏 flet-curry 并使包装函数可以设置?

奖励:该宏能否以 0 运行时开销将包装调用扩展为原始调用?

我尝试在那篇文章中选择答案并使用宏而不是 flet 无济于事。

谢谢!


更新

我被要求为这个通用问题举一个具体的例子。

代码中的愿望注释:

这意味着我想let-curry将该块中的咖喱函数的任何调用从

  1. (f arg1 arg2 ...)
  2. (f scanner arg1 arg2 ...)

就好像我在源代码中写了后一种形式而不是前者一样。如果某些“宏”是这种情况,那么它可以通过设计来设置。

似乎宏将是正确的工具,但我不知道如何。

再次感谢 :)

PS:如果您需要访问完整代码,请访问:https ://github.com/AlbertoEAF/cl-lox (scanner.lisp)

0 投票
3 回答
105 浏览

loops - 在 defmacro 中使用循环

我正在学习(普通)Lisp,作为练习,我想实现一个cond宏“xond”,它可以改变这个愚蠢的例子:

进入 if-else 链:

目前,我有这个宏:

只是扩展前两项x

生产

现在我想处理 中的所有项目x,所以我添加了一个loop来生成一个 if-serie(迈向 if-else-version 的一步):

但随后宏似乎停止工作:

我在这里缺少什么?

verdammelt 的回答让我走上了正确的道路,而 coredump 让我改变了我的迭代方法。

现在我将实现(xond test1 exp1 test2 exp2)为:

这可以通过迭代来完成。

我正在为我的最小 Lisp 解释器写这个;我只实现了最基本的功能。

这是我写的。我la用来累积输出的部分。

结果:

第二版

添加标签block并更改returnreturn-from,以避免与其他return内部参数冲突。还更改pushappend以与参数相同的顺序生成代码。

所以

现在给