首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在SISC方案的第一个参数中生成接受字符串的“定义”?

如何在SISC方案的第一个参数中生成接受字符串的“定义”?
EN

Stack Overflow用户
提问于 2014-04-26 02:40:22
回答 2查看 87关注 0票数 0

让我们把这个函数称为“动态定义”。

基本上,我想编写一个宏或lambda,其工作方式如下:

代码语言:javascript
复制
$ (dynamic-define "variable" 123)
$ variable
$ => 123

我试过:

代码语言:javascript
复制
(define-syntax dynamic-define
    (syntax-rules ()
      ((_ string <body>)
       (eval `(define ,(string->symbol string) <body>)))))

它如预期的那样工作,但似乎不是一个好的解决方案。

我试着用而不用像这样:

代码语言:javascript
复制
(define-syntax dynamic-define                                           
    (syntax-rules ()                                                            
      ((_ string <body>)                                                        
       (define (string->symbol string) <body>))))

但是当我尝试使用时,我得到了这个错误:

代码语言:javascript
复制
Error: invalid syntax (define (string->symbol "variable") 123)

我该怎么办?

(请:请编辑这个问题,以适应本族语,请删除这一行)

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-05-03 16:05:40

您遇到了一个根本的问题:您无法以“干净”的方式进行真正的动态定义,因此您尝试使用eval。请注意,上面两种解决方案都不是动态的--它们给您的只是编写"foo"而不是foo的能力。正如我在其他地方说过的,使用eval通常是不好的,而且在这种情况下更糟糕,因为从宏中使用的是eval,这使得它非常奇怪。这除了在宏中有一个隐含的准引用之外,还会使事情变得更加混乱。您可以将整个过程定义为一个简单的函数:

代码语言:javascript
复制
(define (dynamic-define string <body>)
  (eval `(define ,(string->symbol string) ,<body>)))

如果你真的需要这样做,那么最好退一步,想一想你到底需要什么。一方面,上述解决方案不是动态的,因为它们需要使用带有字符串语法的宏。

代码语言:javascript
复制
(dynamic-define "foo" 123) ; instead of (define foo 123)

但是,如果有一个包含字符串的真正的动态定义,情况会怎样呢?您可能会期望这样定义b

代码语言:javascript
复制
(define a "b")
(dynamic-define a 123)

但是,只有当您考虑到它如何与其他绑定交互时,这才会变得更加混乱。例如:

代码语言:javascript
复制
(define y 123)
(define (foo s)
  (define x 456)
  (dynamic-define s 789)
  (+ x y))

现在,假设dynamic-define完成了您希望它做的事情,那么考虑一下(foo "x")(foo "y")会得到什么。更糟糕的是,以(foo "s")(foo "+")为例。更糟糕的是,

代码语言:javascript
复制
(foo (random-element '("x" "y" "s" "+" "define")))

?显然,如果这个dynamic-define确实做了一些动态定义,那么如果您不提前知道调用foo的名称,就无法理解这段代码。没有这样的意义,编译就脱离了窗口--但更重要的是,正确性(或者通常,代码的意义)消失了。

根据我的经验,这种模式用哈希表和类似的设备处理要好得多。

票数 2
EN

Stack Overflow用户

发布于 2014-04-26 10:33:23

使用define-macro

代码语言:javascript
复制
#> (define-macro (dynamic-define varstr val)
      `(define ,(string->symbol varstr) ,val))

#> (dynamic-define "variable" 123)
#> variable
123

使用syntax-case

代码语言:javascript
复制
#> (define-syntax dynamic-define
     (lambda (stx)
       (syntax-case stx ()
         ((k varstr val)
          (with-syntax ([var (datum->syntax-object 
                              #'k
                              (string->symbol (syntax-object->datum #'varstr)))])
            #'(define var val))))))

#> (dynamic-define "variable" 123)
#> variable
123
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23305997

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档