如何在Racket宏中执行define以定义顶层函数?
生成Church编码的Racket宏问题
我正在尝试编写一个生成Church编码的Racket宏,目前的初始代码如下:
#lang racket (define-syntax data (syntax-rules () [(data _ (ctr args ...) ...) (let ((_ctrs (map car '((ctr) ...))) (_args '((args ...) ...))) (map (lambda (i) (let ((_ctr (list-ref _ctrs i)) (_args (list-ref _args i))) `(define (,_ctr ,@_args) (lambda (,@_ctrs) (,_ctr ,@_args))))) (range 0 (length _ctrs)))) ] )) (pretty-print (data option (some x) (none))
这段代码的输出符合预期:
(data option (some x) (none)) => ((define (some x) (lambda (some none) (some x))) (define (none) (lambda (some none) (none))))
但问题在于,输出里的define语句并没有实际执行,我需要让这些define在顶层环境中生效,定义对应的函数。
第一次修改后的错误
我尝试修改了宏代码:
(define-syntax data (syntax-rules () [(data _ (ctr args ...) ...) `(let ((_ctrs (map car '((ctr) ...))) (_args '((args ...) ...))) ,@(map (lambda (i) (let ((_ctr (list-ref _ctrs i)) (_args (list-ref _args i))) (define (,_ctr ,@_args) (lambda (,@_ctrs) (,_ctr ,@_args))))) (range 0 (length _ctrs)))) ] ))
执行(data option (some x) (none))时出现语法错误:
Error: struct:exn:fail:syntax begin (possibly implicit): the last form is not an expression at: (define ((unquote _ctr) (unquote-splicing _args)) (lambda ((unquote-splicing _ctrs)) ((unquote _ctr) (unquote-splicing _args)))) in: (begin (define ((unquote _ctr) (unquote-splicing _args)) (lambda ((unquote-splicing _ctrs)) ((unquote _ctr) (unquote-splicing _args)))))
我尝试用(expand #'(data option (some x) (none)))调试,但还是触发同样的错误。作为Racket新手,我也希望得到宏调试流程的建议。
更新后的代码与新问题
现在我写出了更接近需求的宏:
(define-syntax data (syntax-rules () [(data _ (ctr args ...) ...) #'((define (ctr) (lambda (ctr ...) (ctr args ...))) ...) ] ))
但如果移除代码里的#',会出现以下错误:
define: not allowed in an expression context in: (define (some) (lambda (some none) (some x)))
内容的提问来源于stack exchange,提问作者geckos
相关产品推荐
相关产品推荐

