我需要一些功能,其中包括一个新的全局符号。所以我可以像这样使用它:
(define (func-prototype symbol value comment)
(define symbol value) ; this should somehow be reformulated
(format "~a=~a !~a\n" symbol value comment))
(define string-list (map func-prototype
'((s1 1 "first value")
(s2 20 "second value")
(s3 300 "third value))))
并且能够获得以下结果:
> string-list
'("s1=1 !first value\n"
"s2=20 !second value\n"
"s3=300 !third value\n")
> s1
1
> s2
20
> s3
300
这可以作为一个函数实现,还是只有在宏的帮助下才能实现?您能否建议任何可能的实施或至少提供一些可能有用的提示/参考?
答案 0 :(得分:3)
我会重新考虑一般方法,使其更简单。我的建议:定义一个全局哈希表,并在函数内部添加绑定,例如:
(define value-map (make-hash))
(define (func-prototype symbol value comment)
(hash-set! value-map symbol value)
(format "~a=~a !~a\n" symbol value comment))
像这样使用:
(define string-list
(map (lambda (lst)
(apply func-prototype lst))
'((s1 1 "first value")
(s2 20 "second value")
(s3 300 "third value"))))
string-list
=> '("s1=1 !first value\n"
"s2=20 !second value\n"
"s3=300 !third value\n")
无论您何时需要引用哈希表中的一个符号,请执行以下操作:
(define (get key)
(hash-ref value-map key))
(get 's1)
=> 1
(get 's2)
=> 20
(get 's3)
=> 300
答案 1 :(得分:2)
一般来说,不可能按照你描述的方式完成你想要完成的任务。您唯一的希望是将文件写入文件,然后将load
该文件写入交互式会话。但即便如此。
在计划中,您无法引入顶级名称,例如您所需的s1
,s2
和s3
,但顶级名称除外。为此,您可以将宏定义为:
>(define-syntax define-foo
(syntax-rules ()
((_ name value)
(define name value))))
>(define-foo s1 1)
<undefined>
> s1
1
如果你试图在一个函数中使用那个宏,它就没有骰子,因为函数的主体必须以一个表达式和任何定义形式结束,就像上面的宏会扩展到的那样,成为局部变量。那就是:
(define (func-prototype name value comment)
(define-foo name value)
name)
>(func-prototype 's1 1 "com")
1
> s1
<error>
如果你的字符串列表是一个常量,你可以采取的一种方法是:
> (define-syntax declare-variables
(syntax-rules ()
((_ (name value comment) ...)
(begin
(define name value)
...))))
> (declare-variables (s1 1 "com") (s2 20 "com") (s3 300 "com"))
> s1
1
这样就完成了(我已经忽略了使用'comment')但是,正如我所说,需要一个编译时字符串列表。
您认为可行的一种可能性,但不会,将eval
用作:
(eval '(define s1 1) (environment ...))
但'eval'仅适用于表达式,不适用于声明。这使我回到“加载”的可能性。
答案 2 :(得分:2)
首先,考虑一下你是否真的想要这样做,或者一个不同的解决方案(如哈希表)是否也能正常工作。
您可以使用eval
程序使用reflection and dynamic evaluation执行此操作。
;; define-variable-with-value! : symbol any -> void
(define (define-variable-with-value! name value)
(eval `(define ,name (quote ,value))))
quote
很重要;否则,您有可能将值重新解释为表达式以进行评估。要查看差异,请考虑示例
(define-variable-with-value! 'x (list 'error "kaboom"))