Chapter 2 First Class Function
First-class functions are functions treated as objects themselves, meaning we can pass a function as a parameter to another function, return a function from a function, or store a function in a variable.
– Becoming Functional
一级函数 高阶函数?
First-Class Function (暂时不知道怎么样翻译较为妥当) 或者 High Order Function 是被视作为对象的函数,也就是说本质上还是一个对象,因此可以作为另一个函数的参数或者在一个函数中返回一个函数,或者将一个函数保存在一个对象中。
函数与对象的区别:函数,顾名思义,就是实现一定功能,是对操作的封装,是有别于存储数据的对象的, 但并不等同于一个类,类中有一个方法。比如定义一个 Student 类,其定义中必定包含相关的属性,如学号、姓名等。 它的对象是存储了数据的,而一个函数仅仅是对输入作相应的操作,并返回一个结果,在 Java 中就可以通过定义一个接口,而这个接口中有一个抽象的方法,作为这个函数相关操作封装的地方。
上述理解我觉得只是在 Java 中的理解,或者面向对象的语言中的理解,运用接口来实现接受和返回 “函数”。在完全的函数式编程语言中的理解留作后续的研究。 纯粹的 First-Class Function 或者 High Order Function 定义就是函数可以作为另一个函数的参数,或者返回值。
在 Java 中, 比如定义了一个 Function 接口:
1 | public interface Function<T, R> { |
那么实现这个接口的任何类或者类的对象都是一个 First-Class Function。 可以作为参数,可以作为一个返回值,可以存储在一个变量中。
1 | Function<T, R> function = t -> r; |
The DRY (Don’t Repeat Yourself) principle has been around for many years; the concept is that we should not be duplicating lines of code. This makes the code harder to maintain. But why is that the case?
Think about what happens if you duplicate a function multiple times. Now imagine that you just found a bug in one of those functions; you’ll have to go through however many other functions to see if that same bug exists.
不要写重复的代码,如果重复的代码出现在多处,那么后来发现有错误,就要进行多处的检查,不好维护,而且没有本质的意义。
匿名函数
Lambda functions are unnamed functions that contain a parameter list, a body, and a return.
作者定义 Lambda 函数包含三部分: 参数列表、函数体、返回值, 并且是没有名称的函数(unnamed)
Closures are much like lambdas, except they reference variables outside the scope of the function. The body references a variable that doesn’t exist in either the body or the parameter list.
Closure 和 lambda function 很像,但区别在于它们引用了函数范围以外的变量,这个变量既不存在参数列表中,也不存在函数体中。
1 | public static List<String> getEnabledCustomerSomeoneEmail(final String someone) { |
Using closures, you can build functions and pass them to other functions while referencing local variables.
使用 Closure,就可以将函数作为一个参数传至另一个函数,并且引用局部变量。
1 | //Example 2-18. getField with test function |