Scala函数式编程设计原理 第一课 编程范式(Programming Paradigms)

     我使用Scala有一两年的时间了,这门语言仿佛有一种魔力,让人用过就不想放手。Scala给我的整个程序生涯带来了非常深刻的影响,让我学会了函数式编程,让我知道了世界上居然还有这么一种优雅、高效、强大的语言。

     Scala在国外已经非常流行,但是不知为何,在国内总是不温不火,在此,我特别想为Scala这门语言在国内的发展做一些事情。不才不敢谈Scala的编程经验,因为要成为Scala大神还有很长的路要走,只好翻译一份Scala视频教程以飨读者,大家发现有误的地方,请多多批评指教。

    这个视频的作者是Scala的作者马丁,出处是coursera。

    下面正式开始:

    

       非常欢迎大家来参加我的“Scala函数式编程设计原理”课程。正如名字所说,我们将要来学习相当多的Scala的编程的知识,但是这不是这个课程的主要目的,这份教程的主要目的是教大家从自身的第一编程范式(母编程范式)转换到函数式的编程范式,你将会看到一些函数式的程序,了解构建这些函数的方法,还有这么写程序的理由。你将会发现函数式编程范式是一种和Java或者C的编程范式截然不同的编程范式,事实上,你可以结合这两种编程范式编程,这是Scala的优点之一,这样一来,它便提供了一种轻量级的编程范式转换,让你可以从其他编程范式转化成纯函数式的编程方式。这堂课我们不打算继续跟进学习,我们全身心的放松一下,先见识一下函数式编程是啥样,让你们开开眼界。这样一来,我相信你能更好的吸收这种编程思想,一旦你开始学函数式的程序,你就要能够把函数式风格整合进你的日常编程中。事实上,Scala是非常适合从面向对象编程范式转化到函数式编程范式的人群,而且Scala把这两种范式结合的非常的好。好,下面我们开始吧:

      函数式编程范式是一种不同的编程范式,如果我们回归这个编程范式这个词的意思,得需要解释一下:

      “编程范式”:“范式”在科学上讲是描述一种清楚描述的概念或者在科学的实践中的思想方式。主要的“编程范式”有:“命令式的编程范式(imperative programing)”、“函数式的编程范式(functional programing)”、“逻辑式的编程范式(logic programing)”。命令式的编程范式语言:Java或者C等。逻辑式的编程范式通常不被提及,还有一种贯穿这三种编程范式的例外一种范式:“面向对象编程范式(object-oriented programing)”。因为面向对象编程范式可以和这三种主要的编程范式任意的结合,例如面向对象和函数式就结合的相当好。

      下面我们复习一下什么是命令式的编程范式——imperative programing。

       命令式的编程有以下几个特点:

       1、定义可变变量,可以修改可变变量

       2、运用各种赋值。(using assignments) 

       3、运用控制语句例如:if-then-else,循环语句(loops),break语句、continue、return等等

      通常认为了解命令式编程范式最好的非正规方式就是去了解冯.若依曼计算机的指令序列,这算是命令式编程的鼻祖。因此,一个冯若依曼计算机,它基本上包含一个信息处理器和一个内存,内存和处理器之间是主线(bus),主线用于两者之间的通信。(如下图所示)最重要的是:这个主线的宽度关乎一个机器字的大小,现在是32位或者64位。因此,产生了这么一种情况,由于现在计算机的架构影响,现在程序都没有小数量级的,全是大数量级的。

Scala函数式编程设计原理 第一课 编程范式(Programming Paradigms)_第1张图片

      现在计算机语言中的很多概念都和当年的冯若依曼机器有很多切合点:

      可变变量     ===     内存单元

      变量的引用   ===   加载指令

      变量的赋值  ===   存储指令

      控制语句    ===     jumps(类似于汇编的jump指令)


      Scala函数式编程设计原理 第一课 编程范式(Programming Paradigms)_第2张图片

