avatar
l*3
1
冰的时候最好吃。。。
一直惦记着小新里的纳豆,
以前曾经尝试过不太接受,
前两天在日本店买了几盒,
趁着还有冰冰觉得很好吃,
可是尝出一丝甜甜的味道,
过来一会常温了又不喜欢。
恩。。。就是这样子。。。跟大家分享下。。。
avatar
u*u
2
挺有新意的,不恐怖,除了最后一集有些唐突
avatar
z*o
3
看到板上有讨论,但是没有一个答案阿。
这东西搞个几块钱的case还差不多,要是花个几十块钱去搞个case就墨有那个必要了
avatar
T*x
4
最近折腾Clojure递归程序,在网上发现一个东西叫Y-Combinator,挺神奇的,号称能
把任何递归程序以非递归的形式写出来。
我看了一个blog,又引到另一个blog,讲的还行,但是不直接,我发现了一个比较直接
的讲法,所以写下来。
先定义一下问题。目标是定义一个Clojure函数Y,把任何给定的Clojure递归程序转化
为非递归形式。
比如一个factorial函数吧,我们命名它为w。它的递归程序是这样的,
(def w (fn [n] (if (= n 0) 1 (* n (w (- n 1))))))
这个定义可以写成这个形式:w=f(w)。其中f就是程序“形式”,也就是从括号fn开始
到括号结束的一堆字符,其中把w虚位,可以写成
f = (fn [n] (if (= n 0) 1 (* n (? (- n 1)))))
f(w)就是把问号换成w。f可以写成高阶函数的形式,
(def f (fn [w] (fn [n] (if (= n 0) 1 (* n (w (- n 1)))))))
f是递归函数w的“形式”,它本身不是递归函数。我们的目标是定义一个函数Y,或者
叫变换Y,使得Y(f)=w,这样我们就通过Y和f,两个非递归函数,复原了w这个递归函数
,达到了目标。
从w=f(w)这个形式,我们也可以说,w是f这个变换的不动点,fixed-point。所以我们
的目标也是找f的不动点,或者说是找一个变换,这个变换把f变为f的不动点,也就是Y
(f)=w。
这里最重要的一个trick是,定义一个函数u,such that,u(x):=f(x(x))。如果这样定
义了,那么代入u本身,
u(u)=f(u(u)),不动点有了,看得更清楚一点,令w=u(u),那么w=f(w)。所以w=u(u)就
是f的不动点。所以Y变换也有了,Y(f)=u(u)。
来我们检查一下这是不是一个well defined function。首先给定任意递归函数的“形
式”f,它本身不是递归的,然后定义u,such that u(x):=f(x(x)),这个函数是well
define的吧?呵呵,数学上它肯定不是,这只是Clojure里well defined。好吧,既然u
是well defined,那么u(u)也是well defined,因此Y这个把f变成w=u(u)的变换也是
well defined。
先写到这,怕丢了。函数Y的形式一会再写。写出来发现只剩一点点了,就合到这里。
f是给定函数,不需要写。先写u,
(def u (fn [x] (f (x x))))
再写w,
(def w (u u))
再写Y,
(def Y (fn [f] w))
合在一起,
(def Y (fn [f] ((fn [x] (f (x x))) (fn [x] (f (x x))))))
哦!u的定义有问题,(x x)这个形式在Clojure里编译的时候会出现stack overflow,
因为它要展开,这个地方我还没完全想明白。总之这里需要另一个trick,使编译器
defer 展开,(x x)其结果应该是一个函数,是函数就可以写成等价形式,
(x x) = (fn [y] ((x x) y))
用这个等价形式替换(x x)的出现(两次),就得到
(def Y (fn [f] ((fn [x] (f (fn [y] ((x x) y)))) (fn [x] (f (fn [y] ((x x) y)
))))))
avatar
d*g
5
好吃么?偶对纳豆木有什么感觉~~~~~~~
avatar
g*m
6
co-ask
avatar
x*4
7
paul graham 写了很多lisp 书和文章。后来开了家vc就叫ycombinator。

