posts - 56, comments - 77, trackbacks - 0, articles - 1
  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

Generic Java Functor 发布首个版本

Posted on 2005-09-06 22:24 切尔斯基 阅读(1923) 评论(5)  编辑  收藏

 

〇,简介

Gavator(Generic Java Functor)试图探索以普通Java语法进行函数式编程的可行性,并尽可能的保证使用的方便性,良好的可读性和基本的类型安全性

一,功能

所有功能都是类型安全的,无需涉及强制转型

  • 提供了若干算法:transform/map, select/filter, accumulate/reduce, foreach/enumerate, findfirst等

  • 提供了若干适配器:bind,bind1st, bind2nd等

  • 提供了常用控制结构的函数形式和functor形式:dowhile/whiledo, dountil/untildo, ifelse等

  • 提供了常用逻辑运算结构的函数形式和functor形式:and,or,not等

  • 提供了常用数据结构:filter,pipe等

二,结构

Gavator的结构是层次化的

  • 最核心的是一组接口:分别定义了Procedure,Predicate,Function的零元,一元,二元形式

  • 基于这些接口,以functor的形式提供了常用概念的实现,包括数据结构,控制结构,适配器等,如Filter/Pipe,Bind,And/Or/Not,WhileDo/IfElse等

  • 基于这些结构和适配器,以function的形式实现了使用方便和可读性好的包装,如pipe,bind,and/or/not, ifelse等

三,用法

附带的测试用例可用来简单说明一下用法;其实所有functor和algorithm都很直观,看到名称和参数,即能领会它的用法;并且代码量非常少,半个小时就能将所有代码浏览一遍

曾经听说ThoughtWorks的敏捷项目中平均每个函数代码控制在三行以下,Gavator中每个函数平均只有不到两行代码

package gavator.test; 

import static gavator.algorithm.Algorithms.*;

import gavator.datastructure.*;

import junit.framework.*;

 

class ToUpperFilter implements Filter<String> {

     public String eval(String obj) {

         return obj.toUpperCase();

     }

class ToLowerFilter implements Filter<String> {

     public String eval(String obj) {

         return obj.toLowerCase();

     }

class DirtyWordsFilter implements Filter<String> {

     public String eval(String obj) {

         return obj.replace("dirty words", "***");

     }

}

 

public class FilterPipeTest extends TestCase {

 

     private Pipe lowerPipe, upperPipe, dirtyWordsPipe; 

     private String string = "abc"; 

     private String dws = "you said dirty words, so...";

 

     public void testFilter() {

         Assert.assertEquals("ABC", new ToUpperFilter().eval(string));

         Assert.assertEquals("abc", new ToLowerFilter().eval(new ToUpperFilter().eval(string)));

         Assert.assertEquals("you said ***, so...", new DirtyWordsFilter().eval(dws));

     } 

     public void testPipe() {

         lowerPipe = new Pipe<String>(new ToUpperFilter(), new ToLowerFilter());

         upperPipe = new Pipe<String>(new ToLowerFilter(), new ToUpperFilter());

         dirtyWordsPipe = new Pipe<String>(lowerPipe, new DirtyWordsFilter());

 

         Assert.assertEquals("abc", lowerPipe.eval("abc"));

         Assert.assertEquals("ABC", upperPipe.eval("abc"));

 

         Assert.assertEquals("hehe***", dirtyWordsPipe.eval("hehedirty words"));

         Assert.assertEquals("hehe***", pipe("hehedirty words", dirtyWordsPipe));

     } 

}

四,扩展

使用者可以在Gavator结构的任何一次层次对Gavator进行扩充,如扩充functor实现其它设计模式和常用概念,或编写更多的算法,结合import static,提高客户代码的可读性

目前Gavator to be contributed的是 ContinuationFramework 和 QueryFramework

五,问题

  • Gavator的主要思想来自C++ STL和Apache Common Funtor,我对纯粹的函数式语言如Scheme,Haskell并没有太多经验,因此Gavator最主要的问题是:它做的是否正确?

  • Gavator还不完整,如尚未将Functor实现为值语义等

  • 好的名称有助于减少文档,促进理解,但同一个概念在不同的社团可能有不同的惯用名称,如transform和map,select和filter,accumulate和reduce,等等;Gavator选择了使用STL和Apache Common Functor中的名称

  • 序列操作的参数应该是Collection还是Iterator ?STL和Apache Common Functor选择了Iterator,我感觉大部分情况下Collection更方便,就用了Collection

  • 目前Gavator其实并不是很实用,像ifelse等基本是花拳绣腿,关键是要基于Gavator,发展出专注于某个应用领域的framework,如Continuation和Query

六、其它

Java语言本身的简单,造成了对Functional Programming支持的限制,Apache Common Functor至今还是sandbox;这些限制包括:

  • 函数不是first class,不是一等公民,更别提lambda表达式

  • primitive type与class无法完全统一,你试试能否写一个通用的accumulate支持int集合,long集合,double集合的累加就知道了

  • 不支持操作符重载,当然,这不是本质问题

  • 使用擦拭法实现generic,使你不能对T调用任意函数,无法特化,没有typedef,只能用继承来模拟,任何动态特性都将使generic丧失类型安全性,如序列化后反序列化,反射等

  • 甚至不能return void,这使Procedure和Function在实现上无法统一以减少代码,虽然在概念上它们是独立的

或许Java平台上的函数式编程的支持将使用专门的语言来解决

Gavator起源于去年的一个项目,在那个项目里实现了一个基于Functor的查询框架,增加一种条件只需实现Condition接口,当然,Condition是一个Predicate,然后就可以和已有的各种Condition通过and,or,not等组合出各种复合查询,提供服务的一方通过恒定不变的代码select(Collection, Condition)来满足任意的查询;希望接下来实现一个封装了各种查询(对象,SQL,XPath/XQuery等)的QueryFramework

另外对Continuation的支持也值得一做,希望得到帮助,mailto:ajaxchelsea@163.com

 


评论

# re: Generic Java Functor 发布首个版本  回复  更多评论   

2005-09-07 11:33 by 江南白衣@ITO
切尔斯基也搬过来啦~~~ 第一个过来串门:)

# re: Generic Java Functor 发布首个版本  回复  更多评论   

2005-09-07 15:46 by chelsea
呵呵,从出租屋搬到经济适用房了;往来有白衣啊

# re: Generic Java Functor 发布首个版本  回复  更多评论   

2005-12-21 04:16 by ajooo
我做过一个依照haskell MonadCont模型的continuation,如果计算模型严格遵照Monad,就可以用。


不过,java 5的generics功能太弱,搞搞stl可能还勉强可以,搞Monad就没戏了,只能cast!

# re: Generic Java Functor 发布首个版本  回复  更多评论   

2005-12-21 09:34 by 切尔斯基
看来java和fp天生阻抗不匹配啊

# re: Generic Java Functor 发布首个版本  回复  更多评论   

2005-12-22 02:20 by ajooo
exception本来就已经是escape-only的continuation了。而这种continuation也是最没争议的一种.所以用exception来实现continuation比较简单实用.代价就是效率有点那个.


另外一种,象ruby和c#的return yield这种也可以说是continuation的应用的东西,可以用多thread的wait(),notify()来模拟,效率差,但是看上去差不多。

至于一般意义上的fp,不太可行。类型安全是一方面,高阶函数的可读性还有可调试性都很差。玩玩可以,我的一个玩具:http://forum.javaeye.com/viewtopic.php?t=7951&start=0
实际真用还是不成熟。


只有注册用户登录后才能发表评论。


网站导航: