如何设计一门语言(十二)——设计可扩展的类型
摘要:在思考怎么写这一篇文章的时候,我又想到了以前讨论正交概念的事情。如果一个系统被设计成正交的,他的功能扩展起来也可以很容易的保持质量这是没错的,但是对于每一个单独给他扩展功能的个体来说,这个系统一点都不好用。所以我觉得现在的语言被设计成这样也是有那么点道理的。就算是设计Java的那谁,他也不是傻逼,那为什么Java会被设计成这样?我觉得这跟他刚开始想让金字塔的底层程序员也可以顺利使用Java是有关系...
阅读全文
posted @
2013-11-10 17:07
陈梓瀚(vczh)
阅读(3985)
推荐(3) 编辑
如何设计一门语言(十一)——删减语言的功能
摘要:大家看到这个标题肯定会欢呼雀跃了,以为功能少的语言就容易学。其实完全不是这样的。功能少的语言如果还适用范围广,那所有的概念必定是正交的,最后就会变得跟数学一样。数学的概念很正交吧,正交的东西都特别抽象,一点都不直观的。不信?出门转左看Haskell,还有抽象代数。因此删减语言的功能是需要高超的技巧的,这跟大家想的,还有跟go那帮人想的,可以断定完全不一样。首先,我们要知道到底为什么需要删减功能。在这里我们首先要达成一个共识——人都是很贱的。一方面在发表言论的时候光面堂皇的表示,要以需求变更和可维护性位中心;另一方面自己写代码的时候又总是不惜“后来的维护者所支付的代价代价”进行偷懒。有些时候,人
阅读全文
posted @
2013-10-19 21:52
陈梓瀚(vczh)
阅读(4450)
推荐(8) 编辑
如何设计一门语言(十)——正则表达式与领域特定语言(DSL)
摘要:几个月前就一直有博友关心DSL的问题,于是我想一想,我在gac.codeplex.com里面也创建了一些DSL,于是今天就来说一说这个事情。 创建DSL恐怕是很多人第一次设计一门语言的经历,很少有人一开始上来就设计通用语言的。我自己第一次做这种事情是在高中写这个傻逼ARPG的时候了。当时做了一个超简单的脚本语言,长的就跟汇编差不多,虽然每一个指令都写成了调用函数的形态。虽然这个游戏需要脚本在剧情...
阅读全文
posted @
2013-09-16 09:27
陈梓瀚(vczh)
阅读(11489)
推荐(10) 编辑
如何设计一门语言(九)——类型
摘要:类型是了解编程语言的重要一环。就算是你喜欢动态类型语言,为了想实现一个靠谱的东西,那也必须了解类型。举个简单的例子,我们都知道+和-是对称的——当然这只是我们的愿望了,在javascript里面,"1"+2和"1"-2就不是一回事。这就是由于不了解类型的操作而犯下的一些滑稽的错误。什么,你觉得因为"1"的类型是string所以"1"+2就应该是"12"?啐!"1"的类型是(string | number),这才是正确的做法。了解编程语言的基本原理并不意味着你一定要成为一名编译
阅读全文
posted @
2013-08-17 16:27
陈梓瀚(vczh)
阅读(6046)
推荐(9) 编辑
如何设计一门语言(八)——异步编程和CPS变换
摘要:关于这个话题,其实在(六)里面已经讨论了一半了。学过Haskell的都知道,这个世界上很多东西都可以用monad和comonad来把一些复杂的代码给抽象成简单的、一看就懂的形式。他们的区别,就像用js做一个复杂的带着几层循环的动画,直接写出来和用jquery的“回调”写出来的代码一样。前者能看不能用,后者能用不能看。那有没有什么又能用又能看的呢?我目前只能在Haskell、C#和F#里面看到。至于...
阅读全文
posted @
2013-07-27 11:13
陈梓瀚(vczh)
阅读(7334)
推荐(4) 编辑
如何设计一门语言(七)——闭包、lambda和interface
摘要:人们都很喜欢讨论闭包这个概念。其实这个概念对于写代码来讲一点用都没有,写代码只需要掌握好lambda表达式和class+interface的语义就行了。基本上只有在写编译器和虚拟机的时候才需要管什么是闭包。不过因为系列文章主题的缘故,在这里我就跟大家讲一下闭包是什么东西。在理解闭包之前,我们得先理解一些常见的argument passing和symbol resolving的规则。首先第一个就是call by value了。这个规则我们大家都很熟悉,因为流行的语言都是这么做的。大家还记得刚开始学编程的时候,书上总是有一道题目,说的是:void Swap(int a, int b){ in...
阅读全文
posted @
2013-07-05 22:32
陈梓瀚(vczh)
阅读(11724)
推荐(16) 编辑
时隔多年我又再一次体验了一把跟大神聊天的感觉
摘要:跟大神聊天是很开心的。这不是因为我激动,而是因为大神说出来的每一个字都是有价值的,一针见血,毫无废话。至于为什么说又,当然是这种事情以前发生过。第一次是在高中认识了龚敏敏。那个时候我刚做完那个傻逼的2D ARPG不久,龚敏敏已经是M$RA的实习生了,图形学上的造诣肯定要比我高许多,其中的差距构成了大神跟菜鸟的关系。当然现在我尽管中心已经放在了程序设计语言(programming language,以下简称PL)上,但是还知道一些图形学的内容,跟龚敏敏的差距自然也已经缩小到了不构成大神和菜鸟的关系的程度了。尽管他还是比我多知道很多东西。第二次是在大学的时候认识了g9yuayon。g9菊苣是做形式
阅读全文
posted @
2013-06-26 01:19
陈梓瀚(vczh)
阅读(20779)
推荐(10) 编辑
如何设计一门语言(六)——exception和error code
摘要:我一直以来对于exception的态度都是很明确的。首先exception是好的,否则就不会有绝大多数的语言都支持他了。其次,error code也没什么问题,只是需要一个前提——你的语言得跟Haskell一样有monad和comonad。你看Haskell就没有exception,大家也写的很开心。为什么呢?因为只要把返回带error code结果的函数给做成一个monad/comonad,那么...
阅读全文
posted @
2013-06-10 15:02
陈梓瀚(vczh)
阅读(3478)
推荐(4) 编辑
如何设计一门语言(五)——面向对象和消息发送
摘要:面向对象这个抽象的特例总是有说不完的话题,更糟糕的是很多语言都错误地实现了面向对象——class居然可以当一个变量类型什么的这只是让人们写代码写的更糟糕而已。当然这个话题第三篇文章已经说过了,现在来谈谈人们喜欢拿来装逼的另一个话题——消息发送。 按照惯例先来点题外话。说到消息发送,有些人喜欢跳出来说,objective-c的消息做得多优雅啊,代码都可以写成一句话[golang screw:you...
阅读全文
posted @
2013-05-25 11:08
陈梓瀚(vczh)
阅读(4200)
推荐(3) 编辑
如何设计一门语言(四)——什么是坑(操作模板)
摘要:其实我在写这个系列的第三篇文章的时候就已经发现,距离机器越远,也就是抽象越高的概念,坑的数量是越少的。但是这并不是说,距离机器越近的概念就越强大或者说越接近本质。这是广大的程序员对计算理论的一种误解。大多数人理解编程的知识结构的时候,都是用还原论来理解的,这个方法其实并没有错。但问题在于,“还原”的方法并不是唯一的。很多人觉得,反正你多高级的语言编译完了无非都是机器码嘛。但是还有另一种解释,你无论多低级的语言编译完了无非也就是带CPS变换(continuation passing style)的λ-calculus程序嘛。他们是等价的,不仅能力上也是,“本质”上也是。一个用CPS变换完整地处理
阅读全文
posted @
2013-05-12 16:34
陈梓瀚(vczh)
阅读(3979)
推荐(4) 编辑
如何设计一门语言(三)——什么是坑(面向对象和异常处理)
摘要:在所有的文字之前,我需要强调一下,我本人对structure typing持反对态度,所以就算文中的内容“看起来很像”go的interface,读者们也最好不要觉得我是在赞扬go的interface。我比较喜欢的是haskell和rust的那种手法。可惜rust跟go一样恨不得把所有的单词都缩成最短,结果代码写出来连可读性都没有了,单词都变成了符号。如果rust把那乱七八糟的指针设计和go的那种屎缩写一起干掉的话,我一定会很喜欢rust的。同理,COM这个东西设计得真是太他妈正确了,简直就是学习面向对象手法的最佳范例,可惜COM在C++下面操作起来有点傻逼,于是很多人看见这个东西就呵呵呵了。上
阅读全文
posted @
2013-05-05 11:29
陈梓瀚(vczh)
阅读(9835)
推荐(9) 编辑
如何设计一门语言(二)——什么是坑(b)
摘要:我从来没有在别的语言的粉里面看见过这么容易展示人性丑陋一面的粉,就算是从十几年前开始的C++和C对喷,GC和非GC对喷,静态类型动态类型对喷的时候,甚至是云风出来喷C++黑得那么惊天动地的时候,都没有发生过这么脑残的事情。这种事情只发生在go语言的脑残粉的身上,这究竟代表什么呢?想学go语言的人最好小心一点了,学怎么用go没关系,go学成了因为受不了跳到别的语言去也没关系,就算是抖M很喜欢被折腾所...
阅读全文
posted @
2013-04-28 18:28
陈梓瀚(vczh)
阅读(7010)
推荐(7) 编辑
如何设计一门语言(一)——什么是坑(a)
摘要:这个系列的起因是这样的,王垠写了一篇喷go的博客http://www.yinwang.org/blog-cn/2013/04/24/go-language/,里面说go已经烂到无可救药了,已经懒得说了,所以让大家去看http://www.mindomo.com/view.htm?m=8cc4f95228f942f8886106d876d1b041,里面有详细的解释。然后这篇东西被发上了微博,很多博...
阅读全文
posted @
2013-04-27 17:28
陈梓瀚(vczh)
阅读(14512)
推荐(22) 编辑
可配置语法分析器开发纪事(六)——构造一个真正能用的状态机(下)
摘要:上一篇文章对大部分文法都构造出了一个使用的状态机了,这次主要来讲右递归的情况。右递归不像左递归那么麻烦,因为大部分右递归写成循环也不会过分的让语法树变得难以操作,不过仍然有少数情况是我们仍然希望保留递归的语法树形状,譬如C++的连等操作,因此这里就来讲一下这个问题。 右递归是怎么形成的呢?在这里我们先不想这个问题,我们来看一个普通的文法。在上一篇文章我们已经说过了,如果一条文法有一个非终结符引用...
阅读全文
posted @
2013-04-13 09:49
陈梓瀚(vczh)
阅读(2137)
推荐(2) 编辑
可配置语法分析器开发纪事(五)——构造一个真正能用的状态机(中)
摘要:上一篇博客写到了如何给一个非终结符的文法规则构造出一个压缩过的下推状态机,那么今天说的就是如何把所有的文法都连接起来。其实主要的idea在(三)和他的勘误(三点五)里面已经说得差不多了。但是今天我们要处理的是带信息的transition,所以还有一些地方要注意。所以在这里我们先把几条文法的最后的状态机都列出来(大图):接下来的这一步,就是要对所有靠非终结符(Exp啊Term这些)进行跳转的transition都执行上一篇文章所说的传说中的交叉链接。在产生链接的时候,我们给shift和reduce的边分别加上shift和reduce。而shift和reduce是有参数的——就是被shift走的状
阅读全文
posted @
2013-01-01 15:55
陈梓瀚(vczh)
阅读(2125)
推荐(0) 编辑
可配置语法分析器开发纪事(四)——构造一个真正能用的状态机(上)
摘要:本来说这一篇文章要把构造确定性状态机和look ahead讲完的,当我真正要写的时候发现东西太多,只好分成两篇了。上一篇文章说道一个基本的状态机是如何构造出来的,但是根据第一篇文章的说法,这一次设计的文法是为了直接构造出语法树服务的,所以必然在执行状态机的时候就要获得构造语法树的一切信息。如果自己开发过类似的东西就会知道,类似LALR这种东西,你可以很容易的把整个字符串分析完判断他是不是属于这个LALR状态机描述的这个集合,但是你却不能拿到语法分析所走的路径,也就是说你很难直接拿到那颗分析树。没有分析树肯定是做不出语法树的。因此我们得把一些信息插入到状态机里面,才能最终把分析树(并不一定真的要
阅读全文
posted @
2012-12-23 00:30
陈梓瀚(vczh)
阅读(2785)
推荐(2) 编辑
可配置语法分析器开发纪事(三点五)——生成下推自动机的具体步骤
摘要:刚刚发了上一篇文章之后就发现状态机画错了。虽然LiveWriter有打开博客并修改文章的功能,不过为了让我留下一个教训,我还是决定发一篇勘误。这个教训就是,作分析的时候不要随便“跳步”,该一步一步来就一步一步来。其实人呢,就是很容易忘掉以前的教训的了。第一个告诉我不能这么干的人其实是小学三年级的数学老师。当时我因为懒得写字,所以计算应用题的时候省了几步,被批评了。故事就从状态机开始。文法我就不重复了,见上一篇文章。现在我们从状态机开始。第一个状态机是直接从文法变过来的:然后我们把所有的非终结符跳转都通过Shift和Reduce连接到该非终结符所代表的状态机的状态上面,就会变成下面的图。具体的做
阅读全文
posted @
2012-12-07 18:50
陈梓瀚(vczh)
阅读(1472)
推荐(1) 编辑
可配置语法分析器开发纪事(三)——生成下推自动机
摘要:上一篇博客讲到了构造符号表的事情。构造完符号表之后,就要进入语义分析的后一个阶段了:构造状态机。跟我以前写的如何实现正则表达式引擎的两篇文章讲的一样,自动机先从Epsilon Nondeterministic Automaton开始,然后一步一步构造成Deterministic Automaton。但是语法分析和正则表达式有很大不同,那么这个自动机是什么样子的呢?(对学术感兴趣的人可以去wiki一下“下推自动机”)下推自动机和有限自动机的区别是,下推自动机扩展成普通的自动机的时候,他的状态的数目是无限的(废话)。但是无限的东西是没办法用编程来表达的,那怎么办呢?那就加入一个不定长度的“状态描述
阅读全文
posted @
2012-12-07 16:44
陈梓瀚(vczh)
阅读(4908)
推荐(4) 编辑
可配置语法分析器开发纪事(二)——构造符号表
摘要:上一篇博客讲到了构造语法树的问题。有朋友在留言问我,为什么一定要让语法分析器产生语法树,而不是让用户自己决定要怎么办呢?在这里我先解答这个问题。 1、大部分情况下都是真的需要有语法树 2、如果要直接返回计算结果之类的事情的话,只需要写一个visitor运行一下语法树就好了,除去自动生成的代码以外(反正这不用人写,不计入代价),代码量基本上没什么区别 3、加入语法树可以让文法本身描述...
阅读全文
posted @
2012-11-29 00:51
陈梓瀚(vczh)
阅读(3106)
推荐(1) 编辑
可配置语法分析器开发纪事(一)——构造语法树
摘要:就像之前的博客文章所说的,(主要还是)因为GacUI的原因,我决定开发一个更好的可配置轻量级语法分析器来代替之前的落后的版本。在说这个文章之前,我还是想在此向大家推荐一本《编程语言实现模式》,这的确是一本好书,让我相见恨晚。 其实说到开发语法分析器,我从2007年就已经开始在思考类似的问题了。当时C++还处于用的不太熟练的时候,难免会做出一些傻逼的事情,不过总的来说当年的idea还是能用的。从那...
阅读全文
posted @
2012-11-21 22:46
陈梓瀚(vczh)
阅读(6258)
推荐(3) 编辑