【在 T*******x 的大作中提到】
: 最近折腾Clojure递归程序,在网上发现一个东西叫Y-Combinator,挺神奇的,号称能
: 把任何递归程序以非递归的形式写出来。
: 我看了一个blog,又引到另一个blog,讲的还行,但是不直接,我发现了一个比较直接
: 的讲法,所以写下来。
: 先定义一下问题。目标是定义一个Clojure函数Y,把任何给定的Clojure递归程序转化
: 为非递归形式。
: 比如一个factorial函数吧,我们命名它为w。它的递归程序是这样的,
: (def w (fn [n] (if (= n 0) 1 (* n (w (- n 1))))))
: 这个定义可以写成这个形式:w=f(w)。其中f就是程序“形式”,也就是从括号fn开始
: 到括号结束的一堆字符,其中把w虚位,可以写成

avatar
E*A
8
刚吃了,下稀饭不错,我家大宝很喜欢
avatar
z*i
9
Ipad 1 case, ok. Almost the same size as touchpad.
ipad 2 case, not ok. Touchpad is thicker.
avatar
c*v
10
For people who may interest:
(1)
https://dl.acm.org/citation.cfm?id=358210
The "Stage I" is a fixed point in C.
(2)
Explained in javascript
http://kestas.kuliukas.com/YCombinatorExplained/

【在 T*******x 的大作中提到】
: 最近折腾Clojure递归程序,在网上发现一个东西叫Y-Combinator,挺神奇的,号称能
: 把任何递归程序以非递归的形式写出来。
: 我看了一个blog,又引到另一个blog,讲的还行,但是不直接,我发现了一个比较直接
: 的讲法,所以写下来。
: 先定义一下问题。目标是定义一个Clojure函数Y,把任何给定的Clojure递归程序转化
: 为非递归形式。
: 比如一个factorial函数吧,我们命名它为w。它的递归程序是这样的,
: (def w (fn [n] (if (= n 0) 1 (* n (w (- n 1))))))
: 这个定义可以写成这个形式:w=f(w)。其中f就是程序“形式”,也就是从括号fn开始
: 到括号结束的一堆字符,其中把w虚位,可以写成

avatar
l*3
11
那样子吃还是不错的。。。不是说健康来这么,觉得不错。。。
哈哈。。。

【在 d******g 的大作中提到】
: 好吃么?偶对纳豆木有什么感觉~~~~~~~
avatar
c*i
12
ipad1 的 也把相机孔盖住了 吧

【在 z*******i 的大作中提到】
: Ipad 1 case, ok. Almost the same size as touchpad.
: ipad 2 case, not ok. Touchpad is thicker.

