Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/scheme/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Lisp 如何在方案中的评估中使用外部变量?_Lisp_Scheme_Eval - Fatal编程技术网

Lisp 如何在方案中的评估中使用外部变量?

Lisp 如何在方案中的评估中使用外部变量?,lisp,scheme,eval,Lisp,Scheme,Eval,我正在尝试一些有趣的计划。我试图创建一个区域函数,它获取它所操作的对象的类型,然后根据对象的类型调用不同的函数。这是我的密码: (define (area object) (if (not (null? (eval (word 'area- (get-type object))))) (eval (list (word 'area- (get-type object)) 'object)) #f ) ) Scheme不喜欢这样,因为它说object是一个未绑定的

我正在尝试一些有趣的计划。我试图创建一个区域函数,它获取它所操作的对象的类型,然后根据对象的类型调用不同的函数。这是我的密码:

(define (area object)
  (if (not (null? (eval (word 'area- (get-type object)))))
      (eval (list (word 'area- (get-type object)) 'object))
      #f
  )
)
Scheme不喜欢这样,因为它说object是一个未绑定的变量。不,我不能把引号拿走,因为它实际上是把值放在那里,然后Scheme抱怨列表格式不正确

如何在eval中使用对象中的值

注意:Scheme显然很好地抓住了全局变量“object”,所以它基本上忽略了它在函数中

这里有一些相关语言的信息:,这似乎表明Scheme中没有解决方案,但如果您知道,我想听听。

没有,这是一个特性
eval
对运行时动态生成的表单进行评估。因此,如果它需要了解本地绑定,那么您需要以不同的方式编译
(lamba(x)x)
(lambda(y)y)
,因为名称很重要。但这只是一个提示,在实现这种特性方面有一大堆问题

至于你的问题——即使有可能做你想做的事,这也是一个脆弱的解决方案,取决于名字。请记住,在Scheme中,您可以像使用任何其他值一样使用函数——因此,不要调用
get type
并将其与某个符号组合以获得名称,而是让您的对象包含所需的函数(此时最好称之为“方法”)

比如:

(define (area object)
  ((get-area-method object) object))
显然,这样做意味着不完全采用以下方式没有什么意义:

(define (area object)
  (get-area object))
这只是

(define area get-area)
但是第一种可能更典型于一般的面向对象系统,它有一种获取方法的方法,因此它可能对您有用。这个方向可以带你去:

(define (area object)
  ((get-method object 'get-area) object))
没有,这是一个特性
eval
对运行时动态生成的表单进行评估。因此,如果它需要了解本地绑定,那么您需要以不同的方式编译
(lamba(x)x)
(lambda(y)y)
,因为名称很重要。但这只是一个提示,在实现这种特性方面有一大堆问题

至于你的问题——即使有可能做你想做的事,这也是一个脆弱的解决方案,取决于名字。请记住,在Scheme中,您可以像使用任何其他值一样使用函数——因此,不要调用
get type
并将其与某个符号组合以获得名称,而是让您的对象包含所需的函数(此时最好称之为“方法”)

比如:

(define (area object)
  ((get-area-method object) object))
显然,这样做意味着不完全采用以下方式没有什么意义:

(define (area object)
  (get-area object))
这只是

(define area get-area)
但是第一种可能更典型于一般的面向对象系统,它有一种获取方法的方法,因此它可能对您有用。这个方向可以带你去:

(define (area object)
  ((get-method object 'get-area) object))

显然,在这个计划中,有一种方法可以实现我想做的事情。代码如下:

(define (area object)
  ((eval (list 'identity (word 'area- (get-type object)))) object)
)
基本上,技巧是这样的:因为eval只知道全局变量,所以我仍然可以使用eval中的identity函数返回全局变量的值。在这个例子中,我感兴趣的全局变量是一个函数,它和其他变量一样。然后我可以返回这个值,并将其用作调用原始参数的过程。这使我能够构造我想要从全局范围中获取的变量的名称,并获取和使用该变量中包含的过程,从而实现我想要的结果

这里有一个更简洁的版本:

(define (area object)
  ((get-function (word 'area- (get-type object))) object)
)

(define (get-function function)
  (eval (list 'identity function)))

显然,is not null部分将不起作用,但是,因为尝试获取不存在的函数的标识会导致未绑定变量错误。因此,仍然需要小心调用支持它的类型上的运算符。

显然有一种方法可以实现我在Scheme中想要做的事情。代码如下:

(define (area object)
  ((eval (list 'identity (word 'area- (get-type object)))) object)
)
基本上,技巧是这样的:因为eval只知道全局变量,所以我仍然可以使用eval中的identity函数返回全局变量的值。在这个例子中,我感兴趣的全局变量是一个函数,它和其他变量一样。然后我可以返回这个值,并将其用作调用原始参数的过程。这使我能够构造我想要从全局范围中获取的变量的名称,并获取和使用该变量中包含的过程,从而实现我想要的结果

这里有一个更简洁的版本:

(define (area object)
  ((get-function (word 'area- (get-type object))) object)
)

(define (get-function function)
  (eval (list 'identity function)))
显然,is not null部分将不起作用,但是,因为尝试获取不存在的函数的标识会导致未绑定变量错误。因此,仍然需要小心呼叫支持它的类型的操作员。

Racket有,您应该使用它

(define circle%
  (class object%
    (init radius)
    (define r radius)
    (super-new)
    (define/public (area)
      (* pi r r))))

(define rectangle%
  (class object%
    (init width height)
    (define w width)
    (define h height)
    (super-new)
    (define/public (area)
      (* w h))))

(define unit-circle (new circle% [radius 1]))
(define unit-square (new rectangle% [width 1] [height 1]))

(send unit-circle area)   ; => 3.141592653589793
(send unit-square area)   ; => 1
比基于姓名的发送要简单得多。

Racket有,你应该使用它

(define circle%
  (class object%
    (init radius)
    (define r radius)
    (super-new)
    (define/public (area)
      (* pi r r))))

(define rectangle%
  (class object%
    (init width height)
    (define w width)
    (define h height)
    (super-new)
    (define/public (area)
      (* w h))))

(define unit-circle (new circle% [radius 1]))
(define unit-square (new rectangle% [width 1] [height 1]))

(send unit-circle area)   ; => 3.141592653589793
(send unit-square area)   ; => 1

比基于姓名的发送要简单得多。

这是非常错误的。从使用
'identity
是多余的这一事实开始(你可以直接
评估
符号——同样的结果),然后你就得到了
get function
的“干净”版本,它本身只是一个identity函数。但是我如何评估构造的符号呢?可能(eval)(list)(append something?问题是,eval从列表构造一个过程,所以如果我(eval'thing)它真的调用(thing)而不带参数,而不是只返回thing的值。不,那是错误的。
(eval'x)
只返回全局
x
的值,它不调用任何函数。(但看看我的答案——你不应该用
eval
来做这样的事情。这肯定是一个糟糕的解决方案。)很好,我以为eval在评估它,但那是因为我在一个列表中传递它,使eval调用I