(本文不保证不误人子弟,切勿轻信)

Unlambda指的是lambda计算中去掉lambda操作(does not have lambda(or abstraction) operation of the lambda calculus),那实现消除abstraction是如何做到的呢?

一、基本的abstraction elimination

假设表达式F,我们想用它创建一个函数(function),将这个函数应用到X上,用符号表示变量并写成$x(即^xF,这里用^表示标准的lambda),那么想得到unlambda,需要消除lambda operation。

对F来说,有三种情况:1. F是内建(函数)(或者是非$x的变量);2. F是$x;3. F 是一个应用(函数),即 `GH,其中G和H是比F简单的表达式(就是降低F表达式复杂度),对这三种情况分别讨论:

1. 从^xF中消除lambda,其中F不依赖于$x,故可以将F看作是常函数,这是因为X是输入,F不依赖于输入自然就表示F是常函数,即 `kF

2. 从^x$x中消除lambda,对于输入X,这个函数返回就是$x,即自身,故对应i

3. 从^x`GH中消除lambda,假定我们已经知道如何从^xG和^xH中消除lambda,根据^x`GH意思是有一个输入X,而`GH表示应用G到H上,这表示可以将X传入到^xG 和^xH中,然后将后者结果作为前者的输入,这正是内建s的作用,故^x`GH对应

  ``s^xG^xH

总结如上规律,考虑消除^xF的lambda,注意这里的F可能是一个复杂的表达式,并且可能跟$x相关,对F从左往右看,遇到一个 `(backquote),将其替代为 ``s, 遇到 $x 则替代为 i, 遇到任何内建函数或者非$x的变量,则在这个函数符号或者变量符号前加一个 `k,如果有几个lambda需要消除,从内部往外部消除,具体参见下面的例子b。

例子:

a.函数 ^x`$xk 的去lambda,此处我们用上面1)、2)和3)的规律来转换。

^x`$xk -> (F是`$xk,是复杂表达式,应用上面第三点)-> ``s^x$x^xk -> (分别对^x$x 和 ^xk 去lambda)-> ``si`kk

b.函数 ^x^y`$y$x 的去lambda,此处我们用上面的总结规律来转换(当然也可以根据1、 2、 3点规律老老实实的转换)

^x^y`$y$x -> (根据例子a的结论)-> ^x``si`k$x ->(根据总结规律先转换左部两个 ` )-> ``s``s    si`k$x ->(从第三个s开始转换内建函数s和i,空白格是故意加上去为了区分左部是已经转换的,右部尚未转换)

      -> ``s``s`ks`ki`    `k$x -> ``s``s`ks`ki``s`kki

如果给出了若干个lambda,那么abstraction eliminate后的表达式将会指数级增长(以3为底的指数)。一个 ` 变为 ``s,然后 ``s 变为 ``s``s`ks,然后又变为 ``s``s`ks``s``s`ks``s`kk`ks,依次类推。

二、高效的abstraction elimination

上面分析的第一种情况下,表达式F是内建函数或者是非$x的变量,则可以将lambda ^xF 写成 `kF,事实上,只要F不包含 x 就可以这么转换,因为此时 F 是与 x 无关的,可以将 F 看作是 x 的常量,此时可以不用遍历繁杂的F表达式而可以直接转换写成`kF。可以将这种转换看作 abstraction elimination的快捷方式(shortcut)。

有一点需要注意,这样的转换在 “纯的隐式类型的lambda计算” 领域可以很好的工作,或者在我们不用过多担心计算非终止(如死循环,或无限大列表)的情况下也是可以很好的工作。因为没有边界作用(side effect),当然目前我们所看到的函数确实不产生边界作用。可是,当我们写 ^xF的时候,我们可能是考虑到有边界作用的或者计算不能结束(因为是lambda),这个边界作用使得某些计算被延迟直到函数被应用到某个变量上(即,直到 $x 接收到一个值,哪怕那个值其实是被忽略的),所以如果我们使用shortcut并写成 `kF,那么一旦遇到这个表达式,F 就会被计算,即使这个函数没有被应用到某个参数变量,这跟原来的 ^xF的延迟性不吻合。

于是使用shortcut将 ^xF写成 `kF 的前提条件是 a)F 不包含 $x;b)计算 F 能计算出来并且没有边界作用。一个确保条件b)能满足的方法是检查F的应用形式为:内建函数 K 应用到一个参数上, 或者内建函数 S 应用到一个或两个参数上,或者内建函数 D 应用到任何表达式上。(这样保证F是无法立即被计算出来)

