Introduction to Smalltalk Programming Language Design and Implementation
- Slides: 17
Introduction to Smalltalk Programming Language Design and Implementation (4 th Edition) by T. Pratt and M. Zelkowitz Prentice Hall, 2001 Section 7. 2. 4 Appendix A. 12
Smalltalk overview Smalltalk was developed by Alan Kay at the Xerox Palo Alto Research Center (PARC) in the early 1970 s. Goal was a total personal computing environment In 1972, Dan Ingalls developed the first implementation of Smalltalk-72, although Smalltalk-80 is the generally accepted definition of the language. Smalltalk has several features that make it unique among most languages: • A total environment design, not just a language • A minimal language design (comes with a predefined set of class definitions) • Execution model - The execution model for Smalltalk is based on a communication model. Data in Smalltalk consist of objects, and methods are considered to be messages sent to objects. • Smalltalk uses a dynamic execution sequencing model.
Language models Look at language execution models again: Imperative - sequences of actions on data: C, C++, FORTRAN, FORTH, Postscript, Ada, Basic, Pascal Applicative - Develop functions that represent final transformation of data: ML, LISP Rule-based - Specify format of results BNF, Prolog Message-based - A program is a network that dynamically sends messages to objects Smalltalk
Smalltalk features Smalltalk: 1. Each object is an instance of a class. 2. Each class has a set of associated methods (functions). 3. Execution proceeds by sending a message (which is one of these methods) to an object of that class. Historically Smalltalk was the first language to have these features. These were later borrowed for C++ and Java.
Smalltalk example 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 Array variable. Subclass: #Datastore instance. Variable. Names: '' class. Variable. Names: 'Data. File Arr. Index Storage Size' pool. Dictionaries: '' category: nil ! !Datastore class methods. For: 'instance creation'! new Data. File _ File. Stream open: 'data' mode: 'r'. Storage _ Array new: 99. Size _ 99. self reset !! !Datastore class methods. For: 'basic'! asgn: a. Value Arr. Index _ Arr. Index + 1. Figure A. 17 Storage at: Arr. Index put: a. Value ! in text getval Arr. Index _ Arr. Index + 1. ^Storage at: Arr. Index !. . . Continued. . .
Smalltalk example (continued) 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 nextval ^((Data. File next) digit. Value - $0 digit. Value)! reset Arr. Index _ 0 !! |k j sum| Datastore new. "Initialize k" [(k _ Datastore nextval) > 0] while. True: [1 to: k do: [(j _ Datastore nextval) print. Character space print. Datastore asgn: j]. Datastore reset. sum _ 0. ' SUM =' print. 1 to: k do: [ sum _ sum + Datastore getval]. sum print. Nl. Datastore reset] !
Smalltalk execution Syntax: object message ! 3 print. Nl ! Send print. Nl message to object 3 print. Nl method prints its argument followed by newline (Nl). print method does same except doesn't add newline. Note naming convention: this. Is. AMethod. Name Words strung together, all except first capitalized.
Smalltalk execution (continued) The print. Nl method is defined for string objects: 'Hello World' print. Nl' ! Send print. Nl message to object ‘Hello World’ Each method returns an object, so can repeat process: object method 1 method 2 method 3 ! Functions are arbitrary so no precedence - left to right evaluation: 2 + 3 * 4 20 (not the expected” 14)
Methods Three kinds of methods: 1. Unary - Method name only; no arguments. E. g. , print. Nl, print. 2. Binary - Operator between objects; builtin, E. g. , 2+3 means: Send the 3 object to the + method of the 2 object. [Very different from (3 + 2)] 2 + 3 * 4! Means - send the 3 object to + of 2 object; return the 5 object. - send the 4 object to * of 5 object; return the 20 object. What happens: 2 + 3 * 4 print. Nl! ? ? ? 2 + 3 results in 5 object 4 print. Nl results in 4 being printed. Unary operator associated with preceding object. 5 * 4 results in 20 object Use parentheses to get desired effect: (( 2 + 3) * 4 ) print. Nl !
Keyword methods 3. Keyword methods: method. Name: argument. Object If A is an array object: A at: 4 put: 7 ! - the at: put: method sets 4 th element = 7 A at: 4 - the at: method returns the 4 th object in A Note naming conventions. Method at: put: may not be same as put: at: method. Other execution features: Blocks: [ smalltalk. Stmt] means return object: A returns object A
True and false in Smalltalk Object true as defined in Smalltalk library: if. True: true. Block if. False: false. Block true. Block value ! (value evaluates block argument) if. False: false. Block if. True: true. Block value ! if. False: false. Block nil ! The if. True argument is evaluated in each case. Object false as defined in Smalltalk library: if. True: true. Block if. False: false. Block value !. . . Others in an analogous way Always evaluate the if. False argument
Use of Smalltalk logical expressions Example method definition: hello 2 = self if. True: [`Hello world' print. Nl] if. False: ['Goodbye world' print. Nl] !! 2 hello ! 2 = self is the argument, which is 2, so returns true passed if. True: if. False: blocks if. True block evaluated print. Nl passed to 'Hello world' printed 3 hello ! 2 = self is the argument, which is 3, so returns false passed if. True: if. False: blocks if. False block evaluated print. Nl passed to 'Goodbye world' printed
Smalltalk inheritance So far we have discussed method invocation. Power of Smalltalk is in inheritance. Smalltalk comes with a predefined class library. All object classes are subclasses of a parent Object class. If any method is not defined for an objects, the parent of that object is called with the same method. Earlier example: 3 print. Nl ! not quite right. print. Nl a method defined on Object class.
Object. st method definitions print self print. On: stdout ! print. Nl self print. stdout nl ! print. On: a. Stream | article name. String | (local variables) name. String _ self class. String. Name. (_ is assignment) article _ name. String first. Is. Vowel if. True: ['an'] if. False: ['a']. a. Stream next. Put. All article; next. Put. All name. String ! In Integer. st: print. On: a. Stream base: b a. Stream next. Put. All: (self radix: b) ! print. On: a. Stream next. Put. All: (self signedstringbase: 10 showradix: false)!
Creating methods Two types of methods: Class methods - Applies to class objects (Integer). ! Class. Name class methods. For: 'description' ! Class instance methods - Applies to instances of class objects (2, 3, 42). ! Class. Name methods. For: 'description' ! Create a new class - Use following 5 -keyword method (which is why all 5 keywords are needed) to create a new subclass of class Object: Object subclass: #new. Class. Name instance. Variable. Names: instance. Variables Local data class. Variable. Names: class. Variables global data pool. Dictionaries: ' ' Can generally ignore category: nil ! Can generally ignore
Creating methods (continued) Example: A Thing which is a subclass of an Integer: Integer subclass: #Thing instance. Variable. Names: 'a. Value’ class. Variable. Names: ' ' pool. Dictionaries: ' ' category: nil ! # gives the name a global attribute ! Thing class methods. For: 'Creation' ! new | r _ super new r init ! (super is superclass of self object. Allocate for Thing the same thing as an Integer (its parent class)) ! Thing methods. For: 'Using things' ! init a. Value _ 0 !!
Method inheritance Review previous definitions of print in Object. st and show that: Integer print. Nl ! Prints “an Integer” 3 print. Nl ! prints “ 3”