Generic Java Functor 发布首个版本

〇,简介

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

  • 项目信息:http://cosoft.org.cn/projects/gavator/

  • CVS信息:http://cosoft.org.cn/cvs/?group_id=5717,推荐Eclipse直连,模块名是Gavator

  • 下载地址:http://cosoft.org.cn/download.php?g_u_n=gavator&f=Gavator_0.6.zip&file_id=7000

一,功能

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

  • 提供了若干算法: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 {

     public String eval(String obj) {

         return obj.toUpperCase();

     }

class ToLowerFilter implements Filter {

     public String eval(String obj) {

         return obj.toLowerCase();

     }

class DirtyWordsFilter implements Filter {

     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(new ToUpperFilter(), new ToLowerFilter());

         upperPipe = new Pipe(new ToLowerFilter(), new ToUpperFilter());

         dirtyWordsPipe = new Pipe(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:[email protected]

 

你可能感兴趣的:(Generic Java Functor 发布首个版本)