Racket 骗局:你如何使用一个参数的值作为一个符号?
我是个新手,正在努力寻找合适的词语来解释我要做的事情。我能想到的最好办法是:如何使用参数的值作为符号,而不调用与参数值同名的函数,也不只是引用参数的名称 这里有一个简单的例子来说明这一点 有一个名为Racket 骗局:你如何使用一个参数的值作为一个符号?,racket,Racket,我是个新手,正在努力寻找合适的词语来解释我要做的事情。我能想到的最好办法是:如何使用参数的值作为符号,而不调用与参数值同名的函数,也不只是引用参数的名称 这里有一个简单的例子来说明这一点 有一个名为ul的函数,它执行一些操作 还有另一个名为生成列表的函数,它有一个参数,列表类型 还有第三个函数,makeul,它使用参数ul调用makelist 在true分支中,应用函数ul。到目前为止还不错 在false分支中,我希望能够使用参数值作为符号,在本例中,参数值是'ul。实际上,这行代码将运行(λa
ul
的函数,它执行一些操作
还有另一个名为生成列表
的函数,它有一个参数,列表类型
还有第三个函数,makeul
,它使用参数ul
调用makelist
在true分支中,应用函数ul
。到目前为止还不错
在false分支中,我希望能够使用参数值作为符号,在本例中,参数值是'ul
。实际上,这行代码将运行(λargs(list*'ul args))
。我如何做到这一点
#朗球拍
(定义(ul.xs)`(div,@xs))
(定义(制作列表类型)
(如果(相等?“某物”或其他)
(λargs(应用列表类型args));真分支:调用函数“ul”
(λargs(列表*列表类型args));false branch:如何在不调用“ul”函数的情况下使用`ul?
(定义制造ul(制造列表ul))
如果你的目标是写出好的拍子代码,那么最好的答案就是不要。
添加单独的参数以获取符号,如下所示:
;; make-list : Procedure Symbol -> Any ... -> Any
(define (make-list proc tag-sym)
(if ....
proc ;; (λ args (apply proc args)) simplifies to just proc
(λ args (list* tag-sym args))))
(define make-ul (make-list ul 'ul))
或者,如果分支独立于args
,则可以只使用一个(U过程符号)
类型的参数:
;; make-list : (U Procedure Symbol) -> Any ... -> Any
(define (make-list list-type)
(cond [(procedure? list-type)
;; (λ args (apply list-type args))
list-type]
[(symbol? list-type)
(λ args (list* list-type args))]))
(define make-ul (make-list ul))
(define make-li (make-list 'li))
如果你想探索球拍的特点,有两种主要的方法
制作列表的第一个版本:
(define-syntax-rule (make-list* proc-name) (make-list proc-name (quote proc-name)))
(define make-ul (make-list* ul)) ;; => (define make-ul (make-list ul 'ul))
对象名称
,询问Racket认为它的名称是什么。例如,(对象名称列表)
返回'list
,而(对象名称ul)
应返回'ul
。但是(对象名make-ul)
不会返回'make-ul
,因为Racket在编译时跟踪名称,而不是在运行时。(我建议不要编写依赖于对象名称的代码;这会使代码非常脆弱。)
我真的很感谢你的回答。你不仅解决了这个问题,还帮助我从不同的角度思考这个问题。我现在已经阅读了有关宏的内容,可以看到它们将如何解决这个问题,但如何添加一个额外的参数将是最简单的解决方案。再次感谢你!