如果F不包含 x 但是包含一些可能导致边界作用或者无法计算完成(比如死循环)的计算,此时虽然不能使用 shortcut 转换,但仍然有另一种方法较高效地实现 abstraction elimination,即使用内建函数 D,转换成 `d`kF 。(可能,对于一个纯函数论者,他是不会在程序中使用 D 的。)

abstraction elimination的另一个快捷方法是将形如 ^x`F$x 转换为 F,当然这需要确保 F 中没有变量 $x。这在F不是内建函数 D 并且非 $x的情况下,转换非常快捷。然而如果 F 可能会产生边界作用时,跟其他shortcut一样,这种转换带有危险(也可以写成 `dF从而绕开这种危险)。

三、更多的unlambda内建函数

1. v 函数

v 函数好比一个黑洞,v需要一个输入参数,并忽略这个参数然后返回v自己,故 v 可以用来吞噬 N个参数。

v函数可以由 s,k 和 i 来实现(即,也可以使用 s 和 k 来实现)。

2.   .x 函数

.x 函数需要一个参数,并将这个参数打印到标准输出。 r 函数 是 .x 函数的一个实例,即x参数是一个换行符, 因此, `ri 的作用是打印一个新行, `rv 或者 `rr 或者 `r(anything) 都是打印一个新行,当然, r 函数本身不会做任何事情,因为 r 函数没有被应用到一个参数中。

3. d 函数

d 函数是一个特例。当unlambda准备计算 `FG,并且 F 计算出来为 d (比如 F 就是 d),那么 G 将不会被计算, 结果为 `dG, `dG允诺会计算G(a promise to evaluate G),只有在 `dG被应用到表达式H上(在此之前,G是保持未计算状态),这时,G 最终被计算出来(在 H 被计算出来之后),然后 再应用到 H 上。

例如, `d`ri 不会做任何事情(保持未计算状态), ``d`rii 打印一个新行,因为 `d`ri 被应用到 i 上,于是 `ri(作为G)被计算出来为i(其副作用是打印新行),然后在应用到 i 上, 还是为 i 本身。另一个例子是 ``dd`ri ,打印一个空白行,事实上, `dd 首先被计算,根据 d 函数的特性,计算结果为允诺计算d(a promise to evaluate d),即可以看作第二个 d 被第一个 d 暂时封住了,所以不会阻止 `ri 打印新行,然后再 计算 d(第二个d),此时新行已经被打印。另一方面, ``id`ri 不会打印新行,因为 `id会被先计算出来为 d,阻止了后面的 `ri, 类似地, ```s`kdri 首先转为 ```kdi`ri (将`kd 看作 X,`r 看作 Y, i 看作 Z),然后 ``kdi 被计算为 d, 然后阻止了后面的 `ri, 故这个函数不会打印新行。

`d`kF 是另一个 promise 的形式(与 `dG 比较):当这个函数 应用到 参数 Y 上, Y 被忽略,然后返回 F 。这在上文 abstraction elimination 中有关 shortcut 的讨论中提到(大概因为 d 函数的 promise 特性与边界作用类似吧)。

