# 一、简介

这一介绍性章节将解决一些你可能对 F# 和函数式编程(FP)有疑问的主要问题。

## 什么是函数式编程？

纯函数式编程将所有程序视为接受参数和返回值的函数的集合。与命令式和面向对象编程不同，它不允许任何副作用，并且使用递归代替循环进行迭代。函数程序中的函数非常像数学函数，因为它们不会改变程序的状态。最简单地说，一旦一个值被赋给一个标识符，它就不会改变，函数也不会改变参数值，函数返回的结果是全新的值。在典型的底层实现中，一旦一个值被分配给内存中的某个区域，它就不会改变。为了创建结果，函数复制值，然后更改副本，留下原始值供其他函数自由使用，并最终在不再需要时丢弃。(这就是垃圾收集的想法起源的地方。)

纯函数式编程的数学基础是优雅的，因此 FP 为许多计算问题提供了漂亮、简洁的解决方案，但它的无状态和递归性质使其他范式便于处理许多常见的编程任务。然而，F# 的一个很大的优势是，你可以使用多种范式，并将它们混合起来，以你认为最方便的方式解决问题。

## 为什么函数式编程很重要？

当人们想到函数式编程时，他们经常认为它的无状态是一个致命的缺陷，而没有考虑它的优点。有人可能会说，既然一个命令式程序通常是 90%的赋值，而一个功能性程序没有赋值，那么一个功能性程序可能会缩短 90%。然而，正如约翰·休斯在他的经典论文《函数式编程为什么重要》中指出的那样，没有多少人被这样的论点所说服，也没有多少人被无状态递归编程的苦行僧世界所吸引

这个函数式程序员听起来很像中世纪的僧侣，否认生活的乐趣，希望生活能让他变得高尚。

