Recently I came to know and started to learn Smalltalk, an age-old pure Object-Oriented programming language. I fell in love with it quickly. Smalltalk is a very small language with some consistent concepts and abundant class libraries. I was puzzled at the very begining, as Smalltalk has very few keywords(maybe 5 I think), and those keywords don't include any control structure(a.k.a if, while, for), how could we write programs? Althougth I know we could implement iterative sturucture via recursion, how about conditional execution? Finally I figured out that Smalltalk provides control strucutre in its class library only using some basic OO concepts. Followings are the codes from Smalltalk class library.
and then in some codes, we could do the conditional execution as follows
In Smalltalk, everything is Object, so that the code above means sending a message named '>' to an Integer object, whose value is 4, with an Integer object parameter. And '>' would return a Boolean object, and then we sent a message named 'ifTrue' to it. This is a typical usage of State Pattern. Here are the equivalent Java codes.
which could be translated in Java like this:
That's quite simple(some dynamic languages on JVM ,e.g. Groovy, do the same thing), but it indeed brings some profound changes to my thought.
First, considering that 'if','for' and 'while' are no longer pre-defined keywords, we could define our own control structures. For example, we could define Order has its own way to do something.
Taking no account of performance and semantic speaking, there is no difference between the code above and undermentioned:
More fancy, we could define a new test structure like this:
So we could have programmable control structure in Smalltalk ( something like we do in Lisp via continuation:) ), and define our own DSL easily.That's the amazing lightweight syntax feature in Smalltalk!
Second, we could get full capability of Von Nouma Style Programming Language via pure OO concepts.We could construct software in consistent OO concepts.
I began my adventure in Object technology by using C++ in 1995, and then I chose Java as my main working language. All my experiences about OO come from half-blooded OO language.So that for a long time, I thought Object-Oriented Programming is a big patch to imperative languages. The imperative languages are desgined to record the sequence of instruments which are used to manipulate the computer, so they are lack in semantic, and poor in abstraction. Though the Object technology introduces a successful type system and provides some abstraction mechanism, I still feel sucks to program in inconsistent concepts, because I should be careful about keeping programming more in OO-style rather than in procedural-style(something like Domina Model or not, sucks!).
Once I accused Object-Oriented Methodology of all the fault, I blamed imperfection on Object-Oriented Methodology.But now, I found out it's only because that I have little talent and learning in OO, it turned out to be my fault, I should say sorry to Object-Oriented Methodology.
最近学习了一下Smalltalk,然后深深的喜欢上了这个古老的语言。Smalltalk语言只具有一个很小的语言核心,这个核心由大约10几个关键字和一些基础的面向对象语义构成。而且关键字都是象: . ; ( ) [ ] | := 之类的简单符号,并没有提供最基本控制的流程。最开始的时候这让我很迷惑,虽然循环结构可以用递归表示,但是分支怎么办?然后发现了一个很酷的特性,Smalltalk可以仅仅通过面向对象的语义来实现分支结构(其实就是State Pattern),具体的代码如下
Boolean>>ifTrue: aBlock self subclassResponsibility
Boolean>>ifFalse: aBlock self subclassResponsibility
True>>ifTrue: aBlock ^aBlock value.
True>>ifFalse: aBlock ^nil.
False>>ifTrue: aBlock ^nil.
False>>ifFalse: aBlock ^aBlock value.
然后就可以,
4 〉3 ifTrue: [Transcript show: 'Hello']
因为在Smalltalk里,一切皆对象且从左到右求值,于是4 > 3 返回true,true是类True的唯一实例,然后就可以对它发送消息,ifTrue:,于是调用了^aBlock value.来对传进去的BlockClosure求值。
下面是类似的java的类似代码。
4 〉3 ifTrue: [Transcript show: 'Hello']就可以对应翻译为:
这个看似简单的应用,却带来了两个有深刻影响的性质。
第一,由于if,else等结构不再是预定义的语法了,而与我们自己写的代码一样,属于莫一个类的特定消息,那么也就意味着,我们可以像ifTrue一样,定义自己的分支结构。比如 aUser ifNotRegistered: [ do redirect to register page ] ifExpired: [ do redirect to active page ]
在不考虑性能优化的前提下,Smalltalk认为和 4 >3 ifTrue: [do something] ifFalse: [do somthing]
是具有一样的语义的。并不因为Boolean属于Kernel就有什么不同。因此控制结构也属于一个可编程的因素,这就是Smalltalk的轻语法特性。
第二,在简单的语法和完全的面向对象语义中,构造与冯诺依曼式语言完全等价的能力(这种能力在语法上表现为赋值,分支,迭代和子程序调用),于是我们可以完全用一致的面向对象的方法来构造软件。
很长一段时间以来,我都认为面向对象方法论是在命令式的冯诺依曼式语言的基础上,通过引入类型系统然后修修补补的得到的,由于冯诺依曼语言式的语言是面向操作层面上的,只是为了更好的刻画操作计算的一个命令的序列,因此冯语言不可避免的具有不完备的语义,混乱的抽象表达以及等等一系列的问题。作为冯语言的一个大补丁的面向对象方法,我也想当然的以为他虽然有了些进步,但是基础问题上面还是不能避免的,加之面向对象缺乏一种一致的构造方法,很多时候我们不得不回归到命令式或者过程式的方法来构造系统,从而破坏掉一种一致清晰的思路,在过程和对象之间不住地权衡(比如Domain Model之争),这个让人非常的不爽。在尝试了一些面向对象语言之后(我是在95年接触C++的时候开始了解面向对象的,而后主要使用Java做为开发语言),我发现这个问题是很难避免,于是我断言这是面向对象技术本身的问题,现在看来不过自己所学有限,没有真正用过纯面向对象语言而已,汗颜得很啊。这里向面向对象方法道个歉,嘿嘿。