为什么不对Scheme进行评估? [英] Why does this not evaluate in Scheme?

查看:61
本文介绍了为什么不对Scheme进行评估?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用DrRacket环境来试用Scheme语言.

I am using the DrRacket environment to try out the Scheme language.

我将sum + 1定义如下:

I defined sum+1 as follows:

(define sum+1 '(+ x y 1))

我想知道为什么以下表达式不求值:

I was wondering why the following expression does not evaluate:

(let ([x 1] [y 2]) (eval sum+1))

执行此操作将返回正确的值:

whereas doing this returns the correct value:

(define x 1)
(define y 2)
(eval sum+1)

推荐答案

eval 完全不适用于词法变量,除非在相同的表达式中创建了词法变量:

eval does not work with lexical variables at all unless the lexical variable was created in the same expression:

#!r7rs 
(import (scheme base)
        (scheme eval))

(define env (environment '(scheme base)))

(let ((x 10))
  (eval 'x env)) ; ERROR! `x` is not defined

您可以将其视为 eval ,它总是与传递给第二个参数的环境的全局绑定一起发生在顶层.您可以通过从词法环境中传递值来欺骗它,如下所示:

You can think of it as eval always happening top level with the global bindings of the environment you pass to the second argument. You can perhaps trick it by passing values from your lexical environment like this:

(eval '(let ((x 10))
         x)
      env) ; ==> 10


(let ((x 10))
  (eval `(let ((x ,x))
           x)
        env) ; ==> 10

在大多数Scheme实现运行代码时,通常会局部分配局部变量.因此,可以想象一下这段代码:

By the time most Scheme implementations run code local variables are usually stack allocated. Thus something imagine this code:

(define (test v)
  (display v)
  (newline)
  (eval 'v))

在运行时可能会变成这样:

Might turn into this at runtime:

(define (test 1 #f) ; indicates 1 argument, no rest
  (display (ref 0)) ; fetches first argument from stack
  (newline)
  (eval 'v))        ; but what is v?, certainly not the first argument

您还可以制作一些特殊情况.如果您突变,会怎样?

Also you can make corner cases. What happens if you mutate?

(define (test v)
  (eval '(set! v 10))
  v)

eval 的结构可能来自用户输入,因此 v 突变并不明显,而且许多编译Scheme实现也需要处理可变突变的变量,因此需要在代码运行之前就知道 v 需要特殊处理,但这是不确定的,因为(set!v 10)可能来自数据库或用户输入.因此,通过不包括本地绑定,您可以避免很多麻烦,并且可以更轻松地优化和编译该语言.

The structure to eval might come from user input so it's not obvious that v gets mutated, also many compiling Scheme implementations need to treat variables that mutate differently so it needs to know before the code runs that v needs special treatment, but it is not decidable because the (set! v 10) might come from the database or user input. Thus by not including local bindings you save yourself a lot of trouble and the language gets easier to optimize and compile.

有些口齿不清的语言只能解释,因为它允许将宏作为第一类对象进行传递.这些语言在编译时是无法推理的.

There are lisp languages that can only be interpreted since it allows for passing macros as first class objects. These languages are impossible to reason about at compile time.

这篇关于为什么不对Scheme进行评估?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