再也不跟没接触过函数式编程的面向对象程序员谈函数式了,简直没法交流啊,要争红了脸呐。
下班的时候看erlang,跟同事聊,我说函数式编程里面函数可以直接作为参数传递,而像java这样的面向对象语言不可以,结果立马被反驳。
俩人争论不休啊,我可急死了,搞的我不想一起聊啊不想聊啊。也或许我水平还不够,心里没底吧。
譬如函数式语言clojure,从http://qiujj.com/static/clojure-handbook.html#_Toc339573062这里取两个例子吧。
函数作为参数
(defn exp [a f1 b f2 c] (f2 (f1 a b) c))
(exp 5 - 2 + 3) ; 6
第一行,是定义了一个名为exp的函数,中括号之间的字符表示参数;
第二行,是使用exp的函数调用,注意 - + 在clojure中都是函数,这里exp后面跟着5个参数,而函数-和函数+正是作为参数进行传递的。
另外,函数也可以作为返回值。
(defn f [a] (fn [b] (- a b)))
((f 7) 4) ; 3
第一行,定义一个只有一个参数a的函数f。
第二行,(f 7)执行后,就返回了一个函数。利用返回的这个函数我们进行调用得到结果。
现在我们来看面向对象的java语言
public class Test{
public static void main(String args[]){}
public void method1(){}
public void method2(method1()){}
}
这个程序对么,刚学java不久的小盆友肯定也知道错了的吧。
同事非要给我举个反例,拿出了静态方法。来看程序
public class Test2 {
public static void main(String[] args) {
System.out.println(method());
}
public static String method(){
return "test";
}
}
乍一看,这个System.out.println(method())中,method()不是方法么,这里不是能当参数传递吗。
method()确实是方法,但是System.out.println(method())中却不是这样
看看这句话另外两种写法System.out.println(this.method())或者System.out.println(Test2.method())
对于静态方法,直接用类调用,一经调用也就是求值了。所以这里实际上已经产生了求值。(其实分歧就在这里,我觉得这个不应算作方法作为参数)
或许这样写应该更明白
public class Test3 {
public static void main(String[] args) {
String s = method();
System.out.println(s);
}
public static String method(){
return "test";
}
}
这个方法乍一看确实挺唬人的,不妨给method()稍加变化
public class Test4 {
public static void main(String[] args) {
System.out.println(method(String a));
}
public static String method(String a){
return "test";
}
}
加了一个参数之后,变成了这样,不用说一看就是错的。你要是写成method("test"),这里就是变现了的,也就不是原来意义的方法了。
我就说一句函数式编程中函数可以作为参数传递,当然java中叫方法,面向对象中不行。这够清楚的了吧,怎么说我解释不清呢。
而且java中方法的调用都离不开类,使用了类基本上就是实例化了。无论方法的调用和构造,都是不可以当参数直接传递的。
我也不一定全对吧,有没有反例谁知道呢,也行我水平还不够未能了解到java的博大精深,更遑论C++了。
好吧,也算我才疏学浅,今天看了耗子蜀黍写的练级攻略,感觉路还是很长啊。http://coolshell.cn/articles/4990.html
补充:晚上回家,又看了一下问题,也许是对静态方法的理解的区别吧。静态方法直接用类调用,而实例方法只能用对象调用。对于实例方法肯定不会有异议。
而静态方法,象System.out.println(method())这里的method()实际上是类调用,能算作所谓的方法作为参数吗,噢,who knows,好像太学院派了。。。