如何设计一门编程语言(五) 面向对象和消息发送

面向对象这个抽象的特例总是有说不完的话题,更糟糕的是很多语言都错误地实现了面向对象——class居然可以当一个变量类型什么的这只是让人们写代码写的更糟糕而已。当然这个话题第三篇文章已经说过了,现在来谈谈人们喜欢拿来装逼的另一个话题——消息发送。

按照惯例先来点题外话。说到消息发送,有些人喜欢跳出来说,objective-c的消息做得多优雅啊,代码都可以写成一句话[golang screw:you you:suck]之类的。其实这个还做得不够彻底。在几年前易语言曾经火了一阵,但是为什么大家这么讨厌他呢?其实显然不是因为每个token都是汉字,而是因为他做的一点都不像中文,谁会说话的时候带那么多符号呀。其实objective-c也一样,没人会因为想在一句英语里面用冒号来分割短语的。

当我还在读大三的时候,我由于受到了Apple Script(也是苹果做的)的启发,试图发明一门语言,让他可以尽量写起来像自然语言——当然他仍然是严格的编程语言。但是这门语言因为其奇特的语法结构,我只好自己想出了一个两遍parse地方法。第一遍parse出所有函数头,让后用这些函数头临时组成一个parser,用它来parse语句的部分。后面整个也实现出来了,然后我就去做了一下调查,发现大家不喜欢,原因是要输入的东西太多了。不过我这里还是贴一下当初是怎么设计的:

phrase print(content) is
    external function "writeln"
end phrase

phrase first (count) items of fibonacci sequence is
    if count equals to 1 then
        result is [1]
    else if count equals to 2 then
        result is [1,1]
    else
        let list be [1,1]
        repeat with i from 3 to count
            let list be list joins with item length of list - 1 of list + item length of list - 2 of list
        end
        result is list
    end
end phrase

phrase (number) is odd is
    result is number mod 2 is 0
end phrase alias odd number

phrase append (item) after (list) is
    let 0 element of list from length of list be [item]
end phrase

phrase ((item) is validated) in (list) is
    let filtered list be []
    repeat with item in list
        append item after filtered list if item is validated
    end
    result is filtered list
end phrase

phrase main is
    print odd number in first 10 items of fibonacci sequence
end phrase

倒数第二个函数声明甚至连函数指针的声明也如此的优雅(我自己认为的),整个程序组织起来,我们要输出斐波那契数列里面前10个数字中间的奇数,于是就写成了

print odd number in first 10 items of fibonacci sequence

看起来比objective-c要漂亮把。其实如果想把所有的东西换成中文,算法也不需要变化。现在用空格来分割一个一个的词,中文直接用字符就好了,剩下的都一样。要parse这个程序根本没办法用流行的那些方法来parse。当然我知道大家也不会关心这些特别复杂的问题,于是题外话就到这里结束了,这个语言的实现的代码你们大概也永远都不会看到的,啊哈哈哈哈。

为什么要提这件事情呢?我主要是想告诉大家,就算你在用面向对象语言,想在程序里面给一个对象发送一条消息,这个对象并不是非得写在最前面的。为什么呢?有的时候对象不止一个——这个东西叫multiple dispatching,著名的问题就是如何给一堆面向对象的几何体类做他们的求交函数——用面向对象的惯用做法做起来会特别的难受。不过现在我们先来看一下普通的消息发送是什么样子的。

对于一个我们知道他是什么类型的对象来说,发送一个消息就跟直接调用一个函数一样,因为你不需要去resolve一下这个函数到底是谁。譬如说下面的代码:

class Language
{
public:
    void YouSuck(){ ... }
};

Language golang;
golang.YouSuck();

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索面向对象
, list
, 函数
, fibonacci数列
, 语言
, 消息
, 消息分割
, golang
, fibonacci堆
, 泛型golang
, 一个
, golang基础
, Fibonacci函数
Golang项目
面向对象 发送消息、js面向对象编程、面向对象编程、面向对象的编程语言、js面向对象编程实例,以便于您获取更多的相关知识。

时间: 2024-10-30 18:46:21

如何设计一门编程语言(五) 面向对象和消息发送的相关文章

如何设计一门编程语言(二) 什么是坑(b)

我从来没有在别的语言的粉里面看见过这么容易展示人性丑陋一面的粉,就算是从十几年前开始的C++和C对喷,GC和非GC对喷,静态类型动态类型对喷的时候,甚至是云风出来喷C++黑得那么惊天动地的时候,都没有发生过这么脑残的事情.这种事情只发生在go语言的脑残粉的身上,这究竟代表什么呢?想学go语言的人最好小心一点了,学怎么用go没关系,go学成了因为受不了跳到别的语言去也没关系,就算是抖M很喜欢被折腾所以坚持用go也没关系,但是把自己学成了脑残粉,自己的心智发生不可逆转的变换,那就不好了. 当然,上一

如何设计一门编程语言(九) 类型