Abstraction elimination的更多相关文章

  1. A.Kaw矩阵代数初步学习笔记 6. Gaussian Elimination

    “矩阵代数初步”(Introduction to MATRIX ALGEBRA)课程由Prof. A.K.Kaw(University of South Florida)设计并讲授. PDF格式学习笔 ...

  2. hdu4975 A simple Gaussian elimination problem.(正确解法 最大流+删边判环)(Updated 2014-10-16)

    这题标程是错的,网上很多题解也是错的. http://acm.hdu.edu.cn/showproblem.php?pid=4975 2014 Multi-University Training Co ...

  3. Effective Java 61 Throw exceptions appropriate to the abstraction

    Exception translation: higher layers should catch lower-level exceptions and, in their place, throw ...

  4. 【转】Duplicate Elimination in Scrapy

    本文转载自:http://blog.pluskid.org/?p=381 之前介绍 Scrapy 的时候提过 Spider Trap ,实际上,就算是正常的网络拓扑,也是很复杂的相互链接,虽然我当时给 ...

  5. SQL Abstraction and Object Hydration

    SQL Abstraction and Object Hydration In the last chapter, we introduced database abstraction and a n ...

  6. 390. Elimination Game

    正规解法直接跳到代码上面一点的部分就可以了.但我想记录下自己的思考和尝试过程,希望二刷能看到问题所在. 找规律的时候写了好多,虽然规律很简单. 只要随便写3以上的例子,就应该发现,相邻的2个最后结果是 ...

  7. Gauss elimination Template

    Gauss elimination : #include <iostream> #include <cstdlib> #include <cstring> #inc ...

  8. 列存储段消除(ColumnStore Segment Elimination)

    列存储索引是好的!对于数据仓库和报表工作量,它们是真正的性能加速器.与聚集列存储结合,你会在常规行存储索引(聚集索引,非聚集索引)上获得巨大的压缩好处.而且创建聚集列存储索引非常简单: CREATE ...

  9. 高斯消元法(Gauss Elimination)【超详解&模板】

    高斯消元法,是线性代数中的一个算法,可用来求解线性方程组,并可以求出矩阵的秩,以及求出可逆方阵的逆矩阵.高斯消元法的原理是:若用初等行变换将增广矩阵 化为 ,则AX = B与CX = D是同解方程组. ...

随机推荐

  1. [google面试CTCI] 1-7.将矩阵中特定行、列置0

    [字符串与数组] Q:Write an algorithm such that if an element in an MxN matrix is 0, its entire row and colu ...

  2. 分布式搜索ElasticSearch构建集群与简单搜索实例应用

    分布式搜索ElasticSearch构建集群与简单搜索实例应用 关于ElasticSearch不介绍了,直接说应用. 分布式ElasticSearch集群构建的方法. 1.通过在程序中创建一个嵌入es ...

  3. MongoDB学习3

    MongoDB学习(翻译3)   支持的where字句(比较多,今天先写一部分) 本节介绍支持的where字句 正如前面提到的,不是所有的C#表达式都支持where子句.您可以以此文为指导,或者你可以 ...

  4. StringEscapeUtils.unescapeHtml的使用

    在做代码高亮时,从数据库中取出代码如下(节选): <pre class="brush: java;"> 需要的应该是<pre class=\"brush ...

  5. scribefire 多博客管理利器 安装详解

    scribefire 多博客管理利器 安装详解 一.ScribeFire介绍 ScribeFire 是 Firefox (火狐浏览器)上著名的博客写作工具,目前已跨平台支持多浏览器(Firefox,C ...

  6. 以helloworld为例讲解magento中控制器的工作

    1.下面介绍的前提是你已经安装了magento ,版本是1.9.1.0. 2.下面是实际步骤 ①在工程下面创建下面的文件目录 app/code/local/Magentotutorial/Hellow ...

  7. spring启用线程空指针异常

    在service里启用了一个线程,线程的run方法调用了service的方法,报了空指针异常,不知道怎么回事.不过貌似是spring的注入问题,只要在线程里调用了dao或者service里的某些方法, ...

  8. 一口一口吃掉Hexo(二)

    如果你想得到更好的阅读效果,请访问我的个人网站 ,版权所有,未经许可不得转载! 本次系列教程的第二篇文章我会介绍如何在本地安装Hexo,请注意我使用的Windows系统,如果你是Mac或者Ubuntu ...

  9. Mvc分页组件MvcSimplePager代码重构

    1 Mvc分页组件MvcSimplePager代码重构 1.1 Intro 1.2 MvcSimplePager 代码优化 1.3 MvcSimplePager 使用 1.4 End Mvc分页组件M ...

  10. C语言之分支结构 if(一)

    一 程序的三种基本结构 顺序结构:程序从上往下依次执行,这个叫顺序结构 分支结构:有选择的执行或者不执行某段代码 循环结构:重复的执行某段代码 二 分支结构之if 最简单的俩种用法 (tips: if ...