我认为后缀比一元函数的前缀符号有两个主要优点:
Input -> Function -> Ouput对数据处理的思考方式。下面是一个示例:
def plus2(v: Int) = v + 2
def double(v: Int) = v * 2
def square(v: Int) = v * v
// prefix
square(
double(
plus2(1)
)
)
// postfix
1.plus2
.double
.square这可以与Java中的方法链接或其他用户技术相类似。但我不熟悉任何为后缀函数应用程序提供一流支持的编程语言。
什么是编程语言的设计原因,不提供一流的后缀符号支持一元函数?支持这一点似乎微不足道。
发布于 2020-02-27 22:31:34
我不熟悉任何允许这样做的编程语言。
您的示例语法非常类似于方法链。在面向对象语言中,没有参数的方法实际上是声明该方法的任何类型的一元操作符。下面是使用相同声明的Java计算,按后缀顺序排列:
class Example {
final int x;
Example(int x) { this.x = x; }
Example add2() { return new Example(x + 2); }
Example mult2() { return new Example(x * 2); }
Example square() { return new Example(x * x); }
public static void main(String[] args) {
Example result =
new Example(1)
.add2()
.mult2()
.square();
}
}当然,您需要方括号()来调用它们,但仍然是后缀顺序。不幸的是,您无法将其调整为使用静态方法而不是实例方法,至少在不滥用Optional或Stream的情况下是这样的:
Optional.of(1)
.map(StaticExample::add2)
.map(StaticExample::mult2)
.map(StaticExample::square)
.get()我想,OOP语言之所以不能以这种方式更容易地使用静态方法,是因为拥有特权静态方法而不是实例方法的特殊语法是很奇怪的。OOP的目的是使用实例和多态性来完成一些事情。
在函数式语言中,也可以使用函数而不是方法:下面是F#:
let add2 x = x * 2
let double x = x * 2
let square x = x * x
let result =
1
|> add2
|> double
|> square在这里,前管操作符|>为.提供了不同的语义角色,但是效果是相同的:函数是用后缀顺序编写的。
我想,前管操作符只存在于函数式语言中的主要原因是,部分应用程序允许您使用非一元函数编写管道式计算。例如:
nums
|> List.filter isEven
|> List.map square在这里,List.filter和List.map接受两个参数,但是如果用一个参数调用它们,那么它们返回一个一元函数。非函数式语言往往没有部分应用(至少不那么容易),因此前向管道操作符就不那么有用了。
还有一个鲜为人知的级联规划范例,在这种模式下,所有的事情都是按后缀顺序自然完成的,不需要额外的语法。这是我自己的玩具语言fffff
(2 +) >!add2
(2 *) >!double
(@ *) >!square
1 add2 double square >result在这里,甚至像>result这样的任务也是按后缀顺序完成的。
https://stackoverflow.com/questions/60442220
复制相似问题