• 👍 换头像了导致我没认出来,哈哈

  • #67楼 @jimrokliu 是的,Supervisor 是 OTP 内建的行为之一,经历了这么多年足够稳健。类似的机制其他语言并不是不能做,不过稳定性这东西是需要时间积累的。

  • 圣诞礼物:Ruby 2.4.0 Released at 2016年12月25日

    每年圣诞有惊喜

  • 思路还是 GraphQL 那一套,那我更宁愿去试试 GraphQL/Falcor 。而且它的简单基于一个假设:JSON resource 结构跟数据库的表结构一致。现实中稍微复杂点的模型都不是这样的。所以 -- 不怎么看好。只说说我还算了解的 JSON API 和 GraphQL 。

    JSON API 适合粗粒度场景,是 REST 思路的延伸,各方面都有所考虑,对处理 relationship 有自己的一套解法。如果自己定义 API 规范有些想不清楚的地方,这个规范值得参考,但不见得值得使用。不过如果非要在同类规范(HAL, Siren 等)中选一个,我更愿意选择它。最后,如果使用 Ember + Ember Data 的话,这个规范还是推荐的。

    GraphQL 没实际写过,感觉适合细粒度场景,适合前端频繁变化的应用,配合 Relay 和 React 可以有效的整合各个组件中的请求。我个人更喜欢这种方式的数据层,屏蔽了发起哪些查询和何时发起查询等细节。

    最后,写 API 本来就是个体力活,这部分本该自动化一点。

  • 果然大部分是 Ruby 转过去的,不过 Erlang 人群居然很少。

  • Leftover 的编程语言漫画 at 2016年12月18日

    上周刚看过,另外 The difference between Java and JavaScript 也很搞人。左箭头翻页就是。

  • #10楼 @chenge 这个别问我,我真的不知道,而且最近也没有学图理论和相关算法的计划。

  • #7楼 @chenge 没有,这属于图理论的,我一点都没学过。你感兴趣的话还是查 wiki 吧,理论搞懂了应该不麻烦。

    #8楼 @nightire 有空写点 Elixir kata 练练?

  • #5楼 @nightire Codewars 上已经有了啊

  • #2楼 @chenge 自己去看吧 。8kyu 是最低难度,1kyu 最高,其实看颜色也看得出来啊。如果是 Codewars 自己推荐的话,应该会根据你的账号等级来推荐匹配的 kata ,也不会开始就给你很难的题目。除非你自己选择 1kyu 去了……

    Codewars 里面也不全是那些枯燥的算法题,也有很多很有意思的题目。所以我还挺喜欢这个,不太想去 Leetcode 。

    • 有的锻炼基础数据结构,比如这个 链表系列。我最近在写一个 系列博客,有兴趣可以看看。
    • 有的需要了解特定的语言特性,比如 A Chain adding function
    • 有的就比较奇怪了,比如 Snail 这种用递归简单的不行但用循环难得要死的题。顺带一提,Ruby 的某个迭代器方法可以一行代码搞定。
  • Codewars 难度也不大啊,5 级以上的几乎没难度。可能你开始没找对难度?他家的是数字越大难度越低。

  • 你如果坚持,同事就会很难过了 😢

  • 这个不错,以后连带的一堆 xxx_tag 的 helper 也可以去掉了。

  • 最近全国网络的显著变化 at 2016年12月04日

    女朋友和老婆,哦…… 两者怎么可能同时存在呢,当然不存在嘛 😆

  • #50楼 @blacktulip 这也是萝卜白菜各有所爱。Web 框架的适用范围也不就那些。如果说比功能现在流行的框架都不差,细节处各有优劣。这些框架多余么?我觉得不多余。毕竟除了考虑功能,照顾开发者偏好也很重要。能让做 Web 的 Elixir 的开发者有个好工具,Phoenix 达到这点就足够了。至于高并发么,我只能说,虽然大多普通人都是钱够用就好,但也没人会嫌自己钱多。

  • #24楼 @rupertqin 我对宏也只是一知半解,但 unquote 还是可用的。一个变通做法如下,来源是这里: http://stackoverflow.com/questions/30498528/how-to-create-a-dynamic-function-name-using-elixir-macro

    defmodule Util do
      for type <- ["function", "list", "map"] do
        def typeof(x) when unquote(:"is_#{type}")(x) do
          unquote(type)
        end
      end
    
      def typeof(_), do: "unknown"
    end
    
    IO.puts Util.typeof(fn -> true end)  # function
    IO.puts Util.typeof([1, 2, 3])       # list
    IO.puts Util.typeof(%{a: 1})         # map
    IO.puts Util.typeof(1)               # unknown
    

    关于 DSL 我还是持谨慎态度(并非觉得研究宏没用)。因为我觉得 Elixir 的主张就是 make the complex part explicit 。Jose 在 Domain Specific Language 里拿 validation 举的例子也挺好。

    # 1. data structures
    import Validator
    validate user, name: [length: 1..100],
                   email: [matches: ~r/@/]
    
    # 2. functions
    import Validator
    user
    |> validate_length(:name, 1..100)
    |> validate_matches(:email, ~r/@/)
    
    # 3. macros + modules
    defmodule MyValidator do
      use Validator
      validate_length :name, 1..100
      validate_matches :email, ~r/@/
    end
    
    MyValidator.validate(user)
    

    总的来说,数据结构的方式最灵活最容易组合。函数的方式适合复杂的 API ,加上管道运算符也足够描述逻辑。宏的方式实现起来最复杂并且限制最大(想想 conditional validation)。这点其实跟 Ruby 社区近几年更推崇传统的 Object 组合而不是更多的 DSL 是一个意思。

  • #21楼 @rupertqin 不知道宏该怎么写,但 typeof 这种需求用 Protocols 来做更好吧。 http://elixir-lang.org/getting-started/protocols.html

  • #25楼 @tony612 这个不错!

    #28楼 @chenge 是的,有些错误不用追究原因,下次还能工作就行。

  • #17楼 @hisea 赞一个。最近在啃 Programming Elixir 1.3 ,这个语言带给人的思维改变是非常有意思的。做练习的时候经常有种感叹 “居然还可以这样用!” 。有些事情对没了解过 Elixir 或者 FP 的人来说是很难描述清楚的。

    我一开始也不理解 let it crash 的设计,觉得如果每个异常都 crash 去了那也太频繁了。深入了解一些后才明白不是这么一回事。很多语言把异常作为控制流的一种,有些地方甚至只用 if/else/case 描述理想状态的流程,其他情况一律设计成异常类。Elixir 并不把异常作为控制流的一种,异常只用在那些 “正常情况下几乎不可能发生的事情” 上,比如数据库断线,HTTP 请求超时,配置文件不存在等等。那些在预料之中情况一般都用 {:error, reason} 加模式匹配处理掉了。这样想其实也挺合理。更进一步思考,没有哪个程序能保证处理了一切意外情况的,这种时候简单重启一下保证服务不挂掉反而是更好的做法。

  • 👍 开始还以为是那篇老的 7 Patterns 。举的例子都挺好。Interactor 那部分感觉有点多余,其实可以跟 Service Object 合并起来。如果遵从 DCI 的模式,也应该是 Interactor 里面调用 Context 的回调(虽然我不喜欢这种做法)。