gpt4 book ai didi

scheme - 如何在方案中将列表转换为代码/lambda?

转载 作者:行者123 更新时间:2023-12-04 22:34:20 25 4
gpt4 key购买 nike

假设我有一个列表,例如:(define a '(+ (* p p) (* x x))) .
如何使用 a 给出的表达式定义过程,例如这里:(define (H x p) (+ (* p p) (* x x)))) ?
我试图做类似的事情:(define (H x p) (eval a))但它说px是未定义的。我想,apply 有一个简单的解决方法或类似的东西,但我无法理解它。
我想我可以修改px根据传递给过程 H 的值在我的列表中然后评估新列表,但它有点难看......或者也许有一个漂亮的方法来做到这一点?

最佳答案

Racket 中的解决方案
您尝试做的实际上是将预定义的函数体列表构造注入(inject)函数定义(宏)调用的主体。

(define expr '(+ (* p p) (* x x)))

(eval `(define (fun x p) ,expr))
如果您离开 (eval ...)层,你看:
`(define (fun x p) ,expr)
;; '(define (fun x p) (+ (* p p) (* x x)))
该代码实际上由 eval 评估.
从此 eval发生在全局环境层面,无需担心任何副作用。
以下是我使用 define-expr 的更复杂的解决方案宏。
他们解释了为什么它如此难以解决。
毕竟,我看到实际上只需要一个 (eval `(define (<args>) ,expr)构造并且实际上没有额外的宏。
Racket 中的复杂解决方案
你也可以在 Racket 中做到这一点:
(define expr '(+ (* p p) (* x x)))

(define-syntax-rule (define-expr args expr)
(define args expr))

(eval `(define-expr (fun x p) ,expr))
此调用在后台执行:
(define (fun x p) (+ (* p p) (* x x)))
您尝试做的实际上是一个动态宏。
问题是你必须给
运行时的函数体代码。
不知何故,您需要通过比宏的其余部分更多的评估来评估函数体表达式。
因此,有必要将宏调用包装成 (eval `<macrocall ,component-to-be-evaluated-once-more>)我称这个结构为 eval-over-macro-call .
在此之后,您可以调用如此定义的 fun功能:
(fun 3 4) ;; 25
常见的口齿不清
就个人而言,我更喜欢 common lisp 的宏系统。它更直接。
(defparameter *expr* '(+ (* p p) (* x x)))

(defmacro defun-expr (fnname args expr)
`(defun ,fnname ,args ,expr))

(macroexpand-1 '(defun-expr fun (x p) *expr*)) ;; doesn't work
;; (DEFUN FUN (X P) *EXPR*) ;
;; T
;; you can see, that *EXPR* actually has to be evaluated once more

(macroexpand-1 `(defun-expr fun (x p) ,*expr*)) ;; this however is correct
;; (DEFUN FUN (X P) (+ (* P P) (* X X)))

;; Thus when you call the macro, you have to execute it using eval:
(eval `(defun-expr fun (x p) ,*expr*))
;; FUN ;; function is defined!

(fun 3 4) ;; 25
由于我对 Racket 的宏系统不太熟悉,所以我在 common lisp 中使用了伟大的 macroexpand-1 进行了宏构造。它显示了宏执行的代码结构。然后转/猜出对应的 define-syntax-rule在 Racket 。
在 Racket 中, macroexpand-1(syntax->datum (expand-once '<macrocall>)) :
(syntax->datum (expand-once `(define-expr (fun x p) ,expr)))
;; '(define (fun x p) (+ (* p p) (* x x)))

关于scheme - 如何在方案中将列表转换为代码/lambda?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68188119/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com