我无法论证, 从最近接触到的一些思想里感受到变量名是很多问题的来源
如果要反驳, 至少看一下我文章里几个链接对应的演讲或者博客
另外如果把这个想法用在现在的编程上, 多半会是错的, 这篇文章只说想法
编程语言的熵
Joe Armstrong 老爷子在 StrangeLoop2014 有个演讲, 我转到微博了
http://weibo.com/1651843872/BnVdW8JTu
里边说到从前那样配置的电脑, 60ms 就能开机了, 现在的电脑反而要几秒几分钟
这些年已经有太多太多的代码了, 就像是熵增一样不可逆转
而内存上的状态数量, 简直比宇宙原子个数还要多, 所以程序员必然无可奈何
那么有没有什么办法, 把代码积累起来的混乱清除干净呢?
比如说常用的逻辑, 显然我们重复了上千遍, 实际上它们应该是一样的
对这类代码, 是否能有一个工具, 将其分析简化到简单的结果呢?
然而像文件压缩一样, 总是有个极限, 取决于软件的熵, 也就是复杂度
变量名就是很明显的一个熵的来源, 其中包含了各种各样的信息
于是这条路往下就走不通了
演讲的意思听不大明白, 但是 Software Entropy 的概念说得很形象
另一个相关的话题是破窗理论, 一旦代码中有混乱, 混乱非常容易扩大
回到变量名的问题上来, 我感到变量名确实带来了巨大的复杂度
编程语言早期想通过抽象符号来取代硬件地址, 可能自由度给得太大了
静态语言编译之后, 有的变量名会消失, 但还会有类型之类多种命名
动态语言当中, 变量名,方法名,数据字段名称, 充斥着整个运行时
此外还有事件, 文件, 网络等等各种可以有命名的复杂度的地方
存在变量名就需要考虑是否重名的问题, 甚至由重名造成的 bug
团队当中变量名也可能成为开发的成本, 因为需要制定规范达成统一
以及变量名增多以后, 管理变量名甚至成为软件复杂度的部分
虽然软件生长过程中, 带来复杂度的因素很多, 比如业务, 平台, 框架
但是变量名复杂度的增长更像是其中特别浪费的一项
Backbone 绑定节点关系
我在写 Backbone 时有一个明显的例子, 就是在 View 当中需要定义变量名
这些变量名有若干个作用:
- 特殊的节点, 用于被 CSS 选择器选中以添加样式
- 被 jQuery 选择器选中, 执行 DOM 操作
- 作为监听事件的标识, 也是借助 jQuery
这些变量名有着实实在在的麻烦, 比较容易重名, 字符的数量也很多
另外让我比较难受的是, 借助已有技术, 大部分名字应该就是很容易去掉的:
- CSS 样式, 我们在 Sketch 当中只有极少的变量, 样式就做好了
样式通常和节点一一, 不值得大量选择器去归纳样式 - DOM 操作, 在 React 当中可以自动完成, 并不需要手动制定标识用于更新
- 事件监听, 比如 React 当中, 或者早期的 ASP 的 onClick 写法,
事件绑定也是和节点对应的, 用一个名字反而增加了成本
还有一种手法是 iOS 当中通过拖拽控件进行绑定, 也可以省掉名称
这个例子里名称几乎都是为了帮助程序结构化, 强制使用的名字
因为拆分以后, 两个元素之间固有的关系被截断, 依靠名字才能重新建立
但这样拆分的成本就是需要人工维护大量的名词
React 内部实现中虽然用了字符串形式的 id, 但维护成本极少
函数式编程
函数式编程除了作为值的函数, 还有不可变数据, 还有隔离副作用等等
不可变数据 immutable 非常有意思, 因为做网页平常都是修改数据状态的
所以真的很难想象都是 Erlang 那样不可变还怎么编程
实际上总有办法的, 比如不断创建新的作用域以及拷贝变量等等
而且在特定的场景, 比如 React 当中, 不可变数据明显是很好的方案
数据不可变同样在并行编程当中, 用来保证数据一致性
数据不会被改变, 意味着数据随时能被缓存下来, 避免掉重复的计算
另一方面, 数据不可变意味着对比数据是否相等只需对比内存地址
可变的数据, 比如 JavaScript 的对象, 对比就非常麻烦跟低效
接受不可变数据好处之后, 可以注意到, 变量正是数据改变的一个原因
因为有个变量, 就存在一个指向相应区域的引用, 容易作为状态进行更改
假如没有变量, 就没有到数据的引用, 也就不能进行修改了
当然实际当中, Haskell 有变量但不能修改, Go 可以有常量
有变量名和可变并不对等, 甚至在 JavaScript 也可能设定属性只读
但我认为这样也存在一种机会, 假如去掉变量名, 程序会更直观
图形化编程
Chris Granger 有个采访里讲为什么对于普通人来说编程那么难
http://podcasts.thoughtbot.com/giantrobots/111
他发现, 作用域的概念对于非程序员来说很难理解, 他们更习惯全局的域
比如电子表格当中进行计算, 直接在格子上计算就看到结果, 没有变量参与
还有数学公式, 所有的符号在全局都是一个意思, 并不为公式设置作用域
不过在他做的未来编程语言的草稿当中, 他调整的不止是作用域
在名字叫做 Aurora 的例子当中, 数据不再以变量的形式传递, 看视频:
http://weibo.com/1651843872/AFf1b1EZ5
而是通过拖拽, 将数据引用到下方的表达式当中用在计算
在这样的环境当中, 变量名不存在, 用户看到的只有数据, 非常直接
这个在 Chris 另一篇文章有提到, 就是编程为什么复杂, 怎么解决?
http://www.chris-granger.com/2014/03/27/toward-a-better-programming/
有中文翻译, 原文大概更明确, 他认为主要是三点:
- 程序的过程是不可观察的
- 代码并不是直观的
- 同时程序的算法会很复杂
另外有一点是工具的门槛, 每个写代码的阶段都太慢, 但也许不算编程本身的问题
在 Aurora 当中, 因为没有变量, 人们看到的和理解的都是数据本身
于是程序的数据转化是非常直观的, 每一个步骤都能看到
借助图形界面, 有更多情况下我们可以简化掉编程当中不直观的概念
这一点在 Bret Victor 诸多的演讲当中能看出来
https://github.com/coffee-js/languages/wiki/Bret-Victor-Videos
原来我们以为需要代码才能输入逻辑, 实际上可以通过设计交互来实现
同时, 图形界面非常直观, 很难想象文字符号能如此易懂
过去的半个世纪, 编程的发展都是建立在文本的解析跟编译之上
少量的图形编程, 只是在特定的领域, 至今没有被大多数人使用
文本当然有着图形很难大到的抽象计算的表达能力, 可是, 图形交互丰富之后呢?
编程当中很多元素是解决问题固有的复杂度, 我们很难再进行简化
但设计和管理变量名很大程度是编程方式造成的复杂度
当更好的方案被设计出来表达计算的逻辑, 变量名应该会淡出人们的视野
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。