《函数式编程入门:使用 Elixir》笔记 1

学习 Elixir。

基本思想

数式编程是一种编程范式。编程范式包括构建软件的规则和设计原则,侧重于使用纯函数构建软件,这些函数的描述方式是要怎么样,而不是使改如何做!使用像 Elixir 这样的函数式语言,可以更好地利用多核 CPU,编写更简洁的代码。在函数式语言中使用函数范式,可以编写出更和谐的程序。前提是要理解其核心概念:不可变性函数声明式代码

不可变数据

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
list = [1, 2, 3]
# => [1, 2, 3]

List.delete_at(list, 1)
# => [1, 3]

list ++ [4]
# => [1, 2, 3, 4]

list
# => [1, 2, 3]

你可能会想每次都创建新值会降低效率,其实并非如此,Elixir 具有灵巧的数据结构来避免这个问题。

函数

将多个小函数组合起来可以创建更大的程序。当函数具有以下属性时,可以降低复杂性,同时具有这些属性的函数我们称之为纯函数

  1. 值是不可变的。
  2. 函数的结果只受函数参数的影响。
  3. 除了返回值,函数不会产生其他影响。

在面向对象的语言中,操作来源于方法调用,而方法属于包含数据的对象,但是在 Elixir 中,操作是独立存在的,数据必须明确的发送给函数。

1
2
3
4
# 在参数中使用函数

Enum.map(["food", "pie"], &String.upercase/1)
# => ["FOOD", "PIE"]

在 Elixir 中,我们可以使用名为管道(|>)的特殊运算符来组合多个函数的调用和结果。从中你会发现,函数式编程的每个基本构建块都是函数,这些函数遵循一些原则(如不变性),从而帮助我们构建更容易理解和更大的函数。

声明式编程

命令式编程强调如何解决问题,将每个步骤描述为操作。相比之下,函数编程是声明式的,关注解决问题的必要步骤,也就是描述数据流。

命令式的例子:

1
2
3
4
5
6
7
8
9
var list = ["dogs", "hot dogs"]

function upcase(list) {
  var newList = [];
  for (var i = 0; i < list.length; i++) {
    newList.push(list[i].toUpperCase())
  }
  return newList;
}

声明式的例子:

1
2
3
4
defmodule StringList do
  def upcase([]), do: []
  def upcase([first | rest]), do: [String.upcase(first) | upcase(rest)]
end

从这里你可以看出,我们描述了数据必须是什么样的,而不是生成结果的操作。

updatedupdated2023-12-052023-12-05