- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在通过 l99 for lisp 学习 lisp。
这是来自 here ,我希望应用宏只是为了练习,用宏编写所有 ((x) (x (evaluate-boolean left bindings) (evaluate-boolean right bindings)))
。
(defun evaluate-boolean (expression bindings)
"Evaluates the boolean expression. Returns t or nil
expression := variable
| constant
| '(' operator expression expression ')'
| '(' not expression ')'
.
constant := 'true' | 'fail' .
variable := symbol .
operator := 'and' | 'or' | 'nand' | 'nor' | 'xor' | 'impl' | 'equ' .
bindings is a list of pairs (variable . constant)
"
(cond ((eq expression 'true) t)
((eq expression 'fail) nil)
((symbolp expression)
(let ((pair (assoc expression bindings)))
(if pair
(progn
(assert (member (cdr pair) '(true fail)))
(eql 'true (cdr pair)))
(error "No variable named ~A in the bindings." expression))))
((atom expression) (error "Invalid atom ~A in the expression." expression))
(t (case (length expression)
((2) (destructuring-bind (op subexpression) expression
(case op
((not) (not (evaluate-boolean subexpression bindings)))
(otherwise (error "Invalid operator ~A in ~A" op expression)))))
((3) (destructuring-bind (op left right) expression
(case op
((and) (and (evaluate-boolean left bindings) (evaluate-boolean right bindings)))
((or) (or (evaluate-boolean left bindings) (evaluate-boolean right bindings)))
((nand) (nand (evaluate-boolean left bindings) (evaluate-boolean right bindings)))
((nor) (nor (evaluate-boolean left bindings) (evaluate-boolean right bindings)))
((xor) (xor (evaluate-boolean left bindings) (evaluate-boolean right bindings)))
((impl) (impl (evaluate-boolean left bindings) (evaluate-boolean right bindings)))
((equ) (equ (evaluate-boolean left bindings) (evaluate-boolean right bindings)))
(otherwise (error "Invalid operator ~A" op)))))
(otherwise (error "Invalid expression ~A" expression))))))
我已经尝试了一些方法,但它们似乎都给出了报告缺少变量的错误。
我将如何实现宏
defmacro
,或者evaluate-boolean
函数中使用 macrolet
?我通常先用 defun
或 defmacro
测试东西,然后用 flet
替换它。对此有何建议?
最佳答案
因为你没有说你尝试了什么,我不知道你做错了什么,但我猜你可能试图用宏调用替换 CASE
中的个别案例?这不起作用,因为外部宏 (CASE
) 在内部宏之前展开,因此内部宏不能用于为外部宏生成语法(除非专门编写外部宏允许这样做,但这里不是这种情况)。
所以解决方案是编写一个宏,为您生成整个 CASE
。像这样的东西:
(macrolet ((ops-case (op-sym (&rest ops))
`(case ,op-sym
,@(loop for op in ops
collect `((,op) (,op (evaluate-boolean left bindings)
(evaluate-boolean right bindings))))
(otherwise (error "Invalid operator ~A" ,op-sym)))))
(ops-case op (and or nand nor xor impl equ)))
虽然我不相信这真的是个好主意。像这样的一次性宏往往会使您的代码更难理解,而且这也不会显着缩短代码。通常您会希望使用宏来抽象化代码中多次出现的模式。
更通用的方法可能是这样的:
(defmacro ecase-template (keyform template &body cases)
`(ecase ,keyform
,@(loop for case in cases
collect (sublis `((_ . ,case)) template))))
这通过用 case 中的值替换模板中的下划线来生成 case 表达式。例如:
CL-USER> (macroexpand-1 '(ecase-template op
((_) (_ (evaluate-boolean left bindings)
(evaluate-boolean right bindings)))
and or nand nor xor impl equ))
(ECASE OP
((AND)
(AND (EVALUATE-BOOLEAN LEFT BINDINGS) (EVALUATE-BOOLEAN RIGHT BINDINGS)))
((OR)
(OR (EVALUATE-BOOLEAN LEFT BINDINGS) (EVALUATE-BOOLEAN RIGHT BINDINGS)))
((NAND)
(NAND (EVALUATE-BOOLEAN LEFT BINDINGS) (EVALUATE-BOOLEAN RIGHT BINDINGS)))
((NOR)
(NOR (EVALUATE-BOOLEAN LEFT BINDINGS) (EVALUATE-BOOLEAN RIGHT BINDINGS)))
((XOR)
(XOR (EVALUATE-BOOLEAN LEFT BINDINGS) (EVALUATE-BOOLEAN RIGHT BINDINGS)))
((IMPL)
(IMPL (EVALUATE-BOOLEAN LEFT BINDINGS) (EVALUATE-BOOLEAN RIGHT BINDINGS)))
((EQU)
(EQU (EVALUATE-BOOLEAN LEFT BINDINGS) (EVALUATE-BOOLEAN RIGHT BINDINGS))))
关于macros - 我如何构造这个 lisp 宏?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37534842/
你们能帮帮我吗,这是我们的讲师给我们的教程问题,无论我们尝试了多少,我们实际上似乎都无法破解它。请帮忙 ; perform some type/error checking, ; then ca
在 Common Lisp 中编写、编译和测试一个函数,该函数接受一个列表并计算列表中正整数的总数。必须编译然后执行包含函数的 .lisp 文件。在编译该文件后开始传递它,列出要生成的结果的结果,从而
我是 Lisp 初学者,我很难理解为什么下面的代码会给我一个错误。 (dolist (elem '(mapcar mapcon)) (when (fboundp `
我听说 Lisp 可以让你重新定义语言本身,我也试图研究它,但没有任何地方明确的解释。有人有一个简单的例子吗? 最佳答案 Lisp 用户将 Lisp 称为 可编程编程语言 .用于符号计算 - 用符号计
Closed. This question is off-topic. It is not currently accepting answers. Learn more。 想改进这个问题吗Updat
这些是 cons 参数的不同组合的输出。我刚开始学习 lisp。有人可以帮我理解这些吗? Break 80 [81]> (CONS '(A) 'B) ((A) . B) Break 80 [81]>
这个问题不太可能帮助任何 future 的访问者;它只与一个小的地理区域、一个特定的时间点或一个非常狭窄的情况有关,这些情况并不普遍适用于互联网的全局受众。为了帮助使这个问题更广泛地适用,visit
我想问一下为什么这个功能不起作用... (defun nenum(ls) (cond ((null ls) nil) ((listp car(ls)) (nenum (rest ls)
如果我有一个原子,例如“a4”,我需要能够将 1 添加到“4”部分以使其成为 a5,但是因为它被认为是一个字符串,所以这是不可能的,所以如果我可以拆分 (a4 ) 到 ((a)(4)) 中,然后我可以
我有一个关于动态构建函数(或类似的东西)的问题。在 Java 中,我可以通过编程将一些 Source 写入字符串,编译该字符串并像函数一样执行它多次。 假设我有一些遗传算法来创建最佳代码以获取 n 个
我是 Common Lisp 的新手,正在学习教程,但无法全神贯注 (equal '(reverse (a b)) '(b a))) 返回零。 非常感谢您的协助。 M. 最佳答案 在 lisp 中引
我有一个使用列表表示的树。例如: (1 ((2 (3)) (3 (2)))) (2 ((1 (3)) (3 (1)))) (3 ((1 (2)) (2 (1)))))` 现在我需要在维护层次结构树的同
在此站点:http://www.gigamonkeys.com/book/practical-a-simple-database.html有如下列出的用户入口函数: (defun prompt-rea
我对 lisp 比较陌生,对在以下上下文中使用嵌套列表的最佳方法很好奇: 所以,我有以下功能: (defun get-p0 (points) (loop for (label x y) in
我正在为 CLOS 类编写一个函数,该函数反转所述类对象的列表元素。 我有一个返回反向列表的方法,但如何让它将对象的列表设置为该列表?我可以在存储列表的函数中有一个实例变量,然后将元素设置为那个吗?或
我知道,严格来说,没有编译语言或解释语言这回事。 但是,一般来说,LISP 是用来编写 Python、bash 脚本、批处理脚本之类的脚本的吗? 还是像 C++、JAVA 和 C# 这样的通用编程语言
在此站点 http://jatha.sourceforge.net/快速函数的示例是通过递归。是不是递归通常比 Lisp 中的迭代更快并且性能更好? 编辑:Lisp 是否比其他语言更优化递归? 最佳答
另一个新手(常见)LISP 问题: 基本上在大多数编程语言中,函数都有一种方法接收对变量的引用而不仅仅是值,即通过引用传递而不是通过值传递。比方说,为了简单起见,我想编写一个 LISP 函数来接收一个
这个问题在这里已经有了答案: How do I find the index of an element in a list in Racket? (3 个答案) 关闭 9 年前。 如果我有这样的列
我在为这个程序生成正确的输出时遇到了一些问题。我的输出几乎是正确的,但缺少一些步骤。我的代码如下: (defun kt (x y m n) ;set the
我是一名优秀的程序员,十分优秀!