问题来了:我们怎样如何避免这种概念化的一个字一个字的编程方式呢?我们想在一个大的机构中来推到程序,而不是一个字一个字的叙述。这个争论是由John Backus提出的,值得注意的是:John Backus 事实上是第一个计算机高级语言的创造者,叫Fortran在1950年左右,大概过了20年后,他发现传统的命令式的编程模式已经不适合,他需要新的编程模式,这个新的编程模式就是函数式编程。当时,John Backus说过纯命令式编程模式会被冯若依曼机器所限制——我们用一个字一个字的构造数据,如果我们想要扩大,我们必须定义更高级编程思想例如:集合(collections),多项(polynomials),几何(geometric),形状(shapes), 字符串(strings),文件(documents)等等。为了彻底的解决,我们需要有一套理论来诠释这些集合(collections),多项(polynomials),几何(geometric),形状(shapes), 字符串(strings),文件(documents)等等东西,以便我们可以更好的来书写和使用它们。那么,这个理论是什么呢?这个理论包含:

   1、一个或者多个数据结构

   2、这些数据结构的操作

   3、描述这些数值和操作关系的法则

   通常情况下,这套理论不推荐可变的!(可变的意思是我们可以改变的东西,例如可变变量)也就是说,理论体系的东西都是没有副作用的,可以重复使用,结果都一致!

  下面有一个关于两个多项式按照理论规则求和的例子:

      

   但它并没有定义一个操作符来改变一个系数,同时保持多项式相同!

  而在命令式的程序中,可以这么写:

  Scala函数式编程设计原理 第一课 编程范式(Programming Paradigms)_第3张图片

我们可以给Polynomial p的coefficient 的第一个数赋值为42,但是这个p还是原来同一个那个p,这在数学中是不可取的,并且会触犯语法,和理论体系相背。下面我们看看另一个例子:

假设这套理论的strings字符串定义了一个连接符“++”,连接符是这么结合的:


但是,这个理论并没有定义一个操作符去改变一个序列中的元素,因此字符串序列一直是同样的!(这一点上,一些语言上做的都是正确的,例如:Java的字符串就是不可变的。)

       如果我们想要履行这种高级的观念,遵从数学理论,就绝不出现可变量!

       1、这套理论体系不允许出现可变量!

       2、可变量能破坏这套理论体系的语法规则

       因此,让我们:

       1、可以把运算符定义成函数,运算符就是函数,可以定义很多运算符。

       2、拒绝可变变量

       3、有一些强大的方式去抽象和构建函数

       因此,开始函数式编程的第一步,意味着要拒绝可变变量。事实上,有两种方式去认识函数式编程,一种受限制的层面和一个更大众的层面。

       以受限制多的层面:函数式编程意味着在没有可变变量、赋值、循环和其他明亮式控制语句的情况下编程。

       以更大众的层面:函数式编程意味着把注意力都集中在函数上。

       特别的,函数就是能被产生、消耗、和组装的数值。

       所有以上内容在函数式的计算机语言中都变得很简单。

       于是,我们可以两种层面去认识函数式编程语言:

       受限制的层面:一个函数式的编程语言是没有可变变量,不能赋值,没有命令式的控制结构的。

       比较大众的层面:一个函数式的编程语言能够把重心侧重于构建优雅的函数上。

       特别的,函数是函数式编程语言的一等公民,这意味着:函数可以被定义在任何位置,包括其他函数中;向其他的值一样,函数可以被当做参数传递;向其他数值一样,存在一套操作符去组件函数。

       下面是一些函数式的编程语言:

        受限制较多的:Pure Lisp family of languages(Pure Lisp、XSLT、XPath、XQuery、FP)、Haskell(without I/O Monad or UnsafePerformIO)

        比较大众的:Lisp family of languages(Lisp、Scheme、Racket、Clojure)、ML family of languages(SML、Ocaml、F#)、Haskell、Scala 



        函数式编程语言的历史:

      Scala函数式编程设计原理 第一课 编程范式(Programming Paradigms)_第4张图片


      函数式编程变得越来越流行,因为它提供了以下这些优点:

      1、更简洁的表达方式

      2、更好的模块化

      3、非常擅长多核并行开发或者云计算的运算

     


你可能感兴趣的:(Scala函数式编程设计原理 第一课 编程范式(Programming Paradigms))