avatar
T*x
13
用factorial的那个f试一下,
(def factorial (Y f))
然后
(factorial 10),
好使。
用跳马问题改一下,
(def moves [[1 2] [2 1] [-1 2] [2 -1] [1 -2] [-2 1] [-1 -2] [-2 -1]])
(def dim 5)
(defn possible-pos [path]
(let [seen (set path) pos (last path)]
(->> moves
(map #(map + pos %))
(filter (fn [[x y]] (and (>= x 0) (>= y 0) (< x dim) (< y dim))))
(remove #(seen %)))))
(defn jump+ [jump-]
(fn [path]
(if (= (count path) (* dim dim))
(list path)
(for [pos (possible-pos path)
fpath (jump- (conj path pos))]
fpath))))
(defn Y [f] ((fn [x] (f (fn [y] ((x x) y)))) (fn [x] (f (fn [y] ((x x) y))))
))
(def jump (Y jump+))
(jump [[0 0]])
也好使。

【在 T*******x 的大作中提到】
: 最近折腾Clojure递归程序,在网上发现一个东西叫Y-Combinator,挺神奇的,号称能
: 把任何递归程序以非递归的形式写出来。
: 我看了一个blog,又引到另一个blog,讲的还行,但是不直接,我发现了一个比较直接
: 的讲法,所以写下来。
: 先定义一下问题。目标是定义一个Clojure函数Y,把任何给定的Clojure递归程序转化
: 为非递归形式。
: 比如一个factorial函数吧,我们命名它为w。它的递归程序是这样的,
: (def w (fn [n] (if (= n 0) 1 (* n (w (- n 1))))))
: 这个定义可以写成这个形式:w=f(w)。其中f就是程序“形式”,也就是从括号fn开始
: 到括号结束的一堆字符,其中把w虚位,可以写成

avatar
l*3
14
哈哈哈。。。真的啊。。。我下次也试试,现在只是干吃。。

【在 E*A 的大作中提到】
: 刚吃了,下稀饭不错,我家大宝很喜欢
avatar
c*v
15
编译器就是把递归程序写成非递归。
汇编语言里只有mov,jump,inc,没有递归。
所以fixed point和编译器的代数性质类似。

【在 T*******x 的大作中提到】
: 用factorial的那个f试一下,
: (def factorial (Y f))
: 然后
: (factorial 10),
: 好使。
: 用跳马问题改一下,
: (def moves [[1 2] [2 1] [-1 2] [2 -1] [1 -2] [-2 1] [-1 -2] [-2 -1]])
: (def dim 5)
: (defn possible-pos [path]
: (let [seen (set path) pos (last path)]

avatar
b*M
16
啊?原来纳豆真是一种食品啊,我还以为纳豆就是特指网球运动员Rafael Nadal 哩

【在 l********3 的大作中提到】
: 哈哈哈。。。真的啊。。。我下次也试试,现在只是干吃。。
avatar
d*r
17
所以看标题,我以为你们在讲融资了

【在 x***4 的大作中提到】
: paul graham 写了很多lisp 书和文章。后来开了家vc就叫ycombinator。
avatar
R*s
18
纳豆是啥子。。

【在 l********3 的大作中提到】
: 冰的时候最好吃。。。
: 一直惦记着小新里的纳豆,
: 以前曾经尝试过不太接受,
: 前两天在日本店买了几盒,
: 趁着还有冰冰觉得很好吃,
: 可是尝出一丝甜甜的味道,
: 过来一会常温了又不喜欢。
: 恩。。。就是这样子。。。跟大家分享下。。。

avatar
z*9
20
我喜欢解冻后加点紫菜酱油拌着吃,觉得太熏的也可以再加入少量洋葱,绿葱类的,

【在 l********3 的大作中提到】
: 冰的时候最好吃。。。
: 一直惦记着小新里的纳豆,
: 以前曾经尝试过不太接受,
: 前两天在日本店买了几盒,
: 趁着还有冰冰觉得很好吃,
: 可是尝出一丝甜甜的味道,
: 过来一会常温了又不喜欢。
: 恩。。。就是这样子。。。跟大家分享下。。。

avatar
T*x
21
经过几次变换,Y变成这样了,
(defn Y [f] (#(% %) #(f (fn [x] ((% %) x)))))
最短,但是只有编译器能懂了。:)

【在 T*******x 的大作中提到】
: 最近折腾Clojure递归程序,在网上发现一个东西叫Y-Combinator,挺神奇的,号称能
: 把任何递归程序以非递归的形式写出来。
: 我看了一个blog,又引到另一个blog,讲的还行,但是不直接,我发现了一个比较直接
: 的讲法,所以写下来。
: 先定义一下问题。目标是定义一个Clojure函数Y,把任何给定的Clojure递归程序转化
: 为非递归形式。
: 比如一个factorial函数吧,我们命名它为w。它的递归程序是这样的,
: (def w (fn [n] (if (= n 0) 1 (* n (w (- n 1))))))
: 这个定义可以写成这个形式:w=f(w)。其中f就是程序“形式”,也就是从括号fn开始
: 到括号结束的一堆字符,其中把w虚位,可以写成

avatar
h*i
22
这个trick还是挺有用的,主要是不用函数名字,这样就可以干很多优化的事情。

【在 T*******x 的大作中提到】
: 最近折腾Clojure递归程序,在网上发现一个东西叫Y-Combinator,挺神奇的,号称能
: 把任何递归程序以非递归的形式写出来。
: 我看了一个blog,又引到另一个blog,讲的还行,但是不直接,我发现了一个比较直接
: 的讲法,所以写下来。
: 先定义一下问题。目标是定义一个Clojure函数Y,把任何给定的Clojure递归程序转化
: 为非递归形式。
: 比如一个factorial函数吧,我们命名它为w。它的递归程序是这样的,
: (def w (fn [n] (if (= n 0) 1 (* n (w (- n 1))))))
: 这个定义可以写成这个形式:w=f(w)。其中f就是程序“形式”,也就是从括号fn开始
: 到括号结束的一堆字符,其中把w虚位,可以写成

avatar
T*x
23
不用函数名字就可以干很多优化的事情,这是什么原理啊?

【在 h*i 的大作中提到】
: 这个trick还是挺有用的,主要是不用函数名字,这样就可以干很多优化的事情。
avatar
h*i
24
函数不用名字,就可以随意被wrapper来替换,而这些wrapper可以干各种优化的事情,
比如他们举例说的memoize,加cache,加各种附属信息,等等。
这个是我觉得的主要有用的地方。

【在 T*******x 的大作中提到】
: 不用函数名字就可以干很多优化的事情,这是什么原理啊?
avatar
N*r
26

这玩意儿属于函数式编程的基础知识吧
居然要在网上才发现

【在 T*******x 的大作中提到】
: 最近折腾Clojure递归程序,在网上发现一个东西叫Y-Combinator,挺神奇的,号称能
: 把任何递归程序以非递归的形式写出来。
: 我看了一个blog,又引到另一个blog,讲的还行,但是不直接,我发现了一个比较直接
: 的讲法,所以写下来。
: 先定义一下问题。目标是定义一个Clojure函数Y,把任何给定的Clojure递归程序转化
: 为非递归形式。
: 比如一个factorial函数吧,我们命名它为w。它的递归程序是这样的,
: (def w (fn [n] (if (= n 0) 1 (* n (w (- n 1))))))
: 这个定义可以写成这个形式:w=f(w)。其中f就是程序“形式”,也就是从括号fn开始
: 到括号结束的一堆字符,其中把w虚位,可以写成

avatar
j*w
27
汇编语言有递归,call 指令。
所谓递归就是堆栈增长,用同样的指令操作不同的堆栈帧。

【在 c*******v 的大作中提到】
: 编译器就是把递归程序写成非递归。
: 汇编语言里只有mov,jump,inc,没有递归。
: 所以fixed point和编译器的代数性质类似。

avatar
g*t
28
你说的对。我都全忘光了。


: 汇编语言有递归,call 指令。

: 所谓递归就是堆栈增长,用同样的指令操作不同的堆栈帧。



【在 j*****w 的大作中提到】
: 汇编语言有递归,call 指令。
: 所谓递归就是堆栈增长,用同样的指令操作不同的堆栈帧。

avatar
T*x
29
最近还是在玩functional programming。碰到了一个递归替换的问题,Java里的,还没
有完全解决。但是发现用Java也能写Y-Combinator。主要借助于Object这个universal
type。挺麻烦的,写完之后我都看不懂了。也用Python实现了一下,非常容易。
相关阅读
logo
联系我们隐私协议©2024 redian.news
Redian新闻
Redian.news刊载任何文章,不代表同意其说法或描述,仅为提供更多信息,也不构成任何建议。文章信息的合法性及真实性由其作者负责,与Redian.news及其运营公司无关。欢迎投稿,如发现稿件侵权,或作者不愿在本网发表文章,请版权拥有者通知本网处理。