Erlang/Elixir Dave:重新思考编程

chenge · 2016年12月04日 · 最后由 xaqi 回复于 2016年12月15日 · 3178 次阅读

这里介绍 Dave 在 14 年的演讲,他归纳了 Elixir 的两个他认为的要点,重新思考编程。分别是:

  • 模式匹配
  • 数据转换

我个人觉得模式匹配可以减轻程序员的工作,数据转换可以改善维护,以及增加对并发的支持,也不一定对,是一个初浅的思考吧。看你是否同意他的看法。

视频链接需要的话自己搜索吧,标题:Think Different。

两个要点

模式匹配

数据转换

個人認為 pattern matching 是個好東西,但是太燒腦子,對寫碼的人要求有點高,一般人容易搞成一坨。

其实这两种东西就是表达式(数据转换)和逆表达式(模式匹配)。前者是 fp 的基石,后者则是前者的解释,或者说是解构过程。

虽然说是这么说,但是对于新手而言后者明显要比前者难理解,特别是后者经常会跟递归一起出现...

#1 楼 @blacktulip 我觉得还好,稍微适应下,感觉代码思路很清楚。比如他演示的例子:

defmodule RLE do
  def encode(list), do: _encode(list, [])

  defp _encode([], result), do: Enum.reverse(result)

  defp _encode([{a,n}, a|tail], result) do
    _encode([{a,n+1}|tail], result)
  end

  defp _encode([a,a|tail], result) do
    _encode([{a,2}|tail], result)
  end

  defp _encode([ a | tail ], result) do
    _encode(tail, [ a | result ])
  end
end

IO.puts inspect RLE.encode([1,2,2,2,3]) #[1,{2,3},3]

你不信用 Ruby 实现来对比看,如何?

#3 楼 @chenge 笑,我当然知道好,问题几个人能写出来?

#4 楼 @blacktulip 比 OO 里黑盒对象传来传去简单多了

#5 楼 @kabie 也许吧,但是 简单 和 容易写 是两回事

@blacktulip 我经常先写一堆 if else 或者 case,然后再重构成 pattern match,先把容易写的写了,然后再重构成简单易读的

#3 楼 @chenge 模式匹配是不符合 ruby 哲学的,模式匹配相当于把对象剖开,但是 OO 哲学里对象内部对于外界都是不可见的,一切操作要以消息传递实现,就像现实中你不能随便拆开一个人的大脑查看。

[a,b] = [1,2] 这种语法糖,你已经钦定了一种数组实现,但是 OO 中数组只是一种能反应:[]消息的对象。

类似地,你要如何实现 ActiveRecord::Relation 的模式匹配呢?

当你{total_count, records} = relation,你已经在relation.instance_eval{|x| @total_count} 了,问题是,你怎么知道 relation 里有@records@total_count

当然,ruby 里也不是没有模式匹配,线性表的(a, (b, c)) = [1,[2,3]]是没问题的。

还有 @Artoria 的面对接口的模式匹配:


OO 的哲学是模拟,FP 的哲学是推导。FP 喜欢赤裸着的纯数据,而 OO 则把每个对象看成“有自己主见的人”。二者的比较其实没有什么意义,完全在于你怎么看世界。纯数据操作当然是 FP 更方便,但是类似游戏这种模拟领域,OO 的好处就非常明显了。

9 楼 已删除

#9 楼 @jackalcooper 我讲模式匹配你又跟我讲 actor。。erlang 那点东西我又不是不知道,ruby 的对象和 actor 本来就是等同的抽象,ruby 的send就是 erl 的!,ruby 有私有状态,actor 的尾递归就不是私有状态了?你要不要记 pid?还有不知道你说的类变量是什么,我写 ruby 没用过类变量。

#10 楼 @Rei 我 10 分钟就看懂 Dave 那个了,你的我估计要半天,当然我 Ruby 没那么熟悉了,Elixir 我也只学了几天。单就这个例子而言,我个人认为 Elixir 更好。

Elixir 继承了 Ruby 的语法,其实是后辈了,本身就是向 Ruby 致敬了。当然彼此有一些竞争,这也是可以理解的。

好的语言是一种进步,但是写一个好的软件仍然不是容易的事,在路上。

13 楼 已删除
14 楼 已删除

#12 楼 @chenge 话很有意思。 一方面你强调你不熟悉 ruby, 但是相比之下又觉得 elixir 更好。这个比较本身是 false 的。 然后你指出的更好的理由是,继承了 ruby 的语法,致敬。这点好像也属于 false。 其实工具的东西,无所谓好不好,唯手熟尔。

不打算引发争论。只是觉得这话很有意思。如有冒犯,请多见谅。

#15 楼 @leiz_me 我只是单就那个例子说 Elixir 好,我没有简单说 Elixir 处处都好,对吧。不要扩大化。

我说不熟只是相对别的更熟的人而言,我也写好几年 Ruby 了,基本的了解还是有的。 我相信 Ruby 还会继续发展,只是我打算换道而已。

Elixir 肯定更适合解决某些问题,不然就没存在的意义了。 Elixir 版的 RLE.encode 感觉比传统算法还难懂一些,如果找一个传统算法很麻烦,Elixir 轻松解决的例子就更有说服力了。

module RLE
  def self.encode(list)
    list.each_with_object([]) { |n, arr|
      arr << [n, 0] if arr.empty? || arr.last[0] != n
      arr.last[1] += 1
    }.map { |x| x[1]>1 ? x : x[0] }
  end
end
需要 登录 后方可回复, 如果你还没有账号请 注册新账号