方案中的数据表示

时间:2013-11-19 23:33:49

标签: lambda scheme racket

我应该开发一个数据表示:

   <exp> = <var> | (lambda (<var>) <exp>) | (<exp> <exp>)

子集包含3个表达式。变量,一个参数的函数和函数应用程序。

我的问题是,如果lambda是没有名字的函数,我应该如何创建上述数据表示?这没有意义。至少对我而言。

2 个答案:

答案 0 :(得分:1)

这听起来像滚动自己的数据类型的练习。这是您可以表示,创建,访问和测试结构的一种方式。我代表:

  • <var>列表(var [name])其中[name]是变量的名称(它可以是字符串,符号,数字或其他任何您想要的名称)是变量的名称);
  • lambda函数列表(lambda [var] [exp]),其中[var][exp]是变量和表达式对象;和
  • 按列表(application [exp1] [exp2])运行应用程序,其中[exp1][exp2]是表达式对象。

重要的是要注意我们只是使用Scheme已经提供给我们的数据结构。这意味着,例如,可以使用v而不是(cadr v)来访问变量(var-name v)的名称,但我们确实应该更喜欢后者。例如,它允许我们稍后更改基础表示,并且只要相应地更新var-name,使用var-name的所有代码将继续有效。

(define (make-var name)
  (list 'var name))

(define (var? thing)
  (and (pair? thing)
       (eq? 'var (car thing))))

(define (var-name var)
  (cadr var))

(define (make-function var expression)
  (list 'lambda var expression))

(define (function? thing)
  (and (pair? thing)
       (eq? 'lambda (car thing))))

(define (function-var function)
  (cadr function))

(define (function-exp function)
  (caddr function))

(define (make-application expression1 expression2)
  (list 'application expression1 expression2))

(define (application? thing)
  (and (pair? thing)
       (eq? 'application (car thing))))

(define (application-applicand application)
  (cadr application))

(define (application-argument application)
  (caddr application))

(define (expression? thing)
  (or (var? thing)
      (function? thing)
      (application? thing)))

答案 1 :(得分:1)

我不会在Joshua has done that already之后在这里制作数据结构,而是谈谈一般的函数。

没有功能需要名称。一些名称指向函数对象(过程,闭包)。

所以你有(lambda (x) x)。在解释器中lambda是一种特殊形式,它将表单转换为procedure(闭包)。评估后的表示可能是(procedure (x) <env> x),其中env是当前环境。评估((lambda (x) x) y)将评估运算符,该运算符的计算结果为(procedure (x) <env> x),评估程序会将其标识为一个过程,以便在使用变量绑定在闭包环境中应用x之前评估该参数。

名字功能如何更有意义? 有一个命名例如。 (define identity (lambda (x) x)使用相同的机制创建过程,但特殊形式define创建了对结果的绑定,以便identity绑定到环境中的(procedure (x) <env> x)。当你执行(identity q)时,它将首先评估identity作为默认情况的一部分,在这种情况下,您有一个应用程序,以便解释器获得(procedure (x) <env> x),并在分析它知道评估参数时在申请之前。

这只是解释代码。在编译过的版本中,差异会小得多,并且它可能会变成完全相同的编译代码,因为这个名称只是程序员将复杂性抽象为易于解决的部分。