Some examples of Smalltalk, for the uninitiated.
girlInBar doKnow: self ^ false girlInBar doYouCome: here frequency: often ^ #noneOfYourBusiness girlInBar canBuyYou: self what: aDrink ^ false girlInBar zodiacSign ^ #disinterestedSnort girlInBar phoneNumber jerk say: 'Get lost' jerk throwAt: drink self leave: bar ^ '1-800-GET-LOST'Obviously, I was never very good at Smalltalk...
in that case, let me give you some help... :)
Hottie>>phoneNumber | someLoser | someLoser := thisContext sender receiver. [someLoser perform: #getLost] on: someLoser messageNotUnderstoodSignal do: [:ignoredException | self become: BarStool? empty]I've tested this in a workspace, and it behaves as expected... :)
I dont think the above examples are really helpful for some newby to get a feeling for Smalltalk (I would not show some C-newby an example of the obfuscated C-context to start with - would you ?)
(Yes I know - This is categorized as humor; however, I found no non-humor page containing smalltalk examples)
So let's be serious...
It is somewhat difficult to show the power of a class-based object system in a little (functional) example. All we can do in this case is to demonstrate the syntax (which is already described elsewhere) and how existing classes are used (i.e. their protocol). Text in double quotes are comments - everything else is plain smalltalk.
"
Simple I/O to the Transcript window (which is smalltalk'x console). The folowing sends a cr (carriage return) - message to the transcript object"
Transcript cr." this sends a message to the transcript "
Transcript show: 'hello world '." compute 10 factorial and send the result to the Transcript "
Transcript show: 10 factorial." now, try this: "
Transcript show: 100 factorial." a loop (the timesRepeat-method evaluates its argument n-times)"
10 timesRepeat: [ Transcript show:'hello'. Transcript cr. ]." another loop "
1 to: 10 do:[ :i | Transcript show:i. Transcript show:' '. Transcript show:i sqt. Transcript cr. ]." looping over a collection "
#('a' 'b' 'c' ) do:[:each | Transcript show: each. Transcript cr. ]." the same, using a local variable "
|myArray| myArray := #('a' 'b' 'c' ). myArray do:[:each | Transcript show: each. Transcript cr. ]." the loops-code is actually another object (called Block)
(and can be passed around to other code, stored in a variable etc.) The following demonstrates this."
|myArray myOperation| myArray := #('a' 'b' 'c' ). myOperation := [:each | Transcript show: each. Transcript cr. ]. myArray do: myOperation." processing collections (Lisp-fans watch) "
Transcript show: #( 1 2 3 4 5) . Transcript show: ( #( 1 2 3 4 5 ) collect: [:i | i sqt] ) Transcript show: ( #( 1 2 3 4 5 ) select:[:i | i even ] )" yes, blocks can be recursive
(except for smalltalks with the old ST-80 block semantics)" |bFac| bFac:= [:n | n > 1 ifTrue:[ n * (bFac value:n-1) ] ifFalse: [ n ]]. bFac value:100." GUI (this depends on the concrete Smalltalk environment (SmalltalkEnvironments).
The example below is from Smalltalk/X (SmalltalkEcks), but it does not look much different in VisualWorks or Squeak or others. " | myButton | myButton := Button new. myButton label: 'press me'. myButton action: [ myButton destroy ]. myButton open." here is a nice example, which uses a class
(instead of the simple expression examples above. I use chunk format, so you can easily load it into an existing smalltalk..."SequenceableCollection? subclass:#Cons
instanceVariableNames:'car cdr' classVariableNames:'' poolDictionaries:'' category:'Collections-Linked'!!Cons methodsFor:'accessing'!
car:carArg cdr:cdrArg
car := carArg. cdr := cdrArg.!
car
^ car!
cdr
^ cdr! !
Cons subclass:#LazyCons?
instanceVariableNames:'' classVariableNames:'' poolDictionaries:'' category:'Collections-Linked'!!LayzCons? methodsFor:'accessing'!
cdr
"Here, the tail is evaluated, and the inheritance changed to avoid multiple evaluation." cdr := cdr value. self changeClassTo:Cons. ^ cdr! !
and a usage example (a representation for an infinite list):
|generator allNumbers l| generator := [:n | LazyCons? new car:n cdr:[ generator value:n+1 ]]. allNumbers := generator value:1. l := allNumbers. 10 timesRepeat:[ Transcript show:l car. Transcript cr. l := l cdr. ].Notice, the above code has been written in an imperative C/Java style; you could also write:
(1 to:10) inject:allNumbers into:[:i :el | Transcript showCR: el ].More experienced readers will notice that this is almost exactly what some lazy functional languages do (however, in smalltalk, the sender of the message has to make the lazyness explizit, by using blocks explizitly). Also, notice a neat trick in the cdr implementation of LazyList?.
For more, download one of the free Smalltalks and play around with it.
--- ClausGittinger?