The central idea is that each process is a functional program over an input stream of messages. The result from the functional program is an output stream of messages to others. From this perspective, Erlang is a rather clean functional language; there are no destructive updates to data structures (like setcar in Lisp and most Schemes).
With few exceptions, all built-in functions such as operations on ETS tables also follow this model: apart from efficiency issues, those BIFs could actually have been implemented with pure Erlang processes and message passing.
So yes, the Erlang language is functional, but a collection of interacting Erlang processes is a different thing. Each process is an ongoing computation, and as such it has a current state, which can change in relation to the other processes. Even a database is just another process in this respect.
In my mind, this is one of the most important things about Erlang: outside the process, there could be a storm raging, but inside, things are calm, letting you focus on what that process should do - and only that.
It is useful and powerful to have strong controls over value mutability and side effects, but I believe these are peripheral to functional programming. Nice to have, but not essential. Even in languages that do have these properties, there is always a way to escape the purity of the paradigm.1
There is a grayscale continuum between truly pure FP languages that you can't actually use for anything practical and languages that are really quite impure but still have some of the FP nature to them:
Book FP: Introductory books on FP languages frequently show only a subset of the language, with all examples done within the language's REPL, so that you never get to see the purely functional paradigm get broken. A good example of this is Scheme as presented in The Little Schemer.
You can come away from reading such a book with the false impression that FP languages can't actually do anything useful.
Haskell: The creators of Haskell went to uncommon lengths to wall off impurity via the famous I/O monad. Everything on one side of the wall is purely functional, so that the compiler can reason confidently about the code.
But the important thing is, despite the existence of this wall, you have to use the I/O monad to get anything useful done in Haskell.2 In that sense, Haskell isn't as "pure" as some would like you to believe. The I/O monad allows you to build any sort of "impure" software you like in Haskell: database clients, highly stateful GUIs, etc.
Erlang: Has immutable values and first-class functions, but lacks a strong wall between the core language and the impure bits.
Erlang ships with Mnesia, a disk-backed in-memory DBMS, which is about as impure as software gets. It's scarcely different in practice from a global variable store. Erlang also has great support for communicating with external programs via ports, sockets, etc.
Erlang doesn't impose any kind of purity policy on you, the programmer, at the language level. It just gives you the tools and lets you decide how to use them.
OCaml and F#: These closely-related multiparadigm languages include both purely functional elements as well as imperative and object-oriented characteristics.
The imperative programming bits allow you to do things like write a traditional for loop with a mutable counter variable, whereas a pure FP program would probably try to recurse over a list instead to accomplish the same result.
The OO parts are pretty much useless without the mutable keyword, which turns a value definition into a variable, so that the compiler won't complain if you change the variable's value. Mutable variables in OCaml and F# have some limitations, but you can escape even those limitations with the ref keyword.
If you're using F# with .NET, you're going to be mutating values all the time, because most of .NET is mutable, in one way or another. Any .NET object with a settable property is mutable, for example, and all the GUI stuff inherently has side-effects. The only immutable part of .NET that immediately comes to mind is System.String.
Despite all this, no one would argue that OCaml and F# are not functional programming languages.
JavaScript, R, Lua, Perl...: There are many languages even less pure than OCaml which can still be considered functional in some sense. Such languages have first-class functions, but values are mutable by default.
Foototes:
Any truly pure FP language is a toy language or someone's research project.
That is, unless your idea of "useful" is to keep everything in the ghci REPL. You can use Haskell like a glorified calculator, if you like, so it's pure FP.
Erlang 的消息传递/进程处理是 Actor 模型的实现。你可能会说 Erlang 是一种 Actor 语言,是一种用于各个 Actor 的函数式语言。
Yes, it's a functional language. It's not a pure functional language like Haskell, but then again, neither is LISP (and nobody really argues that LISP isn't functional).
The message-passing/process handling of Erlang is an implementation of the Actor model. You could argue that Erlang is an Actor language, with a functional language used for the individual Actors.
The functional part is that you tend to pass around functions. Most langauges can be used both as a functional language, and as an imperative language, even C (it's quite possible to make a program consisting of only function pointers and constants).
I guess the distinguishing factor is usually the lack of mutable variables in functional languages.
发布评论
评论(4)
中心思想是每个进程都是一个基于消息输入流的功能程序。功能程序的结果是向其他程序输出消息流。从这个角度来看,Erlang 是一种相当干净的函数式语言;没有对数据结构的破坏性更新(如 Lisp 和大多数方案中的 setcar)。
除了少数例外,所有内置函数(例如 ETS 表上的操作)也遵循此模型:除了效率问题之外,这些 BIF 实际上可以通过纯 Erlang 流程和消息传递来实现。
所以,是的,Erlang 语言是函数式的,但是交互的 Erlang 进程的集合是另一回事。每个进程都是一个正在进行的计算,因此它具有当前状态,该状态可以相对于其他进程发生变化。在这方面,即使是数据库也只是另一个过程。
在我看来,这是 Erlang 最重要的事情之一:在进程之外,可能会有风暴肆虐,但在内部,一切都很平静,让你专注于该进程应该做什么——仅此而已。
The central idea is that each process is a functional program over an input stream of messages. The result from the functional program is an output stream of messages to others. From this perspective, Erlang is a rather clean functional language; there are no destructive updates to data structures (like setcar in Lisp and most Schemes).
With few exceptions, all built-in functions such as operations on ETS tables also follow this model: apart from efficiency issues, those BIFs could actually have been implemented with pure Erlang processes and message passing.
So yes, the Erlang language is functional, but a collection of interacting Erlang processes is a different thing. Each process is an ongoing computation, and as such it has a current state, which can change in relation to the other processes. Even a database is just another process in this respect.
In my mind, this is one of the most important things about Erlang: outside the process, there could be a storm raging, but inside, things are calm, letting you focus on what that process should do - and only that.
有一个模因认为函数式语言必须具有不可变值并且是无副作用,但我说任何具有 一流函数 是一种函数式编程语言。
对值可变性和副作用进行强有力的控制是有用且强大的,但我相信这些对于函数式编程来说是外围的。很高兴拥有,但不是必需的。即使在确实具有这些属性的语言中,也总有办法逃避范式的纯粹性。1
真正纯粹的 FP 语言之间存在灰度连续体,您实际上无法将其用于任何实际用途以及那些确实很不纯粹但仍然具有一些 FP 本质的语言:
书籍 FP: 有关 FP 语言的介绍性书籍通常只展示该语言的一个子集,所有示例都在该语言的 REPL,这样你就永远不会看到纯函数范式被破坏。一个很好的例子就是小计划者中介绍的计划。
读完这样一本书后,您可能会产生一种错误的印象,即 FP 语言实际上不能做任何有用的事情。
Haskell:Haskell 的创建者不遗余力地通过著名的 I/O 单子。墙一侧的所有内容都是纯功能性的,以便编译器可以自信地推理代码。
但重要的是,尽管存在这堵墙,你仍然必须使用 I/O monad 才能在 Haskell 中完成任何有用的事情。2从某种意义上说,Haskell 并不像有些人希望你相信的那样“纯粹”。 I/O monad 允许您在 Haskell 中构建您喜欢的任何类型的“不纯”软件:数据库客户端、高状态 GUI 等。
Erlang: 具有不可变的值和一流的函数,但在核心语言和不纯的部分之间缺乏坚固的墙。
Erlang 附带 Mnesia,一个磁盘支持的内存 DBMS,这与软件一样不纯粹。实际上,它与全局变量存储几乎没有什么不同。 Erlang 还大力支持通过 端口 与外部程序进行通信,套接字等
Erlang 不会在语言级别对你(程序员)强加任何类型的纯度政策。它只是为您提供工具并让您决定如何使用它们。
OCaml 和 F#:这些密切相关的多范式语言既包括纯函数式元素,也包括命令式和面向对象的特征。
命令式编程位允许您执行诸如使用可变计数器变量编写传统
for
循环之类的操作,而纯 FP 程序可能会尝试在列表上递归来实现相同的结果.如果没有<,OO部分几乎毫无用处code>mutable 关键字,它变成值定义到 变量 中,这样如果您更改变量的值,编译器就不会抱怨。 OCaml 和 F# 中的可变变量有一些限制,但您甚至可以使用 来逃避这些限制
ref
关键字。如果您将 F# 与 .NET 结合使用,则您将一直在改变值,因为大多数 .NET 都是可变的,无论以何种方式。例如,任何具有可设置属性的 .NET 对象都是可变的,并且所有 GUI 内容本质上都有副作用。立即想到的 .NET 中唯一不可变的部分是
System .字符串
。尽管如此,没有人会认为 OCaml 和 F# 不是函数式编程语言。
JavaScript、R、Lua、Perl...: 有许多语言甚至比 OCaml 更不纯粹,但在某种意义上仍然可以被认为是函数式的。这些语言具有一流的函数,但默认情况下值是可变的。
脚注:
任何真正纯粹的函数式编程语言都是玩具语言或某人的研究项目。
也就是说,除非您认为“有用”的想法是将所有内容都保留在
ghci
REPL 中。如果您愿意,您可以像使用精美的计算器一样使用 Haskell,因此它是纯粹的 FP。There's a meme that functional languages must have immutable values and be side-effect free, but I say that any language with first-class functions is a functional programming language.
It is useful and powerful to have strong controls over value mutability and side effects, but I believe these are peripheral to functional programming. Nice to have, but not essential. Even in languages that do have these properties, there is always a way to escape the purity of the paradigm.1
There is a grayscale continuum between truly pure FP languages that you can't actually use for anything practical and languages that are really quite impure but still have some of the FP nature to them:
Book FP: Introductory books on FP languages frequently show only a subset of the language, with all examples done within the language's REPL, so that you never get to see the purely functional paradigm get broken. A good example of this is Scheme as presented in The Little Schemer.
You can come away from reading such a book with the false impression that FP languages can't actually do anything useful.
Haskell: The creators of Haskell went to uncommon lengths to wall off impurity via the famous I/O monad. Everything on one side of the wall is purely functional, so that the compiler can reason confidently about the code.
But the important thing is, despite the existence of this wall, you have to use the I/O monad to get anything useful done in Haskell.2 In that sense, Haskell isn't as "pure" as some would like you to believe. The I/O monad allows you to build any sort of "impure" software you like in Haskell: database clients, highly stateful GUIs, etc.
Erlang: Has immutable values and first-class functions, but lacks a strong wall between the core language and the impure bits.
Erlang ships with Mnesia, a disk-backed in-memory DBMS, which is about as impure as software gets. It's scarcely different in practice from a global variable store. Erlang also has great support for communicating with external programs via ports, sockets, etc.
Erlang doesn't impose any kind of purity policy on you, the programmer, at the language level. It just gives you the tools and lets you decide how to use them.
OCaml and F#: These closely-related multiparadigm languages include both purely functional elements as well as imperative and object-oriented characteristics.
The imperative programming bits allow you to do things like write a traditional
for
loop with a mutable counter variable, whereas a pure FP program would probably try to recurse over a list instead to accomplish the same result.The OO parts are pretty much useless without the
mutable
keyword, which turns a value definition into a variable, so that the compiler won't complain if you change the variable's value. Mutable variables in OCaml and F# have some limitations, but you can escape even those limitations with theref
keyword.If you're using F# with .NET, you're going to be mutating values all the time, because most of .NET is mutable, in one way or another. Any .NET object with a settable property is mutable, for example, and all the GUI stuff inherently has side-effects. The only immutable part of .NET that immediately comes to mind is
System.String
.Despite all this, no one would argue that OCaml and F# are not functional programming languages.
JavaScript, R, Lua, Perl...: There are many languages even less pure than OCaml which can still be considered functional in some sense. Such languages have first-class functions, but values are mutable by default.
Foototes:
Any truly pure FP language is a toy language or someone's research project.
That is, unless your idea of "useful" is to keep everything in the
ghci
REPL. You can use Haskell like a glorified calculator, if you like, so it's pure FP.是的,它是一种函数式语言。它不像 Haskell 那样是一种纯函数式语言,但话又说回来,LISP 也不是(而且没有人真正认为 LISP 不是函数式语言)。
Erlang 的消息传递/进程处理是 Actor 模型的实现。你可能会说 Erlang 是一种 Actor 语言,是一种用于各个 Actor 的函数式语言。
Yes, it's a functional language. It's not a pure functional language like Haskell, but then again, neither is LISP (and nobody really argues that LISP isn't functional).
The message-passing/process handling of Erlang is an implementation of the Actor model. You could argue that Erlang is an Actor language, with a functional language used for the individual Actors.
功能部分是您倾向于传递功能。大多数语言既可以用作函数式语言,也可以用作命令式语言,甚至 C(很可能制作一个仅由函数指针和常量组成的程序)。
我想区别因素通常是函数式语言中缺乏可变变量。
The functional part is that you tend to pass around functions. Most langauges can be used both as a functional language, and as an imperative language, even C (it's quite possible to make a program consisting of only function pointers and constants).
I guess the distinguishing factor is usually the lack of mutable variables in functional languages.