Ruby 用 Ruby 简单模拟 Lambda 演算

lanzhiheng · 发布于 2017年08月29日 · 最后由 jiyinyiyong 回复于 2017年09月04日 · 2126 次阅读
744a59
本帖已被设为精华帖!
共收到 36 条回复
19812

之前有用lambda实现FizzBuzz的, 可惜因为ruby的proc没有尾递归, 只能循环到50...

744a59
19812shinkxw 回复

尾递归这个了解不多,我稍后去看看。

744a59
162quakewang 回复

cool.受教了 👏 之前不知道还有

2.3.3 :016 > Proc.instance_methods.grep /curry/
 => [:curry]

这个方法可以用。

12706

昨天刚看了计算的本质中的lambda演算😁

30806

@alixiaomiao @lanzhiheng 不要看 《计算的本质-深入剖析程序和计算机》啦, 看 SICP 吧, SICP才是圣经级别读物.

《计算的本质-深入剖析程序和计算机》展现的只是 SICP的冰山一角 ... ...

744a59

我打算看完《计算的本质》就去看SICP了🐭 。 Clojure 的头像...... 看来是FP粉。

30806
744a59lanzhiheng 回复

我也是因为 读《计算的本质-深入剖析程序和计算机》,才知道背后 有这么 牛B的 SICP, 作者Tom 只是借鉴SICP思想而已, 然后用Ruby语言表达.

SICP这本书改变了我, 让我转向了Clojure开发, 释放Lisp函数式强大的原力.

30806
162quakewang 回复

Lisp语言里面一般都是用partial, 函数式数据分析, 还有在线数据流机器学习, 实在是太方便了.

