F#奇妙游(3):函数与编程
函数与编程
程序设计的概念
编程,programming,也叫做程序设计,有很多小的方向,有些方向接近使用机器进行计算的科学研究,有些方向接近使用机器、程序设计语言来解决实际问题。这是驱动编程这门工程+艺术的行当的两个驱动方向。理论与应用,一方面进行分析,探索可能性、边界,一方面进行综合,与领域结合提供解决方案或者提供答案。
函数
这与数学这门学问也有一定的相似之处,数学理论与应用数学,共同推动这门科学的发展。数学里面,对关于函数这个表达映射的概念,有海量的研究,高等数学层次关于函数定义域、值域的初步分析,实函数、复变函数、泛函是值域方面从实数空间、复数和函数的不同研究对象。
由于数学极度抽象接近本质的特性,计算机研究之初就把函数作为一个非常基本的概念引入。
从最早的汇编跳转到子程序,到Fortran、C成为面向过程的程序设计语言,到包罗万象的Lisp系列,然后因为大型工程代码的面向对象编程,到现在主流的多范式程序设计,函数一直就在那里,不同的形式、不同的名称,实质上都是对同一个概念的反复定义、再定义。
那么学习编程,函数是一个无法绕过的切入点。函数作为核心的抽象概念,理解函数才能理解计算机工作室重复进行一些列操作的核心观念。计算机,只不过是能够以极高地速度(频率)执行一些操作,这些操作从定义域 Ω ↦ Π \Omega\mapsto\Pi Ω↦Π值域。只是根据定义域和值域的不同,函数才有各种分类。
- 纯函数:定义域和值域都是一些抽象的数据,不影响硬件;
- 有副作用的函数:定义域和值域中包括了硬件(例如寄存器)的状态,最简单的,输出函数,改变了屏幕像素对应的寄存器;
- 对象的成员方法:定义域和值域中包括了强内聚数据块状态的函数;
从抽象的层次来说,建立包括什么东西的定义域和值域,是不同类型函数的核心区别。而程序设计的不同范式,却别仅仅就在于函数的上下文识别方式、函数的表达方式、函数定义域的表达方式、函数值域的表达方式。
从不同函数的实现方式来说:
纯函数
输入是一块内存,输出是一块内存,输出的内存与输入的内存没有交叉,输入的内存只读;
有副作用的函数
输入的是一些内存,输出的一些内存,输入的内存和输出的内存有交叉(也就是输入的内存可能被改变),并且输入的内存可能不显式给定为函数的参数(还是以输入输出函数为例,F#中的printfn,输入就是字符串,屏幕像素对应的内存是隐式输入,输出就是屏幕像素对应内存被改变的状态。
对象的成员函数
在有些语言中,比如Python,对象用self
作为参数输入,函数改变其状态。
在F#中,面向对象的范式是直接支持的,而为对象扩展方法也是很简单的。
// 把这段代码存储为functions.fsx,就可以直接运行
// `dotnent fsi functions.fsx`
// 来运行
open System
type Int32 with
member this.Prod ()=
let rec prod n p =
match n with
| 1 -> p
| _ -> prod (n-1) (p*n)
prod this 1
let prod n =
let rec _prod _n p =
match _n with
| 1 -> p
| _ -> _prod (_n-1) (p*_n)
_prod n 1
printf $"%d{(int 10).Prod ()} %d{prod 10}"
从只读对象Int32
的成员函数Prod
和函数prod
来比较,明显这两个函数的语义是一样的,唯一不同的就是定义和调用的语法。
总结
- 函数是一个很好的抽象工具;
- 程序设计中,掌握函数的概念非常有力;
- 不同的编程范式,都可以用函数的概念来予以描述;
- 表达定义域的内存(输入)与表达值域的内存(输出)重叠,就称为纯函数式语言和其他范式语言的差别。
用F#来入门程序设计
函数式
经过对函数的一番胡说八道,本秃觉得函数式程序设计语言实际上可以作为很好的入门程序设计教学工具。
总的来看,有以下几个优点:
- 更加接近计算机利用电路进行计算的本质;
- 学过高等数学或者类似函数概念的人更容易理解编程的基础概念;
- 与面向对象这些更加抽象的东西相比,输入一个(堆)数字,输出一个(堆)数字很直观;
- 兼容性好,很容易扩展到更高阶的程序设计概念;
- 对数据+算法=程序的核心打下好的基础;
- 容易灌输分而治之的核心程序设计核心理念。
F#
而F#作为一个不做作、不强迫的函数式程序设计语言,是一个非常好的入门对象。
- 虽然F#不算流行的语言,但是背靠大树.NET平台,还是很香的,很容易上手能够干有意义的事情;
- F#的工具支持非常完善,windows上装了.NET SDK就有全套F#用,VS和VS Code可重可轻;
- F#的语法噪音非常少,
let
和=
包打天下,上手5分钟fsx可以编起来了; - F#多范式编程上限高,web开发、数据处理,值得长期投入。