Elixir属于函数式编程语言系列,因此可以安全地说出你输入函数的所有内容,你将得到一个输出。
现在考虑模块流程中的函数register/2。
作为参数,如果一切正常,它需要pid,name和return true(原子)。
pid将被保存在哪里?如果erlang将pid保存到变量(映射,键列表)中,则存在共享状态存储器,并且禁止在函数编程中将变量保存到共享存储器中。
答案 0 :(得分:2)
我认为你从错误的假设出发。没有什么可说的,对于函数的每个参数都有相应的输出。这不仅仅是功能所固有的,也不是必需的固有功能。
那就是说,我认为pid和name之间的关联存储在Erlang Global Process Registry中。您可以阅读有关gproc here的更多信息。
答案 1 :(得分:2)
Erlang是一种非常实用的语言/运行时。它从来没有打算发挥作用 - 它只是以这种方式结束。由于纯度不是其意图,因此需要进行一些权衡以换取易用性,其中一个例子是流程注册表。另一个例子是向进程发送消息 - 它纯粹是没有返回值的副作用。
对于存储位置,VM在内存中维护进程的本地注册表。整个集群的全局注册由:global模块处理,并通过:erlang.register / 2 BIF(内置函数)进行本地注册。
答案 2 :(得分:2)
您在断言中混淆了状态和共享状态。
在Erlang / Elixir状态下,多个进程之间不共享。这是因为每个进程都有自己的内存和其他资源。但是,状态可以保存在单独的进程中,并由其他进程查询而不进行共享。由于消息传递和进程邮箱,两个进程都不可能同时访问数据而导致竞争条件。每条消息都在邮箱中排队,并由发送到的进程一次处理一条。您可以将此视为面向数据库的Web服务,该服务一次只允许一个连接。
此外,我相信你正在混淆Erlang / Elixir存储状态的方式以及OO语言实现它的方式。 OO语言具有从存储器分配的存储器,并且实际上将状态存储在存储器中,其具有指向它的指针以供稍后访问Erlang / Elixir通过receive
函数调用暂停递归过程来存储状态。由于收到消息后进程再次处于活动状态,因此可以转换数据。
因此,功能编程范例没有被打破。回想一下,这个范例的一部分是一个小函数的流水线,它可以一次转换一点数据。好吧,持有我们状态的进程仍然是一个函数的管道(递归),一次一点地转换数据。但是,在每个步骤之后,该前进动力将被暂停,直到收到另一条消息。