我从SML书中了解到,SML中的函数总是只有一个参数:一个元组。带有多个参数的函数只是一个函数,它将一个元组作为参数,在函数绑定中使用元组绑定实现。我理解这一点。
但在此之后,这本书说了一些我不理解的东西:
this point makes SML language flexible and elegant design, and you can do something useful that you cannot do in Java.
为什么这种设计会使语言变得灵活?什么是文本,SML可以,但java不能?
答案 0 :(得分:6)
使用元组而不是多个参数可以增加灵活性,因为高阶函数可以处理任何“arity”的函数。例如,要创建列表[f x, f y, f z]
,您可以使用高阶函数map
,如下所示:
map f [x, y, z]
这很容易 - 你可以用任何语言做到这一点。但现在让我们考虑f
实际上需要两个参数的情况。如果f
是真正的二元函数(假设SML具有这样的函数),我们需要一个不同版本的map
,它可以使用二进制函数而不是一元函数(如果我们想要使用3-ary函数,我们也需要一个版本。但是使用元组我们可以像这样写:
map f [(x,a), (y,b), (z,c)]
这将创建列表[f (x,a), f (y,b), f (z,c)]
。
PS:所有需要多个参数的函数都在SML中使用元组并不是真的。通常函数使用currying而不是元组来表示多个参数,但我认为你的书还没有被讨论。 Curried函数不能以与上述相同的方式使用,因此它们在这个意义上并不一般。
答案 1 :(得分:2)
实际上我认为你根本不理解这一点。
首先,SML中的函数不会将元组作为参数,它们可以将任何内容作为参数。使用元组作为传递多个参数的方法有时很方便。例如,函数可以将记录作为参数,整数,字符串,或者甚至可以将另一个函数作为参数。也可以说,它可以采取“无论证”,因为它可能以单位为参数。
如果我理解你的陈述正确地讲述了带有“多个参数”的函数,那你就是在讨论currying。例如
fun add x y = x + y
在SML中,currying是作为派生形式(语法糖)实现的。有关其实际工作原理的详细说明,请参见this answer。总之,SML中只有匿名函数,但是我们可以将它们绑定到名称,以便它们可以“引用”/稍后使用。
看哪,ramblings即将开始。
在谈论任何事情的灵活性之前,我认为这是为了说明我对它的看法。我非常喜欢flexibility of programming languages的这个定义:“ [...]出乎意料的多种方式可以使用该语言的说法”
在SML的情况下,选择了一种小而简单的核心语言。这使得实现编译器和解释器变得容易。灵活性的形式是使用这些核心语言功能实现了SML语言的许多功能,例如匿名函数,模式匹配以及SML具有高阶函数的事实。
这方面的例子是currying,case表达式,记录选择器,if-the-else表达式,表达式序列。
我想说这使得SML核心语言非常灵活,坦率地说非常优雅。
我不太确定作者关于SML可以做什么,java不能(在这种情况下)。但是我很确定作者可能有点偏颇,因为你也可以在java中做任何事情。然而,它可能需要大量的编码:)