# 现代编程语言终极测评：三星篇（下）

## 函数式编程=安心

### 纯函数编程

// Impure, returns different values on subsequent calls.
// Giveaway: takes no arguments.
Math.random(); // => 0.5456412841544522
Math.random(); // => 0.7542151348966241
Math.random(); // => 0.4534865342354886

let result;
// Impure, mutates outside state (the result variable)
// Giveaway: returns nothing
function append(array, item) {
result = [ ...array, item ];
}


// Pure, doesn't mutate anything outside the body of the function
function append(array, item) {
return [ ...array, item ];
}

// Pure, always returns the same output given the same input.
function square(x) { return x * x; }


### 代数数据类型

type shape =
| Square(int)
| Rectangle(int, int)
| Circle(int);


interface Shape {}

public class Square implements Shape {
private int width;

public int getWidth() {
return width;
}

public void setWidth(int width) {
this.width = width;
}
}

public class Rectangle implements Shape {
private int width;
private int height;

public int getWidth() {
return width;
}

public void setWidth(int width) {
this.width = width;
}

public int getHeight() {
return height;
}

public void setHeight(int height) {
this.height = height;
}
}

public class Circle implements Shape {

}

}
}


### 模式匹配

type optionBool =
| Some(bool)
| None;

let optionBoolToBool = (opt: optionBool) => {
switch (opt) {
| None => false
| Some(true) => true
| Some(false) => false
}
};


let optionBoolToBool = opt => {
if (opt == None) {
false
} else if (opt === Some(true)) {
true
} else {
false
}
}


### 空值

let happyBirthday = (user: option(string)) => {
switch (user) {
| Some(person) => "Happy birthday " ++ person.name
};
};


### 错误处理

type result('value, 'error) =
| Ok('value)
| Error('error);

let happyBirthday = (user: result(person, string)) => {
switch (user) {
| Ok(person) => "Happy birthday " ++ person.name
| Error(error) => "An error occured: " ++ error
};
};


### 管道向右操作符

let isValid = validateAge(getAge(parseData(person)));


let isValid =
person
|> parseData
|> getAge
|> validateAge;


### :-1::-1:社区

——国际威胁情报、黑客动向以及维基解密资讯平台Hacker News @momentoftop

### 结论

——摘自博客文章《软件设计的4项更佳原则》（Four Better Rules for Software Design），作者David Bryant Copeland

## OCaml

OCaml是一门函数式编程语言，它是Object Caml的简写。但事实上，你几乎不会发现有任何人在OCaml中使用对象。

OCaml的问世时间几乎和Java相当，名字中的“Object”可能反映了“Object”在那个年代的夸张宣传。OCaml是在Caml基础上进行设计的。

### :-1::-1:生态系统

OCaml社区很小，这意味着我们不能找到适用普遍用例的高质量库。举个例子，OCaml缺少良好的web框架。

### :-1:工具

OCaml的工具很糟糕，它有三个包管理器——Opam，Dune以及Esy。

OCaml以特别差的编译器错误信息而“臭名昭著”，这虽然不是一个致命伤，但也足以令人沮丧了，开发者效率也会受到影响。

### :-1:并发性

“多核随处可见（Multicore is coming Any Day Now™️）”总结了OCaml中并发性的事。OCaml开发者等待恰当的多核支持已经等了很多年了，它在近期似乎还不会加入到OCaml中。OCaml似乎是现在唯一一门缺少恰当多核支持的函数式语言。

### :+1:空值

OCaml没有空引用，它使用Option模式来表示可能不存在的值。

### :+1:不可变性

OCaml为不可变性数据结构提供了一流支持。

### :+1:模式匹配

OCaml有很好的模式匹配支持。

### 结论

OCaml是一门挺好的函数式语言。它最主要的缺点就是有点劣势的并发性支持，并且OCaml社区很小，因此生态系统也很小，缺乏学习资源。

## Scala

Scala是少数真正的多重范式编程语言之一，对面向对象编程和函数式编程都有很好的支持。

### :+1:生态系统

Scala在JVM之上运行，这意味着它能获取Java库的大生态系统。这能大幅提高后端开发者的生产力。

### :+1:类型系统

Scala可能是唯一一个缺乏恰当类型推论的类型化函数式语言，它的类型系统并不健全。Scala的类型系统不像其他函数式语言那么好。

### :-1:简洁性/可读性

Scala是少数属于C语言家族的函数式编程语言之一。C语系的编程语言更多使用命令式编程，而ML语系的编程语言更多是函数式编程。

Scala中的代数数据类型没有合适的语法，这会降低可读性：

sealed abstract class Shape extends Product with Serializable

object Shape {
final case class Square(size: Int) extends Shape
final case class Rectangle(width: Int, height: Int) extends Shape
final case class Circle(radius: Int) extends Shape
}


type shape =
| Square(int)
| Rectangle(int, int)
| Circle(int);


### :-1::-1: 速度

Scala在JVM之上运行，意味着它的程序会花更长时间启动。

### :-1:学习时需要付出的代价

Scala有许多特征，这使得它很难学。和C++一样，Scala的语言特征过多了。

### :+1:不可变性

Scala为不可变性数据结构提供了一流支持（使用样本类）。

### :ok_hand:并发性

Scala运行在JVM之上，但JVM不是为并发性建立的。从好的方面而言，Akka工具箱非常成熟，在JVM上提供了类似Erlang的并发性。

Scala有很好的模式匹配支持。