Functional programming 在公共Lisp中求值
Functional programming 在公共Lisp中求值,functional-programming,lisp,eval,common-lisp,Functional Programming,Lisp,Eval,Common Lisp,我不熟悉lisp,下面是我的问题: 我有一个类似的清单 ((a ((length 3) (size 5))) (b ((length 5) (size 7))))... 上面的列表只是一个示例。 我想要的是一个函数find,它可以像数据库查询一样工作 (find (and (gt length 4) (lt size 8))) 在这种情况下,上述函数应该为我找到b。请注意,此函数的条件参数可以用和或或展开。。。 我做了一些研究,知道eval可以在某种程度上帮助我,但我不确定它到底是如何工作的
我不熟悉lisp,下面是我的问题:
我有一个类似的清单
((a ((length 3) (size 5))) (b ((length 5) (size 7))))...
上面的列表只是一个示例。
我想要的是一个函数
find
,它可以像数据库查询一样工作
(find (and (gt length 4) (lt size 8)))
在这种情况下,上述函数应该为我找到b
。请注意,此函数的条件参数可以用和或或展开。。。
我做了一些研究,知道eval
可以在某种程度上帮助我,但我不确定它到底是如何工作的。
有人能给我举个例子或给我一些提示吗
谢谢我不会为此使用eval。但这样做相对容易
您有一系列项目:
((a ((length 3) (size 5)))
(b ((length 5) (size 7))))
您有一个测试描述,如下所示:
(and (> length 4) (< size 8))
现在应该很容易写出我的等号了
你可以把它当作
(find term sequence :test #'my-equal :key #'second)
请注意,对从流中读取的任意代码进行评估是一种安全风险
奖金
我们可以使用COMPILE
而不是EVAL:
(defun lookup (v bindings)
(let ((result (assoc v bindings)))
(if result
(second result)
(error "variable ~a not known" v))))
(defparameter *query-operators* '(and or > < =))
(defun generate-query-code (q bindings)
(cond ((numberp q) q)
((symbolp q) `(lookup ',q ,bindings))
((consp q)
(destructuring-bind (op . args)
q
(if (member op *query-operators*)
`(,op ,@(mapcar (lambda (arg)
(generate-query-code arg bindings))
args))
(error "Unknown op ~a" op))))))
(defun compile-query (q)
(compile nil
(let* ((bindings (gensym "bindings"))
(code (generate-query-code q bindings)))
`(lambda (,bindings)
,code))))
(defun find-query (query descriptions)
(find-if (compile-query query)
descriptions
:key #'second))
(defun查找(v绑定)
(let((结果(关联v绑定)))
(如有结果)
(第二个结果)
(错误“变量~a未知”v)))
(defparameter*查询运算符*'(和或><=)
(定义生成查询代码(q绑定)
(条件((编号q)q)
((symbolp q)`(lookup',q,bindings))
((消费q)
(解构绑定(op.args)
Q
(如果(成员op*查询运算符*)
`(,op,@(地图车(阿格州)
(生成查询代码参数绑定))
args)
(错误“未知op~a”op()()))
(定义编译查询(q)
(无
(let*((绑定(gensym“绑定”))
(代码(生成查询代码q绑定)))
`(λ(,绑定)
,代码)))
(定义查找查询(查询描述)
(查找if(编译查询)
描述
:键(秒)
例如:
CL-USER 39 > (find-query '(and (> length 4) (< size 8))
'((a ((length 3) (size 5)))
(b ((length 5) (size 7)))))
(B ((LENGTH 5) (SIZE 7)))
CL-USER 39>(查找查询“(和(>长度4)(
这篇博文似乎与您的问题有关:
(您必须使用长度
和大小
与每个记录的实际值之间的小映射来展开它,以便可以对每个记录调用闭包链)
(defun lookup (v bindings)
(let ((result (assoc v bindings)))
(if result
(second result)
(error "variable ~a not known" v))))
(defparameter *query-operators* '(and or > < =))
(defun generate-query-code (q bindings)
(cond ((numberp q) q)
((symbolp q) `(lookup ',q ,bindings))
((consp q)
(destructuring-bind (op . args)
q
(if (member op *query-operators*)
`(,op ,@(mapcar (lambda (arg)
(generate-query-code arg bindings))
args))
(error "Unknown op ~a" op))))))
(defun compile-query (q)
(compile nil
(let* ((bindings (gensym "bindings"))
(code (generate-query-code q bindings)))
`(lambda (,bindings)
,code))))
(defun find-query (query descriptions)
(find-if (compile-query query)
descriptions
:key #'second))
CL-USER 39 > (find-query '(and (> length 4) (< size 8))
'((a ((length 3) (size 5)))
(b ((length 5) (size 7)))))
(B ((LENGTH 5) (SIZE 7)))