从工具的奴隶到工具的主人

2023-05-16

摘要:我们每个人都是工具的奴隶。随着我们的学习,我们不断的加深自己对工具的认识,从而从它们里面解脱出来。现在我就来说一下我作为各种工具的奴隶,以及逐渐摆脱它们的思想控制的历史吧。

当我高中毕业进入大学计算机系的时候,辅导员对我们说:“你们不要只学书本知识,也要多见识一下业界的动态,比如去电脑城看看人家怎么装机。”当然他说我们要多动手,多长见识,这是对的。不过如果成天就研究怎么“装机”,研究哪种主板配哪种 CPU 之类的东西,你恐怕以后就只有去电脑城卖电脑了。

本科的时候,我经常发现一些同学不来上数学课。后来却发现他们在宿舍自己写程序,对MFC之类的东西津津乐道,引以为豪。当然会用MFC没有什么不好,可是如果你完全沉迷于这些东西,恐怕就完全局限于Windows的一些表面现象了。

所以我在大学的时候就开始折腾Linux,因为它貌似让我能够“深入”到计算机内部。那个时候,书店里只有一本 Linux 的书,封面非常简陋。这是一本非常古老的书,它教的是怎样得到Slackware Linux,然后把它从二三十张软盘装到电脑上。总之,我就是这样开始使用Linux的。后来我就走火入魔了,有时候上课居然在看GCC的内部结构文档。后来我又开始折腾TeX,把TeXbook都看了两遍,恁是用它写了我的本科毕业论文。

后来进了清华,因为不满意有人嘲笑我用Linux这种“像DOS的东西”,以及国内网站都对Windows和IE进行“优化”的情况,就写了个“完全用Linux工作”。确实,会Linux的人现在更容易找到工作,更容易被人当成高手。但是那些工具同样的奴役了我,经常以一些雕虫小技而自豪,让我看不到如何才能设计出新的,更好的东西。当它们的设计改变的时候,我就会像奴隶一样被牵着鼻子走。

这也许就是为什么我在清华的图书馆发现《SICP》的时候如此的欣喜。那本书是崭新的,后面的借书记录几乎是空白的。这些看似简单的东西教会我的,却比那些大部头和各种 HOWTO 教会我的更多,因为它们教会我的是WHY,而不只是HOW。当时我就发现,虽然自认为是一个“资深”的研究生,学过那么多种程序语言,各种系统工具甚至内核实现,可是相对于SICP的认识深度,我其实几乎完全不会写程序!在第三章,SICP 教会了我如何实现一个面向对象系统。这是我第一次感觉到自己真正的在开始认识和控制自己所用的工具。

因为通常人们认为Scheme不是一个“实用”的语言,没有很多“库”可以用,效率也不高,而Common Lisp是“工业标准”,再加上Paul Graham文章的怂恿,所以我就开始了解Common Lisp。在那段时间,我看了Paul Graham的《On Lisp》和Peter Norvig的 《Paradigms of Artificial Intelligence Programming》。怎么说呢?当时我以为自己学到很多,可是现在看来,它们教会我的并没有《SICP》的东西那么精髓和深刻。开头以为一山还有一山高,最后回头望去,其实复杂的东西并不比简单的好。现在当我再看Paul Graham和Peter Norvig的文章,就觉得相当幼稚了,而且有很大的宗教成分。

进入Cornell之后,因为Cornell的程序语言课是用SML的,我才真正的开始学习“静态类型”的函数式语言。之前在清华的时候,有个同学建议我试试ML和Haskell,可是因为我对Lisp 的执着,把他的话当成了耳边风。当然现在用上SML就免不了发现ML的类型系统的一些挠人的问题,所以我就开始了解Haskell,并且由于它看似优美的设计,我把“终极语言”的希望寄托于它。我开始着迷一些像monads,type class,lazy evaluation 一类的东西,看Simon Peyton Jones的一些关于函数式语言编译器的书。以至于走火入魔,对其它一切“常规”语言都持鄙视态度,看到什么都说“那只不过是个monad”。虽然有些语言被鄙视是合理的,有些却是被错怪了的。后来我也发现monad, type class, lazy evaluation这些东西其实并不是什么包治百病的灵丹妙药。

