寻找功能语言

时间:2009-07-18 21:39:19

标签: programming-languages functional-programming

我是一名主要使用C ++的科学家,但我希望找到更好的语言。我正在寻找建议,我甚至不确定我的“梦想语言”是否存在,但这是我的愿望清单;

重要功能 (按重要性排序)

1.1:表现:对于科学而言,表现非常重要。我完全理解生产力的重要性,而不仅仅是执行速度,但是当你的程序必须运行几个小时时,你就无法用Python或Ruby编写它。它不需要像C ++一样快,但它必须相当接近(例如:Fortran,Java,C#,OCaml ......)。

1.2:高水平和优雅:我希望能够尽可能地集中精力学习科学并获得清晰的代码。我也不喜欢像Java那样的冗长语言。

1.3:功能完备:我喜欢功能编程,我认为它非常适合我的风格和科学编程。我不在乎语言是否支持命令式编程,它可能是一个优点,但它必须集中并鼓励函数式编程。

1.4:可移植性:应该在Linux(特别是Linux!),Mac和Windows上运行良好。不,我不认为F#在单声道Linux上运行良好,我不确定OCaml在windows上运行良好;)

1.5:面向对象,最好是在“一切都是对象”的理念下:我意识到在不久前我不得不处理纯C的时候,我更喜欢面向对象的编程。我喜欢对面向对象编程有强烈承诺的语言,而不仅仅是胆小的支持。

不是非常重要,但是那些事情会很好

2.1:“不太强”打字:我发现Haskell强大的打字系统很烦人,我喜欢能够做一些隐式转换。

2.2:工具:好的工具总是有加分,但我想这实际上取决于语言。我使用轻量级编辑Geany与Haskell一起玩,我从未感到残疾。另一方面,我不会用Java甚至Scala做同样的事情(特别是Scala似乎缺乏好的工具,这实在是太遗憾了)。 Java在这里确实是第一语言,使用NetBeans和Javadoc,使用Java编程非常简单有趣。

2.3:收集了垃圾,但没有虚拟机进行翻译或编译。我对虚拟机没有任何反对意见,但域中的两个巨头都存在问题。在纸面上,.net框架看起来好多了,特别适合函数式编程,但在实践中它仍然以Windows为中心,对Linux / MacOS的支持可怕不如它应该的那样好,所以这不值得考虑。 Java现在是一个成熟的虚拟机,但它在某些层面上让我很烦恼:我不喜欢它处理可执行文件,泛型的方式,并且它写了可怕的GUI(尽管这些东西并不是那么糟糕)。

15 个答案:

答案 0 :(得分:17)

在我看来,有三个可行的候选人:Haskell,标准ML,OCaml。 (Scala因为它编译为JVM代码而出局,因此当程序必须运行数天时,它不可能足够快。) 一切都是功能性的。我会在我知道的地方发表评论。

高性能

  • OCaml为所有情况提供最稳定的性能,但性能难以改善。你得到的是你得到的: - )

  • Haskell具有最佳并行性能,可以在8核或16核机器上得到很好的使用。如果您的未来是平行的,我建议您掌握您对类型系统的厌恶,并学会有效地使用Haskell,包括Data Parallel Haskell扩展。

    Haskell性能的缺点是,很难预测评估惰性函数程序所需的空间和时间。有很好的分析工具,但可能还需要付出很大的努力。

  • 使用MLton编译器的标准ML提供了出色的性能。 MLton是一个完整的程序编译器,并且做得非常好。

高层次,优雅

  • 语法上Haskell是明显的赢家。然而,类型系统与最近实验的遗留物混杂在一起。然而,类型系统的核心是高级和优雅的。 “类型类”机制特别强大。

  • 标准ML具有丑陋的语法,但是非常干净的类型系统和语义。

  • 从语法和类型系统的角度来看,OCaml是最不优雅的。过去实验的遗骸比Haskell更加突兀。此外,标准库不支持您可能期望的函数式编程。