(def sigma
  (fn [sf f a b]
    (->> (range a (inc b))
         (map #(f %))
         (reduce sf))))

(def sum-of-number (partial sigma + (fn [n] n)))
(def sum-of-square (partial sigma + #(* % %)))

(sum-of-number 1 10) ;;=> 55
(sum-of-square 1 10) ;;=> 385

(def pi (partial sigma *))

(pi (fn [n] n) 1 3) ;;=> 6

Lisp用于Spark数据分析:

(defn ratings->matrix [data]
  (let [cardinality (-> data
                        (spark/map #(.product %))
                        (spark/reduce max)
                        (inc))]
    (->> data
         (spark/group-by #(.user %))
         (spark/values)
         (spark/map (to-sparse-vector cardinality))
         (to-matrix))))
4215

SICP比较难,能看懂部分。刚卖掉了。

744a59

这本书稍后会读一读,一年前有看过一部分,后来觉得用不上就没看了。现在觉得这些才是有意思的地方。

4215

partial的可读性明显比ruby好。->, ->>有什么区别呢?

30806
744a59lanzhiheng 回复

这是函数式圣经级别读物, 我第一次看到这部著作的时候,也直接丢掉了.

Jim Weirich的演讲, 让我深度思考了函数式, 使得我重新读完这部书的前面四章, 被SICP 震惊了, 发现我错了. 才知道邱奇是多么的伟大, Lisp 是多么伟大.

30806
4215chenge 回复

吃透了SICP, 一般的程序员的功力就干不过你了. 所以它不是那么容易吃透的呀.

-> & ->>的区别是 :

(macroexpand-1 '(-> 100 (+ 1) (+ 2) (+ 3)))    ;;=> (+ (+ (+ 100 1) 2) 3)

(macroexpand-1 '(->> 100 (+ 1) (+ 2) (+ 3)))   ;;=> (+ 3 (+ 2 (+ 1 100)))

744a59

为什么选择clojure?我之前花了很大的力气装了 clisp,不过感觉它的REPL用起来不算太舒服,安装也比较麻烦。也有试过scheme感觉还不错。现在用的比较多是elisp,平时会用来改一下emacs的配置。

30806
744a59lanzhiheng 回复

Clojure 除了具备了 Lisp开发的 最佳体验 (Emacs + REPL) 开发, 没有比这个开发体验更好的, 我用过如此多的语言里面.

而且Clojure的资源几乎是无限的, Java资源轻易封装使用, 如我自己封装的一些 : 讯飞Clojure的SDK, Hanlping, 阿里云aliyun-oss-clj 等等.

而且ClojureScript函数式来写复杂前端都轻易搞定: https://github.com/chanshunli/clojurescript-study, https://github.com/clojurescript-scope-games/flappy-bird-demo 等等. 也是Lisp的开发体验, 甚至不需要离开编辑器就完成了复杂单页面或者游戏.

还有我用Clojure调用Spark数据分析, 机器学习等: 如 https://github.com/clojure-spark/sparkling-streaming-ml

我还用Clojure来写安卓APP收集传感器数据, 做流式数据在线学习 等,

Java能做的, Clojure一样能做, 而且速度快的 惊人, 曾经我认为Ruby是最好的语言, 但是我错了, 能够开发Clojure是我命运的眷顾, 让我知道 什么才是程序员的幸福 😍 😍 😍 , Clojure给我的感觉是, 优美的极点 + 无穷的强大几乎没有它干不了的事情.

90

@lanzhiheng ClojureScript 安装相对容易, 直接用 Brew 或者 npm 就能装好. REPL 环境现在有 Lumo 和 Planck, 启动很快, 不知道你需要什么功能, 应该是有常用功能的. ClojureScript 社区比较注重工程化的实用性, 不过也难说, 毕竟 js 生态有些坑, Lisp 社区放不下身段, 也就跟着坑了.

744a59
90jiyinyiyong 回复

感谢您的推荐,我是之前装cLisp感觉有点折腾,要编译安装跟 homebrew一起用才行. ClojureScript还没了解过,说实在干了大半年前端,感觉完全跟不上前端的节奏。自从小程序这种东西出来之后这种感觉更强烈。我也就没花太多时间去折腾前端的事情了。平时就上班时间好好写样式,写JavaScript框架看需要,业余有时间就去搞搞Ruby或者看看你们所说的Lisp。

12834

你这有很严重的广告嫌疑啊,说的我都想试试了。传销!😜

1553

传销~

先做个记号

30806
12834hemengzhi88 回复

@Peter 如果你们学习Lambda演算, 连 它的 鼻祖都 不知道, 那有何意义呢?

Ruby社区很多高手, 比如 @luikore 等, 都是修炼过SICP的, 如果你不知道他们为什么这么厉害, 只能说你们在社区白混了.

今年的RubyConf China 2017, 都已经有三个主题是 关于函数式的了, 难道你们还要停留在学习的舒适区吗?

2880

嗯 Lisp 的正统是 Scheme, Scheme 的正统是 Racket ...

Racket 不仅开箱即 R5RS, R6RS, R7RS... 现在还能跑在 Chez Scheme 上了, Chez Scheme 那代码库克隆下来都上 G 了咯.

小心莫走进 Clojure 或者 Common Lisp 的邪路呀!

744a59
2880luikore 回复

Common Lisp 是邪路?

2653

一入「邪教」深似海

4215

还是这个Elixir更吸引ruby圈子吧。对比一下,没有@变量的耦合,是不是觉得更清楚些呢?

defmodule DrawShapes do
  def areas(shapes) do
    for shape <- shapes do
      area(shape)
    end
  end

  def area(shape) do
    module = shape.__struct__
    apply(module, :area, [shape])
  end
end

defmodule Circle do
  defstruct radius: nil

  def new(radius), do: %Circle{radius: radius}

  def area(circle) do
    (circle.radius * :math.pi) |> :math.pow(2)
  end
end

defmodule Square do
  defstruct side: nil

  def new(side), do: %Square{side: side}

  def area(square) do
    square.side |> :math.pow(2)
  end
end

shapes = [Circle.new(3), Square.new(4)]
DrawShapes.areas(shapes)
1

我是个新手,Lisp 和 Erlang 到底哪个好啊,急,在线等。

744a59
1Rei 回复

我给你 💯

90
2880luikore 回复

虽然这么说, 现在和业界结合比较紧密的 Lisp 方言还是腰酸 Clojure 啊. 再说 Lisp 本身不是就已经算邪路了吗 - -

2880
744a59lanzhiheng 回复

是啊, Common Lisp 你一个 Lisp 搞什么 Object, Meta-Object Protocol?

你跟别人讲我用 Common Lisp 啦, 下了一个世界最快的编译器 sbcl ! 别人说好牛哦那你能 call/cc 吗? 玩不了这些花为什么不用 Java? 你就 sb 了...

讲真 Racket 的社区比 CL 更活跃, Scheme 也更纯粹简单, 装个 Racket 什么都有了, 何苦搞 CL?

744a59
2880luikore 回复

多谢推荐,会抽时间看看scheme。

2880
90jiyinyiyong 回复

Clojure 和 Racket 还算相似... 不过你干点什么事情都得找 Java 的库看 Java, 这不仅是一门语言...

0b45a6
2880luikore 回复

Common Lisp 不是有。。。Common Lisp Object System (CLOS) 嘛。。。像 Scheme 上的 Gauche、Meroon,还有 Guile 上的 GOOPS 都可以看作是受这玩意的启发在其它语言上的实践。call/cc 是真痛。。。很多时候只能靠 handler-bind 苟活一下😩

30806

@luikore Scheme 和 Racket, 是Lisp界的标准, 这一点不容置疑, 学透SICP可以完全升级一个程序员的 内功.

但Scheme的问题是停留在教育层面的, 虽然Racket尝试生产方面, 毕竟还没成功.

Scheme和Clojure是很像的, 但是Clojure的生产效率是非常高的, 它和Java之间的互操作, 都是简单得让你惊奇. 而且Ruby底子好的人, 看Java代码是不难的.

Clojure后端开发 非常成熟, ClojureScript前端开发体验也是一流的, 而且Clojure在大数据和数据分析领域也是非常成熟的, 如Storm, Cascalog, 包括Clojure调用Spark也是非常容易的.

Common Lisp已经是混合多范式了, 虽然根植于Lisp, 我不想用它的原因是, CLOS 不应该继承到 它的核心里面, 使得 Clisp过度复杂.

1107 jasl 将本帖设为了精华贴 09月03日 18:57
90
2880luikore 回复

还真是有这个问题... 主要是我对 js 生态已经熟悉了, 觉得作为低级语言被 ClojureScript 这个高级语言调用就当是平台 API 了 - -

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册