但是我很不喜欢Cornell的压抑气氛,所以最后决定离开。在不知何去何从的时候,我发了一封email给曾经给过我fellowship的IU教授Doug Hofstadter(《GEB》的作者)。我说我不知道该怎么办,后悔来了 Cornell,我现在对函数式语言感兴趣。他跟我说,IU的Dan Friedman就是做函数式语言的啊,你跟他联系一下,就说是我介绍你来的。我开头看过一点The Little Schemer,跟小人书似的,所以还以为Friedman是个年轻小伙。当我联系上Friedman的时候,他貌似早就认识我了一样。他说当年你的申请材料非常impressive,可惜你最后没有选择我们。你要知道,世界上最重要的不是名气,而是找到赏识你,能够跟你融洽共事的人。你的材料都还在,我会请委员会重新考虑你的申请。IU 的名气实在不大,而Friedman 实在是太谦虚了,所以连跟他打电话都没有明确表态想来IU,只是说“我考虑一下……”这就是我怎么进入IU的。

Friedman的教学真的有一手。虽然每个人对他看法不同,但是有几个最重要的地方他的指点是帮了我大忙的。有人可能想象不到,在Scheme这种动态类型语言的“老槽”,其实有人对“静态类型系统”的理解如此深刻。也就是在Friedman的指点下,我发现类型推导系统不过是一种“抽象解释”,而各种所谓的“typing rule”,不过是抽象解释器里面的分支语句。我后来就通过这个“直觉”,再加上Friedman的逻辑语言miniKanren里面对逻辑变量和unification的实现,做出了一个Hindley-Milner类型推导系统(HM 系统),也就是ML和 Haskell的类型系统。虽然我在Cornell的课程作业里实现过一个HM系统,但是直到Friedman的提点,我才明白了它“为什么”是那个样子,以至于达到更加优美的实现。后来经他一句话点拨,我又写出了一个lazy evaluation的解释器(也就是Haskell的语义),才发现原来SPJ的书里所谓的“graph reduction”,不过就是如此简单的思想。只不过在SPJ的书里,细节掩盖了本质。后来我在之前的HM系统之上做了一个非常小的改动,就实现了type class的功能,并且比Haskell的实现更加灵活。所以,就此我基本上掌握了ML和Haskell的理论精髓。

可是类型系统却貌似一个无止境的东西。在ML的系统之上,还有System F,Fw,MLF,Martin Lof Type Theory,CIC,……怎么没完没了?我一直觉得这些东西过度复杂,有那个必要吗?直到Amal Ahmed来到IU,我才相信了自己的感觉。然而,这却是以一种“反面”的方式达到的。

Amal是著名的Andrew Appel(“虎书”的作者)的学生,在类型系统和编译器的逻辑验证方面做过很多工作。可是她比较让人受不了,她总是显得好像自己是这里唯一懂得类型的人,而其他人都是类型白痴。她不时的提到跟Bob Harper, Benjamin Pierce等类型大牛一起合作的事情。如果你问她什么问题,她经常会回答你:“Bob Harper说……”她提到一个术语的时候总是把它说得无比神奇,把它的提出者的名字叫得异常响亮。有一次她上课给我们讲System F,我问她,为什么这个系统有两个“binder”,貌似太复杂了,为什么不能只用一个?她没有正面回答,而是嘲讽似的说:“不是你说可以就可以的。它就是这个样子的。”后来我却发现其实有另外一个系统,它只有一个binder,而且设计得更加简洁。后来我又在课程的 ailing list 了一个问题,质疑一个编译器验证方面的概念。本来是纯粹的学术讨论,却发现这封email根本没有发到全班同学信箱里,被Amal给moderate掉了!