主要功能性

Haskell纯粹是功能性的;标准ML非常实用; OCaml主要是功能性的(但要注意可变字符串以及库中的一些令人惊讶的遗漏;例如,列表函数对于长列表是不安全的。)

可移植性

这三个在Linux上运行良好。 Haskell开发人员使用Windows并且它得到了很好的支持(虽然它会导致它们的痛苦)。我知道OCaml在OSX上运行良好,因为我使用OCaml编写的应用程序已经移植到OSX。但我在这里的消息很少。

面向对象

在Haskell或SML中找不到。 OCaml有一个标准的OO系统被嫁接到核心语言上,并没有很好地与其他语言集成。

你没有说明为什么你热衷于面向对象。 ML仿函数和Haskell类型类提供了一些C ++中的封装和多态(也称为“泛型编程”)。

类型系统可以被破坏

所有三种语言都提供不安全的演员表。在所有这三种情况下,它们都是获得核心转储的好方法。

  

我希望能够做一些隐式演员。

我认为你会发现Haskell的类型级系统符合你的喜好 - 你可以获得一些类似于隐式转换的效果,但是安全。特别是,数字和字符串文字可以隐式地转换为您喜欢的任何类型。

工具

Haskell有很好的分析工具。标准ML有蹩脚的工具。 OCaml基本上具有标准的Unix分析和一个不可用的调试器。 (调试器拒绝跨越抽象障碍,并且它不适用于本机代码。)

我的信息可能已过期;工具图片一直在变化。

垃圾收集并编译为本机代码

检查。没有什么可以选择的。

建议

克服您对安全,安全类型系统的厌恶。研究Haskell的类型类(Wadler和Blott的原始论文以及Mark Jones的教程可能很有启发性)。 深入了解Haskell ,并确保在Hackage了解大量相关软件。

答案 1 :(得分:7)

