【问题标题】:Lexical or Dynamic scope - Haskell implemented evaluator词法或动态范围 - Haskell 实现的评估器
【发布时间】:2021-05-21 23:18:00
【问题描述】:

在谈到词法作用域和动态作用域之间的区别后,我的教授给了我们一个问题。他向我们展示了一个用 Haskell 编码的简单求值器(一种虚构的语言)。以下是代码:

type Var = ... 
type Env = ...
data Val = Vnum Int 
           | Vfun Var Exp 

data Exp = Enum Int
         | Evar Var
         | Efun Var Exp
         | Ecall Exp Exp
         | Elet Var Exp Exp

-- Predefined. Find the correspondent value of a variable
env_lookup :: Env -> Var -> Val
...

-- Predefined. Add the variable and its associated value to the environment
env_add :: Env -> Var -> Val -> Env
...

eval env (Enum n) = Vnum n
eval env (Evar x) = env_lookup x env
eval env (Ecall fun actual)
  = case (eval env fun) of
     Vnum n -> error "Not a Function!"
     Vfun formal body ->
           eval (env_add env formal (eval env actual)) body
-- To be completed --

问题问:

这种实现的语言是使用词法作用域还是动态作用域?以及我们应该如何更改代码以使其具有另一种类型的范围

坦率地说,这是一个非常困难的问题。从代码中很容易看出,这种语言是实现“按名称调用”还是“按值调用”(在本例中为“按值调用”)。但是分析它是动态作用域还是词法作用域是另一回事

【问题讨论】:

    标签: haskell lexical-scope dynamic-scope


    【解决方案1】:

    您的代码不完整:

    eval env (Ecall fun actual)
      = case fun of
         Vnum n -> error "Not a Function!"
         Vfun formal body ->
               eval (env_add env formal (eval     actual)) body
                                             ^^^^^
    

    缺少参数。但是你只有一个选择来修复它,在此处添加env

    那么意思就变成了,在env扩展的环境中评估body,参数和参数的配对。

    当前环境,env。不是函数创建时的那个。

    这意味着动态范围。

    要修复它,我们可以使用FUNARG 设备:在创建函数(因此是闭包)时将定义环境与主体和形式参数一起存储。然后在 definitional 环境中评估主体,就像现在一样,在 current 环境中评估的形式参数和实际参数对env

    另请参阅:此相关answer by me

    您甚至可以同时拥有动态和词法范围,例如从 (lambda ...) 形式生成一个普通的 lambda,它将在动态范围下进行评估,并从例如 @987654329 生成 lambda 及其定义环境的闭包@ 形式(用 Lisp 说话),用于词法范围。因此必须在eval 中处理这两种情况,就像我在上面提到的另一个答案中所做的那样。

    【讨论】:

      猜你喜欢
      • 2012-09-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-04-03
      • 1970-01-01
      • 2011-06-07
      • 1970-01-01
      相关资源
      最近更新 更多