Racket如何处理(定义(f(xy))体)?

ked*_*bug 4 lisp scheme racket

我正在学习Racket,并写了这个定义:

(define y 2)
(define (f (x y))
  (print x)
  (print y))
Run Code Online (Sandbox Code Playgroud)

当我评价(f 1),x必然1,并且y必然2.这对我来说似乎很奇怪.这个表达式是如何扩展的?口译员对此做了什么?

Jos*_*lor 6

这是一个可选参数

Racket中定义的语法在文档中.

3.14定义:define,define-syntax,...

(define id expr)
(define (head args) body ...+)

head  =       id
      |       (head args)

args  =       arg ...
      |       arg ... . rest-id

arg   =       arg-id
      |       [arg-id default-expr]
      |       keyword arg-id
      |       keyword [arg-id default-expr]
Run Code Online (Sandbox Code Playgroud)

我的大多数Lisping都在Common Lisp中,方括号不是括号,所以我最初误读了语法.关于部分[arg-id default-expr]意味着您可以使用具有默认值的可选参数.所以

(define (f (x y)) …)
Run Code Online (Sandbox Code Playgroud)

定义f为接受0或1个参数的过程.如果未提供参数,则其默认值为y.这就是为什么当你有一个早期的定义时,这是有效的y.这也意味着你可以打电话(f),你应该看到y打印的价值:

在此输入图像描述

当y具有先前的定义时,Robby Findler和Tony Garnock-Jones在线程[racket](定义(f(xy))主体)的Racket用户邮件列表中向我指出了这一点.

这在R5RS中是不合法的

这在R 5 RS Scheme中是不合法的.定义的定义见:

5.2定义

定义在允许表达式的某些(但不是全部)上下文中有效.它们仅在a的顶层和a的开头有效.

定义应具有以下形式之一:

(define <variable> <expression>)
(define (<variable> <formals>) <body>)
Run Code Online (Sandbox Code Playgroud)

应该是零个或多个变量的序列,或者一个或多个变量的序列,后跟空格分隔的句点和另一个变量(如lambda表达式).这个表格相当于

(define <variable>
  (lambda (<formals>) <body>)).

(define (<variable> . <formal>) <body>)
Run Code Online (Sandbox Code Playgroud)

应该是一个变量.这个表格相当于

(define <variable>
  (lambda <formal> <body>)).
Run Code Online (Sandbox Code Playgroud)

Dr.Racket不接受您在R5RS语言中的定义:

Dr.Racket截图