fbpx
维基百科

Smalltalk

Smalltalk是一种动态类型反射式面向对象编程语言。Smalltalk由艾伦·凯、Dan Ingalls、Ted Kaehler、Adele Goldberg等于1970年代在施乐帕羅奧多研究中心开始开发。

Smalltalk
编程范型面向对象反射式
設計者Alan KayDan Ingalls英语Dan IngallsAdele Goldberg英语Adele Goldberg (computer scientist)
實作者Alan KayDan Ingalls英语Dan IngallsAdele Goldberg英语Adele Goldberg (computer scientist)Ted Kaehler英语Ted KaehlerDiana Merry英语Diana Merry、Scott Wallace、Peter DeutschXerox PARC其他人
发行时间1972年,​51年前​(1972(開發始於1969年)
穩定版本
Smalltalk-80版本2
(1983年,​40年前​(1983
型態系統動態
作用域词法(静态)
系统平台Xerox Alto[1][2]
作業系統跨平台
主要實作產品
Amber英语Amber Smalltalk, Dolphin英语Dolphin Smalltalk, GemStone/S英语Gemstone (database), GNU Smalltalk, Pharo, Smalltalk/X, Squeak, VisualAge英语VisualAge, VisualWorks英语VisualWorks
衍生副語言
Self, GNU Smalltalk
啟發語言
Lisp,[3] Simula,[3] Euler英语Euler (programming language),[3] IMP英语IMP (programming language),[3] Planner英语Planner (programming language),[3] Logo[4],Sketchpad,[3] ARPAnet,[3] Burroughs B5000英语Burroughs large systems[3]
影響語言
AppleScript, CLOS, Dart, Dylan, Erlang, Etoys英语Etoys (programming language), Falcon, Go, Groovy, Io, Ioke, Java, Lasso英语Lasso (programming language), Logtalk英语Logtalk, Newspeak英语Newspeak (programming language), NewtonScript, Object REXX英语Object REXX, Objective-C, PHP 5, Perl 6, Python, Ruby, Scala, Scratch, Self

Smalltalk对其它众多的程序设计语言的产生起到了极大的推动作用,特別是Objective-CCLOSPythonRuby等。1990年代涌现的许多软件开发思想都得益于Smalltalk,例如设计模式敏捷编程代码重构[5]等。

概述

Smalltalk和许多程序设计语言不同,它不仅仅是一门语言。下面从几个不同的角度来解释Smalltalk。

  • 一种面向对象的程序设计语言:它是一种面向对象的语言,包含语言的语法和语义。一些编译器可以透过Smalltalk源程序产生可执行文件。这些编译器通常产生一种能在虚拟机上运行的二进制代码。Smalltalk语言本身非常精炼。
  • 一种程序设计环境:这里指的是一种提供许多对象的系统,而不是某种特殊的开发环境。和许多语言不同(包括C++),Smalltalk附带有一个巨大的、相当标准的类库。这些使得开发Smalltalk程序的效率非常高。在其它语言(例如AdaCPascal)中,通常被作为语言的一部分的功能(例如条件判断,循环等),在Smalltalk由特定的类提供。
  • 一个应用开发环境(ADE):由于Smalltalk的历史原因,它具有一个非常优秀的高度集成、开放的应用开发环境。由于开发环境中的浏览器、监视器以及调试器,都由同样的源程序衍生出来的,不同的版本之间也具有相当好的兼容性。此外,这些工具的源程序都可以在ADE直接存取。

历史

 
Smalltalk-76
 
Smalltalk的VisualWorks商业实现
 
Smalltalk-80的从Squeak分叉出的开源实现Pharo

最早的Smalltalk原型由艾伦·凯于1970年代初提出。(来自Simula 67)、海龟绘图英语Turtle graphics(来自LOGO)以及图形用户界面(来自Sketchpad等先驱系统)等概念的有机组合,构成了Smalltalk的最初的蓝图[4]

在1971年到1975年之间,艾伦·凯在Xerox PARC的小组,在Xerox Alto计算机上,设计并实现了第一个真正的Smalltalk语言系统,編譯器由Dan Ingalls負責主要實作。这个系统被称为Smalltalk-71與Smalltalk-72,具有以下几个技术创新:

  • 语言完全基于消息交换Simula 67的类的概念。
  • 语言没有固定的语法,语法分析由类本身完成。

开发环境的革新相当迅速。虽然当时的位图显示器十分昂贵,但是艾伦·凯却说服了PARC,让他使用这些位图显示器,这使得艾伦·凯和他的小组,能够实现不同大小和字体的文字,使用多窗口环境,以及一些对图像处理的高端支持。Smalltalk-72影响了演员模型的发展[6],它的语法和执行模型,与现代的Smalltalk变体有着显著的差异。

在1975到1976年间,艾伦·凯小组认识到应当对执行效率和规模进行优化。于是他们在许多重要方面重新设计了Smalltalk系统,被称为Smalltalk-76,它在语言上:

  • 引入了继承和子类的概念[7]
  • 确定了语言的语法,这使得编译器能够产生高效、可执行、精炼的二进制代码。
  • 拉里·泰斯勒设计了类浏览器,这极大地提高了Smalltalk程序员的编程效率。

前述的所有Smalltalk系统,都是在特殊的硬件上实现的,直到1977年至1978年,Bruce Horn和Ted Kaehler把Smalltalk-76移植到Xerox NoteTaker英语Xerox NoteTaker上,它是由Intel 8086处理器和自定显示器所组成的硬件环境。虽然这种硬件环境只生产了10台,但是它证明了在通常的处理器上实现Smalltalk的可能性。

在1979至1980年,部分受NoteTaker项目的影响,Smalltalk小组的注意力转移到Smalltalk的销售可行性上。小组设计并实现了新一代的Smalltalk系统,这次修改的目标着重于在标准硬件上的移植性等方面,被称为Smalltalk-80,它包括:

  • 采取ASCII码字符集,摒弃了原先在Smalltalk-72和Smalltalk-76中使用的特殊字符。
  • 取消了原始方法直接存取内存的能力。取而代之的是引入一系列的原始方法提供相应的功能。
  • 引入了元类的概念[8]
  • 引入MVC(模型-视图-控制器)系统以方便交互式应用软件的开发。

Smalltalk-80是在PARC之外能获得到的第一个语言变体,最初作为Smalltalk-80版本1,给与了少数公司(惠普苹果公司泰克DEC)和大学(UC Berkeley),用于同行评审和在它们自己的平台上实现。后来在1983年普遍可获得的实现,叫做Smalltalk-80版本2,发行为虚拟机规定和映像(具有对象定义的独立于平台的文件)[9]

1988年Xerox PARC为了将Smalltalk推向市场而成立了分拆公司ParcPlace Systems。ANSI Smalltalk自从1998年来是标准的语言参考[10]

两个当前流行的Smalltalk实现变体,是这些最初Smalltalk-80映像的后代。Squeak开源实现,它经由Apple Smalltalk[11],派生自Smalltalk-80版本1.03[12]VisualWorks英语VisualWorks经由Smalltalk-80 2.5和ObjectWorks(二者都是ParcPlace Systems的产品),派生自Smalltalk-80版本2[9]

面向对象编程

 
Smalltalk-80例子代码在Squeak下的类层级和与之并行的元类层级的示意图。其中的rProtoObjectcClassmcMetaclass。蓝色连接表示实例联系,绿色连接表示继承联系。

如同其他面向对象语言,Smalltalk-80(而非Smalltalk-72)的中心概念是“对象” 。一个对象总是一个“”的一个“实例”。类是描述它们的实例的属性和行为的“蓝图”。例如,一个GUI窗口类,可以声明窗口拥有的属性,比如标签、位置和窗口是否可见。这个类还可以声明其实例支持的操作,比如打开、关闭、移动和隐藏。每个特定窗口对象,对这些属性都有自己的值,它们每个都能进行它的类定义的操作。

Smalltalk对象确切的可以做三件事:

  1. 持有状态(引用到其他对象)。
  2. 接收消息自本身或其他对象。
  3. 在处理一个消息的过程中,发送消息至本身或其他对象。

一个对象持有的状态总是私有于这个对象。其他对象只能通过发动请求(消息)至这个对象,来让它做出查询或变更这个状态。任何消息可以发送给任何对象:当接收到一个消息的时候,接收者确定这个消息是否合适。Alan Kay评论说,尽管关注于对象,消息才是Smalltalk中最重要的概念:“最大的想法是消息传递,它是Smalltalk/Squeak核心的全部意义所在(它是我们在Xerox PARC阶段从未真正完成的某种东西)。”[13]

不同于多数其他语言,Smalltalk对象可以在系统运行的同时进行修改。现场编码和飞速应用补丁,是Smalltalk的主导编程方法论,并且是它高效的主要原因。

Smalltalk是“纯”面向对象编程语言,这意味着,不像C++Java,在作为对象的值和作为原始类型的值之间没有区别。在Smalltalk中,原始值比如整数、布尔值和字符,也是对象,这么说的意义在于它们也是相应类的实例,而且要发送消息来调用在它们上的运算。编程者可以通过子类,改变或扩展实现原始值的类,使得可以向它们的实例定义新行为,例如实现一个新的控制结构,甚至使得它们现有行为得以改变。这个事实被总结成常听到的一句短语:“在Smalltalk中,所有东西都是对象”,它可以更精确的表达为:“所有的值都是对象”,因为变量不是。

因为所有的值都是对象,也是对象。每个类都是这个类的元类的一个实例。元类都是Metaclass(元类类)的实例,它也是对象,并且是Metaclass class(元类元类)的实例。代码块是Smalltalk表达匿名函数的方式,它也是对象[14]

Hello, World!例子

Hello, World!程序,实质上被所有计算机语言的课本用作要学习的第一个程序,它展示了这个语言的最基本语法和环境。对于Smalltalk,这个程序可极其简单的书写。下列代码中,消息show:被发送给对象Transcript,具有字符串文字'Hello, World!'作为它的实际参数。调用show:方法,导致它的实际参数,即字符串文字'Hello, World!',显示在叫做“副本”(Transcript)的终端窗口:

Transcript show: 'Hello, World!'. 

注意需要打开Transcript窗口,来看到这个例子的结果。

语法

Smalltalk-80语法是相当极简主义的,只基于了一小把的声明和保留字。事实上,Smalltalk中只保留了六个“关键字”:truefalsenilselfsuperthisContext。它们的准确术语是“伪变量”,是服从变量标识符规则的标识符,但指示了编程者所不能变更的绑定。truefalsenil伪变量是单例实例。selfsuper,在响应一个消息而激活的方法中,指称这个消息的接收者;但是发送给super的消息,在这个方法的定义类的超类中查找方法,而非这个接收者的类中,这允许子类中的方法调用在超类中的同名方法。thisContext指称当前的活动记录。

内建的语言构造只有消息发送、赋值、方法返回和某些对象的文字语法。从它最初作为给所有年龄儿童的语言开始,标准的Smalltalk语法以更像英语,而非主流编码语言的方式使用标点符号。语言余下部份,包括用于条件求值和迭代的控制结构,都由标准Smalltalk类库实现在内建构造之上。出于性能上的原因,实现可以识别并特殊处理某些这种消息,但这只是优化而并未硬性规定入语言语法。

谚语“Smalltalk语法适合一张明信片”,所提及的是Ralph Johnson英语Ralph Johnson (computer scientist)的一个代码片段,展示了一个方法的所有基本标准语法元素[15]

exampleWithNumber: x | y | true & false not & (nil isNil) ifFalse: [self halt]. y := self size + super size. #($a #a 'a' 1 1.0) do: [ :each | Transcript show: (each class name); show: ' ']. ^x < y 

文字

下列例子诠释了最常用的对象,可以在Smalltalk-80方法中被写为文字英语Literal (computer programming)值。

数和字符

下列是数的某些可能例子:

42 -42 123.45 1.2345e2 2r10010010 16rA000 

最后两个项目分别是二进制和十六进制数。在r前的数是底数或基数。基数不必须是二的幂;例如36rSMALLTALK是一个有效的数值,等价于十进制的80738163270632

字符书写时带有前导的美元符:

$A 

字符串

字符串是包围在单引号内的字符序列:

'Hello, world!' 

要在一个字符串中包括一个引号,使用另一个引号来转义

'I said, ''Hello, world!'' to them.' 

双引号不需要转义,因为单引号界定字符串:

'I said, "Hello, world!" to them.' 

两个相等的字符串(字符串相等,如果它们包含完全相同的字符)可以是驻留在内存不同位置中的不同对象。

符号

除了字符串,Smalltalk有一类叫做符号英语Symbol (programming)Symbol)的字符序列对象。符号保证是唯一的,没有作为不同对象的两个相等的符号。因此,符号非常易于比较,并经常用于语言构造中,比如用作消息选择子。

符号被写为#跟随着字符串文字英语string literal。比如:

#'foo' 

如果一个序列不包含空白或标点字符,还可以写为:

#foo 

数组

例如定义了四个整数的一个数组:

#(1 2 3 4) 

很多实现支持下列字节数组(ByteArray)的文字语法,例如定义了四个整数的字节数组:

#[1 2 3 4] 

其他

最后却重要的是块(匿名函数文字):

[... 一些smalltalk代码 ...] 

很多Smalltalk方言为其他对象实现了额外的语法,但是上述的是所有方言都本质上支持的。

变量声明

在各种Smalltalk中共同使用的有两种变量:实例变量和临时变量。其他变量和有关术语依赖于特定实现,例如VisualWorks英语VisualWorks有类共享变量和名字空间共享变量,而Squeak和很多其他实现,有类变量、池变量和全局变量。

在Smalltalk中临时变量声明是在方法(见后)内声明的变量。它们声明在方法的顶部,作为由竖杠包围的空格分隔的名字。例如:

| index | 

声明一个临时变量名叫index,可以包含初始值nil

多个变量可以在一组竖杠内声明:

| index vowels | 

声明了两个变量:indexvowels。所有变量都要初始化。字符串的索引变量,初始化为null字符或初始为0ByteArray,此外的所有变量初始化为nil

按命名约定,实例变量、临时变量、方法或块的参数,应当以小写字母开头,指示它们具有私有作用域,它们合称为局部变量。而全局变量、类变量、池字典、类名字,应当以大写字母开头,它们合称为共享变量。

赋值

变量通过:=语法来指定一个值。比如:

vowels := 'aeiou' 

指定字符串'aeiou'至前面声明的vowels变量。这个字符串是个对象(在单引号之间的字符序列是文字字符串的语法),在编译时间由编译器创建。

在最初的Parc Place映像中,现在下划线(_)的字形,在那时是左向箭头()字形(就像1963年版本ASCII代码中那样)。Smalltalk最初接受左向箭头,作为唯一的赋值算符。一些现代代码仍然包含充当赋值的下划线,会让人想起这种最初的用法。多数现代的Smalltalk实现接受要么下划线,要么冒号等号语法。

消息

消息是Smalltalk中最基础的语言构造。所有控制结构都实现为消息发送。Smalltalk缺省的采用动态分派单一分派策略,这是相对于其他一些面向对象语言使用的多分派而言的。

一元消息

下列例子是发送消息factorial至数值42

42 factorial 

在这种情况下,42叫做这个消息的“接收者”,而factorial是消息的选择子。接收者通过返回一个值来相应这个消息(这个情形中是42的阶乘)。同其他事物一样,消息的结果可以赋值给一个变量:

aRatherBigNumber := 42 factorial 

上面的factorial是“一元”消息,因为只涉及了一个对象,即接收者。

关键字消息

消息可以承载额外的对象作为实际参数,比如:

2 raisedTo: 4 

在这个表达式中,涉及了两个变量:2作为接收者而4作为消息的实际参数。消息结果,或用Smalltalk的说法,回答被认定为16。这种消息叫做“关键字”消息。消息可以有多个实际参数,使用如下语法:

'hello world' indexOf: $o startingAt: 6 

它的回答是在接收者字符串中字符o的索引,从索引6开始查找。这个消息的选择子是indexOf:startingAt:,构成自两个部份或关键字。

这种关键字和实际参数的交织意图改进代码的可读性,因为实际参数由前导于它们的关键字来解释。例如,要建立一个矩形的表达式使用C++或Java类语法可以写为:

new Rectangle(100, 200); 

不清楚这些实际参数分别是什么。与之相反,在Smalltalk中,这个代码可以写为:

Rectangle width: 100 height: 200 

这个情况下接收者是Rectangle类,回答是这个类的具有指定宽度和高度的一个实例。

二元消息

最后,多数特殊(非字母)字符可以被用作所谓的“二元消息”。这些允许了数学和逻辑算符以传统形式书写:

3 + 4 

它发送消息+给接收者3,具有4作为实际参数传递(回答将是7)。类似的:

3 > 4 

将消息>发送给3具有实际参数4(回答将是false)。

注意,Smalltalk-80语言自身,不包含着这些算符的含义。上述的结果,都只是这些消息的接收者(这里是数值实例),为了响应消息+>而定义并返回的。这个机制的副作用是运算符重载,消息>可以被其他对象所理解,允许使用形如a > b的表达式来比较它们。

表达式

一元消息可以一个接一个的写成方法链式调用

3 factorial factorial log 

它发送factorial3,接着发送factorial到前面的结果6,接着发送log到前面的结果720,产生最终的结果2.85733

一个表达式可以包括多次消息发送。在这个情况下,表达式依据一个简单的优先级次序来分析。一元消息有最高的优先级,随后是二元消息,最后是关键字消息。例如:

3 factorial + 4 factorial between: 10 and: 100 

被求值如下:

  1. 3接收消息factorial并回答6
  2. 4接收消息factorial并回答24
  3. 6接收消息+具有24作为实际参数并回答30
  4. 30接收消息between:and:具有10100作为实际参数并回答true

最后的消息发送的回答,是整个表达式的结果。

组合

在需要的时候使用圆括号可以改变求值的次序。例如:

(3 factorial + 4) factorial between: 10 and: 100 

将改变表达式含义,首先计算3 factorial + 4产生10。接着10接收第二个factorial消息,产生36288003628800接着接收between:and:,回答false

注意由于二元消息的含义,不是硬性规定入Smalltalk-80语法的,它们全部都被认为有相等的优先级,并简单的从左至右来求值。因此,使用二元消息的Smalltalk表达式的含义,可能不同于传统释义:

3 + 4 * 5 

被求值为(3 + 4) * 5,产生35。要得到预期回答23,必须使用圆括号来显式的定义运算次序:

3 + (4 * 5) 

复合

以点号分隔的表示式按顺序执行。注意在变量定义和随后的表达式之间没有点号。一个表达式序列的值,是最后的表达式的值。除了最后的表达式之外,所有的表达式的值都被忽略。注意点号是分隔符而并非终结符,因此最终的点号是可选的。

下列(假想)例子中,书写了一序列的表达式,每个都用点号分隔。这个例子首先建立类Window的一个新实例,存储它在一个变量中,接着向它发送两个消息:

| window | window := Window new. window label: 'Hello'. window open 

级联

如果像上述例子这样,将一序列消息都发送给相同的接收者,它们也可以写为方法级联调用,具有用分号分隔的单独消息:

Window new label: 'Hello'; open 

这种将前面例子的重新为一个单一表达式,避免了对将新窗口存储在临时变量的需要。依据平常的优先级规则,首先向Window类发送一元消息new,接着向new回答的那个对象,发送label:open

可以使用yourself消息来返回一个级联消息的接收者。

代码块

头等对象。代码块即匿名函数,可以被表达一个文字值(它是一个对象,因为所有值都是对象)。这是通过方括号达成的:

[ :params | <消息表达式> ] 

这里的:params是代码可以接受的形式参数的列表。结果的块对象可以形成一个闭包:它可以在任何时间访问它外围的词法作用域内的变量。这意味着下列Smalltalk代码:

[:x | x + 1] 

可以理解为: ,或用λ演算表达为:  :  

块可以通过发送给它们value消息来执行。块有一个参数用value:,有2个参数使用value:value:,以此类推直到4个参数,对多于4个参数使用valueWithArguments:并将参数作为数组传递。例如下面的表达式:

[:x | x + 1] value: 3 

可以被求值为: ,或用λ演算表达为: 

块返回(常称为回答)其主体的最后一个表达式的值,除非有一个由显式的^指示的返回,这时返回这个返回表达式的值。在块内部的返回,充当了一种逃出(escape)机制。在一个嵌套的块表达中的返回表达式,将终止在字面上包围的方法。

块的文字表示是一种创新,它一方面允许特定代码有更重大的可读性;它允许涉及迭代的算法一更清晰和简洁的方式编码。典型的在某些语言中使用循环写成的代码,可以在Smalltalk中使用块简洁的书写,有时在单一一行之内。更加重要的,块允许使用消息和多态来表达控制结构,因为块推延了计算,而多态可以用来选择交替者(alternative)。所以在Smalltalk 80中,if…then…else被书写和实现为:

expr ifTrue: [ expr为真时求值的语句 ] ifFalse: [ expr为假时求值的语句 ] 

再举一例,向一个搜集发送消息select:

positiveAmounts := allAmounts select: [:anAmount | anAmount isPositive] 

注意这与函数式编程有关,这里的计算模式被抽象成了高阶函数select:等价于在一个适当的函子上的高阶函数filter[16]

控制结构

在Smalltalk中控制结构没有特殊的语法。它们转而实现为发送到对象上的消息。以条件执行为例,布尔类Boolean定义了ifTrue:ifFalse:ifTrue:ifFalse:ifFalse:ifTrue:方法。比如向一个布尔对象,发送ifTrue:消息,并传递一个代码块作为实际参数,这个块被执行当且仅当布尔接收者为真。下面用一个例子来展示:

result := a > b ifTrue: [ 'greater' ] ifFalse: [ 'less or equal' ] 

块也被用来实现,用户定义控制结构、枚举器访问者异常处理、可插拔的行为和很多其他模式。

迭代

下面例子,从一个字符串中过滤出其中所含有的元音字符:

| aString vowels | aString := 'This is a string'. vowels := aString select: [:aCharacter | aCharacter isVowel]. 

在最后一行,向字符串对象aString发送一个select:消息,它具有一个代码块[:aCharacter | aCharacter isVowel]作为实际参数。这个代码块,表示一个测试,代码块文字将被用作一个谓词函数,它回答true,当且仅当这个字符串的一个元素aCharacter,应当被包括在满足这个测试的字符搜集之中。

字符串类String响应select:消息,要调用的select:方法,定义并实现在搜集类Collection[17];它将给select:的实际参数选择块,传送给形式参数aBlock;然后将绑定了选择块的aBlock嵌入到迭代块的代码之中,再把这个迭代块作为向字符串自身发送的do:消息的实际参数,从而将这个字符串所包含的每个字符,都作为实际参数传送给这个迭代块,而各做一次求值。在求值迭代块的时候,通过value:消息,将迭代元素传送给aBlock所绑定的选择块,它回答一个布尔值;接着向它发送ifTrue:消息,如果这个布尔值是对象true,则将这个字符增加到要返回的字符串中。

字符串类String响应do:消息,要调用的do:方法,定义在可迭代类Iterable[18],而实现在可序列化搜集类SequenceableCollection[19],这个类是Iterable类的子类和String类的超类。

异常处理

Smalltalk的异常处理机制,Exception类及其子类比如Error类,类似于CLOS的异常处理样式,使用块作为处理器:

[ 一些运算. Error signal: 'an error occurred'. 另一些运算 ] on: Error do: [ :ex | 处理器代码. ex return ] 

异常处理器的ex实际参数,提供对挂起运算的状态的访问,比如它的栈帧、行号、接收者和实际参数等,并且通过发送ex proceedex rejectex restartex return之一,还可用来控制计算怎样继续。

类通过实例变量定义它的实例的结构,通过方法定义它的实例的行为。每个方法都有叫做选择子的一个名字,它在这个类之内是唯一性的。

定义

下面是个平凡的类定义[20]

Object subclass: #MessagePublisher instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'Smalltalk Examples' 

多数这种定义经常由编程环境来填充。这里的类定义是给Object类的一个消息,用来建立它叫做MessagePublisher的一个子类。

在Smalltalk中类是头等对象,它可以就像任何其他对象一样接收消息,并可以在执行时间动态的创建。Object类在收到这个subclass:instanceVariableNames:classVariableNames:poolDictionaries:category:消息之时,原则上首先在其元类Object class中查找对应方法,未果而上溯继承链在其超类Class类中找到对应方法实现。

在Smalltalk中,实例变量英语Instance variable是这个实例的私有变量,它可以在定义它们的类的任何实例方法中,还有在它的子类中定义的方法中,通过名字来访问。在需要于一个类的所有实例、这个类本身和它的子类之间,共享某个数据的时候,要使用类变量英语Class variable,它是由这个类和它的所有实例共享的私有变量。池变量是在可以没有继承关联的多个类之间共享的变量。池变量最初存储在池字典中,现在它们应当被定义为专门的类(SharedPool的子类)的类变量。

category指示有关的类的“群组”,在现代Smalltalk版本如Pharo中被替代为package,包系统是利用简单的命名约定,组织SqueakPharo源代码的简单而轻量级的方式。

在一个类所对应的元类中定义的实例变量叫做类实例变量,每个类都有自己私有的类实例变量,子类将继承这些类实例变量,但是子类会拥有这些变量的它们自己的私有复本,类和它们的子类不分享类实例变量。例如,可以定义一个类实例变量叫做count来跟踪一个给定的类有多少实例。

类不能直接访问它的实例的实例变量,而实例不能访问它们的类的类实例变量。如果需要的话必须定义变异子与访问子

方法

当一个对象接收到一个消息的时候,调用匹配这个消息名字的一个方法。所有方法都是公开的和虚拟的(也就是动态查找的)。方法被分组入指示它们意图的协议(protocol)之中。

为一个类增加方法涉及到Behavior类,其中的compile:方法,编译一个方法源代码并返回一个CompiledMethod类的实例;addSelector:withMethod:方法,将给定的一个编译过的方法增加到方法字典中。在Behavior类的子类ClassDescription类中,compile:classified:方法,编译一个方法的源代码,并为这个方法指派上给定的归类(对于方法称为协议)。

对象负责在运行时间动态的确定,执行哪个方法来响应一个消息,尽管在很多语言中,这可能是(有时或总是)在编译时间静态确定的。下列代码定义一个方法publish,并且这个定义将在这个对象收到publish消息的时候发生。

publish Transcript show: 'Hello World!' 

下列名字为#quadMultiply:and:的方法,演示了接收多个实际参数并返回一个值:

quadMultiply: i1 and: i2 "这个方法将给定的两个数相乘并对结果乘以4." | mul | mul := i1 * i2. ^mul * 4 

执行任何前导了^脱字符)的表达式,都导致这个方法于这一点退出,并返回这个表达式的值。终止而没有显式返回某个表达式的一个方法,将隐含的返回自身。

实例化

为一个类新建一个实例,要用到new方法,它定义在Behavior类中。下列例子代码:

MessagePublisher new 

建立并返回MessagePublisher类的一个新实例。它典型的会被赋值到一个变量:

publisher := MessagePublisher new 

但是也可以向一个临时的匿名对象发送一个消息:

MessagePublisher new publish 

类方法

类方法就是在一个类的元类中定义的方法。

比如搜集类Collection的类方法中,实例创建方法有with:with:with:[21]、一直到with:with:with:with:with:with:方法。在下面的例子中,将with:with:用于有序搜集类OrderedCollection,它是SequenceableCollection类的子类,故而能最终上溯至超类搜集类:

| rectangles aPoint collisions | rectangles := OrderedCollection with: (Rectangle left: 0 right: 10 top: 100 bottom: 200) with: (Rectangle left: 10 right: 10 top: 110 bottom: 210). aPoint := Point x: 20 y: 20. collisions := rectangles select: [:aRect | aRect containsPoint: aPoint]. 

反射

反射是一个计算机科学术语,适用于有能力检查它们自己的结构的软件程序,例如检查它们的分析树或输入和输出参数的数据类型。反射是动态、交互式语言比如Smalltalk和Lisp的一个特征。具有反射的交互式程序(要么解释的要么编译的)维护所有内存内对象的状态,包括代码对象自身,这是在解析/编译期间生成的,并且是在编程上可访问和修改的。

反射也是Smalltalk这种有元模型的语言的一个特征。元模型是描述这个语言的模型,开发者可以使用元模型来做事,比如游历、检查和修改一个对象的分析树,或找到特定种类的结构的所有实例(例如在元模型中Method类的所有实例)。

Smalltalk-80是完全的反射式系统,用Smalltalk-80语言实现。Smalltalk-80提供了结构性和计算性反射二者。Smalltalk是结构性反射式系统,其结构是由Smalltalk-80对象定义的。定义这个系统的类和方法也是对象,并且完全是它们所有助力定义的系统的一部份。Smalltalk编译器将文本源代码编译成方法对象,典型是的CompiledMethod的实例。通过把它们存储入一个类的方法字典,而增加到这个类。类层级的定义类的那部份,可以向系统增加新类。这个系统是通过运行建立或定义类和方法的Smalltalk-80代码来扩展的。Smalltalk-80系统是个现场(living)系统,承载着在运行时间扩展自身的能力。

因为类是对象,可以向它们提问比如:“你实现了哪些方法?”或“你定义了什么字段/槽/实例变量?”。所以通过能应用于系统中的任何对象的普通的代码,对象可以轻易的检查、复制、(去)序列化,诸如此类[22]

Smalltalk-80还提供计算性反射,有能力观察系统的计算状态。在派生自最初Smalltalk-80的语言中,一个方法的当前活动(activation),可以作为通过伪变量命名的一个对象来访问,这个伪变量是作为六个保留字之一的thisContext。通过发送消息至thisContext,一个方法活动可以提问比如:“谁给你发送了这个消息?”。这些设施使得有可能实现协程,或类似Prolog回溯,而不需要修改虚拟机。异常系统也是使用这个设施实现的。这个设施更有趣的用法之一,是在Seaside英语Seaside (software) web框架之中,它通过为每个编辑的页面存储续体,并在它们之间切换来导航一个web站点,缓解了编程者处理Web浏览器的返回按钮的复杂性。使用Seaside编程web服务器,可以使用更常规的编程风格来完成[23]

Smalltalk如何使用反射的一个例子,是处理错误的机制。当一个对象被发送了一个它没有实现的消息的时候,虚拟机发送给这个对象doesNotUnderstand:消息,具有这个消息的实化作为实际参数。这个消息(它是另一个对象,是Message的实例),包含这个消息的选择子和它的实际参数的一个Array。在交互式Smalltalk系统中,doesNotUnderstand:的缺省实现,是打开一个错误窗口(一个Notifier)向用户报告错误。通过它和反射设施,用户可以检查错误在其中发生的上下文,重新定义犯错的代码,并继续,这一切都在这个系统之中,使用Smalltalk-80的反射设施[24][25]

通过建立只理解(实现)doesNotUnderstand:的一个类,可以建立一个实例,经由它的doesNotUnderstand:方法能拦截发送给它的任何消息。这种实例可以叫做透明代理(proxy)[26]。可以使用这种代理来实现很多设施,比如分布式Smalltalk,这里的消息在多个Smalltalk系统之间交换,和数据库接口,这里的对象透明的从数据库中排除错误,还有promise等。分布式Smalltalk的设计影响了如CORBA这样的系统。

基于映像的持久存储

多数流行的编程系统,将静态的程序代码(以类定义、函数或过程的形式),分离于动态的或运行时间的程序状态(比如对象或其他形式的程序数据)。它们在程序启动的时候装载程序代码,而任何先前的程序状态必须从配置文件或其他数据源显式的重新建立。程序(和编程者)未显式保存的设置,在每次重启时都必须再次设立。传统的程序在每次程序保存一个文件、退出和重载的时候,还失去很多有用的文档信息。这会失去细节比如回退历史或光标位置。基于映像的系统不会因为计算机关闭或OS更新,而强制失去所有这些东西。

但是很多Smalltalk系统,不区分程序数据(对象)和代码(类)。事实上,类也是对象。因此,多数Smalltalk系统,存储整个程序状态(包括类和非类对象二者)在一个映像英语system image文件之中。这个映像可以接着由Smalltalk虚拟机装载,将类Smalltalk系统恢复成先前的状态[27]。这是受到了FLEX的启发,它是Alan Kay创建的语言并描述于他的科学硕士毕业论文中[28]

Smalltalk映像类似于(可重启的)核心转储,并可以提供与核心转储相同的功能,比如延迟或远程调试,具有对出错时刻的程序状态的完全访问。将应用代码建模为某种形式的数据的其他语言比如Lisp,也经常使用基于映像的持久存储。这种持久存储的方法,对于快速开发是强力的,因为所有开发信息(比如程序的解析树),都保存而利用于调试。但是它作为一个真实的持久存储机制,也有一个严重的缺点。首先,开发者可能经常想要隐藏实现细节,并使它们在运行时间不可获得。出于法律和维护的原因,允许任何人在运行时间修改程序,对于在运行时间环境不暴露源代码的编译后的系统,不可避免的介入复杂性和潜在的错误。其次,尽管持久存储机制易于使用,它缺乏多数多用户系统需要的真正持久存储能力。最明显的是进行同多个用户并行访问相同的数据库的事务[29]

实现列表

OpenSmaltalk

OpenSmaltalk VM(OS VM)是Smalltalk运行时环境的著名实现,很多现代Smalltalk VM基于或派生自它[30]。OS VM自身是从一组Smalltalk源代码文件(它们叫做VMMaker),转译成原生C语言源代码(通过使用叫做Slang的转译器[31][32]),它依次再针对特定平台和硬件架构来编译,实际上确使Smalltalk映像的跨平台执行。源代码可以在GitHub上获得并在MIT许可证下发布。OS VM的知名派生者有:

  • Squeak,一个开源Smalltalk。
  • Pharo Smalltalk,一个开源跨平台语言。
  • Croquet VM,Croquet OS的一个与Squeak有关的Smalltalk VM。
  • Cuis-Smalltalkf[33],一个开源的小型、简洁和适用的Smalltalk。
  • Haver-Smalltalk[34],Cuis的具有完整模块系统的扩展。

JavaScript VM

  • PharoJS[35],一个开源的从Smalltalk到Javascript的转译器,扩展了Pharo环境。
  • SqueakJS[36],用于web的一个OpenSmalltalk兼容的VM,还能运行老旧的Squeak应用如Etoys英语Etoys (programming language)Scratch

其他

  • Amber Smalltalk英语Amber Smalltalk,通过转译运行在JavaScript上。
  • Cincom英语Cincom Systems Smalltalk,包含下列产品:VisualWorks英语VisualWorks、ObjectStudio和WebVelocity。
  • Visual Smalltalk Enterprise英语Visual Smalltalk Enterprise,一个家族,包括Smalltalk/V。
  • Smalltalk/X[37],由Claus Gittinger开发。
  • F-Script英语F-Script (programming language),在2009年写的只用于macOS的实现。
  • GemStone/S英语Gemstone (database),GemTalk系统出品。
  • GNU Smalltalk,Smalltalk的无头(缺少GUI)实现。
  • StepTalk英语StepTalkGNUstep脚本框架,它在Objective-C运行时上使用Smalltalk语言。
  • VisualAge英语VisualAge Smalltalk。
  • VAST平台(VA Smalltalk)[38],Instantiations公司开发。
  • Little Smalltalk英语Little Smalltalk
  • Dolphin Smalltalk英语Dolphin Smalltalk,Object Arts出品。
  • Smalltalk MT英语Smalltalk MT,Object Connect出品的Windows平台Smalltalk。
  • Pocket Smalltalk英语Pocket Smalltalk,运行于Palm Pilot。
  • SmallJ[39],一个开源的基于Java的Smalltalk,派生自SmallWorld[40]
  • Etoys英语Etoys (programming language),用于学习的可视编程系统。
  • Strongtalk英语Strongtalk,提供可选的强类型。
  • TruffleSqueak[41],用于GraalVM的一个Squeak/Smalltalk VM和Polyglot编程环境(更多基于GraalVM的Smalltalk实现可见于官网[42])

参见

  • Seaside英语Seaside (software)
  • GLASS

引用

  1. ^ (PDF). Bitsavers: 54. [21 July 2016]. (原始内容 (PDF)存档于2021-02-24). 
  2. ^ . [2016-04-19]. (原始内容存档于2020-12-05). 
  3. ^ 3.0 3.1 3.2 3.3 3.4 3.5 3.6 3.7 Kay, Alan; Stefan Ram. E-Mail of 2003-07-23. Dr. Alan Kay on the Meaning of “Object-Oriented Programming”. 2003-07-23 [2009-01-03]. (原始内容于2020-09-16). 
  4. ^ 4.0 4.1 Alan Kay. . 1993 [2021-03-06]. doi:10.1145/155360.155364. (原始内容存档于2011-04-29). What Sketchpad called masters and instances, Simula called activities and processes. Moreover, Simula was a procedural language for controlling Sketchpad-like objects, thus having considerably more flexibility than constraints (though at some cost in elegance) ……. ……
    This Smalltalk language (today labeled -71) was very influenced by FLEX英语Flex (programming language), PLANNER英语Planner (programming language), LOGO, META II英语META II, and my own derivatives from them. ……
    One of the styles retained from Smalltalk-71 was the comingling of function and class ideas. In other works, Smalltalk-72 classes looked like and could be used as functions, but it was easy to produce an instance (a kind of closure) by using the object ISNEW. ……
    Overlapping windows were the first project tackled (With Diana Merry) after writing the code to read the keyboard and create a string of text. ……
    One of the next classes to be implemented on the Interim Dynabook (after the basics of numbers, strings, etc.) was an object-oriented version of the LOGO turtle implemented by Ted. ……
    Our early “LISP-pair” definition is an example of an abstract data type because it preserves the “field access” and “field rebinding” that is the hallmark of a data structure. …… What I got from Simula was that you could now replace bindings and assignment with goals. ……
    Where does the special efficiency of object-oriented design come from? …… Four techniques used together – persistent state, polymorphism, instantiation, and methods-as-goals for the object – account for much of the power. None of these require an “object-oriented language” to be employed – ALGOL 68 can almost be turned to this style – and OOPL merely focuses the designer’s mind in a particular fruitful direction. ……
    Simula-I had neither classes as objects nor inheritance. Simula-67 added the latter as a generalization to the ALGOL-60 <block> structure. ……
    On the other hand, since things can be done with a dynamic language that the difficult with a statically compiled one, I just decided to leave inhertance out as a feature in Smalltalk-72, knowing that we could simulate it back using Smalltalk’s LISPlike flexibility. ……
    By the time Smalltalk-76 cam along, Dan Ingalis had come up with a scheme that was Simula-like in its semantics but could be incrementally changed on the fly to be in accord with our goals of close interaction.
     
  5. ^ . sourcemaking.com. [17 December 2013]. (原始内容存档于2016-03-31). 
  6. ^ Carl Hewitt英语Carl Hewitt; Peter Bishop, Richard Steiger. (PDF). IJCAI. 1973 [2022-04-11]. (原始内容 (PDF)存档于2021-02-25). Alan Kay whose FLEX and SMALLTALK machines have influenced our work. Alan emphasized the crucial importance of using intentional definitions of data structures and of passing messages to them. This paper explores the consequences of generalizing the message mechanism of SMALLTALK and SIMULA-67; ……. 
  7. ^ Learning Research Group. (PDF) (Report). Xerox Palo Alto Research Center. October 1979 [2022-03-12]. (原始内容 (PDF)存档于2022-04-12). To define a new class, select a class category in the first pane of the browse window. This selection specifies the category to which the new class will be added, and causes a template to appear in the largest pane of the browse window, the code pane. ……
    The template presented in the code pane looks as follows
        Class new title: ’NameofClass’
        subclassof: Object
        fields: ’names of fields’
        declare: ’names of class variables’
     
  8. ^ Alan Kay. . [2021-03-06]. (原始内容存档于2011-04-29). The most puzzling strange idea – at least to me as a new outsider – was the introduction of metaclasses (really just to make instance initialization a little easier – a very minor improvement over what Smalltalk-76 did quite reasonably already).
    Peter’s 1989 comment is typical and true: “metaclasses have proven confusing to many users, and perhaps in the balance more confusing than valuable.” In fact, in their PIE system, Goldstein and Bobrow had already implemented in Smalltalk on “observer language”, somewhat following the view-oriented approach Ihad been advocating and in some ways like the “perspectives” proposed in KRL [Goldstein *].
    Once one can view an instance via multiple perspectives even “sem-metaclasses” like Class Class and Class Object are not really necessary since the object-role and instance-of-a-class-role are just different views and it is easy to deal with life-history issues includeding instantiation. This was there for the taking (along with quite a few other good ideas), but it wsn’t adopted. My guess is that Smalltalk had moved into the final phase I memntioned at the beginning of this story, in which a way of doing things finally gets canonized into an inflexible belief structure.
     
  9. ^ 9.0 9.1 . [2022-02-16]. (原始内容存档于2022-03-20). 
  10. ^ (PDF). squeak.org. [2022-02-09]. (原始内容 (PDF)存档于2021-10-20). 
  11. ^ Apple Smalltalk 80. [2022-05-22]. (原始内容于2022-05-30). 
  12. ^ . [2022-02-24]. (原始内容存档于2017-06-27). 
  13. ^ Kay, Alan. . October 10, 1998 [2021-03-06]. (原始内容存档于2021-02-16). 
  14. ^ Goldberg, Adele; Robson, David. Smalltalk-80 The Language. Addison Wesley. 1989: 31, 75–89. ISBN 0-201-13688-0. 
  15. ^ (PDF). [2021-03-06]. (原始内容 (PDF)存档于2018-06-13). 
    (PDF). [2021-03-06]. (原始内容 (PDF)存档于2021-01-21). 
  16. ^ Goldberg, Adele; Robson, David. Smalltalk-80 The Language. Addison Wesley. 1989: 17–37. ISBN 0-201-13688-0. 
  17. ^ Collection Method Definitions:
    select: aBlock "Answer a new instance of a Collection containing all the elements  in the receiver which, when passed to aBlock, answer true" | newCollection | newCollection := self copyEmpty. self do: [:element | (aBlock value: element) ifTrue: [newCollection add: element]]. ^newCollection 
  18. ^ Iterable Method Definitions:
    do: aBlock "Enumerate each object of the receiver, passing them to aBlock" self subclassResponsibility 
  19. ^ SequenceableCollection Method Definitions:
    do: aBlock "Evaluate aBlock for all the elements in the sequenceable collection" 1 to: self size do: [:i | aBlock value: (self at: i)] 

    Interval Method Definitions:

    do: aBlock "Evaluate the receiver for each element in aBlock" | i | i := start. step > 0 ifTrue: [[i <= stop] whileTrue: [aBlock value: i. i := i + step]] ifFalse: [[i >= stop] whileTrue: [aBlock value: i. i := i + step]] 
  20. ^ Goldberg, Adele; Robson, David. Smalltalk-80 The Language. Addison Wesley. 1989: 39–53. ISBN 0-201-13688-0. 
  21. ^ Collection Method Definitions:
    Collection class >> with: firstObject with: secondObject "Answer a collection whose only elements are the parameters  in the order they were passed" ^(self new) add: firstObject; add: secondObject; yourself 
  22. ^ Clark, A.N. Metaclasses and Reflection in Smalltalk. 1997. 
  23. ^ Ducasse, Stéphane; Lienhard, Adrian; Renggli, Lukas. (PDF). scg.unibe.ch. Software Composition Group Institut fur Informatik und angewandte Mathematik Universitaat Bern, Switzerland. [16 December 2013]. (原始内容 (PDF)存档于2020-01-31). 
  24. ^ Foote, Brian; Johnson, Ralph. . Oopsla '89. 1–6 October 1989: 327–335 [16 December 2013]. ISBN 0897913337. doi:10.1145/74877.74911. (原始内容存档于2021-03-24). 
  25. ^ Smith, Brian C. . MIT Technical Report. 1982-01-01, (MIT-LCS-TR-272) [16 December 2013]. (原始内容存档于2015-12-13). 
  26. ^ Denker, Marcus; Peck, Mariano Martinez; Bouraqadi, Noury; Fabresse, Luc; Ducasse, Stéphane. (PDF). [2021-03-07]. (原始内容 (PDF)存档于2021-03-03). 
  27. ^ . book.seaside.st. [17 December 2013]. (原始内容存档于2013-12-17). 
  28. ^ Kay, Allen. . University of Utah MSC Thesis. 1968 [2021-03-08]. (原始内容存档于2018-07-18). 
  29. ^ Fowler, Martin. . martinfowler.com. [17 December 2013]. (原始内容存档于2021-05-07). 
  30. ^ , OpenSmalltalk, 2020-11-03 [2020-11-08], (原始内容存档于2021-03-10) 
  31. ^ . wiki.squeak.org. [2020-11-08]. (原始内容存档于2021-06-08). 
  32. ^ . jedsoft.org. [2020-11-08]. (原始内容存档于2019-08-27). 
  33. ^ . [2022-02-16]. (原始内容存档于2022-02-07). 
  34. ^ . [2022-02-12]. (原始内容存档于2022-02-12). 
  35. ^ . [2022-05-17]. (原始内容存档于2022-05-01). 
  36. ^ . [2022-05-17]. (原始内容存档于2022-05-01). 
  37. ^ . [2022-02-12]. (原始内容存档于2022-04-13). 
  38. ^ . [2022-02-25]. (原始内容存档于2022-04-13). 
  39. ^ . [2022-05-17]. (原始内容存档于2021-03-01). 
  40. ^ . [2021-03-07]. (原始内容存档于2009-02-26). 
  41. ^ . [2022-02-12]. (原始内容存档于2022-04-16). 
  42. ^ . [2022-02-12]. (原始内容存档于2022-03-17). 

延伸阅读

  • Adele Goldberg英语Adele Goldberg (computer scientist); David Robson. (PDF). Addison-Wesley. May 1983 [2022-02-16]. ISBN 0-201-11371-6. (原始内容 (PDF)存档于2017-08-07). 
  • Adele Goldberg英语Adele Goldberg (computer scientist). . Addison-Wesley. December 1983 [2022-02-09]. ISBN 0-201-11372-4. (原始内容存档于2022-02-09). 
  • Glen Krasner (编). . Addison-Wesley. August 1983 [2022-02-09]. ISBN 0-201-11669-3. (原始内容存档于2022-02-09). 
  • Adele Goldberg英语Adele Goldberg (computer scientist); David Robson. Smalltalk 80: The Language. Addison-Wesley. 11 January 1989. ISBN 0-201-13688-0. 
  • Dan Ingalls英语Dan Ingalls. (PDF). Xerox Palo Alto Research Center. January 1978 [2022-03-12]. (原始内容 (PDF)存档于2021-11-21). 
  • Learning Research Group. (PDF) (Report). Xerox Palo Alto Research Center. October 1979 [2022-03-12]. (原始内容 (PDF)存档于2022-04-12). 
  • Adele Goldberg英语Adele Goldberg (computer scientist); Alan Kay (编). (PDF). Xerox Palo Alto Research Center. March 1976 [2021-03-06]. (原始内容 (PDF)存档于2020-11-12). 
  • Alan Kay. (PDF). ACM SIGPLAN Notices (ACM). March 1993, 28 (3): 69–95 [2021-03-06]. doi:10.1145/155360.155364. (原始内容 (PDF)存档于2021-03-23). 
  • Nierstrasz, Oscar; Ducasse, Stéphane; Pollet, Damien; Black, Andrew P. . Kehrsatz, Switzerland: Square Bracket Associates. 2009-10-07 [2022-03-12]. ISBN 978-3-9523341-0-2. (原始内容存档于2022-03-18). 
  • Nierstrasz, Oscar; Ducasse, Stéphane; Pollet, Damien; Black, Andrew P. . Kehrsatz, Switzerland: Square Bracket Publishing. February 23, 2010 [2022-03-12]. ISBN 978-3-9523341-4-0. (原始内容存档于2022-02-10). 
  • Special Issue on Smalltalk. Byte英语Byte (magazine) (McGraw-Hill). August 1981, 6 (8) [2013-10-18]. 
    • Adele Goldberg英语Adele Goldberg (computer scientist). Introducing the Smalltalk-80 System. Byte英语Byte (magazine) (McGraw-Hill). August 1981, 6 (8) [2013-10-18]. 
    • Dan Ingalls英语Dan Ingalls. Design Principles Behind Smalltalk. Byte英语Byte (magazine) (McGraw-Hill). August 1981, 6 (8) [2011-11-11]. 
    • Larry Tesler. The Smalltalk Environment. Byte英语Byte (magazine) (McGraw-Hill). August 1981, 6 (8) [2016-05-02]. 

外部链接

  • Free Online Smalltalk Books (页面存档备份,存于互联网档案馆
  • Smalltalk Zoo (页面存档备份,存于互联网档案馆
  • Smalltalk-80 Bluebook implementations in C++: by dbanay (页面存档备份,存于互联网档案馆) and rochus-keller (页面存档备份,存于互联网档案馆) on github
  • . [2022-02-09]. (原始内容存档于2022-03-28). 

smalltalk, 是一种动态类型, 反射式的面向对象编程语言, 由艾伦, ingalls, kaehler, adele, goldberg等于1970年代在施乐帕羅奧多研究中心开始开发, 编程范型面向对象, 反射式設計者alan, ingalls, 英语, ingalls, adele, goldberg, 英语, adele, goldberg, computer, scientist, 實作者alan, ingalls, 英语, ingalls, adele, goldberg, 英语, adele, g. Smalltalk是一种动态类型 反射式的面向对象编程语言 Smalltalk由艾伦 凯 Dan Ingalls Ted Kaehler Adele Goldberg等于1970年代在施乐帕羅奧多研究中心开始开发 Smalltalk编程范型面向对象 反射式設計者Alan Kay Dan Ingalls 英语 Dan Ingalls Adele Goldberg 英语 Adele Goldberg computer scientist 實作者Alan Kay Dan Ingalls 英语 Dan Ingalls Adele Goldberg 英语 Adele Goldberg computer scientist Ted Kaehler 英语 Ted Kaehler Diana Merry 英语 Diana Merry Scott Wallace Peter Deutsch Xerox PARC其他人发行时间1972年 51年前 1972 開發始於1969年 穩定版本Smalltalk 80版本2 1983年 40年前 1983 型態系統強 動態作用域词法 静态 系统平台Xerox Alto 1 2 作業系統跨平台主要實作產品Amber 英语 Amber Smalltalk Dolphin 英语 Dolphin Smalltalk GemStone S 英语 Gemstone database GNU Smalltalk Pharo Smalltalk X Squeak VisualAge 英语 VisualAge VisualWorks 英语 VisualWorks 衍生副語言Self GNU Smalltalk啟發語言Lisp 3 Simula 3 Euler 英语 Euler programming language 3 IMP 英语 IMP programming language 3 Planner 英语 Planner programming language 3 Logo 4 Sketchpad 3 ARPAnet 3 Burroughs B5000 英语 Burroughs large systems 3 影響語言AppleScript CLOS Dart Dylan Erlang Etoys 英语 Etoys programming language Falcon Go Groovy Io Ioke Java Lasso 英语 Lasso programming language Logtalk 英语 Logtalk Newspeak 英语 Newspeak programming language NewtonScript Object REXX 英语 Object REXX Objective C PHP 5 Perl 6 Python Ruby Scala Scratch Self維基教科書中有關Smalltalk的文本Smalltalk对其它众多的程序设计语言的产生起到了极大的推动作用 特別是Objective C CLOS Python和Ruby等 1990年代涌现的许多软件开发思想都得益于Smalltalk 例如设计模式 敏捷编程和代码重构 5 等 目录 1 概述 2 历史 3 面向对象编程 4 Hello World 例子 5 语法 5 1 文字 5 1 1 数和字符 5 1 2 字符串 5 1 3 符号 5 1 4 数组 5 1 5 其他 5 2 变量声明 5 3 赋值 5 4 消息 5 4 1 一元消息 5 4 2 关键字消息 5 4 3 二元消息 5 5 表达式 5 5 1 组合 5 5 2 复合 5 5 3 级联 5 6 代码块 6 控制结构 6 1 迭代 6 2 异常处理 7 类 7 1 定义 7 2 方法 7 3 实例化 7 4 类方法 8 反射 9 基于映像的持久存储 10 实现列表 10 1 OpenSmaltalk 10 2 JavaScript VM 10 3 其他 11 参见 12 引用 13 延伸阅读 14 外部链接概述 编辑Smalltalk和许多程序设计语言不同 它不仅仅是一门语言 下面从几个不同的角度来解释Smalltalk 一种面向对象的程序设计语言 它是一种面向对象的语言 包含语言的语法和语义 一些编译器可以透过Smalltalk源程序产生可执行文件 这些编译器通常产生一种能在虚拟机上运行的二进制代码 Smalltalk语言本身非常精炼 一种程序设计环境 这里指的是一种提供许多对象的系统 而不是某种特殊的开发环境 和许多语言不同 包括C Smalltalk附带有一个巨大的 相当标准的类库 这些类使得开发Smalltalk程序的效率非常高 在其它语言 例如Ada C和Pascal 中 通常被作为语言的一部分的功能 例如条件判断 循环等 在Smalltalk由特定的类提供 一个应用开发环境 ADE 由于Smalltalk的历史原因 它具有一个非常优秀的高度集成 开放的应用开发环境 由于开发环境中的浏览器 监视器以及调试器 都由同样的源程序衍生出来的 不同的版本之间也具有相当好的兼容性 此外 这些工具的源程序都可以在ADE直接存取 历史 编辑 Smalltalk 76 Smalltalk的VisualWorks商业实现 Smalltalk 80的从Squeak分叉出的开源实现Pharo 最早的Smalltalk原型由艾伦 凯于1970年代初提出 类 来自Simula 67 海龟绘图 英语 Turtle graphics 来自LOGO 以及图形用户界面 来自Sketchpad等先驱系统 等概念的有机组合 构成了Smalltalk的最初的蓝图 4 在1971年到1975年之间 艾伦 凯在Xerox PARC的小组 在Xerox Alto计算机上 设计并实现了第一个真正的Smalltalk语言系统 編譯器由Dan Ingalls負責主要實作 这个系统被称为Smalltalk 71與Smalltalk 72 具有以下几个技术创新 语言完全基于消息交换和Simula 67的类的概念 语言没有固定的语法 语法分析由类本身完成 开发环境的革新相当迅速 虽然当时的位图显示器十分昂贵 但是艾伦 凯却说服了PARC 让他使用这些位图显示器 这使得艾伦 凯和他的小组 能够实现不同大小和字体的文字 使用多窗口环境 以及一些对图像处理的高端支持 Smalltalk 72影响了演员模型的发展 6 它的语法和执行模型 与现代的Smalltalk变体有着显著的差异 在1975到1976年间 艾伦 凯小组认识到应当对执行效率和规模进行优化 于是他们在许多重要方面重新设计了Smalltalk系统 被称为Smalltalk 76 它在语言上 引入了继承和子类的概念 7 确定了语言的语法 这使得编译器能够产生高效 可执行 精炼的二进制代码 拉里 泰斯勒设计了类浏览器 这极大地提高了Smalltalk程序员的编程效率 前述的所有Smalltalk系统 都是在特殊的硬件上实现的 直到1977年至1978年 Bruce Horn和Ted Kaehler把Smalltalk 76移植到Xerox NoteTaker 英语 Xerox NoteTaker 上 它是由Intel 8086处理器和自定显示器所组成的硬件环境 虽然这种硬件环境只生产了10台 但是它证明了在通常的处理器上实现Smalltalk的可能性 在1979至1980年 部分受NoteTaker项目的影响 Smalltalk小组的注意力转移到Smalltalk的销售可行性上 小组设计并实现了新一代的Smalltalk系统 这次修改的目标着重于在标准硬件上的移植性等方面 被称为Smalltalk 80 它包括 采取ASCII码字符集 摒弃了原先在Smalltalk 72和Smalltalk 76中使用的特殊字符 取消了原始方法直接存取内存的能力 取而代之的是引入一系列的原始方法提供相应的功能 引入了元类的概念 8 引入MVC 模型 视图 控制器 系统以方便交互式应用软件的开发 Smalltalk 80是在PARC之外能获得到的第一个语言变体 最初作为Smalltalk 80版本1 给与了少数公司 惠普 苹果公司 泰克和DEC 和大学 UC Berkeley 用于同行评审和在它们自己的平台上实现 后来在1983年普遍可获得的实现 叫做Smalltalk 80版本2 发行为虚拟机规定和映像 具有对象定义的独立于平台的文件 9 1988年Xerox PARC为了将Smalltalk推向市场而成立了分拆公司ParcPlace Systems ANSI Smalltalk自从1998年来是标准的语言参考 10 两个当前流行的Smalltalk实现变体 是这些最初Smalltalk 80映像的后代 Squeak是开源实现 它经由Apple Smalltalk 11 派生自Smalltalk 80版本1 03 12 VisualWorks 英语 VisualWorks 经由Smalltalk 80 2 5和ObjectWorks 二者都是ParcPlace Systems的产品 派生自Smalltalk 80版本2 9 面向对象编程 编辑主条目 面向对象编程 Smalltalk 80例子代码在Squeak下的类层级和与之并行的元类层级的示意图 其中的r是ProtoObject c是Class mc是Metaclass 蓝色连接表示实例联系 绿色连接表示继承联系 如同其他面向对象语言 Smalltalk 80 而非Smalltalk 72 的中心概念是 对象 一个对象总是一个 类 的一个 实例 类是描述它们的实例的属性和行为的 蓝图 例如 一个GUI窗口类 可以声明窗口拥有的属性 比如标签 位置和窗口是否可见 这个类还可以声明其实例支持的操作 比如打开 关闭 移动和隐藏 每个特定窗口对象 对这些属性都有自己的值 它们每个都能进行它的类定义的操作 Smalltalk对象确切的可以做三件事 持有状态 引用到其他对象 接收消息自本身或其他对象 在处理一个消息的过程中 发送消息至本身或其他对象 一个对象持有的状态总是私有于这个对象 其他对象只能通过发动请求 消息 至这个对象 来让它做出查询或变更这个状态 任何消息可以发送给任何对象 当接收到一个消息的时候 接收者确定这个消息是否合适 Alan Kay评论说 尽管关注于对象 消息才是Smalltalk中最重要的概念 最大的想法是消息传递 它是Smalltalk Squeak核心的全部意义所在 它是我们在Xerox PARC阶段从未真正完成的某种东西 13 不同于多数其他语言 Smalltalk对象可以在系统运行的同时进行修改 现场编码和飞速应用补丁 是Smalltalk的主导编程方法论 并且是它高效的主要原因 Smalltalk是 纯 面向对象编程语言 这意味着 不像C 和Java 在作为对象的值和作为原始类型的值之间没有区别 在Smalltalk中 原始值比如整数 布尔值和字符 也是对象 这么说的意义在于它们也是相应类的实例 而且要发送消息来调用在它们上的运算 编程者可以通过子类 改变或扩展实现原始值的类 使得可以向它们的实例定义新行为 例如实现一个新的控制结构 甚至使得它们现有行为得以改变 这个事实被总结成常听到的一句短语 在Smalltalk中 所有东西都是对象 它可以更精确的表达为 所有的值都是对象 因为变量不是 因为所有的值都是对象 类也是对象 每个类都是这个类的元类的一个实例 元类都是Metaclass 元类类 的实例 它也是对象 并且是Metaclass class 元类元类 的实例 代码块是Smalltalk表达匿名函数的方式 它也是对象 14 Hello World 例子 编辑Hello World 程序 实质上被所有计算机语言的课本用作要学习的第一个程序 它展示了这个语言的最基本语法和环境 对于Smalltalk 这个程序可极其简单的书写 下列代码中 消息show 被发送给对象Transcript 具有字符串文字 Hello World 作为它的实际参数 调用show 方法 导致它的实际参数 即字符串文字 Hello World 显示在叫做 副本 Transcript 的终端窗口 Transcript show Hello World 注意需要打开Transcript窗口 来看到这个例子的结果 语法 编辑Smalltalk 80语法是相当极简主义的 只基于了一小把的声明和保留字 事实上 Smalltalk中只保留了六个 关键字 true false nil self super和thisContext 它们的准确术语是 伪变量 是服从变量标识符规则的标识符 但指示了编程者所不能变更的绑定 true false和nil伪变量是单例实例 self和super 在响应一个消息而激活的方法中 指称这个消息的接收者 但是发送给super的消息 在这个方法的定义类的超类中查找方法 而非这个接收者的类中 这允许子类中的方法调用在超类中的同名方法 thisContext指称当前的活动记录 内建的语言构造只有消息发送 赋值 方法返回和某些对象的文字语法 从它最初作为给所有年龄儿童的语言开始 标准的Smalltalk语法以更像英语 而非主流编码语言的方式使用标点符号 语言余下部份 包括用于条件求值和迭代的控制结构 都由标准Smalltalk类库实现在内建构造之上 出于性能上的原因 实现可以识别并特殊处理某些这种消息 但这只是优化而并未硬性规定入语言语法 谚语 Smalltalk语法适合一张明信片 所提及的是Ralph Johnson 英语 Ralph Johnson computer scientist 的一个代码片段 展示了一个方法的所有基本标准语法元素 15 exampleWithNumber x y true amp false not amp nil isNil ifFalse self halt y self size super size a a a 1 1 0 do each Transcript show each class name show x lt y 文字 编辑 下列例子诠释了最常用的对象 可以在Smalltalk 80方法中被写为文字 英语 Literal computer programming 值 数和字符 编辑 下列是数的某些可能例子 42 42 123 45 1 2345e2 2r10010010 16rA000 最后两个项目分别是二进制和十六进制数 在r前的数是底数或基数 基数不必须是二的幂 例如36rSMALLTALK是一个有效的数值 等价于十进制的80738163270632 字符书写时带有前导的美元符 A 字符串 编辑 字符串是包围在单引号内的字符序列 Hello world 要在一个字符串中包括一个引号 使用另一个引号来转义 I said Hello world to them 双引号不需要转义 因为单引号界定字符串 I said Hello world to them 两个相等的字符串 字符串相等 如果它们包含完全相同的字符 可以是驻留在内存不同位置中的不同对象 符号 编辑 除了字符串 Smalltalk有一类叫做符号 英语 Symbol programming Symbol 的字符序列对象 符号保证是唯一的 没有作为不同对象的两个相等的符号 因此 符号非常易于比较 并经常用于语言构造中 比如用作消息选择子 符号被写为 跟随着字符串文字 英语 string literal 比如 foo 如果一个序列不包含空白或标点字符 还可以写为 foo 数组 编辑 例如定义了四个整数的一个数组 1 2 3 4 很多实现支持下列字节数组 ByteArray 的文字语法 例如定义了四个整数的字节数组 1 2 3 4 其他 编辑 最后却重要的是块 匿名函数文字 一些smalltalk代码 很多Smalltalk方言为其他对象实现了额外的语法 但是上述的是所有方言都本质上支持的 变量声明 编辑 在各种Smalltalk中共同使用的有两种变量 实例变量和临时变量 其他变量和有关术语依赖于特定实现 例如VisualWorks 英语 VisualWorks 有类共享变量和名字空间共享变量 而Squeak和很多其他实现 有类变量 池变量和全局变量 在Smalltalk中临时变量声明是在方法 见后 内声明的变量 它们声明在方法的顶部 作为由竖杠包围的空格分隔的名字 例如 index 声明一个临时变量名叫index 可以包含初始值nil 多个变量可以在一组竖杠内声明 index vowels 声明了两个变量 index和vowels 所有变量都要初始化 字符串的索引变量 初始化为null字符或初始为0的ByteArray 此外的所有变量初始化为nil 按命名约定 实例变量 临时变量 方法或块的参数 应当以小写字母开头 指示它们具有私有作用域 它们合称为局部变量 而全局变量 类变量 池字典 类名字 应当以大写字母开头 它们合称为共享变量 赋值 编辑 变量通过 语法来指定一个值 比如 vowels aeiou 指定字符串 aeiou 至前面声明的vowels变量 这个字符串是个对象 在单引号之间的字符序列是文字字符串的语法 在编译时间由编译器创建 在最初的Parc Place映像中 现在下划线 的字形 在那时是左向箭头 字形 就像1963年版本ASCII代码中那样 Smalltalk最初接受左向箭头 作为唯一的赋值算符 一些现代代码仍然包含充当赋值的下划线 会让人想起这种最初的用法 多数现代的Smalltalk实现接受要么下划线 要么冒号等号语法 消息 编辑 消息是Smalltalk中最基础的语言构造 所有控制结构都实现为消息发送 Smalltalk缺省的采用动态分派和单一分派策略 这是相对于其他一些面向对象语言使用的多分派而言的 一元消息 编辑 下列例子是发送消息factorial至数值42 42 factorial 在这种情况下 42叫做这个消息的 接收者 而factorial是消息的选择子 接收者通过返回一个值来相应这个消息 这个情形中是42的阶乘 同其他事物一样 消息的结果可以赋值给一个变量 aRatherBigNumber 42 factorial 上面的factorial是 一元 消息 因为只涉及了一个对象 即接收者 关键字消息 编辑 消息可以承载额外的对象作为实际参数 比如 2 raisedTo 4 在这个表达式中 涉及了两个变量 2作为接收者而4作为消息的实际参数 消息结果 或用Smalltalk的说法 回答被认定为16 这种消息叫做 关键字 消息 消息可以有多个实际参数 使用如下语法 hello world indexOf o startingAt 6 它的回答是在接收者字符串中字符o的索引 从索引6开始查找 这个消息的选择子是indexOf startingAt 构成自两个部份或关键字 这种关键字和实际参数的交织意图改进代码的可读性 因为实际参数由前导于它们的关键字来解释 例如 要建立一个矩形的表达式使用C 或Java类语法可以写为 new Rectangle 100 200 不清楚这些实际参数分别是什么 与之相反 在Smalltalk中 这个代码可以写为 Rectangle width 100 height 200 这个情况下接收者是Rectangle类 回答是这个类的具有指定宽度和高度的一个实例 二元消息 编辑 最后 多数特殊 非字母 字符可以被用作所谓的 二元消息 这些允许了数学和逻辑算符以传统形式书写 3 4 它发送消息 给接收者3 具有4作为实际参数传递 回答将是7 类似的 3 gt 4 将消息 gt 发送给3具有实际参数4 回答将是false 注意 Smalltalk 80语言自身 不包含着这些算符的含义 上述的结果 都只是这些消息的接收者 这里是数值实例 为了响应消息 和 gt 而定义并返回的 这个机制的副作用是运算符重载 消息 gt 可以被其他对象所理解 允许使用形如a gt b的表达式来比较它们 表达式 编辑 一元消息可以一个接一个的写成方法链式调用 3 factorial factorial log 它发送factorial到3 接着发送factorial到前面的结果6 接着发送log到前面的结果720 产生最终的结果2 85733 一个表达式可以包括多次消息发送 在这个情况下 表达式依据一个简单的优先级次序来分析 一元消息有最高的优先级 随后是二元消息 最后是关键字消息 例如 3 factorial 4 factorial between 10 and 100 被求值如下 3接收消息factorial并回答6 4接收消息factorial并回答24 6接收消息 具有24作为实际参数并回答30 30接收消息between and 具有10和100作为实际参数并回答true最后的消息发送的回答 是整个表达式的结果 组合 编辑 在需要的时候使用圆括号可以改变求值的次序 例如 3 factorial 4 factorial between 10 and 100 将改变表达式含义 首先计算3 factorial 4产生10 接着10接收第二个factorial消息 产生3628800 3628800接着接收between and 回答false 注意由于二元消息的含义 不是硬性规定入Smalltalk 80语法的 它们全部都被认为有相等的优先级 并简单的从左至右来求值 因此 使用二元消息的Smalltalk表达式的含义 可能不同于传统释义 3 4 5 被求值为 3 4 5 产生35 要得到预期回答23 必须使用圆括号来显式的定义运算次序 3 4 5 复合 编辑 以点号分隔的表示式按顺序执行 注意在变量定义和随后的表达式之间没有点号 一个表达式序列的值 是最后的表达式的值 除了最后的表达式之外 所有的表达式的值都被忽略 注意点号是分隔符而并非终结符 因此最终的点号是可选的 下列 假想 例子中 书写了一序列的表达式 每个都用点号分隔 这个例子首先建立类Window的一个新实例 存储它在一个变量中 接着向它发送两个消息 window window Window new window label Hello window open 级联 编辑 如果像上述例子这样 将一序列消息都发送给相同的接收者 它们也可以写为方法级联调用 具有用分号分隔的单独消息 Window new label Hello open 这种将前面例子的重新为一个单一表达式 避免了对将新窗口存储在临时变量的需要 依据平常的优先级规则 首先向Window类发送一元消息new 接着向new回答的那个对象 发送label 和open 可以使用yourself消息来返回一个级联消息的接收者 代码块 编辑 块是头等对象 代码块即匿名函数 可以被表达一个文字值 它是一个对象 因为所有值都是对象 这是通过方括号达成的 params lt 消息表达式 gt 这里的 params是代码可以接受的形式参数的列表 结果的块对象可以形成一个闭包 它可以在任何时间访问它外围的词法作用域内的变量 这意味着下列Smalltalk代码 x x 1 可以理解为 f x x 1 displaystyle f x x 1 或用l演算表达为 l x displaystyle lambda x x 1 displaystyle x 1 块可以通过发送给它们value消息来执行 块有一个参数用value 有2个参数使用value value 以此类推直到4个参数 对多于4个参数使用valueWithArguments 并将参数作为数组传递 例如下面的表达式 x x 1 value 3 可以被求值为 f 3 3 1 displaystyle f 3 3 1 或用l演算表达为 l x x 1 3 b 3 1 displaystyle lambda x x 1 3 underset beta rightarrow 3 1 块返回 常称为回答 其主体的最后一个表达式的值 除非有一个由显式的 指示的返回 这时返回这个返回表达式的值 在块内部的返回 充当了一种逃出 escape 机制 在一个嵌套的块表达中的返回表达式 将终止在字面上包围的方法 块的文字表示是一种创新 它一方面允许特定代码有更重大的可读性 它允许涉及迭代的算法一更清晰和简洁的方式编码 典型的在某些语言中使用循环写成的代码 可以在Smalltalk中使用块简洁的书写 有时在单一一行之内 更加重要的 块允许使用消息和多态来表达控制结构 因为块推延了计算 而多态可以用来选择交替者 alternative 所以在Smalltalk 80中 if then else被书写和实现为 expr ifTrue expr为真时求值的语句 ifFalse expr为假时求值的语句 再举一例 向一个搜集发送消息select positiveAmounts allAmounts select anAmount anAmount isPositive 注意这与函数式编程有关 这里的计算模式被抽象成了高阶函数 select 等价于在一个适当的函子上的高阶函数filter 16 控制结构 编辑在Smalltalk中控制结构没有特殊的语法 它们转而实现为发送到对象上的消息 以条件执行为例 布尔类Boolean定义了ifTrue ifFalse ifTrue ifFalse 和ifFalse ifTrue 方法 比如向一个布尔对象 发送ifTrue 消息 并传递一个代码块作为实际参数 这个块被执行当且仅当布尔接收者为真 下面用一个例子来展示 result a gt b ifTrue greater ifFalse less or equal 块也被用来实现 用户定义控制结构 枚举器 访问者 异常处理 可插拔的行为和很多其他模式 迭代 编辑 下面例子 从一个字符串中过滤出其中所含有的元音字符 aString vowels aString This is a string vowels aString select aCharacter aCharacter isVowel 在最后一行 向字符串对象aString发送一个select 消息 它具有一个代码块 aCharacter aCharacter isVowel 作为实际参数 这个代码块 表示一个测试 代码块文字将被用作一个谓词函数 它回答true 当且仅当这个字符串的一个元素aCharacter 应当被包括在满足这个测试的字符搜集之中 字符串类String响应select 消息 要调用的select 方法 定义并实现在搜集类Collection中 17 它将给select 的实际参数选择块 传送给形式参数aBlock 然后将绑定了选择块的aBlock嵌入到迭代块的代码之中 再把这个迭代块作为向字符串自身发送的do 消息的实际参数 从而将这个字符串所包含的每个字符 都作为实际参数传送给这个迭代块 而各做一次求值 在求值迭代块的时候 通过value 消息 将迭代元素传送给aBlock所绑定的选择块 它回答一个布尔值 接着向它发送ifTrue 消息 如果这个布尔值是对象true 则将这个字符增加到要返回的字符串中 字符串类String响应do 消息 要调用的do 方法 定义在可迭代类Iterable中 18 而实现在可序列化搜集类SequenceableCollection中 19 这个类是Iterable类的子类和String类的超类 异常处理 编辑 Smalltalk的异常处理机制 Exception类及其子类比如Error类 类似于CLOS的异常处理样式 使用块作为处理器 一些运算 Error signal an error occurred 另一些运算 on Error do ex 处理器代码 ex return 异常处理器的ex实际参数 提供对挂起运算的状态的访问 比如它的栈帧 行号 接收者和实际参数等 并且通过发送ex proceed ex reject ex restart或ex return之一 还可用来控制计算怎样继续 类 编辑类通过实例变量定义它的实例的结构 通过方法定义它的实例的行为 每个方法都有叫做选择子的一个名字 它在这个类之内是唯一性的 定义 编辑 下面是个平凡的类定义 20 Object subclass MessagePublisher instanceVariableNames classVariableNames poolDictionaries category Smalltalk Examples 多数这种定义经常由编程环境来填充 这里的类定义是给Object类的一个消息 用来建立它叫做MessagePublisher的一个子类 在Smalltalk中类是头等对象 它可以就像任何其他对象一样接收消息 并可以在执行时间动态的创建 Object类在收到这个subclass instanceVariableNames classVariableNames poolDictionaries category 消息之时 原则上首先在其元类Object class中查找对应方法 未果而上溯继承链在其超类Class类中找到对应方法实现 在Smalltalk中 实例变量 英语 Instance variable 是这个实例的私有变量 它可以在定义它们的类的任何实例方法中 还有在它的子类中定义的方法中 通过名字来访问 在需要于一个类的所有实例 这个类本身和它的子类之间 共享某个数据的时候 要使用类变量 英语 Class variable 它是由这个类和它的所有实例共享的私有变量 池变量是在可以没有继承关联的多个类之间共享的变量 池变量最初存储在池字典中 现在它们应当被定义为专门的类 SharedPool的子类 的类变量 category指示有关的类的 群组 在现代Smalltalk版本如Pharo中被替代为package 包系统是利用简单的命名约定 组织Squeak和Pharo源代码的简单而轻量级的方式 在一个类所对应的元类中定义的实例变量叫做类实例变量 每个类都有自己私有的类实例变量 子类将继承这些类实例变量 但是子类会拥有这些变量的它们自己的私有复本 类和它们的子类不分享类实例变量 例如 可以定义一个类实例变量叫做count来跟踪一个给定的类有多少实例 类不能直接访问它的实例的实例变量 而实例不能访问它们的类的类实例变量 如果需要的话必须定义变异子与访问子 方法 编辑 当一个对象接收到一个消息的时候 调用匹配这个消息名字的一个方法 所有方法都是公开的和虚拟的 也就是动态查找的 方法被分组入指示它们意图的协议 protocol 之中 为一个类增加方法涉及到Behavior类 其中的compile 方法 编译一个方法源代码并返回一个CompiledMethod类的实例 addSelector withMethod 方法 将给定的一个编译过的方法增加到方法字典中 在Behavior类的子类ClassDescription类中 compile classified 方法 编译一个方法的源代码 并为这个方法指派上给定的归类 对于方法称为协议 对象负责在运行时间动态的确定 执行哪个方法来响应一个消息 尽管在很多语言中 这可能是 有时或总是 在编译时间静态确定的 下列代码定义一个方法publish 并且这个定义将在这个对象收到publish消息的时候发生 publish Transcript show Hello World 下列名字为 quadMultiply and 的方法 演示了接收多个实际参数并返回一个值 quadMultiply i1 and i2 这个方法将给定的两个数相乘并对结果乘以4 mul mul i1 i2 mul 4 执行任何前导了 脱字符或 的表达式 都导致这个方法于这一点退出 并返回这个表达式的值 终止而没有显式返回某个表达式的一个方法 将隐含的返回自身 实例化 编辑 为一个类新建一个实例 要用到new方法 它定义在Behavior类中 下列例子代码 MessagePublisher new 建立并返回MessagePublisher类的一个新实例 它典型的会被赋值到一个变量 publisher MessagePublisher new 但是也可以向一个临时的匿名对象发送一个消息 MessagePublisher new publish 类方法 编辑 类方法就是在一个类的元类中定义的方法 比如搜集类Collection的类方法中 实例创建方法有with with with 21 一直到with with with with with with 方法 在下面的例子中 将with with 用于有序搜集类OrderedCollection 它是SequenceableCollection类的子类 故而能最终上溯至超类搜集类 rectangles aPoint collisions rectangles OrderedCollection with Rectangle left 0 right 10 top 100 bottom 200 with Rectangle left 10 right 10 top 110 bottom 210 aPoint Point x 20 y 20 collisions rectangles select aRect aRect containsPoint aPoint 反射 编辑主条目 反射式编程 反射是一个计算机科学术语 适用于有能力检查它们自己的结构的软件程序 例如检查它们的分析树或输入和输出参数的数据类型 反射是动态 交互式语言比如Smalltalk和Lisp的一个特征 具有反射的交互式程序 要么解释的要么编译的 维护所有内存内对象的状态 包括代码对象自身 这是在解析 编译期间生成的 并且是在编程上可访问和修改的 反射也是Smalltalk这种有元模型的语言的一个特征 元模型是描述这个语言的模型 开发者可以使用元模型来做事 比如游历 检查和修改一个对象的分析树 或找到特定种类的结构的所有实例 例如在元模型中Method类的所有实例 Smalltalk 80是完全的反射式系统 用Smalltalk 80语言实现 Smalltalk 80提供了结构性和计算性反射二者 Smalltalk是结构性反射式系统 其结构是由Smalltalk 80对象定义的 定义这个系统的类和方法也是对象 并且完全是它们所有助力定义的系统的一部份 Smalltalk编译器将文本源代码编译成方法对象 典型是的CompiledMethod的实例 通过把它们存储入一个类的方法字典 而增加到这个类 类层级的定义类的那部份 可以向系统增加新类 这个系统是通过运行建立或定义类和方法的Smalltalk 80代码来扩展的 Smalltalk 80系统是个现场 living 系统 承载着在运行时间扩展自身的能力 因为类是对象 可以向它们提问比如 你实现了哪些方法 或 你定义了什么字段 槽 实例变量 所以通过能应用于系统中的任何对象的普通的代码 对象可以轻易的检查 复制 去 序列化 诸如此类 22 Smalltalk 80还提供计算性反射 有能力观察系统的计算状态 在派生自最初Smalltalk 80的语言中 一个方法的当前活动 activation 可以作为通过伪变量命名的一个对象来访问 这个伪变量是作为六个保留字之一的thisContext 通过发送消息至thisContext 一个方法活动可以提问比如 谁给你发送了这个消息 这些设施使得有可能实现协程 或类似Prolog的回溯 而不需要修改虚拟机 异常系统也是使用这个设施实现的 这个设施更有趣的用法之一 是在Seaside 英语 Seaside software web框架之中 它通过为每个编辑的页面存储续体 并在它们之间切换来导航一个web站点 缓解了编程者处理Web浏览器的返回按钮的复杂性 使用Seaside编程web服务器 可以使用更常规的编程风格来完成 23 Smalltalk如何使用反射的一个例子 是处理错误的机制 当一个对象被发送了一个它没有实现的消息的时候 虚拟机发送给这个对象doesNotUnderstand 消息 具有这个消息的实化作为实际参数 这个消息 它是另一个对象 是Message的实例 包含这个消息的选择子和它的实际参数的一个Array 在交互式Smalltalk系统中 doesNotUnderstand 的缺省实现 是打开一个错误窗口 一个Notifier 向用户报告错误 通过它和反射设施 用户可以检查错误在其中发生的上下文 重新定义犯错的代码 并继续 这一切都在这个系统之中 使用Smalltalk 80的反射设施 24 25 通过建立只理解 实现 doesNotUnderstand 的一个类 可以建立一个实例 经由它的doesNotUnderstand 方法能拦截发送给它的任何消息 这种实例可以叫做透明代理 proxy 26 可以使用这种代理来实现很多设施 比如分布式Smalltalk 这里的消息在多个Smalltalk系统之间交换 和数据库接口 这里的对象透明的从数据库中排除错误 还有promise等 分布式Smalltalk的设计影响了如CORBA这样的系统 基于映像的持久存储 编辑多数流行的编程系统 将静态的程序代码 以类定义 函数或过程的形式 分离于动态的或运行时间的程序状态 比如对象或其他形式的程序数据 它们在程序启动的时候装载程序代码 而任何先前的程序状态必须从配置文件或其他数据源显式的重新建立 程序 和编程者 未显式保存的设置 在每次重启时都必须再次设立 传统的程序在每次程序保存一个文件 退出和重载的时候 还失去很多有用的文档信息 这会失去细节比如回退历史或光标位置 基于映像的系统不会因为计算机关闭或OS更新 而强制失去所有这些东西 但是很多Smalltalk系统 不区分程序数据 对象 和代码 类 事实上 类也是对象 因此 多数Smalltalk系统 存储整个程序状态 包括类和非类对象二者 在一个映像 英语 system image 文件之中 这个映像可以接着由Smalltalk虚拟机装载 将类Smalltalk系统恢复成先前的状态 27 这是受到了FLEX的启发 它是Alan Kay创建的语言并描述于他的科学硕士毕业论文中 28 Smalltalk映像类似于 可重启的 核心转储 并可以提供与核心转储相同的功能 比如延迟或远程调试 具有对出错时刻的程序状态的完全访问 将应用代码建模为某种形式的数据的其他语言比如Lisp 也经常使用基于映像的持久存储 这种持久存储的方法 对于快速开发是强力的 因为所有开发信息 比如程序的解析树 都保存而利用于调试 但是它作为一个真实的持久存储机制 也有一个严重的缺点 首先 开发者可能经常想要隐藏实现细节 并使它们在运行时间不可获得 出于法律和维护的原因 允许任何人在运行时间修改程序 对于在运行时间环境不暴露源代码的编译后的系统 不可避免的介入复杂性和潜在的错误 其次 尽管持久存储机制易于使用 它缺乏多数多用户系统需要的真正持久存储能力 最明显的是进行同多个用户并行访问相同的数据库的事务 29 实现列表 编辑OpenSmaltalk 编辑 OpenSmaltalk VM OS VM 是Smalltalk运行时环境的著名实现 很多现代Smalltalk VM基于或派生自它 30 OS VM自身是从一组Smalltalk源代码文件 它们叫做VMMaker 转译成原生C语言源代码 通过使用叫做Slang的转译器 31 32 它依次再针对特定平台和硬件架构来编译 实际上确使Smalltalk映像的跨平台执行 源代码可以在GitHub上获得并在MIT许可证下发布 OS VM的知名派生者有 Squeak 一个开源Smalltalk Pharo Smalltalk 一个开源跨平台语言 Croquet VM Croquet OS的一个与Squeak有关的Smalltalk VM Cuis Smalltalkf 33 一个开源的小型 简洁和适用的Smalltalk Haver Smalltalk 34 Cuis的具有完整模块系统的扩展 JavaScript VM 编辑 PharoJS 35 一个开源的从Smalltalk到Javascript的转译器 扩展了Pharo环境 SqueakJS 36 用于web的一个OpenSmalltalk兼容的VM 还能运行老旧的Squeak应用如Etoys 英语 Etoys programming language 或Scratch 其他 编辑 Amber Smalltalk 英语 Amber Smalltalk 通过转译运行在JavaScript上 Cincom 英语 Cincom Systems Smalltalk 包含下列产品 VisualWorks 英语 VisualWorks ObjectStudio和WebVelocity Visual Smalltalk Enterprise 英语 Visual Smalltalk Enterprise 一个家族 包括Smalltalk V Smalltalk X 37 由Claus Gittinger开发 F Script 英语 F Script programming language 在2009年写的只用于macOS的实现 GemStone S 英语 Gemstone database GemTalk系统出品 GNU Smalltalk Smalltalk的无头 缺少GUI 实现 StepTalk 英语 StepTalk GNUstep脚本框架 它在Objective C运行时上使用Smalltalk语言 VisualAge 英语 VisualAge Smalltalk VAST平台 VA Smalltalk 38 Instantiations公司开发 Little Smalltalk 英语 Little Smalltalk Dolphin Smalltalk 英语 Dolphin Smalltalk Object Arts出品 Smalltalk MT 英语 Smalltalk MT Object Connect出品的Windows平台Smalltalk Pocket Smalltalk 英语 Pocket Smalltalk 运行于Palm Pilot SmallJ 39 一个开源的基于Java的Smalltalk 派生自SmallWorld 40 Etoys 英语 Etoys programming language 用于学习的可视编程系统 Strongtalk 英语 Strongtalk 提供可选的强类型 TruffleSqueak 41 用于GraalVM的一个Squeak Smalltalk VM和Polyglot编程环境 更多基于GraalVM的Smalltalk实现可见于官网 42 参见 编辑Seaside 英语 Seaside software GLASS引用 编辑 Alto I Schematics PDF Bitsavers 54 21 July 2016 原始内容 PDF 存档于2021 02 24 History of Computers and Computing Birth of the modern computer Personal computer Xerox Alto 2016 04 19 原始内容存档于2020 12 05 3 0 3 1 3 2 3 3 3 4 3 5 3 6 3 7 Kay Alan Stefan Ram E Mail of 2003 07 23 Dr Alan Kay on the Meaning of Object Oriented Programming 2003 07 23 2009 01 03 原始内容存档于2020 09 16 4 0 4 1 Alan Kay The Early History of Smalltalk 1993 2021 03 06 doi 10 1145 155360 155364 原始内容存档于2011 04 29 What Sketchpad called masters and instances Simula called activities and processes Moreover Simula was a procedural language for controlling Sketchpad like objects thus having considerably more flexibility than constraints though at some cost in elegance This Smalltalk language today labeled 71 was very influenced by FLEX 英语 Flex programming language PLANNER 英语 Planner programming language LOGO META II 英语 META II and my own derivatives from them One of the styles retained from Smalltalk 71 was the comingling of function and class ideas In other works Smalltalk 72 classes looked like and could be used as functions but it was easy to produce an instance a kind of closure by using the object ISNEW Overlapping windows were the first project tackled With Diana Merry after writing the code to read the keyboard and create a string of text One of the next classes to be implemented on the Interim Dynabook after the basics of numbers strings etc was an object oriented version of the LOGO turtle implemented by Ted Our early LISP pair definition is an example of an abstract data type because it preserves the field access and field rebinding that is the hallmark of a data structure What I got from Simula was that you could now replace bindings and assignment with goals Where does the special efficiency of object oriented design come from Four techniques used together persistent state polymorphism instantiation and methods as goals for the object account for much of the power None of these require an object oriented language to be employed ALGOL 68 can almost be turned to this style and OOPL merely focuses the designer s mind in a particular fruitful direction Simula I had neither classes as objects nor inheritance Simula 67 added the latter as a generalization to the ALGOL 60 lt block gt structure On the other hand since things can be done with a dynamic language that the difficult with a statically compiled one I just decided to leave inhertance out as a feature in Smalltalk 72 knowing that we could simulate it back using Smalltalk s LISPlike flexibility By the time Smalltalk 76 cam along Dan Ingalis had come up with a scheme that was Simula like in its semantics but could be incrementally changed on the fly to be in accord with our goals of close interaction Where Did Refactoring Come From sourcemaking com 17 December 2013 原始内容存档于2016 03 31 Carl Hewitt 英语 Carl Hewitt Peter Bishop Richard Steiger A Universal Modular Actor Formalism for Artificial Intelligence PDF IJCAI 1973 2022 04 11 原始内容 PDF 存档于2021 02 25 Alan Kay whose FLEX and SMALLTALK machines have influenced our work Alan emphasized the crucial importance of using intentional definitions of data structures and of passing messages to them This paper explores the consequences of generalizing the message mechanism of SMALLTALK and SIMULA 67 引文使用过时参数coauthors 帮助 Learning Research Group How To Use the Smalltalk 76 System PDF Report Xerox Palo Alto Research Center October 1979 2022 03 12 原始内容 PDF 存档于2022 04 12 To define a new class select a class category in the first pane of the browse window This selection specifies the category to which the new class will be added and causes a template to appear in the largest pane of the browse window the code pane The template presented in the code pane looks as follows br Class new title NameofClass br subclassof Object br fields names of fields br declare names of class variables Alan Kay The Early History of Smalltalk 2021 03 06 原始内容存档于2011 04 29 The most puzzling strange idea at least to me as a new outsider was the introduction of metaclasses really just to make instance initialization a little easier a very minor improvement over what Smalltalk 76 did quite reasonably already Peter s 1989 comment is typical and true metaclasses have proven confusing to many users and perhaps in the balance more confusing than valuable In fact in their PIE system Goldstein and Bobrow had already implemented in Smalltalk on observer language somewhat following the view oriented approach Ihad been advocating and in some ways like the perspectives proposed in KRL Goldstein Once one can view an instance via multiple perspectives even sem metaclasses like Class Class and Class Object are not really necessary since the object role and instance of a class role are just different views and it is easy to deal with life history issues includeding instantiation This was there for the taking along with quite a few other good ideas but it wsn t adopted My guess is that Smalltalk had moved into the final phase I memntioned at the beginning of this story in which a way of doing things finally gets canonized into an inflexible belief structure 9 0 9 1 Smalltalk 80 v2 image 2022 02 16 原始内容存档于2022 03 20 Draft American National Standard for Information Systems Programming Languages Smalltalk PDF squeak org 2022 02 09 原始内容 PDF 存档于2021 10 20 Apple Smalltalk 80 2022 05 22 原始内容存档于2022 05 30 Squeak V1 Sources 2022 02 24 原始内容存档于2017 06 27 Kay Alan Prototypes vs Classes e mail on Squeak list October 10 1998 2021 03 06 原始内容存档于2021 02 16 Goldberg Adele Robson David Smalltalk 80 The Language Addison Wesley 1989 31 75 89 ISBN 0 201 13688 0 Squeak A minimalist syntax PDF 2021 03 06 原始内容 PDF 存档于2018 06 13 Object Oriented Design with Smalltalk a Pure Object Language and its Environment PDF 2021 03 06 原始内容 PDF 存档于2021 01 21 Goldberg Adele Robson David Smalltalk 80 The Language Addison Wesley 1989 17 37 ISBN 0 201 13688 0 Collection Method Definitions select aBlock Answer a new instance of a Collection containing all the elements in the receiver which when passed to aBlock answer true newCollection newCollection self copyEmpty self do element aBlock value element ifTrue newCollection add element newCollection Iterable Method Definitions do aBlock Enumerate each object of the receiver passing them to aBlock self subclassResponsibility SequenceableCollection Method Definitions do aBlock Evaluate aBlock for all the elements in the sequenceable collection 1 to self size do i aBlock value self at i Interval Method Definitions do aBlock Evaluate the receiver for each element in aBlock i i start step gt 0 ifTrue i lt stop whileTrue aBlock value i i i step ifFalse i gt stop whileTrue aBlock value i i i step Goldberg Adele Robson David Smalltalk 80 The Language Addison Wesley 1989 39 53 ISBN 0 201 13688 0 Collection Method Definitions Collection class gt gt with firstObject with secondObject Answer a collection whose only elements are the parameters in the order they were passed self new add firstObject add secondObject yourself Clark A N Metaclasses and Reflection in Smalltalk 1997 Ducasse Stephane Lienhard Adrian Renggli Lukas Seaside A Multiple Control Flow Web Application Framework PDF scg unibe ch Software Composition Group Institut fur Informatik und angewandte Mathematik Universitaat Bern Switzerland 16 December 2013 原始内容 PDF 存档于2020 01 31 Foote Brian Johnson Ralph Reflective Facilities in Smalltalk 80 Oopsla 89 1 6 October 1989 327 335 16 December 2013 ISBN 0897913337 doi 10 1145 74877 74911 原始内容存档于2021 03 24 Smith Brian C Procedural Reflection in Programming Languages MIT Technical Report 1982 01 01 MIT LCS TR 272 16 December 2013 原始内容存档于2015 12 13 Denker Marcus Peck Mariano Martinez Bouraqadi Noury Fabresse Luc Ducasse Stephane Efficient Proxies in Smalltalk PDF 2021 03 07 原始内容 PDF 存档于2021 03 03 Image Based Persistence book seaside st 17 December 2013 原始内容存档于2013 12 17 Kay Allen FLEX A flexible extendable language University of Utah MSC Thesis 1968 2021 03 08 原始内容存档于2018 07 18 Fowler Martin Memory Image martinfowler com 17 December 2013 原始内容存档于2021 05 07 OpenSmalltalk opensmalltalk vm OpenSmalltalk 2020 11 03 2020 11 08 原始内容存档于2021 03 10 Slang wiki squeak org 2020 11 08 原始内容存档于2021 06 08 A Guide to the S Lang Language v2 3 0 Preface jedsoft org 2020 11 08 原始内容存档于2019 08 27 Cuis Smalltalk 2022 02 16 原始内容存档于2022 02 07 Haver Smalltalk 2022 02 12 原始内容存档于2022 02 12 PharoJS 2022 05 17 原始内容存档于2022 05 01 SqueakJS 2022 05 17 原始内容存档于2022 05 01 Smalltalk X 2022 02 12 原始内容存档于2022 04 13 VA Smalltalk 2022 02 25 原始内容存档于2022 04 13 SmallJ 2022 05 17 原始内容存档于2021 03 01 SmallWorld 2021 03 07 原始内容存档于2009 02 26 TruffleSqueak 2022 02 12 原始内容存档于2022 04 16 www graalvm org 2022 02 12 原始内容存档于2022 03 17 延伸阅读 编辑Adele Goldberg 英语 Adele Goldberg computer scientist David Robson Smalltalk 80 The Language and its Implementation PDF Addison Wesley May 1983 2022 02 16 ISBN 0 201 11371 6 原始内容 PDF 存档于2017 08 07 Adele Goldberg 英语 Adele Goldberg computer scientist Smalltalk 80 The Interactive Programming Environment Addison Wesley December 1983 2022 02 09 ISBN 0 201 11372 4 原始内容存档于2022 02 09 Glen Krasner 编 Smalltalk 80 Bits of History Words of Advice Addison Wesley August 1983 2022 02 09 ISBN 0 201 11669 3 原始内容存档于2022 02 09 Adele Goldberg 英语 Adele Goldberg computer scientist David Robson Smalltalk 80 The Language Addison Wesley 11 January 1989 ISBN 0 201 13688 0 Dan Ingalls 英语 Dan Ingalls The Smalltalk 76 programming system design and implementation PDF Xerox Palo Alto Research Center January 1978 2022 03 12 原始内容 PDF 存档于2021 11 21 Learning Research Group How To Use the Smalltalk 76 System PDF Report Xerox Palo Alto Research Center October 1979 2022 03 12 原始内容 PDF 存档于2022 04 12 Adele Goldberg 英语 Adele Goldberg computer scientist Alan Kay 编 Smalltalk 72 Instruction Manual PDF Xerox Palo Alto Research Center March 1976 2021 03 06 原始内容 PDF 存档于2020 11 12 Alan Kay The Early History of Smalltalk PDF ACM SIGPLAN Notices ACM March 1993 28 3 69 95 2021 03 06 doi 10 1145 155360 155364 原始内容 PDF 存档于2021 03 23 Nierstrasz Oscar Ducasse Stephane Pollet Damien Black Andrew P Squeak by Example Kehrsatz Switzerland Square Bracket Associates 2009 10 07 2022 03 12 ISBN 978 3 9523341 0 2 原始内容存档于2022 03 18 Nierstrasz Oscar Ducasse Stephane Pollet Damien Black Andrew P Pharo by Example Kehrsatz Switzerland Square Bracket Publishing February 23 2010 2022 03 12 ISBN 978 3 9523341 4 0 原始内容存档于2022 02 10 Special Issue on Smalltalk Byte 英语 Byte magazine McGraw Hill August 1981 6 8 2013 10 18 Adele Goldberg 英语 Adele Goldberg computer scientist Introducing the Smalltalk 80 System Byte 英语 Byte magazine McGraw Hill August 1981 6 8 2013 10 18 Dan Ingalls 英语 Dan Ingalls Design Principles Behind Smalltalk Byte 英语 Byte magazine McGraw Hill August 1981 6 8 2011 11 11 Larry Tesler The Smalltalk Environment Byte 英语 Byte magazine McGraw Hill August 1981 6 8 2016 05 02 外部链接 编辑維基教科書中的相關電子教程 en Smalltalk ProgrammingFree Online Smalltalk Books 页面存档备份 存于互联网档案馆 Smalltalk Zoo 页面存档备份 存于互联网档案馆 Smalltalk 80 Bluebook implementations in C by dbanay 页面存档备份 存于互联网档案馆 and rochus keller 页面存档备份 存于互联网档案馆 on github A minimal Smalltalk for teaching of and research on Virtual Machines 2022 02 09 原始内容存档于2022 03 28 取自 https zh wikipedia org w index php title Smalltalk amp oldid 75094678, 维基百科,wiki,书籍,书籍,图书馆,

文章

,阅读,下载,免费,免费下载,mp3,视频,mp4,3gp, jpg,jpeg,gif,png,图片,音乐,歌曲,电影,书籍,游戏,游戏。