看到这种种诡异的行为,我才意识到原来学术界存在各种“帮派”。即使一些人的理论完全被更简单的理论超越,他们也会为“自己人”的理论说话,让你搞不清到底什么好,什么不好。所以后来我对一些类型系统,以及Hoare Logic一类的“程序逻辑”产生了怀疑。我的课程project报告,就是指出Hoare Logic和Separation Logic所能完成的功能,其实用“符号执行”或者“model checking”就能完成。而这些程序逻辑所做的事情,不过是把程序翻译成了等价的逻辑表达式而已。到时候你要得知这些逻辑表达式的真伪,又必须经过一个类似程序分析的过程,所以这些逻辑只不过让你白走了一些弯路。当Amal听完我的报告,勉强的笑着说:“你告诉了我们这个结论,可是你能用它来做什么呢?”我才发现原来透彻的看法,并不一定能带来认同。人们都太喜欢“发明”东西,却不喜欢“归并”和“简化”东西。

可是这类型系统的迷雾却始终没有散去,像一座大山压在我头上。我不满意Haskell和ML的类型系统,又觉得System F等过于复杂。可是由于它们的“理论性”和它们创造者的“权威”,我不敢断定自己的看法就不是偏颇的。对付疑惑和恐惧的办法就是面对它们,看透它们,消灭它们。于是,我利用一个independent study的时间,独立实现了一个类型系统。我试图让它极度的简单,却又“包罗万象”。经过一番努力,这个类型系统“涵盖”了System F, MLF 以及另外一些类似系统的推导功能,却不直接“实现”他们。后来我就开始试图让它涵盖一种非常强大的类型系统,叫做intersection types。这种类型系统的研究已经进行了20多年,它不需要程序员写任何类型标记,却可以给任何“停机”的程序以类型。著名的Benjamin Pierce当年的博士论文,就是有关intersection types的。没几天,我就对自己的系统稍作改动,让它涵盖了一种最强大的intersection type系统(System I)的所有功能。然而我却很快发现这个系统是不能实用的,因为它在进行类型推导的时候相当于是在运行这个程序,这样类型推导的计算复杂度就会跟这个程序一样。这肯定是完全不能接受的。后来我才发现,原来已经有人指出了 System I 的这个问题。但是由于我事先实现了这个系统,所以我直接的看到了这个结论,而不需要通过繁琐的证明。

所以,我对类型推导的探索就这样到达了一个终点。我的类型系统是如此的简单,以至于我看到了类型推导的本质,而不需要记住复杂的符号和推理规则。我的系统在去掉了intersection type之后,仍然比System F和MLF都要强大。我也看到了Hindley-Milner系统里面的一个严重问题,它导致了这几十年来很多对于相关类型系统的研究,其实是在解决一个根本不存在的问题。而自动定理证明的研究者们,却直接的“绕过”了这个问题。这也就是我为什么开始对自动定理证明开始感兴趣。

后来对自动定理证明,Partial Evaluation 和 supercompilation的探索,让我看到那些看似高深的Martin Lof Type Theory, Linear Logic等概念,其实不过也就是用不同的说法来重复相同的话题。具体的内容我现在还不想谈,但是我清楚的看到在“形式化”的美丽外衣下,其实有很多等价的,重复的,无聊的东西。与其继续“钻研”它们,反复的叨咕差不多的内容,还不如用它们的“精髓”来做点有用的事情。

所以到现在,我已经基本上摆脱了几乎所有程序语言,编译器,类型系统,操作系统,逻辑推理系统给我设置的思维障碍。它们对我来说不再是什么神物,它们的设计者对我来说也不再是高不可攀的权威。我很开心,经过这段漫长的探索,让我自己的思想得到了解放,翻身成为了这些工具的主人。虽然我看到某些理论工具的研究恐怕早就已经到达路的尽头,然而它们里面隐含的美却是无价和永恒的。这种美让我对这个世界的许多其它方面有了焕然一新的看法。一个工具的价值不在于它自己,而在于你如何利用它创造出对人有益的东西,以及如何让更多的人掌握它。这就是我打算现在去做的。