查尔莫斯理工大学约翰·休斯分校(http://www.cse.chalmers.se/~rjmh/Papers/whyfp.html 大学 T2 分校)

要看到函数式编程的优势，你必须看看 FP 允许什么，而不是禁止什么。例如，函数编程允许您将函数本身视为值，并将它们传递给其他函数。乍一看，这可能并不那么重要，但其影响非同寻常。消除数据和函数之间的区别意味着许多问题可以更自然地得到解决。功能程序可以比相应的命令式和面向对象程序更短、更模块化。

除了将函数视为值之外，函数式语言还提供了从数学中借用的其他特性，这些特性在命令式语言中并不常见。例如，函数式编程语言通常提供 *curried functions* ，其中参数可以一次传递给一个函数，如果没有给出所有参数，结果就是一个剩余的函数等待它的其余参数。对于函数式语言来说，提供具有更好的功率重量比的类型系统也是很常见的，可以用更少的努力提供更多的性能和正确性。

## 什么是 F#？

函数式编程是解决许多棘手计算问题的最佳方法，但纯 FP 通常不适合通用编程。正因为如此，FP 语言已经逐渐接受了命令式和 OO 范例的某些方面，保持了对 FP 范例的忠实，但是包含了轻松编写任何类型程序所需的特性。F# 是这条道路上的天然接班人。它也不仅仅是一种 FP 语言。

一些最流行的函数式语言，包括 OCaml、Haskell、Lisp 和 Scheme，传统上都是使用定制运行时实现的，这导致了缺乏互操作性等问题。F# 是一种通用编程语言。NET，一个通用运行时。F# 平滑地集成了所有三种主要的编程范例。使用 F#，您可以选择最能有效解决问题的范式。如果你是一个纯粹主义者，你可以做纯函数式编程，但是你可以很容易地在同一个程序中结合函数式、命令式和面向对象的风格，并利用每种范式的优势。像其他类型化函数语言一样，F# 是强类型化的，但也使用推断类型，因此程序员不需要花时间明确指定类型，除非存在歧义。此外，F# 与无缝集成。NET 框架基类库。在 F# 中使用 BCL 就像在 C#或 Visual Basic 中使用它一样简单(甚至可能更简单)。

F# 是以 Objective Caml (OCaml)为模型的，OCaml 是一种成功的面向对象的函数式编程语言，然后经过调整和扩展，在技术上和哲学上与. NET 很好地结合在一起。NET，并使用户能够做任何事情。NET 允许。F# 编译器可以编译它所支持的公共语言基础设施的所有实现。NET 泛型，它甚至提供了内联中间语言代码。F# 编译器不仅为任何命令行界面生成可执行文件，还可以在任何有命令行界面的环境下运行，这意味着 F# 不限于 Windows，而是可以在 Linux、苹果的 OS X 和 iOS 以及谷歌的安卓操作系统上运行。

F# 2.0 编译器与 Visual Studio 2012、Visual Studio 2010 一起分发，并作为 Visual Studio 2008 的插件提供。它支持智能感知表达式完成和自动表达式检查。它还提供工具提示来显示已经为表达式推断了哪些类型。程序员经常评论说，这真的有助于将语言带入生活。F# 2.0 也有一个开源版本，根据 Apache 许可证授权，可从[http://github.com/fsharp](http://github.com/fsharp)获得。

F# 首先由剑桥微软研究院(MSR)的唐·赛姆实现。该项目现已被华盛顿州雷德蒙的微软公司接受，编译器和 Visual Studio 集成的实现现已由位于剑桥和雷德蒙的团队开发。在撰写本文时，团队专注于实现 F# 3.0，它在 Visual Studio“dev 11”测试版中可用。

虽然其他 FP 语言运行在。NET，F# 已经确立了自己作为事实上的。NET 函数式编程语言，因为它的实现质量及其与。NET 和 Visual Studio。

没有其他的。NET 语言和 F# 一样好用，一样灵活！

## 谁在用 F#？

F# 在微软内部有着强大的影响力，无论是在 MSR 还是整个公司。拉尔夫·赫布里奇是 MSR 应用游戏集团的领导者，该集团专门研究机器学习技术，是 F# 越来越多粉丝的典型代表:

第一个应用是解析分布在 300 多个目录中的 11，000 多个文本文件中的 110GB 日志数据，并将其导入到一个 SQL 数据库中。整个应用长达 90 行(包括注释！)并在 18 小时内完成了解析源文件和导入数据的任务；这样算下来，每秒钟要处理惊人的 10，000 个日志行！请注意，我根本没有优化代码，而是以最明显的方式编写了应用。我真的很惊讶，因为我计划了至少一周的时间来编写和运行应用。

第二个应用是对数百万条反馈的分析。我们已经开发了模型方程，我只是把它们作为 F# 程序输入；加上从 SQL 数据库读取数据和将结果写入 MATLAB 数据文件，F# 源代码有 100 行长(包括注释)。再次，我对运行时间感到惊讶；在一台标准的台式计算机上，数百万个数据项的整个处理过程需要 10 分钟。我的 C#参考应用(来自一些早期的任务)几乎有 1000 行长，速度也并不快。从开发模型方程到获得第一个真实世界的数据结果，整个工作花了两天时间。

拉尔夫·赫布里奇，微软研究院(http://blogs.msdn.com/dsyme/archive/2006/04/01/566301.aspx T2)

微软之外的 F# 使用也在快速增长。我问了 Cyfeon Solutions 的 Chance Coble，关于 F# 给他的工作带来了什么。

F# 一遍又一遍地向我陈述它的理由。我决定尝试的第一个项目是机器视觉努力，它将从提交的指纹卡中识别和提取指纹，并将它们加载到生物识别系统中。项目计划是手动执行指纹提取，这变得越来越麻烦，自动化结果是一个巨大的胜利(用很少的代码)。后来我们决定将 F# 工作包含在一个用 C#编写的更大的应用中，并轻松地完成了集成。从那以后，我在机器学习、特定领域语言设计、三维可视化、符号分析和任何需要高性能数据处理的项目中使用了 F#。能够轻松地将功能模块集成到现有的生产规模应用中，这使得 F# 不仅很有趣，而且是项目领导的重要补充。用一个成熟而丰富的平台统一函数式编程。NET 开辟了大量的机会。

Cyfeon Solutions 首席技术官 Chance Coble(私人电子邮件)

## 这本书是给谁的？

这本书主要面向想要在 F# 上快速上手的 IT 专业人士。工作知识。NET 框架和一些 C#或 Visual Basic 的知识会很好，但这不是必需的。你真正需要的只是一些用任何语言编程的经验，这样你才能舒服地学习 F#。

即使是完全的初学者，他们以前从未编程过，并且正在学习 F# 作为他们的第一种计算机语言，也应该会发现这本书非常易读。虽然它本身并不试图教授入门编程，但它确实仔细呈现了 F# 的所有重要细节。