A.4 Frege(Haskell)
Frege是Haskell语言的一种方言,它无疑是第一款用于JVM的纯粹的函数式编程语言。在Frege中,函数是一等公民,可传递给其他函数;变量都是不可变的(Frege根本就没有提供赋值语句),而使用这种语言创建的方法都没有副作用。
另一个不同于Clojure的地方是,Frege是一种静态类型语言,而Clojure是一种动态类型语言。在Frege中,变量的类型是固定的且在编译阶段就必须知道。然而,在大多数情况下,Frege都能够根据代码推断出变量的类型。
有趣的是,Frege编译器将Frege源代码转换为Java代码,再调用标准的JDK编译器
javac,将生成的Java代码转换为Java字节码。
Frege官网的地址如下(编写本书期间,访问这个网站将被重定向到其GitHub页面):http://frege-lang.org/。
要下载编译器,请访问其GitHub页面(http://github.com/Frege/frege/releases)。
Frege是一种相对较新的语言,其工具集还不太完备。虽然有用于Eclipse IDE的插件,但本书出版时,该插件与最新的Eclipse版本不兼容。Frege的wiki页面(可在其GitHub页面中找到)指出,使用Frege进行开发时,JetBrains的IntelliJ IDEA IDE是不错的选择,这种说法应该对IntelliJ IDEA的免费社区版和收费版都适用。
A.4.1 在Frege中调用Java代码
JVM本身并没有遵守纯粹的函数式编程规则:Java类库中很多的内置类都是可变的,流行的JVM框架和库提供的大多数类亦如此。有鉴于此,Frege设计者必须找出规避方案,让Frege代码能够调用不纯粹的JVM方法。
由于没有可靠的方法来自动检测方法是否具有副作用(它可能直接修改实例变量,也可能调用对实例变量进行修改的方法),程序员必须向Frege指出方法是否是纯粹的(没有副作用)。如果JVM方法被宣称为纯粹的,就可像调用其他Frege函数一样调用它;而对于被声明为包含状态的方法,就使用内置的monad来调用它。monad将返回一个不可变值,这个值是由方法计算得到的。可变数据放在monad里面,这样程序就无法直接访问它了。
A.4.2 运行Frege
Frege是以单个可执行的JAR文件的方式发行的。当前,标准发行版中没有自带REPL,但可从http://github.com/Frege/frege-repl/releases单独下载它。
请下载最新版本的REPL,并将ZIP文件解压缩。可将其解压缩到包含Frege编译器的JAR文件所在的目录。然后,切换到其中的子目录bin,并执行如下命令来启动REPL:
frege-repl
要退出这个shell,可执行命令quit。
另外,对于非常简单的程序,也可使用在线REPL:http://try.frege-lang.org/。
有趣的是,Frege编译器将Frege源代码转换为Java代码,再调用标准的JDK编译器