首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Scala和Frege (在编程范式方面)的主要区别是什么?

Scala和Frege (在编程范式方面)的主要区别是什么?
EN

Stack Overflow用户
提问于 2013-07-28 13:33:44
回答 3查看 5K关注 0票数 33

Scala和Frege都是面向JVM的类型化函数式语言。

Frege更接近Haskell,Scala有更独立的历史。

但是,如果我们不看语法差异,那么两者在允许的编程技术、风格和概念上有什么不同呢?

EN

回答 3

Stack Overflow用户

发布于 2013-07-29 03:29:35

我觉得两者都是很好的语言,但就范式而言,Scala比Frege做得更好,但Frege比Scala做得更好。至于区别,主要归结为Haskell和Scala,因为Frege是(或者说几乎是Haskell和Frege here之间的区别)。

  1. Frege的类型推断是全局的,所以我们不必像在Scala中那样频繁地注释类型(本地推断)。
  2. 在Frege中,模块只是类型和函数的命名空间,而Scala有更好的模块系统。http://2013.flatmap.no/spiewak.html
  3. 在Frege中,函数默认是curried的,因此不需要为部分函数应用程序添加额外的构造。分部类型构造函数application.
  4. In Frege也是如此,没有defval,一切都是函数。因此,函数比Scala更高级,
  5. Frege没有子类型,但是类型系统在本机调用上识别子类型。例如,您可以将ArrayList传递给需要Java List的函数。

由于没有子类型,在Frege中我们不能扩展Java类或实现接口(将来可能会支持),所以我们需要一个可以扩展/实现的Java类,但方法实现将作为Java从Frege传递,调用functions.

  • From很容易,但在Frege中,必须在使用之前声明一个Java类/方法(仅是类型和纯度注释)。例如,要使用Java的LinkedList

data LinkedList a= native java.util.LinkedList where native add ::Mutable s (LinkedList a) -> a -> ST s Bool native get ::Mutable s (LinkedList a) -> Int -> ST s(可能a)抛出IndexOutOfBoundsException native new ::() -> STMutable s (LinkedList a)

在这里,因为函数会改变对象,所以它们必须是ST monad。还要注意,在这里,Frege还处理从get方法返回的null,因为它是用Maybe类型注释的。null可以连接到Frege程序的唯一方法是通过本机接口,因为Frege没有null的概念。

另一个例子:pure native floor Math.floor :: Double -> Double

它声明函数是纯的,因此签名直接反映了没有IO的原始Java签名,或者ST.

  • Frege没有像Scala的var中那样的变量,并且副作用通过类型更加明确。(只是没有null,没有var和明显的副作用让Frege更有趣,至少对我来说是这样。在某种意义上,Frege就像Haskell一样,是一种“很好的命令式编程语言”,对于JVM虚拟机来说!)

  • 是一种Haskell方言,Frege对函数器、应用程序、Monad和其他函数“模式”更自然,并在其标准库中提供了这些模式,而在Scala中,您可能需要Scalaz.

  • Frege默认情况下是惰性的,但在必要的地方可以通过!启用严格性,而Scala默认情况下是严格的,但具有用于惰性计算的lazy关键字。

然而,作为JVM语言,一种语言可以从另一种语言中受益。我曾经移植过一台Akka example to Frege。最后,它归结为严格性、纯洁性、函数性、面向对象和类型推断以及它们对您有多重要。

票数 41
EN

Stack Overflow用户

发布于 2013-07-28 16:53:42

除了语法问题之外,最大的区别在于类型系统和执行模型。

正如@senia已经指出的,scala是严格的,不是纯的,这并不意味着你不能写纯函数(你也可以用C写),只是编译器不会强制执行它。

Frege,OTOH是懒惰和纯洁的,这意味着所有不纯净的效果都被迫生活在ST或IO monad中。类型系统是Haskell 2010的基本系统,具有类型类和附加的更高等级的函数类型。类型推断在整个程序范围内工作,唯一的例外是具有更高等级类型的函数,其中至少必须对多态参数进行注释。下面是一个示例:

代码语言:javascript
复制
both f xs ys = (f xs, f ys)

对于此函数,编译器会推断类型:

代码语言:javascript
复制
both :: (α->β) -> α -> α -> (β, β)

请注意,由于应用了fxsys都具有相同的类型。但是现在让我们假设我们想要使用一个多态列表函数,我们可以使用不同类型的xs和ys。例如,我们想要这样写:

代码语言:javascript
复制
both reverse [1,2,3] ['a' .. 'z']

因为这两个列表具有不同的元素类型,因此具有不同的类型,所以该应用程序可能会出错。所以编译器会拒绝字符列表。

幸运的是,我们可以通过类型注释更准确地告诉编译器我们想要什么:

代码语言:javascript
复制
both :: (forall e.[e] -> [e]) -> [a] -> [b] -> ([a], [b])

这说明了以下问题:我们将传递给both一个函数,该函数执行一些列表转换,但不关心列表元素类型。然后我们传递2个可能具有不同元素类型的列表。然后我们得到一个元组,其中包含转换后的列表。请注意,both的代码不需要更改。

实现相同目标的另一种方法是编写:

代码语言:javascript
复制
both (f :: forall e.[e]->[e]) xs ys = (f xs, f ys)

类型检查器推断其余的,即xsys必须是列表,但可以有不同的元素类型。

Scalas类型系统完全(据我所知)支持OO。而Frege仅部分支持为Java导入的类型,但不支持定义自己的OO类类型。

因此,这两种语言都支持JVM环境中的函数式编程,尽管它们所处的环境完全不同。第三个利基是动态类型的,其中Clojure是JVM世界的王者。

票数 17
EN

Stack Overflow用户

发布于 2013-08-08 22:47:27

也许这是离题的,但是Scala可以用来开发Android应用程序(*),但是Frege还没有被成功使用。(**) IIRC,这是因为与现有Java库的互操作在Scala中比在Frege中容易得多,还有其他问题。

(*)买者自负。我自己只做过一些小的示例程序。

(**) Frege/Java混合已经用于Android应用程序,但仅支持Frege的应用程序仍然不可用,AFAIK。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17905322

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档