我是Scheme的新手,只是对'define'感到好奇。我见过这样的话:
(define (square x) (* x x))
这是有道理的[函数名称'square'输入参数'x']。但是,我发现了90年代的一些示例代码,我试图弄清楚:
(define (play-loop-iter strat0 strat1 count history0 history1 limit) (~Code for function~)
除了函数名称,所有这些输入参数都是什么?
答案 0 :(得分:3)
简短回答 - 是的,第一个之后的所有符号都是程序的参数(第一个是程序的名称)。另外,最好指出这一点:
(define (f x y)
(+ x y))
这只是语法糖,两种形式都是等价的:
(define f
(lambda (x y)
(+ x y)))
一般情况下 - 您使用特殊格式define
将名称绑定到值,该值可以是任何可用的数据类型,尤其包括函数(lambdas)。
关于参数和过程定义的更多信息 - 最好知道.
符号可用于定义具有可变数量参数的过程,例如:
(define (f . x) ; here `x` is a list with all the parameters
(apply + x))
(f 1 2 3 4 5) ; 0 or more parameters can be passed
=> 15
最后一招define
(并非在所有口译中都有,但在Racket中有效)。用于定义返回过程的过程的快捷方式,如下所示:
(define (f x)
(lambda (y)
(+ x y)))
......这相当于这个,更短的语法:
(define ((f x) y)
(+ x y))
((f 1) 2)
=> 3
答案 1 :(得分:1)
是的,strat0
到limit
是play-loop-iter
功能的参数。
答案 2 :(得分:0)
定义的一般形式是:
(define (desired-name-of-procedure item-1 item-2 item-3 ... item-n)
(; what to do with the items))
另一种解释define
行为的方法是“组合方式”和“抽象方式”。
[A] 组合方式简单来说:
语法(item-1 item-2 item-3 ... ... item-n)
是Scheme(和Lisp)提供的基本组合方式。
[B] 抽象手段很简单;一种命名的方式。
一个例子将演示这一切如何融入define
原语的想法......
示例 - 以自下而上的方式抵达define
考虑这个表达式:
(lambda (x y) (* x y))
用简单的英语,上面的表达式转换为“创建一个接受两个参数的无名过程,并返回其产品的值”。请注意,这会生成无名过程。
更准确地说,就组合方式 而言,Scheme为我们提供了关键字lambda
作为创建用户定义过程的原始运算符。
最左边的项目lambda
- 作为参数传递了项(x y)
和(* x y)
,并且运算符应用程序规则强制lambda
对项目执行某些操作。
内部定义lambda
的方式使其解析列表(x y)
,并将x
和y
视为传递到列表(* x y)
的参数,lambda
假设的是用户对遇到参数x
和y
时要执行的操作的定义。分配给x
和y
的任何值都将根据规则(* x y)
进行处理。
输入抽象方式 ...
假设我想在程序的几个地方引用这种类型的乘法,我可能会像这样调整上面的lambda表达式:
(define mul-two-things (lambda (x y) (* x y)))
define
将mul-two-things和lambda表达式作为参数,并将“绑定”在一起。现在Scheme知道mul-two-things
应该与一个过程相关联,以获取两个参数并返回它们的产品。
实际上,命名过程的要求非常普遍,并且提供了如此强大的表达能力,Scheme提供了一种更清晰的快捷方式。
就像@ oscar-lopez所说,define
是方案提供的“特殊形式”。就Scheme的口译员而言,以下两个定义都是相同的:
(define (mul-two-things x y) (* x y))
(define mul-two-things (lambda (x y) (* x y))