Racket/Scheme - (define ((function-name arg1) arg2) (body ...)) - 符号
Racket/Scheme - (define ((function-name arg1) arg2) (body ...)) - Notation
这个符号的名称是什么/它代表什么?
(define ((function-name arg1) arg2) (body ...))
我了解到在Racket/Scheme中您可以通过以下两种方式定义一个函数:
(define (function-name arg1 arg2 ...) (body ...))
(define function-name (lambda (arg1 ...) (body ...))
但是,我最近在 Chris Hanson 和 Gerald Jay Sussmaan 的软件设计中发现了这种表示法:
(define ((function-name arg1) arg2) (body ...))
我注意到这个符号在 Scheme(这本书是用它写的)和 Racket 中也有效。
有谁知道定义语句参数中函数应用程序的这种表示法的名称? / 它可能代表什么?
这绝对是不寻常的,我从未在任何地方看到它的明确记录,但它至少在某些方案实现上有效(Chicken、Racket,无论您尝试接受它的任何其他方案,Guile 都不接受)。
R7RS的写法给了一些启示:
(define (〈variable〉 〈formals〉)〈body〉)
〈Formals〉
are either a sequence of zero or more variables, or a sequence of one or more variables followed by a space-delimited period and another variable (as in a lambda expression). This form is equivalent to (define〈variable〉(lambda (〈formals〉)〈body〉))
.
所以这个:
(define ((example a) b) (printf "~A~%~A~%" a b))
可以认为等同于
(define (example a) (lambda (b) (printf "~A~%~A~%" a b)))
这又等同于
(define example (lambda (a) (lambda (b) (printf "~A~%~A~%" a b))))
并且接受这种表示法的方案可能会在某些时候在内部进行类似的转换,作为它们如何实现 define
-ing 函数的一部分。当使用第一种形式定义鸡肉时,这确实符合 example
在鸡肉上的行为。
这是一个扩展,不是标准方案的一部分。这个扩展已经在 MIT/GNU Scheme 中可用了很长一段时间,其他一些实现也采用了它。
R7RS 规范未显示与 OP 发布的示例定义相匹配的表单。最接近的匹配是 5.3 中的这个。变量定义:
(define (<variable> <formals>) <body>)
<Formals>
are either a sequence of zero or more variables, or a sequence one or more variables followed by a space-delimited period and another variable (as in a lambda expression).
有问题的定义是:
(define ((function-name arg1) arg2) (body ...))
此处,(function-name arg1)
必须被视为一个变量,以便与标准中的描述相匹配;但它不是变量,甚至不是标识符。
来自 3.1。变量、语法关键字和区域:
An identifier that names a location is called a variable and is said to be bound to that location.
值得指出的是,Hanson 和 Sussman 的书的附录 B 简要讨论了这种结构:
In MIT/GNU Scheme we can use the sugar recursively, to write:
(define ((compose f g) x)
(f (g x)))
现在,在第MIT/GNU方案参考手册的17(11.1)表明:
(define (name1 name2 ...)
expression
expression ...)
相当于:
(define name1
(named-lambda (name1 name2 ...)
expression
expression ...))
请注意 MIT/GNU 手册中显示的语法显示 lambda
:
lambda formals expr expr ... [extended standard special form]
此处,formals 被描述为“形式参数列表”,但请注意未使用术语 variable。术语 变量 在手册的其他地方使用,例如,在 let
表格的描述中。
named-lambda
特殊形式说明:
named-lambda formals expression expression ... [special form]
The named-lambda special form is similar to lambda, except that the first "required parameter" in formals is not a parameter but the name of the resulting procedure; thus formals must have at least one required parameter. This name has no semantic meaning, but is included in the external representation of the procedure, making it useful for debugging. In MIT/GNU Scheme, lambda is implemented as named-lambda, with a special name that means "unnamed".
所以,定义(define ((function-name arg1) arg2) (body ...))
可以重写为:
(define (function-name arg1)
(named-lambda ((function-name arg1) arg2) (body ...)))
通过手册提供的上述转换规则,由于形式参数列表在MIT/GNU Scheme中被扩展为不限于包含变量 仅。
然后可以使用相同的规则再次(递归)扩展最后的结果:
(define function-name
(named-lambda (function-name arg1)
(named-lambda ((function-name arg1) arg2)
(body ...))))
因为 named-lambda
类似于 lambda
,即不同之处仅在于有一些额外的元数据与之关联,但语义相同,我们可以编写语义等价物:
(define function-name
(lambda (arg1)
(lambda (arg2)
(body ...))))
这只是高阶过程的定义。因此,所讨论的符号只是语法糖,以促进高阶过程的定义。请注意,SRFI 201 旨在为其他 Scheme 实现提供此功能,并将其称为“高阶 define
形式 ”,以及“ define
形式的 'currying' 变体 。
回到Software Design for Flexibility的附录B中的示例程序,可以看出如何使用这种语法糖来巧妙地表达函数组合的思想.
(define ((compose f g) x)
(f (g x)))
这里,compose
是一个接受两个参数的过程,f
和g
,returns是一个接受一个参数的过程x
:
1 (user) => (define my-composition (compose square cube))
;Value: my-composition
1 (user) => (my-composition 2)
;Value: 64
这个符号的名称是什么/它代表什么?
(define ((function-name arg1) arg2) (body ...))
我了解到在Racket/Scheme中您可以通过以下两种方式定义一个函数:
(define (function-name arg1 arg2 ...) (body ...))
(define function-name (lambda (arg1 ...) (body ...))
但是,我最近在 Chris Hanson 和 Gerald Jay Sussmaan 的软件设计中发现了这种表示法:
(define ((function-name arg1) arg2) (body ...))
我注意到这个符号在 Scheme(这本书是用它写的)和 Racket 中也有效。
有谁知道定义语句参数中函数应用程序的这种表示法的名称? / 它可能代表什么?
这绝对是不寻常的,我从未在任何地方看到它的明确记录,但它至少在某些方案实现上有效(Chicken、Racket,无论您尝试接受它的任何其他方案,Guile 都不接受)。
R7RS的写法给了一些启示:
(define (〈variable〉 〈formals〉)〈body〉)
〈Formals〉
are either a sequence of zero or more variables, or a sequence of one or more variables followed by a space-delimited period and another variable (as in a lambda expression). This form is equivalent to(define〈variable〉(lambda (〈formals〉)〈body〉))
.
所以这个:
(define ((example a) b) (printf "~A~%~A~%" a b))
可以认为等同于
(define (example a) (lambda (b) (printf "~A~%~A~%" a b)))
这又等同于
(define example (lambda (a) (lambda (b) (printf "~A~%~A~%" a b))))
并且接受这种表示法的方案可能会在某些时候在内部进行类似的转换,作为它们如何实现 define
-ing 函数的一部分。当使用第一种形式定义鸡肉时,这确实符合 example
在鸡肉上的行为。
这是一个扩展,不是标准方案的一部分。这个扩展已经在 MIT/GNU Scheme 中可用了很长一段时间,其他一些实现也采用了它。
R7RS 规范未显示与 OP 发布的示例定义相匹配的表单。最接近的匹配是 5.3 中的这个。变量定义:
(define (<variable> <formals>) <body>)
<Formals>
are either a sequence of zero or more variables, or a sequence one or more variables followed by a space-delimited period and another variable (as in a lambda expression).
有问题的定义是:
(define ((function-name arg1) arg2) (body ...))
此处,(function-name arg1)
必须被视为一个变量,以便与标准中的描述相匹配;但它不是变量,甚至不是标识符。
来自 3.1。变量、语法关键字和区域:
An identifier that names a location is called a variable and is said to be bound to that location.
值得指出的是,Hanson 和 Sussman 的书的附录 B 简要讨论了这种结构:
In MIT/GNU Scheme we can use the sugar recursively, to write:
(define ((compose f g) x) (f (g x)))
现在,在第MIT/GNU方案参考手册的17(11.1)表明:
(define (name1 name2 ...)
expression
expression ...)
相当于:
(define name1
(named-lambda (name1 name2 ...)
expression
expression ...))
请注意 MIT/GNU 手册中显示的语法显示 lambda
:
lambda formals expr expr ... [extended standard special form]
此处,formals 被描述为“形式参数列表”,但请注意未使用术语 variable。术语 变量 在手册的其他地方使用,例如,在 let
表格的描述中。
named-lambda
特殊形式说明:
named-lambda formals expression expression ... [special form]
The named-lambda special form is similar to lambda, except that the first "required parameter" in formals is not a parameter but the name of the resulting procedure; thus formals must have at least one required parameter. This name has no semantic meaning, but is included in the external representation of the procedure, making it useful for debugging. In MIT/GNU Scheme, lambda is implemented as named-lambda, with a special name that means "unnamed".
所以,定义(define ((function-name arg1) arg2) (body ...))
可以重写为:
(define (function-name arg1)
(named-lambda ((function-name arg1) arg2) (body ...)))
通过手册提供的上述转换规则,由于形式参数列表在MIT/GNU Scheme中被扩展为不限于包含变量 仅。
然后可以使用相同的规则再次(递归)扩展最后的结果:
(define function-name
(named-lambda (function-name arg1)
(named-lambda ((function-name arg1) arg2)
(body ...))))
因为 named-lambda
类似于 lambda
,即不同之处仅在于有一些额外的元数据与之关联,但语义相同,我们可以编写语义等价物:
(define function-name
(lambda (arg1)
(lambda (arg2)
(body ...))))
这只是高阶过程的定义。因此,所讨论的符号只是语法糖,以促进高阶过程的定义。请注意,SRFI 201 旨在为其他 Scheme 实现提供此功能,并将其称为“高阶 define
形式 ”,以及“ define
形式的 'currying' 变体 。
回到Software Design for Flexibility的附录B中的示例程序,可以看出如何使用这种语法糖来巧妙地表达函数组合的思想.
(define ((compose f g) x)
(f (g x)))
这里,compose
是一个接受两个参数的过程,f
和g
,returns是一个接受一个参数的过程x
:
1 (user) => (define my-composition (compose square cube))
;Value: my-composition
1 (user) => (my-composition 2)
;Value: 64