感恩节和朋友一起玩了很多音游捏。
感謝祭の間に、音ゲームをいっぱいやったね。
I played a lot of rhythm games with my friends during the Thanksgiving break.
感恩节和朋友一起玩了很多音游捏。
感謝祭の間に、音ゲームをいっぱいやったね。
I played a lot of rhythm games with my friends during the Thanksgiving break.
在过去的很长一段时间里我其实一直都是对可乐抱有好感的,哪怕关于可乐骇人听闻的负面新闻层出不穷,当我在不同场合见到可乐的面孔,我都会上前装上一杯或买上一瓶。哪怕现在我早已没有当年那份对可乐执着的喜爱,但每当我选择到学校的餐厅用餐,大多数时候我还是会选择来上一杯Diet Coke,然后享受气泡在舌尖绽放的快感。
今天与往常一样,我在餐厅取完餐后,也给自己装了一杯可乐。但由于略有些赶时间,我便急匆匆的用杯沿顶下自主饮料机上对应可乐的开关,待到倾泻而下的可乐裹挟着滋滋作响泡沫一将杯子填满,我就拿着杯子快速走向我所在的桌位。或许是我的速度够快,当我到达桌位时菜品还尚有余温。但当我将杯子放在桌面上时,我却注意到原本在饮料机前看似被可乐填满的杯子,现在只剩下三分之一了。
我当即便反应了过来,当时填满杯子的大部分并不是溶液,而是碳酸因分解出二氧化碳而产生的气泡。我过于着急的装满可乐,可到最后结果却并不如我所愿,甚至适得其反。
是啊,或许是我太着急了。
其实仔细想想,从过去到现在,我对现实生活中的很多事,似乎都或多或少有过急功近利的心态。随着逐渐走向成熟,我通常不会向熟人或朋友过多的展现自己的一颦一簇,但是内心的一部分想法却没有太多的变化。对学业,竞赛,日常,乃至对自己的一些事,我几乎都有过急于求成的时候,但最后看来,先不论取得的成果如何,付出了多少时间精力,我最后都不大快乐,就像一杯刚刚装好的可乐,刚开始似乎满满当当,但随着时间的推移气泡的消散,最后也所剩无几。
或许与装可乐一样,在面对生活中的很多事或许都不需要太着急,在旅途的过程中,或许目的地并没有想象中那么值得期待,但沿途的风景可能比想象中更值得欣赏。
注:阅读本文可能需要一定 LISP或 Racket的基础知识,若没有相关基础则可查阅 Racket官方文档 来进行对照学习。
在Rakect中存在一个特性叫“Y Combinator”, 它可以使你在不使用 letrec 或正常使用 define 来定义一个过程(procedure)的情况下以匿名过程 (anonymous procedures)的方式写出递归函数。我们可以先从介绍它的使用方式作为开头。例如,在Racket中,我们可以使用Y Combinator来书写一个求整数n阶乘的过程如下:
(def Fact
(Y (λ (fact)
(λ (n)
(if (zero? n)
1
(* n (fact (- n 1))))))))
由上面的例子我们可以看出,对于一个过程 f, Y Combinator的使用方式是 (Y f) , 且由于我们使用匿名过程的原因,我们需要将一个我们想使用的过程名字作为 f 的参数, 然后将对应问题的输入作为 f 所返回的过程的参数。在求阶乘的问题里,我们选用整数 n 作为我们返回的过程的参数。
那么, 接下来的问题是,为什么我们可以这么做?Y Combinator的运作原理又是什么?简单来说,Y Combinator的理论来自于Lambda Calculus中的Eta-Reduction,其相关内容在这里不做讲述。我们主要从Y Combinator的实现来解决该疑问。下面是Y Combinator的具体实现:
(define Y
(λ (f)
((λ (g) (f (g g)))
(λ (g) (f (g g))))))
这段代码可能阅读与理解起来有些困难,但我们可以把它进行一些简化之后再进行分析。我们首先添加如下的定义:
(define p (λ (g) (f (g g))))
利用上述定义,我们就可以讲Y Combinator的实现简化为如下形式:
(define Y (λ (f) (p p)))
通过简化后的代码我们不难看出,Y 是一个过程,且这个过程返回的是将上文定义的过程p作为参数传入自己本身后得出的结果,即 (p p)。接下来,我们可以尝试给过程 Y 传入一个过程 k 作为参数,看一看会发生什么。
(Y k) = (λ (g) (k (g g)))
(λ (g) (k (g g)))
= (k (λ (g) (k (g g)))
(λ (g) (k (g g))))
= (k (Y k))
由此,我们不难得出,对于任意过程 f,(Y f) = (f (Y f))。根据这点,我们也可以知晓Y Combinator就是利用了 (Y f) = (f (Y f)) 的特性来实现递归。
在Racket中Y Combinator的确很巧妙,但是在Scheme中,使用Y Combinator则会导致Scheme先解析 (Y f) 而陷入死循环。于是,我们便有了Z Combinator作为契合Scheme特点的Y Combinator。我在这里放出Z Combinator的实现,大家可以依照上文的分析来推导出Z Combinator的原理。
(define Z
(λ (f)
((λ (g) (f (λ (v) ((g g) v)))
(λ (g) (f (λ (v) ((g g) v))))))
在Z Combinator中, v是作为问题要求的输入存在的。
除了Z Combinator,我们还有针对不确定数量参数的过程的Z* Combinator,由于它和Z Combinator除了构造上有所不同其他方面并无太大差别,所以在此只给出实现代码,具体原理与特性可以依照上一节的内容进行推理。
(define Z*
(λ (f)
((λ (g) (f (λ args (apply (g g) args)))
(λ (g) (f (λ args (apply (g g) args))))))
明明天气已经很冷了,可是寝室里却还是开着冷空调……
気温がとても寒いが、寮のエアコンは冷たい風を吹いています。。。
The cold wind is still coming out from the AC in my dorm even though the weather is cold.
今天和可爱的女孩子一起吃了中饭,开心。
今日は可愛い女の子と一緒に昼ご飯をたべました。嬉しいです。qwq
I had lunch with a sweet girl today, which makes me happy.
你好,我是Twilight,是一名欧柏林学院的大三在读学生,专业是计算机科学。
这个博客会用来记录我的一些见闻,感想,和一些有趣的事。较短的博客我会尝试用中,英,日三种语言进行写作。
最后,谢谢大家的光临。
こんにちは、Twilightと申します。オバリーン大学の三年生で、専攻は情報科学です。
このブログの目的は、自分の感想と見聞と面白いことを記録します。短いポストにとって、私は中国語と英語と日本語で書いてみます。
よろしくお願いします。
Hi, I’m Twilight, a junior student at Oberlin College who major in computer science.
This blog is for showing some of my thoughts, anecdotes, and interesting stuff. I will try to use Chinese, English, and Japanese to write those relatively shorter posts.
Finally, thank you very much for coming and reading my blogs.