尝试Scala。它是一种在JVM中运行的面向对象的函数式语言,因此您可以访问用Java编写的所有内容。它具有您所有重要的功能,并且具有很好的功能之一。 (显然不是#2.2 :)但是这可能会很快变得更好。)它确实有很强的打字功能,但是通过类型推断它并没有真正妨碍你。

答案 2 :(得分:5)

你刚才描述了Common Lisp ......

答案 3 :(得分:4)

在我看来,你的要求很好地描述了ocaml,除了“不太强”的打字。至于工具,我使用和喜欢tuareg模式的emacs。 Ocaml应该在windows上运行(虽然我自己没有使用它),并且非常类似于F#,FWIW。

我也考虑围绕语言的生态系统。在我看来,Ocaml的主要缺点是它没有庞大的社区,因此缺少庞大的第三方模块库,这些模块是python如此方便的一部分。必须编写自己的代码或修改其他人在互联网上找到的一次性原型模块,可以通过写一个很好的函数式语言来节省一些时间。

答案 4 :(得分:4)

你可以在单声道上使用F#;或许值得一看?我知道单声道不是100%完美(没有任何东西),但它远远不是“可怕”的非常;大多数差距都在像WCF / WPF这样的东西,我怀疑你想从FP中使用它。这似乎提供了你想要的大部分(除了显然它在VM中运行 - 但你在讨价还价中获得了大量可用的库(即大多数.NET) - 比它所基于的OCaml容易得多)

答案 5 :(得分:4)

我仍然会选择Python,但是使用NumPy或其他一些外部模块进行数字运算,或者使用Python中的逻辑和C /汇编程序中的热点。

你总是放弃舒适的周期,越多的周期越舒适。因此,您的要求是相互排斥的。

答案 6 :(得分:4)

我认为Common Lisp很适合你的描述。

1.1:性能:现代CL实现几乎与C相同。还有外部函数接口与C库交互,并且已经完成了许多绑定(例如GNU Scientific Library)。

1.2:高级优雅:是的。

1.3:主要功能:是的,但你也可以在需要的地方“必须”; CL是“多范式”。

1.4:可移植性:有几种实现对每个平台都有不同的支持。有些链接位于CLikiALU Wiki

1.5:面向对象,最好是在“一切都是对象”的理念下:CLOS,Common Lisp对象系统,比任何“卷曲”语言更接近“面向对象”,并且还具有特征你会非常想念其他地方,比如多方法。

2.1:“不太强”的打字:CL具有动态,强烈的打字,这似乎是你想要的。

2.2:工具:Emacs + SLIME(Emacs的高级Lisp交互模式)是一个非常好的免费IDE。 Eclipse(Cusp)还有一个插件,商业CL实现也会带来一个自己的IDE。

2.3:收集垃圾,但在没有虚拟机的情况下进行翻译或编译。您将要处理的Lisp图像是一种VM,但我认为这不是您的意思。

进一步的优势是增量开发:运行REPL(read-eval-print-loop),为运行映像提供实时接口。您可以动态编译和重新编译各个函数,并检查实时系统上的当前程序状态。由于编译,您没有被强制中断。

答案 7 :(得分:4)

如果您喜欢使用列表来处理大多数事情并关心性能,请使用Haskell或Ocaml。尽管Ocaml受到严重影响,因为VM设计需要将堆上的浮点数装箱(但是浮点数组和纯浮点数记录不是单独装箱的,这很好)。

如果您愿意使用多于列表的数组,或者计划使用可变状态进行编程,请使用Scala而不是Haskell。如果您正在寻找编写线程化多核代码,请使用Scala或Haskell(Ocaml要求您分叉)。

Scala的列表是多态的,因此一个int列表实际上是一个盒装的Int对象列表。当然,您可以在Scala中编写自己的int列表,但速度要快,但我认为您宁愿使用标准库。 Scala确实具有尽可能多的JVM上的尾递归。

Ocaml对我来说在Vista 64上失败了,我想是因为他们刚刚更新了最新版本(3.11.1?)中的链接器,但早期版本工作正常。

如果你正在使用夜间版本,那么Scala工具支持目前是错误的,但很快就会很好。有eclipse和netbeans插件。我正在使用emacs。我以前成功地使用了eclipse和netbeans调试器GUI。

Scala,Ocaml或Haskell都没有真正优秀的标准库,但至少可以在Scala中轻松使用Java库。如果使用mapreduce,Scala会在集成方面获胜。 Haskell和Ocaml拥有合理数量的第三方库。令我很生气的是,在Haskell中有2-3种类型的monad有不同名称的组合器。

http://metamatix.org/~ocaml/price-of-abstraction.html可能会说服你继续使用C ++。可以编写与Java / C ++几乎完全相同的Scala,但不一定是高级功能或OO风格。

http://gcc.gnu.org/projects/cxx0x.html似乎表明auto x = ...(表达式的类型推断)和lambdas是可用的。带有提升的C ++ 0x,如果你可以忍受它,看起来非常实用。当然,C ++高性能模板滥用库的缺点是编译时间。

答案 8 :(得分:2)

短版:D编程语言

Yum Yum Yum,这是一套很大的要求。

正如您可能知道的那样,从技术角度来看,面向对象,高级语义,性能,可移植性以及所有其他需求不倾向于组合。让我们将其拆分为不同的视图:

语法要求

  1. 面向对象的演示文稿
  2. 内存管理复杂性低
  3. 允许功能样式
  4. 不是Haskell(该死的)
  5. 后端要求

    1. 科学的快速
    2. 收集垃圾
    3. 在此基础上我会推荐 D编程语言它是C的继承者,试图成为所有人的一切。

      D上的

      This article是关于它的函数式编程方面。它是面向对象的,垃圾收集并编译成机器代码所以很快!

      祝你好运

答案 9 :(得分:2)

Clojure和/或Scala是JVM的理想选择

答案 10 :(得分:1)

我将假设您对您提到的语言已经足够熟悉,可以将它们排除在外。鉴于此,我认为没有一种语言可以满足您的所有期望。但是,您仍然可以查看几种语言:

  1. Clojure 这真是一种非常好的语言。它的语法基于LISP,它在JVM上运行。

  2. D 这就像C ++做得好。它具有您想要的所有功能,只是它在功能编程方面很弱。

  3. 清理这非常基于Haskell,但删除了一些Haskell的问题。缺点是它不是很成熟,并且没有很多库。

  4. 因子从语法上讲,它基于Forth,但支持类似LISP的函数式编程以及对类的更好支持。

答案 11 :(得分:1)

看一看Erlang。最初,Erlang旨在构建容错,高度并行的系统。它是一种功能性语言,包含不变性和一流功能。它有一个官方的Windows二进制版本,可以为许多* NIX平台编译源代码(例如,有一个MacPorts构建)。

就高级功能而言,Erlang支持列表推导,模式匹配,保护子句,结构化数据以及您期望的其他内容。它在顺序计算中相对较慢,但如果你正在进行并行计算,那就相当惊人了。 Erlang确实在VM上运行,但它运行在自己的VM上,这是分发的一部分。

Erlang虽然不是严格面向对象的,但确实受益于OO思维模式。 Erlang使用一个称为进程的东西作为它的并发单元。 Erlang进程实际上很像本机线程,除了开销少得多。每个进程都有一个邮箱,将发送邮件,并将处理这些邮件。将流程视为对象就足够了。

我不知道它是否对科学图书馆有很大影响。它可能不适合您的需求,但它是一种很少有人似乎知道的很酷的语言。

答案 12 :(得分:0)

你确定你真的需要一种功能语言吗?我在lisp中完成了大部分编程,这显然是一种函数式语言,但我发现函数式编程更像是一种思维集而不是语言特性。我现在正在使用VB,我认为它是一种优秀的语言(速度,支持,IDE),我基本上使用与lisp中相同的编程风格 - 函数调用其他调用其他函数的函数 - 函数通常为1 -5行长。

我知道Lisp具有良好的性能,可以在所有平台上运行,但在对图形,多线程等功能的最新支持方面,它有点过时了。

我看过clojure,但如果你不喜欢java,你可能不喜欢clojure。它是一种在java之上实现的函数式lisp风格的语言 - 但是你可能会发现自己一直使用java库来添加java的verbosoity。我喜欢口齿不清但我不喜欢clojure尽管炒作。

您是否也确定您的性能要求? Matlab是很多科学计算的优秀语言,但它有点慢,我讨厌阅读它。对于原型/场景/子单元,您可能会发现它非常有用,尤其是与其他语言结合使用。

答案 13 :(得分:0)

您的许多要求都基于传闻。一个例子:单声道“可怕”的想法。

http://banshee-project.org/

这是许多Linux发行版的官方媒体播放器。它是用C#编写的。 (他们甚至没有公开的Windows版本!)

你对各种语言相对表现的断言同样可疑。并且要求语言不使用虚拟机是非常不现实的并且完全不合需要。甚至操作系统也是运行应用程序的VM的一种形式,它可以虚拟化机器的硬件设备。

虽然您因提及工具而获得积分(虽然没有足够的优先权)。正如Knuth所说,关于某种语言的第一个问题是“调试器是什么样的?”

答案 14 :(得分:-2)

查看您的要求,我建议在Mono或运行Windows的虚拟机上安装VB。正如之前的一张海报所说,关于语言的第一件事是“调试器是什么样的”,VB / C#拥有最好的调试器。只是因为所有那些微软员工都在抨击调试器,并让附近的团队发现错误(没有双关语)来修复它。

关于VB和C#的最好的事情是大量的开发人员工具,社区,谷歌帮助,代码问题,库,与它接口的软件等等。过去我使用过各种各样的软件开发环境27年来,唯一接近的是Xerox Lisp机器环境(更好)和Symbolics Lisp机器(更糟糕)。