函数式编程(Functional Programming)

在了解Scheme的语法之前,我们首先应该明白函数式编程(Functional Programming)这种范式(Paradigm)。简单引用一下我们老师的描述:

Functional Programming is a paradigm that is defined by building software out of pure functions and avoiding shared states, mutable data and side-effects.

函数式编程时一种通过使用纯函数来避免共享状态、可变数据以及副作用的编程范式。

用自己的话翻译一下,函数式编程强调输入和输出,而不是其实现的步骤和过程。在函数式编程中,相同的输入必然会有相同的输出,不会受到外在因素的影响。因此,函数式编程通常具有以下特性:

  • 无状态(stateless)

    • 无状态也意味着函数式编程中没有变量这个概念。本质上来说,变量就是在描述程序的某种状态。

      • 输入
      • 经过函数处理
      • 输出
  • 无副作用(Side-effect free)

    • 由于函数式编程不存在变量,更不存在全局变量。它只使用输入值进行函数式加工,然后输出。因此它几乎没有副作用。
  • 强模块化设计(Enforced modular design)

    • 一个函数只干一件事情,每件事情都可以打包为一个模块
  • 不原生支持for、while等循环语句

    • 虽然不支持,但是所有的循环均可通过递归实现

常见的函数式编程语言:

  • Scheme
  • LIPS

Tips:除了除函数式编程外的其他范式

  • 面向对象(Object-Oriented Programming, OOP)

    • 抽象类(Abstract data types)
    • 封装(Encapsulation )
    • 继承(Inheritance)
    • 动态绑定(Dynamic binding)
  • 逻辑编程(Logic Programming)

    • 数据库(Database)
    • 关联(Relations)
    • 查询与匹配(Query and matching)
    • 推理(Reasoning)
  • 面向服务编程(Service-Oriented Programming)

    • 面向服务编程是面向对象、函数式编程、逻辑编程的结合体。

Scheme入门

IDE

“Hello World"

(write “Hello World!”)

语法

  • 语句构成

    (<operator> <operand>, <operand>*)
    (<操作符> <操作数>, <操作数>*)
  • 关键字(keywords)

  • 标识符(Identifiers)

    • 与OOP中的变量含义不同,标识符只是常量的昵称
  • 结构形式(structured forms)

    • lists, vectors
  • 常量(constant data)

    • numbers, characters, strings, quoted vectors, quoted lists, quoted symbols, etc.
  • 空白(whitespace)

    • Scheme忽略空白
  • 注释(comments)

    ; 等同于//#

    #|
    多行注释
    多行注释
    #|

数据类型

  • Numbers

    整数(Integer),实数(reals),有理数(rationals),复数(complex)

  • Booleans

    #t - true

    #f - false

  • Characters - make up strings

    #\space, #\sp
    #\newline, #\nl
    #\tab, #\ht
    #\backspace, #\bs
    #\return, #\cr
    #\page, #\np
    #\null, #\nul
  • Symbols

    (quote E)
    'x
    'y
    (symbol? 'xyz) =>  #t
    (symbol? 42)   =>  #f
  • Strings

    "This is a string"
    "This is a string \"with quotes\""
    "" – empty string
    There are a series of (string-<operator> commands
    (string-append “Hello ” “World!”)

    Symbols vs Strings

    (string-length "James") => 5
    (string-length 'James) => error, string type expected.
    (symbol-length 'James) => error, function does not exist
    (symbol? 'James) => true        (string? 'James) => false
    (symbol? 'Ja  mes) => error        (string? "Ja  mes") => true
  • identifiers/variables - sequences of characters without the double quotes that serve as identifiers

      i
      not
      +
      this-is-a-test
  • Lists

    (1 2 3)
    (1 2.5 33/2)
    (“hi” (1 2 3) 27/2)

基本操作

定义函数

  • 在Scheme中,我们使用lambda定义函数

    • 语法:

      (lambda (parameter list) function definition)
      ((lambda (x y) (+ x y)) 1 2) 
        => 3
  • define关键字

    (define <function name> (lambda (<params>) <function>))
    (define addTwo (lambda (x y) (+ x y)) )
    (addTwo 1 2) => 3
  • Example;

    ; Scheme
    (define absolute (lambda (x)
                       (if (negative? x)
                           (- x)
                           x
                           ) ;end if
                       ) ; end lambda
      ) ; end define
    # Same as in Python
    def absolute(x):
     if (x < 0):
         return -x
     else:
        return x

数学运算符

  • 加减乘除

    (+ a b) -> a + b
    (- a b) -> a - b
    (\ a b) -> a \ b
    (* a b) -> a * b
  • 其它常用运算函数

    (abs x)
        ; returns absolute value
    
    (max …)
        ; returns the maximum value in the parameters
    
    (min …)
        ; returns minimum
    
    (round x)
        ; rounds toward zero
    
    (floor x)  - (ceiling x)
        ; round value down or up 

逻辑运算符

  • 基本逻辑运算符

    (and
    (or
        ; And 和 or可以传递多个参数,不仅限于2个
    
    (not
  • 关系运算符

    (= a b)
        ; 注意:没有==
  • Sameness in Scheme

    (eq?
        ; 类似于eqv,但是可以辨别的更精细一些
    (equal?
        ; 如果两个项目递归等价,则返回 true — paris、vectors、字符串等..
    (sqv?
        ; 返回 true 通常应被视为相同 - 适用于integer, characters 和实数(real)

参考

Scheme语言简明教程

什么是函数式编程,它解决什么问题?

什么是 Functional Programming?