再也不跟没接触过函数式编程的面向对象程序员谈函数式了,简直没法交流啊,要争红了脸呐。

下班的时候看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,好像太学院派了。。。