CS 541 Lecture -*- Outline -*- * Smalltalk ** Message expression syntax *** Basic expressions **** Identifiers ------------------------------------------ SMALLTALK: IDENTIFIERS Identifier Conventions Upper case: ClassNames lower case: instancevar Pseudo Variables self, super, smalltalk Special Names Instances: true, false, nil Classes: True, False, UndefinedObject Case matters: True (the class) vs. true (the instance) ------------------------------------------ **** Literals ------------------------------------------ LITERALS 3 30.45 $a "the character a" 'a string, don''t laugh!' #aSymbol #aSymbol:composed:ofKeywords: #* "also a symbol" #(1 2 3) "an array constant" #(foo bar 'and me') ------------------------------------------ symbols, arrays are like in LISP/Scheme symbols give a fast comparison as opposed to strings *** messages ------------------------------------------ KINDS OF MESSAGES Unary messages: 1 negated theta sin Pen new home green Binary messages: 3 + 4 5 - 4 * 2 (sum / count) * (reserve amount) Keyword messages: 3 max: 2 anArray at: 2 put: 3 (anArray at: 2) at: 3 ------------------------------------------ binary messages always use operator characters note the colons on keyword messages *** Parsing This really is important for reading existing code! ------------------------------------------ PRECEDENCE unary highest (most tight) binary keyword lowest (least tight) ASSOCITIVITY IS LEFT TO RIGHT 4 - 5 * 3 is (4 - 5) * 3 2 * theta sin is 2 * (theta sin) frame width: otherFrame width * 2 is frame width: ((otherFrame width) * 2) FOR YOU TO DO Parenthesize the following: foo at: 2 negated put: 4 + 3 * 2 negated ------------------------------------------ ** Blocks (closures) a procedure closure *** statically scoped ------------------------------------------ BLOCKS Block = Examples: [ i print ] [ k <- k+1. k print. k ] [ :x :y | (x+y) print ] FOR YOU TO DO What is (a) printed and (b) returned by: [ :y | (y + 2) print. y ] value: 4 ------------------------------------------ translate into Haskell or ML show how these execute in response to message value, value:value: returns value of last expression (like begin in Scheme) point out formal parameters binds x to 3, then runs x+2 in that environment. ** Control Structures messages sent to Booleans, Blocks, Integers, Intervals give output of the last 3 ------------------------------------------ CONTROL STRUCTURES (x > y) ifTrue: [x print] ifFalse: [y print] (x > y) and: [y > z] [i > 0] whileTrue: [i print. i <- i - 1] 3 timesRepeat: [4 print] ((1 to: 5) step: 2) do: [:i | i print] ------------------------------------------ derived methods built on top of these, invent your own! collections support do:, inject:into:, collect:, select:, ... ------------------------------------------ FOR YOU TO DO 1. Write a statement that prints the numbers from i to 10 in ascending order. 2. Write a statement that prints all the numbers in a set s that are greater than 3 s do: ------------------------------------------ ** Classes Modules that implement abstract types (like a cluster in CLU, package in Ada) *** Stack example ------------------------------------------ MAKING A CLASS > Object addSubClass: #Stack \ instanceVariableNames: 'elems' Object > Stack display Class Name: Stack SuperClass: Object Instance Variables: elems Subclasses: Stack TO ADD METHODS > Stack addMethod ------------------------------------------ use addMethod to add methods to stack edit using editMethod: (set editor by editor <- 'vi', default is 'emacs') ------------------------------------------ "methods for Stack" new elems <- List new push: anElement elems addFirst: anElement pop elems removeFirst isEmpty ^ elems isEmpty top ^ elems first printString "would be 'contents' in ST-80" | s | s <- 'Stack ('. elems do: [ :e | s <- s , ' ', e printString]. ^ s , ' )' ------------------------------------------ Another way to do it is to edit in the form used by fileOut... Be careful to get printString right! can cause very subtle, hard to find errors *** Exercise ------------------------------------------ FOR YOU TO DO Complete the following class for a counter > Object addSubClass: #Counter \ instanceVariableNames: ' ' "methods for Counter" new increment value printString ------------------------------------------ ** object creation in little smalltalk ------------------------------------------ OBJECT CREATION IN LITTLE SMALLTALK How Stack new executes 1. send the "new" message to the class object "Stack" This: - creates - sets instance variables to 2. The new instance is sent the message ------------------------------------------ ... a new (fresh) instance of class stack, i.e., allocates memory ... nil ... new no arguments to new are possible You can have some message to pass arguments if you want, then you have to write Foo new init: 5 or whatever. ** Semantics of variables, assignment, and mutation draw pictures of heap, objects, classes *** object identity ------------------------------------------ OBJECT IDENTITY objects have an identitity = state = EXAMPLE s <- Stack new. s push: 1. s push: (Stack new push: 2). s push: s ------------------------------------------ object like a variable in C or Pascal, but allocated on the heap ... identity = address ... state = value (bits) the value may contain other objects (means their value contains the other's identity) so object identities are a subset of object values. *** mutable vs. immutable ------------------------------------------ MUTABLE vs. IMMUTABLE OBJECTS def: an object is *mutable* if otherwise an object is *immutable* ------------------------------------------ ... its state can (be observed to) change over time. draw graph of time vs value Q: are integers mutable in smalltalk? what about i <- i + 1? *** variables and assigment environment maps names (of global vars, classes, and locals) to cells (locations) that contain (point to) objects ------------------------------------------ VARIABLES AND ASSIGNMENT def: a variable in Smalltalk is EXAMPLE p1 <- p2 like Pascal: var p1, p2: Point; { a pointer!} new(p); new(p2); p1 := p2. or C: typedef PointStruct * Point; Point p1, p2; ... p1 = p2; ------------------------------------------ .... changable ref. to an object, not themselves objects (as they are in C++) can't send a message to a variable, only to the object it denotes (like a pointer variable in C or Pascal, but don't have to dereference it) draw picture Q: Does an assigment copy the object in Smalltalk? no, it creates an alias (copies reference to object) Q: What kind of value is in a Smalltalk variable? an object identity