类型是了解编程语言的重要一环.就算是你喜欢动态类型语言,为了想实现一个靠谱的东西,那也必须了解类型.举个简单的例子,我们都知道+和-是对称的--当然这只是我们的愿望了,在javascript里面,"1"+2和"1"-2就不是一回事.这就是由于不了解类型的操作而犯下的一些滑稽的错误.什么,你觉得因为"1"的类型是string所以"1"+2就应该是"12"?啐!"1"的类型是(string

如何设计一门编程语言(一) 什么是坑(a)

这个系列的起因是这样的,王垠写了一篇喷go的博客http://www.yinwang.org/blog-cn/2013/04/24/go-language/,里面说go已经烂到无可救药了,已经懒得说了,所以让大家去看http://www.mindomo.com/view.htm?m=8cc4f95228f942f8886106d876d1b041,里面有详细的解释.然后这篇东西被发上了微博,很多博友立刻展示了人性丑陋的一面: 1.那些go的拥护者们,因为go被喷了,就觉得自己的人格受到了侮辱一样

如何设计一门编程语言(十) 正则表达式与领域特定语言(DSL)

几个月前就一直有博友关心DSL的问题,于是我想一想,我在gac.codeplex.com里面也创建了一些DSL,于是今天就来说一说这个事情. 创建DSL恐怕是很多人第一次设计一门语言的经历,很少有人一开始上来就设计通用语言的.我自己第一次做这种事情是在高中写这个傻逼ARPG的时候了.当时做了一个超简单的脚本语言,长的就跟汇编差不多,虽然每一个指令都写成了调用函数的形态.虽然这个游戏需要脚本在剧情里面控制一些人物的走动什么的,但是所幸并不复杂,于是还是完成了任务.一眨眼10年过去了,现在在写Gac

如何设计一门编程语言(三) 什么是坑(面向对象和异常处理)

在所有的文字之前,我需要强调一下,我本人对structure typing持反对态度,所以就算文中的内容"看起来很像"go的interface,读者们也最好不要觉得我是在赞扬go的interface.我比较喜欢的是haskell和rust的那种手法.可惜rust跟go一样恨不得把所有的单词都缩成最短,结果代码写出来连可读性都没有了,单词都变成了符号.如果rust把那乱七八糟的指针设计和go的那种屎缩写一起干掉的话,我一定会很喜欢rust的.同理,COM这个东西设计得真是太他妈正确了,简

如何设计一门编程语言(八) 异步编程和CPS变换

关于这个话题,其实在(六)里面已经讨论了一半了.学过Haskell的都知道,这个世界上很多东西都可以用monad和comonad来把一些复杂的代码给抽象成简单的.一看就懂的形式.他们的区别,就像用js做一个复杂的带着几层循环的动画,直接写出来和用jquery的"回调"写出来的代码一样.前者能看不能用,后者能用不能看.那有没有什么又能用又能看的呢?我目前只能在Haskell.C#和F#里面看到.至于说为什么,当然是因为他们都支持了monad和comonad.只不过C#作为一门不把&quo

如何设计一门编程语言(十一) 删减语言的功能

大家看到这个标题肯定会欢呼雀跃了,以为功能少的语言就容易学.其实完全不是这样的.功能少的语言如果还适用范围广,那所有的概念必定是正交的,最后就会变得跟数学一样.数学的概念很正交吧,正交的东西都特别抽象,一点都不直观的.不信?出门转左看Haskell,还有抽象代数.因此删减语言的功能是需要高超的技巧的,这跟大家想的,还有跟go那帮人想的,可以断定完全不一样. 首先,我们要知道到底为什么需要删减功能.在这里我们首先要达成一个共识--人都是很贱的.一方面在发表言论的时候光面堂皇的表示,要以需求变更和可

如何设计一门编程语言(四) 什么是坑(操作模板)

其实我在写这个系列的第三篇文章的时候就已经发现,距离机器越远,也就是抽象越高的概念,坑的数量是越少的.但是这并不是说,距离机器越近的概念就越强大或者说越接近本质.这是广大的程序员对计算理论的一种误解.大多数人理解编程的知识结构的时候,都是用还原论来理解的,这个方法其实并没有错.但问题在于,"还原"的方法并不是唯一的.很多人觉得,反正你多高级的语言编译完了无非都是机器码嘛.但是还有另一种解释,你无论多低级的语言编译完了无非也就是带CPS变换(continuation passing st

如何设计一门编程语言(七) 闭包、lambda和interface

人们都很喜欢讨论闭包这个概念.其实这个概念对于写代码来讲一点用都没有,写代码只需要掌握好lambda表达式和class+interface的语义就行了.基本上只有在写编译器和虚拟机的时候才需要管什么是闭包.不过因为系列文章主题的缘故,在这里我就跟大家讲一下闭包是什么东西.在理解闭包之前,我们得先理解一些常见的argument passing和symbol resolving的规则. 首先第一个就是call by value了.这个规则我们大家都很熟悉,因为流行的语言都是这么做的.大家还记得刚开始