本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

从工具的奴隶到工具的主人 的相关文章

  • Unreal Engine 网络系统(一):网络模型及网络视角下的Gameplay框架

    个人学习记录 xff0c 如有错误请及时联系我 xff01 欢迎交流 xff01 1 客户端 服务器模型 服务器 xff1a 有一个客户端担当游戏状态的主控者 作用 xff1a 做出所有重要决定 xff0c 保证公平性 xff0c 包含所有
  • Unreal Engine 网络系统(二):网络对象同步、网络身份

    目录 网络身份 行为同步和属性同步 Actor网络身份 区分Client amp Server 身份授权类别 划分终端所在用途 思考几个问题 xff1a 什么是同步 xff1f 网络游戏中 xff0c 什么内容需要同步 xff1f 虚幻中的
  • Unreal Engine 网络系统(三):RPC同步

    目录 RPC RPC执行分三种形式 修改所有权 RPC 全称Remote Procedure Call xff0c 远端调用 指在本机上调用函数 xff0c 但在其他机器上远程执行的函数 RPC函数可以允许Client或Server通过网络
  • Unreal Engine 网络系统(四):UEC++的RPC

    目录 行为同步 On Server xff1a 服务端的RPC代码 On Client xff1a 客户端的RPC代码 NetMulticast xff1a 广播的RPC代码 属性同步 行为同步 借助UFUNCTION进行函数标记 UFUN
  • Unreal Engine 网络系统(五):带宽管理(相关性及优先级)

    目录 相关性 优先级 创建 查找 加入房间 xff08 Session xff09 网络游戏是通过计算机硬件通信方案将多台终端连接 xff0c 组建的玩家沟通环境 xff0c 从而使得玩家连接到一起游戏 受限于网络传输环境的影响 xff0c
  • 字串起始位置最大值

    给定两个字符串s1和s2 xff0c 如果s1删除若干个字符后变成s2 xff0c 则称s2为s1的子串 xff0c 求s2在s1中的起始位置的最大值 输入描述 xff1a 只有一行 s1 xff0c s2 xff0c s1和s2用空格隔开
  • 【c++】的作用域 (局部域,类域,名字命名空间,文件域)

    这里写目录标题 局部域类域类修饰指针由类限制修饰指向变量的指针由类修饰指向函数的指针 命名空间背景 xff1a 文件域 c 43 43 支持四个域 xff1a 局部域 xff0c 类域 xff0c 名字空间域 xff0c 文件域 局部域 函
  • Java变量名规则

    给大家简单介绍一下java中的变量名规则 和实用的起名工具 记忆变量名起名规则小技巧 变量名开头可用的类型 字下美人 字母 下划线 美元符号 人民币符号 变量名开头后面可用的类型 字下美人数非 字母 下划线 美元符号 人民币符号 数字 非关
  • Linux中的字符串和字节序列处理函数

    花了两天的时间总结了Linux编程时的字符串操作函数和字节序列操作函数 xff0c 以便后续查阅 这些函数大都不会去检查传入的参数是否为NULL xff0c 因此在使用之前要自己做检查 xff0c 否则后果你懂的 一个基本知识点 xff1a
  • extern "c"用法解析

    引言 C 43 43 保留了一部分过程式语言的特点 xff0c 因而它可以定义不属于任何类的全局变量和函数 但是 xff0c C 43 43 毕竟是一种面向对象的程序设计语言 xff0c 为了支持函数的重载 xff0c C 43 43 对全
  • 解决树莓派Unbuntu mate 使用VNC连接灰屏报错“Could not acquire name on session bus”问题

    修改 vnc xstartup 文件 打开 vnc xstartup 文件 1 添加两行 unset SESSION MANAGER unset DBUS SESSION BUS ADDRESS 2 查看桌面环境是什么 xff1a 先查看系
  • python:isinstance用法

    isinstance xff08 object xff0c type xff09 只要object是type类型 xff0c 返回True xff1b 否则返回False 作用 xff1a 来判断一个对象是否是一个已知的类型 其第一个参数
  • windows下开启Qemu串口调试

    1 EDKII 包编译 如果要在 windows 下启用串口信息打印 xff0c 需要在 build 时加 D DEBUG ON SERIAL PORT 选项 需要注意的是 xff0c 在 target txt 中 TARGET 只能是 D
  • 关于深度学习主机的一些选配问题

    作为一个深度学习的初学者 xff0c 你可能会遇到这样的问题 xff1a 我该如何训练我自己或者别人的Model xff1f 我该如何配置一台合适的主机 xff1f 目前有哪几种训练模型的方式 xff1f 接下来 xff0c 我将会对此进行
  • FreeRTOS中两个同等级无阻塞打印任务,只有一个能正常打印

    环境 xff1a STM32CubeMX 43 MDK5 printf重定向用的是官方例子 ifdef GNUC With GCC small printf option LD Linker gt Libraries gt Small pr
  • putty 连接Debian linux 报错Connection refused

    ubuntu默认并没有安装ssh服务 xff0c 如果通过ssh链接ubuntu xff0c 需要自己手动安装ssh server 判断是否安装ssh服务 xff0c 可以通过如下命令进行 xff1a xjj 64 xjj desktop

