- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我想使用已经过宏扩展和非宏扩展的 Emacs Lisp 代码。我在 Emacs 论坛上问过这个问题,但没有成功。看: https://emacs.stackexchange.com/questions/35913/program-rewriting-systems-unexpanded-a-defmacro-given-a-list-of-macros-to-undo
然而,人们会认为这种东西,S 表达式转换,是 Lisp 的拿手好戏。我相信 defmacro
在 Lisp 中可用,就像在 Emacs Lisp 中一样。
所以肯定有程序转换系统或术语重写系统可以在这里进行调整。
理想情况下,在某些情况下,这样的工具将能够直接脱离 defmacro
进行模式查找和替换。然而,即使我必须手动提出特定的搜索和替换模式以添加到转换系统中,拥有这样一个工作框架仍然很有用
到目前为止的结果摘要: 虽然已经有一些探索有趣可能性的答案,但目前还没有确定的答案。所以我认为最好保持开放状态。我将总结一些建议。 (我对所有实际上是答案的答案都投了赞成票,而不是对困难的评论。)
首先,许多人建议考虑仅进行扩展的特殊形式的宏,或者如 Drew 所说:
macro-expansion (i.e., not expansion followed by Lisp evaluation). Macro-expansion is another way of saying reduction semantics, or rewriting.
在我看来,目前的领跑者是 phils post,他使用了似乎特定于 Emacs 的模式匹配工具:pcase
。我将对此进行探索,并将发布我的发现结果。如果其他人对此有想法,请插话。
Drew 编写了一个名为 FTOC 的程序,其目的是将 Franz Lisp 转换为 Common Lisp;谷歌搜索出现comp.lang.lisp posting
我发现了一个名为 optima 的 Common Lisp 包与 fare-quasiquote . Paulo 认为这可能不够强大,因为它不能开箱即用地处理回溯,但可以手动编程。尽管回溯的通用性可能不错,但我不认为在最常用的情况下我需要它。)
旁注:有些人似乎被引起我最初兴趣的特定应用程序推迟了。 (但请注意,在研究中,以最初未设想的方式应用好的解决方案并不少见。)
因此,本着这种精神,这里有一些更改最终应用程序的建议。一个好的解决方案可能会转化为 Emacs Lisp 的解决方案。 (如果可以帮助您假装我对 Emacs Lisp 不感兴趣,那我也无所谓)。假设我想为 clojure 或某些 Common Lisp 系统编写一个反编译器,而不是 Emacs Lisp 的反编译器。或者正如 Sylwester 的回答所建议的那样,假设我想自动重构我的代码,考虑到使用更简洁的宏的好处,这些宏已经存在或已经得到改进。回想一下,Emacs Lisp 曾一度没有“when”或“unless”宏。
最佳答案
30 多年前,我使用 macrolet
做过类似的事情。
(实际上,我使用了 defmacro
,因为我们只有 Common Lisp 的早期实现,还没有 macrolet
。但是 macrolet
是正确的用法。)
我没有将宏扩展代码翻译成它的扩展源代码,但想法几乎是一样的。我预计您会遇到一些不同的困难,因为您的翻译距离一对一更远。
我编写了一个从(当时的)Franz Lisp 到 Common Lisp 的翻译器,以帮助将大量现有代码移植到 Lisp+Prolog 机器项目中。当时的 Franz Lisp 只是动态作用域,而 Common Lisp 是(通常)词法作用域。
是的,显然没有自动翻译 Lisp 代码的通用方法(特别是),特别是考虑到它可以生成然后评估其他代码——但即使忽略这种特殊情况。许多函数非常相似,但存在词法/动态差异,以及一些看似相似的函数在语义上的显着差异。
对于任何想要使用翻译结果的人来说,所有这些都必须从一开始就被理解并视为理所当然。
不过,还有很多有用的事情可以做。如果生成的代码是 self 记录的,告诉你它是从什么派生的等等,那么当在结果上下文中时,你可以决定如何处理这个或那个可能很棘手的位(例如,手动重写它,从划伤或只是调整它)。在实践中,许多代码很容易从 Franz 转换为 Common - 它节省了大量的重新编程工作。
翻译程序是用 Common Lisp 编写的。它可以交互使用,也可以批量使用。当以交互方式使用时,它实际上提供了一个基于 Common Lisp 的 Franz Lisp 解释器。
该程序仅使用宏扩展(即,不扩展后跟 Lisp 求值)。 宏扩展是另一种表达缩减语义或重写的方式。
输入的 Franz-Lisp 代码通过函数定义映射宏进行宏扩展以生成 Common-Lisp 代码。翻译有问题的代码被标记(在代码中),并带有描述情况的描述/分析。
该程序称为 FTOC。我认为您仍然可以通过谷歌搜索 (ftoc lisp
) 找到它,或者至少可以找到它的引用资料。 (这是我编写的第一个 Lisp 程序,我仍然对这段经历内存犹新。这是学习 Lisp 方言和一般学习 Lisp 的好方法。)
玩得开心!
关于macros - Lisp源代码重写系统,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47145868/
是否可以传递带有宏触发器的字符串作为宏参数?请参阅下面的示例代码: options mprint; %let string5='%abc%def%'; %macro test(string); dat
我意识到我的代码的某个部分由看起来相似的方法组组成(就像我有多个三重奏:一个辅助函数被另外两个为程序员准备的函数调用)。我正在尝试编写一个宏来为我定义这三个函数,这样我需要做的就是调用宏。但我的尝试导
这个问题在这里已经有了答案: What can you do with Lisp macros that you can't do with first-class functions? (8 个回答
在 haxe 宏中,对于每个表达式,我们可以以 http://api.haxe.org/haxe/macro/Position.html 的形式获取它的位置。 : { file:String,
如果我评价 (def ^:macro my-defn1 #'defn) 定义了一个名为“my-defn1”的宏,我可以像使用“defn”一样使用它。 但是,如果我改为求值 (if true (de
我想知道这段代码输出背后的原因。我想不出答案。 #define f(a,b) a##b #define g(a) #a #define h(a) g(a) void main() { print
我正在尝试编写一个宏,该宏扩展为具有解构的 let 形式。我的问题是我想拥有以 let 形式定义的符号列表,包括通过解构获得的符号列表。 用例 我试图排除这种行为,例如验证: (let [a (foo
这段代码: macro FL(message) return @sprintf("%s:%d | %s", @__FILE__, @__LINE__, message) # line 2 en
此宏的目的是创建一个宏,该宏为访问关联列表的某个键提供名称。 (defmacro generate-accessor (key-symbol prefix) (let ((mac-name
在mcpp.exe --help Options available with only -@std (default) option: -@compat Expand recursive ma
鉴于: (define-syntax (test stx) (syntax-case stx () [(_ body ...) (with-syntax ([body0 (pro
Doug Hoyte 在他对 Let Over Lambda 的介绍中将 symb 函数定义为使用宏进行元编程的基本实用程序: 在剪辑中: (defun mkstr (&rest args) (w
我的代码需要两种模式,debug 和 verbose。我在头文件中将它们定义为, #define verbose TRUE #define debug TRUE 到目前为止,在我的代码中,我一直在使用
Set-macro-character 有一个名为 non-terminating-p 的可选参数。好像是用来表示读完宏字符后是否要读另一个字符,但是reader algorithm似乎忽略了这个论点
我一直在搜索,但几乎找不到关于 LibreOffice Basic 的信息 我有点习惯在 excel 中编写宏,但这次需要做一个循环,直到我到达第一个空列并且它需要在 libreoffice 中。 在
我正在尝试编写一个调用某些函数的宏。这些函数只能由宏使用,因此我将它们放在包装宏的 letfn 中。伪代码: (letfn [(fn-a [] ...) (fn-b [] ...)
我发现对于任何在 clojure.tools.macro 中编写类似 defn 的宏的人来说,这将是一个很棒的工具。图书馆:name-with-attributes功能。文档字符串说: To be u
假设: (defmacro testing (&optional var) `(list 'this 'is ,@(when (consp var) `('a 'list)))
在 SBCL 中,我可以使用以下内容获取函数的文档字符串: (documentation #'mapcar t) 但是,我不明白如何获取宏的文档字符串。例如,给定宏: (defmacro with-l
想了解 undef 和将宏定义为 0 之间的区别。谢谢。 最佳答案 #define MACRO 0 定义预处理器标记 MACRO成为文字 0 #undef MACRO 删除预处理器标记 MACRO 的
我是一名优秀的程序员,十分优秀!