510 likes | 528 Views
Learn the basics of Smalltalk-80 programming language through this informative overview covering class hierarchy, messages, expressions, literals, and variables. Discover its rules, components, and design principles.
E N D
CS 598 Scripting Languages Design and Implementation7. Smalltalk 80
Smalltalk • From the Wikipedia: • Smalltalk is an object-oriented, dynamically typed, reflective programming language. Smalltalk was created as the language to underpin the "new world" of computing exemplified by "human–computer symbiosis.” • It was designed and created in part for educational use, more so for constructionist learning, at the Learning Research Group (LRG) of Xerox PARC by Alan Kay, Dan Ingalls, Adele Goldberg, Ted Kaehler, Scott Wallace, and others during the 1970s.
Source of the material in these slides • Much of the text in these slides is taken verbaim from the blue book:
Implementations today • There are multiple implementations, (see http://www.world.st/try/implementations ) including: • Amber Smalltalk Smalltalk running atop JavaScript • GNU Smalltalk • Pharo Smalltalk, Pharo Project's open-source multi-platform Smalltalk ( http://pharo.org ) • Watch: https://www.youtube.com/watch?v=WPIrfeNhYSk • Squeak, open source Smalltalk
Smalltalk Rules • Rule 1. Everything is an object. • Rule 2. Every object is an instance of a class. • Rule 3. Every class has a superclass. • Rule 4. Everything happens by sending messages. • Rule 5. Method lookup follows the inheritance chain (single inheritance)
‘Hello, world!’ example Object message
Objects • Components of the software system representing • Numbers • Character strings • Queues • Dictionaries • Programs • Compilers • Consist of • some private memory and • a set of operations
Messages, receivers, and interfaces • A message is a request for an object to carry out one of its operations. • The receiver, the object to which the message was sent, determines how to carry out the requested operation • The interface of an object with the rest of the system is the set of messages to which an object can respond. • An important part of designing Smalltalk-80 programs is determining which kinds of objects should be described and which message names provide a useful vocabulary of interaction between these objects.
Messages examples • unary messages • examples:new, copy, size • Date today • Time now hours • anArray size • someCollection copy • keyword messages • examples: new:, at:, at: put: • Array new: 10 • someArray at: 1 put: 54 • anArray at: 1 • binary messages • examples: + - * / • 5 * 9 • 3 + 2 * 5
Classesand instances • A class describes the implementation of a set of objects that all represent the same kind of system component. • The individual objects described by a class are called its instances • Every object is an instance of a class.
Methods and instance variables • The methods of an object describe how to carry out its operations. • Messages cause methods to be executed. • The instances of a class have the same set of methods. • Each instance has its own set of instance variables, but they generally have the same number of instance variables.
Expressions • components of expressions: • Literals which are constant object such as numbers and character strings • Variable names. These are the only expressions whose validity is context dependent • Message expressions which describe messages to receivers. • Block expressions whichdescribe objects representing computations to be carried out when invoked. • Expressions appear in methods and in the console (Playground).
Literals • Numbers • Integers: regular numbers such as 42 and radix notation. Thus, 2r101is 5 in binary. • Floating point numbers can be specified with their base-ten exponent (e.g. 2.4e7) • Characters: Introduced with the $ sign. $a is the literal for ’a’. Also obtained sending messages to the Character class (e.g. Characterspaceand Character tab)
Literals • Strings. Use single quotes • Symbols: Like strings, but unlike strings are guaranteed to be globally unique. Use # to identify them (e.g. #Hello). • Compile-time (constant) Arrays: Preceded by # and enclosed in parenthesis (e.g. #(27 (true false) abc) )
Variables • Local variables: start with lower case letters • Shared variables are identifiers that start with upper case letters and represent global variables, class variables, pool dictionaries and class names. • Pseudo variables: nil, true, false, self, super, and thisContext
Examples • Consider the class Number. • 3@2 is an expression that sends the message @ with parameter 2 to the number 3.
More examples of Messages • A message requests an operation from the receiver. • Messages to numbers can represent arithmetic operations. • 3+4. • index + 1. • Messages to linear data structures can represent the addition or removal of information • list := LinkedList new. • list addFirst: newComponent. • Messages to associative data structures can be used to add or remove entries • Ages:= Dictionary new. • ages at: ‘Jonathan’ put: 6 • Messages to rectangles represent graphical enquires • frame center Message to list Messageto ages
Selectors and Arguments • A message expression describes a receiver, selector, and possibly some arguments. • In 3+4, • 3 is the receiver • + is the selector • 4 the argument. • Unary messages are message without arguments: • HoseholdFinancescashOnHand • Keyword Messages have arguments identified by keywords. • HouseholdFinancestotalSpentOn: ‘utilities’ • Ages at: ‘Jonathan’ put: 3 • Binary Messages are those that contain one or two nonalphanumeric characters • total <= max • 3+4
Returning values • The receiver transmit information back by returning an object that becomes the value of the message expression. • sum := 3+4 • The receiver always returns a value for the message expression. • When no value is needed, the receiver returns itself
Precedence • Unary messages are always sent first, then binary messages, and finally keyword messages • Parenthesized expressions have precedence over unary message • 3+4 factorial → 27 • (3+4) factorial →5040 • Messages of the same kind are evaluated from left to right
Cascading • A cascaded message expression consist of one description of the receiver followed by several messages separated by semicolons • c:= LinkedList new. • c add: 1; add: 2; add: 3. • LinkedList new add: 1; add: 7; add: 3; at: 2→ 7
Blocks • Objects used in many of the control structures. • Represents a deferred sequence of actions • It is a sequence of expressions separated by periods and delimited by []s • [index:= index+1. array at: index put: 0] • The sequence of actions take place when the block receives the unary message value. • Can be assigned to variables • t := [x+1] • t value • Blocks may take parameters, which are declared with a leading colon • [:x | 1+x] value: 2
Blocks (cont.) • They may also declare local variables. • [:x :y ||z| z:=x+y. z] value: 1 value: 2 → 3 • Blocks are actually lexical closures since they can refer to variables in the surrounding environment. |x| x:=1. [:y | x+y] value: 2 → 3
Control structures • Nonsequential control structures can be implemented with blocks • Numbers and Booleans accept messages to repetitively execute a block i:=1. 4 timesRepeat: [i:=i+1] i:=1. [i <= list size] whileTrue: [list at: i put: 0. i:=i+1] Result:= ‘ ‘ 1 to: 10 do: [:n| result:=result, n printString, ‘ ‘] #(2 3 5 7 11) collect: [ :p|p*p ] → #(4 9 25 49 121)
Conditionals • Conditionals are expressed by sending one of the messages ifTrue: ifFalse:, or ifTrue:ifFalse: to a Boolean • 17*13>220 ifTrue:[‘bigger'] ifFalse: ['smaller'] → ‘bigger' Argument is a block
Classes and instances • Every object in Smalltalk-80 is an instance of a class • Each operation is described by a method. A class has a method for each selector in its interface • A protocol are groups of messages understood by objects. Each class has one or more protocols. The protocols indicate the intent of the messages. Some common protocol names have been established by convention (e.g. accessing, initialization) • Protocols are also called categories in the Blue Book
Implementation descriptions • To describe a class we use • A name • A declaration of variables available to the instances • The methods used by the instances to respond to messages • To find out the class of an object, you can send the class message • 1 class → SmallInteger • 20 factorial class → largePositiveInteger • (4@5) class → Point
Variables • Five classes • Instance variables which exist for the lifetime of the object • Temporary variables which exist for the lifetime of the scope • Class variables which are shared by all instances of a class • Global variables which are shared by all instances of all classes • Pool variables which are shared by the instances of a subset of the classes
Instance variables • Are declared in each class • Are not typed • They are private to the instances of the class (and its subclasses) • Can be access by the instance methods of the class
Methods • A method describes how an object will perform its operations • Example 1 Point»dist: aPoint "Answer the distance between aPoint and the receiver." | dx dy | dx := aPoint x − x. dy:= aPoint y − y. ^((dx * dx) + (dy * dy)) sqrt • 1@1 dist: 4@5 →5.0
Methods (cont.) • Example 2 FinancialHistory»spend: amount for: reason expenditure at: reason put: (self totalSpentFor: reason)+ amount. cashOnHand := cashOnHand – amount • To return a value, we can use the ^ character • Example 3: FinancialHistory»totalSpentFor: reason (expenditures includesKey: reason) ifTrue: [^expenditures at: reason] ifFalse[^0]
The pseudo variable self • All methods have access to the pseudo variable self that refers to the receiver of the message itself. • Example Integer»factorial "Answer the factorial of the receiver." self = 0 ifTrue: [^ 1]. self > 0 ifTrue: [^ self * (self - 1) factorial]. self error: 'Not valid for negative integers'
Temporary variables • The argument names and self are available only during execution of a method. In addition, the method may obtain other variable during its execution. • Example FinancialHistory»spend: amount for: reason | previousExpenditures | previousExpenditures:= self totalSpentFor: reason. expenditures at:reason put: previousExpenditures + amount. cashOnHand := cashOnHand – amount.
Temporary Variables • They can also be created in a Playground • Example |list| list:=Array new: 3. list at:1 put ‘one’. list at: 2 put ‘two’. list printString.
Primitive methods • Implemented not as Smalltalk code, but in the virtual machine. • Type <primitive integer> at the beginning of the method to invoke it • If the primitive fails, the rest of the method is executed, typically to report an error • See e.g. SmallInteger»+
Metaclasses • Since classes are objects, they are instances of other classes called metaclasses. • There is a metaclass for each class. • The methods of the metaclass are called class methods • And the variables in a metaclass are called Class instance variables
Class methods • They apply to classes • Example aColor := Color blue. "Class side method blue" aColor→ Color blue aColor red →0.0 "Instance side accessor method red" aColor blue →1.0 "Instance side accessor method blue"
Class instance variables • These are instance variables declared in the metaclass. • They are private to the class in the same way that instance variables are private to the instances. • Instances of a class X cannot access class instance variables of X. • Subclasses have their own copies of the class instance variables.
Class instance variable examples Object subclass: #Dog instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'PBE−CIV‘. Dog class instanceVariableNames: 'count‘. Dog subclass: #Hyena instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'PBE−CIV‘. Dog initialize. Hyena initialize. Dog count → 0 Hyena count →0 Dog new. Dog count → 1 Dog new. Dog count → 2 Hyena new. Hyena count →1 Dog class»initialize super initialize. count := 0. Dog class»new count := count +1. ^ super new Dog class»count ^ count
Superclasses • Every class has a super class. • Single inheritance • Methods can be overridden • Search proceeds in the superclass chain, terminating in Object (or ProtoObject in the case of Pharo). • If no matching method is found, the receiver is sent the message doesNotUnderstand:
A example of classCopied from somewhere pop | item | item := anArray at: top. top := top-1. ^ item setsize: n anArray := Array new: n. top := 0. Some code to test the stack: s := CS598Stack new. s setsize: 10. s inspect. s push: 'hi there'. s push: 3.14159. s pop • First we define a new class. Object subclass: #CS598Stack instanceVariableNames: 'anArray top' classVariableNames: '' poolDictionaries: '' • Now define some methods: push: item top := top+1. anArray at: top put: item
Profiling • Can measure total time | coll | coll := #(1 2 3 4 5 6 7 8) asOrderedCollection. [ 1000000 timesRepeat: [ (coll select: [:each | each > 5]) collect: [:i|i*i]]] timeToRun. • Can profile time per method MessageTally spyOn: [ 500 timesRepeat: [ | str | str := '’. 9000 timesRepeat: [ str := str, 'A' ]]].
Profinling (cont.) • And number of sends MessageTally tallySends: [ 1000 timesRepeat: [3.14159 printString]]. • See chapter 17 in http://www.deepintopharo.com/
Reflection • From wikipedia entry on reflection: • In computer science, reflection is the ability of a computer program to examine … and modify its own structure and behavior (specifically the values, meta-data, properties and functions) at runtime • reflection allows inspection of classes, interfaces, fields and methods at runtime without knowing the names of the interfaces, fields, methods at compile time. • Reflection is also a key strategy for metaprogramming.
Reflection (Cont.) • From wikipedia entry on metaprogramming • Metaprogramming is the writing of computer programs with the ability to treat programs as their data. It means that a program could be designed to read, generate, analyse or transform other programs, and even modify itself while running. • In some cases, this allows programmers to minimize the number of lines of code to express a solution (hence reducing development time)[citation needed], or it gives programs greater flexibility to efficiently handle new situations without recompilation. • The language in which the metaprogram is written is called the metalanguage. The language of the programs that are manipulated is called the object language. The ability of a programming language to be its own metalanguage is called reflection or reflexivity
Reflexion in Pharo • We can see instance variables using inpect: w := Workspace new. w openLabel: 'My Workspace'. w inspect • Or their name w instVarNamed: #contents • Or their position w instVarAt: 10 • Now, we can modify it • using the name of the instance variable: w instVarNamed: #contents put: 'howdy!'; changed: #contents • or its position: w instVarAt: 10 put: ‘epa!'; changed: #contents.
You can find out the number and name of instance variables by inspecting the class (1@2) class instVarNames #(‘x’ ‘y’) (1@2) class instSize 2