随机推荐

  • python 使用playsound模块出现编码问题。

    Error 259 for command play sound zhou mp3 wait 驱动程序无法识别指定的命令参数 Error 263 for command close sound zhou mp3 指定的设备未打开 xff0c
  • C/C++ 编程推荐学习顺序和书籍

    自学或者学习C C 43 43 编程不知道怎么办 xff1f 那么恭喜你看到本文 xff0c 本文将会为你提供C C 43 43 编程的学习书籍顺序推荐 xff0c 希望对大家有帮助 xff01 C C 43 43 语言基础入门书籍 xff
  • Android Studio 控制台中文乱码,解决方案都在这里了,完美解决

    前言 Android Studio 如果不进行配置的话 xff0c 运行程序时控制台中文乱码问题会非常严重 xff0c 甚至影响我们对信息的获取和程序的跟踪 通过历年的开发经验 xff0c 在本文中我总结出四点用于解决控制台中文乱码问题的方
  • 【C/C++】中的__FILE__、__LINE__、#line、__func__关键字(预定义宏)

    c 43 43 11预先定义了一些标识符 xff0c 其实也就是宏 现在简单说几个 xff1a 1 FILE 用于指示本行语句所在源文件的文件名 xff0c 如下 xff08 test c xff09 xff1a include lt st
  • 视觉SLAM入门十四讲

    视觉SLAM入门十四讲 写在前面的话什么是视觉SLAM视觉SLAM中所使用的摄像头传感器单目摄像头双目摄像头深度摄像头 经典视觉SLAM框架 写在前面的话 考研期间迷上了SLAM xff0c 买来了高翔 张涛等著的 视觉SLAM十四讲 从理
  • px4源码编译指南

    px4源码编译指南 强烈推荐大家去看官网的英文文档 xff0c 国内的博客杂七杂八 xff0c 官网的中文也很久没有更新 xff0c 这几天自己踩了很多坑 xff0c 写个教程希望能帮助到大家 xff08 本文选用平台是pixhawk1 1
  • 敏捷开发:做一个合格的Scrum Master

    图片来源于网络 Scrum Master Beauty and Beast 在Scrum敏捷开发中有三种主要的角色 xff1a Product Owner xff08 产品负责人 xff0c 简称 34 PO 34 xff09 Scrum
  • 嵌入式软件:通过串口进行调试的一些思考和实践

    最近的工作还是改那坨代码 维护这摊东西也快要2年了 xff0c 好几次想重构它 xff0c 顺便整理一下 xff0c 不过我还是缺乏那种毅力 在这段时间里我还加了一些功能模块 xff0c 估计如果以后有新人接手这摊东西 xff0c 会抱怨这
  • 串口调试助手没有显示

    用cubeMX生成工程之后 xff0c 笔者写了下面两句话 xff08 向串口发送一个字符串 xff09 xff1a 但是 xff0c 打开调试工具怎么也接受不到数据 xff0c 魔术棒里面的 芯片型号 xff0c 调试 xff08 J L
  • vscode使用gitee

    vscode使用gitee 首先选择文件夹右键用vscode打开 然后打开vscode的终端 xff1a 在终端输入命令 xff1a xff08 每行命令输入完成之后记得敲回车 xff09 xff1a git init然后敲回车就有 xff
  • 深度揭秘阿里(蚂蚁金服)技术面试流程!附前期准备,学习方向

    上半年公司的项目很闲 xff0c 很多人觉得没意思陆续走了 xff0c 我考虑到自己的发展 xff0c 从6月底开始面 xff0c 面到7月底 xff0c 三十家公司 我从不打没准备的仗 xff0c 我是一个喜欢总结经验的人 xff0c 每
  • Git 中submodule的使用,终于有人说明白了

    背景 面对比较复杂的项目 xff0c 我们有可能会将代码根据功能拆解成不同的子模块 主项目对子模块有依赖关系 xff0c 却又并不关心子模块的内部开发流程细节 这种情况下 xff0c 通常不会把所有源码都放在同一个 Git 仓库中 有一种比
  • git 工具GitEye使用

    二 xff1a 签入 右键commit 可以选择需要签入的 xff0c 要加入注释才能签入 一 xff1a 比较
  • ROS笔记十(基于Python、Kinetic):rviz基础——快速配置并渲染点云和摄像机图像数据

    前言 xff1a rviz xff08 ROS visualization xff09 xff1a 用于机器人 传感器和算法的通用3D可视化系统 rviz能够绘制多种类型的数据流 特别是三维的数据 在ROS中所有类型的数据都被关联到一个参考
  • java面试必看书单

    编程之法 https legacy gitbook com book wizardforcel the art of programming by july details 白话经典算法之七大排序 链接 xff1a https pan ba
  • Java基础 - Integer和int的区别

    一 int和Integer的区别 两者的区别主要体现在以下几个方面 xff1a 1 数据类型不同 xff1a int 是基础数据类型 xff0c 而 Integer 是包装数据类型 xff1b 2 默认值不同 xff1a int 的默认值是
  • Lua + GraphicsMagick安装

    Lua 43 GraphicsMagick安装 图片的实时缩放功能是Nginx调用Lua脚本 xff0c Lua脚本在FastDFS中下载对应的图片保存到本地 xff0c 然后Lua调用GraphicsMagick实现图片的缩放功能 1 安
  • 零基础应该选择学习 C、C++、Java、python、web前端、C#、PHP、Linux选哪个编程语言好呢?

    众多的语言 xff0c 到底哪一门才是适合我呢 xff1f 小白 xff1a 大佬 xff0c 大佬 xff0c 编程语言也太多了 xff0c 到底我应该选择哪一种呢 xff1f 大佬 xff1a 首先呢 xff0c 我们先对常见的编程语言
  • 如何看英文技术文档

    https www jianshu com p af7d39cac6b8
  • 从工具的奴隶到工具的主人

    摘要 xff1a 我们每个人都是工具的奴隶 随着我们的学习 xff0c 我们不断的加深自己对工具的认识 xff0c 从而从它们里面解脱出来 现在我就来说一下我作为各种工具的奴隶 xff0c 以及逐渐摆脱它们的思想控制的历史吧 当我高中毕业进