1.2 当下的OCaml

589 阅读5分钟

OCaml是一种函数式编程语言。函数式语言的关键语言抽象是数学函数。一个函数将输入映射到输出;对于相同的输入,它总是产生相同的输出。也就是说,数学函数是无状态 的:它们不维护任何额外的信息或状态,这些信息在函数的使用之间不会持久存在。函数是首类对象:你可以将它们用作其他函数的输入,并产生函数作为输出。用函数表达一切使得统一简单的编程模型易于推理,而不像其他家族的语言中找到的过程和方法那样复杂。

命令式 编程语言 (如 C 和 Java ) 涉及可变状态,该状态在整个执行过程中会发生变化。命令指定如何通过破坏性地更改状态来计算。过程 (或方法) 除了产生返回值之外,还有更新状态的副作用。

可变性幻想 是这样的:它易于推理:机器这样做,然后那样做等等。

可变性的现实 是,机器擅长复杂的状态操作,而人类不擅长理解它。之所以如此,其本质在于可变性破坏了引用透明度 :用表达式的值替换表达式而不影响计算结果的能力。在数学中,如果 f(x)=yf(x)=y, 那么你可以用 yy 替换你在任何地方看到的 f(x)f(x)。在命令式语言中,你不能这样做:ff 可能有副作用,因此在时间 tt 计算f(x)f(x)可能与时间 tt' 计算的结果不同。

相信机器操纵单个状态并一次执行一件事情的诱惑很大。计算机系统会不遗余力地尝试提供这种错觉。但这只是一种错觉:实际上,有许多状态分布在线程、核心、处理器和网络计算机之间。并且机器同时做许多事情。可变性使得分布式状态和并发执行的推理变得极其困难。

然而,不可变性,使程序员免于这些担忧。它提供了构建正确和并发程序的强大方式。OCaml主要是一门不可变的语言,像大多数函数式语言一样。它确实支持命令式编程的可变状态,但我们将在本书的许多章节之后才使用这些功能 —— 部分是因为我们根本不需要它们,部分是为了让你从一种你可能没有意识到的依赖中“戒断”。这种对不可变性的自由是OCaml能够给你带来最大的视角变化之一。

OCaml 的特点

OCaml是一种静态类型类型安全 的编程语言。静态类型语言在编译时检测类型错误;如果检测到类型错误,该语言将不允许程序执行。类型安全的语言限制了可以在哪种数据上执行哪种操作。实际上,这可以防止许多愚蠢的错误(例如,将整数视为函数)以及许多安全问题:超过一半的计算机紧急情况响应小组(CERT,一个负责网络安全的美国政府机构)报告的入侵是由于缓冲区溢出引起的,而这是类型安全语言中不可能发生的。

一些语言,比如 Python 和 Racket,是类型安全的,但是是动态类型 的。也就是说,只有在运行时才能捕获到类型错误。其他语言,如 C 和 C++,是静态类型的,但不是类型安全的:它们检查某些类型错误,但不能保证不存在所有类型错误。也就是说,没有保证在运行时不会出现类型错误。还有一些语言,如Java,使用静态和动态类型的组合来实现类型安全。

OCaml 支持许多高级特性,其中一些你可能已经遇到过,而另一些可能是新的特性:

  • 代数数据类型: 你可以轻松地在OCaml中构建复杂的数据结构,而无需费心处理指针和内存管理。模式匹配 —— 我们很快就会了解的一个特性,它可以检查数据结构的形状 —— 使它们更加方便。

  • 类型推断: 你不必在每个地方都写下类型信息。编译器自动推断出大多数类型。这可以使代码更容易阅读和维护。

  • 参数化多态: 函数和数据结构可以通过类型参数化。这是能够重用代码的关键。

  • 垃圾收集: 自动内存管理减轻了内存分配和释放的负担,这对于像 C 这样的语言来说,是常见的错误来源。

  • 模块: OCaml 通过使用模块轻松地组织大型系统。模块用于将实现封装在接口后面。OCaml 通过提供操作模块的函数(称为函子),来扩展大多数语言的模块功能。

工业中的 OCaml

OCaml 和其他函数式语言远不如 Python、C 或 Java 流行。OCaml 的真正优势在于语言操作(即编译器、分析器、验证器、证明器等)。这并不奇怪,因为 OCaml 是从定理证明领域演变而来的。

这并不是说函数式语言没有在工业中使用。有许多行业项目使用 OCamlHaskell 以及其他语言。Yaron Minsky (康奈尔大学02届博士) 甚至写了一篇关于在金融行业使用 OCaml 的论文。它解释了 OCaml 的特性如何使其成为快速构建有效的复杂软件的好选择。

注:本书是康奈尔大学 CS 3110 数据结构和函数式编程的教材。原书为英文版,在学习的过程中,根据自己的理解,翻译了一些,做一个记录,版权归原作者所有,如有侵权,请联系我删除。