如何在Racket中通过模板命名循环定义多个变量?
按命名规则批量定义顶层变量的宏实现
我需要重构这类模式:按指定命名规则定义多个顶层变量。现有可正常运行的代码如下:
#lang racket (define ((f-x/y x y) z) ;; 示例代码 (list x y z)) (match-define (list f-a/a f-a/b f-a/c f-b/a f-b/b f-b/c f-c/a f-c/b f-c/c) (for*/list ([x '(a b c)] [y '(a b c)]) (f-x/y x y))) (f-b/a 'd) ;; => '(b a d)
该问题的核心需求有两点:
- 让循环内定义的变量能在外部可见(突破词法作用域限制)
- 按模板自动生成变量名,
format-id看起来是正确的技术方向
理想的实现方式类似以下概念性代码:
(require racket/syntax) ;; 概念性代码 (for*/defs ([x '(a b c)] [y '(a b c)]) (define (format-id #'x "f-~a/~a" x y) (f-x/y x y)))
说明:所有'(a b c)的元素在编译时是固定已知的,现有代码能正常运行,但我希望学习解决此类问题的宏技术。
更新:最终实现变体
我基于Shawn的答案实现了一个变体:
(require (for-syntax racket/syntax syntax/parse)) (define-syntax (define-all-options stx) (syntax-parse stx [(_ f:id (sym:id ...)) (for*/lists (ids defs #:result #`(begin (define-values (sym ...) (values 'sym ...)) (define-values #,ids (values #,@defs)))) ([x (in-list (syntax->list #'(sym ...)))] [y (in-list (syntax->list #'(sym ...)))]) (values (format-id stx "f-~a/~a" x y) #`(f #,x #,y)))])) (define ((f-x/y x y) z) (list x y z)) (define-all-options f-x/y (a b c)) (println (f-a/b 'd))
内容的提问来源于stack exchange,提问作者Gregory T
相关产品推荐
相关产品推荐

