# Smalltalk Introduction

### by "Blag" - Senior Developer Evangelist ## Who uses Smalltalk?

### Smalltalk has many implementations like Pharo, Cincom Smalltalk and GemTalk Visual Works for Smalltalk...

• JPMorgan
• Desjardins
• Texas Instruments
• Telecom Argentina
• Siemens AG
• Penn State University
• UBS

## Basic Concepts

### Precedence must be enforced by parenthesis...and you will see later on who important this is...

```				```
(2*3+5)

=>11

(2*(3+5))

=>16
``````

## Basic Concepts

### Printing on the screen is easy...

```				```
text := "This is Smalltalk!"

text printNl.

=>'This is Smalltalk'
``````

### This is another way (that gets rid of the ' too...

```				```
text := "This is Smalltalk!"

Transcript show: text

=>This is Smalltalk
``````

### You assign values using :=

```				```
| a b |

a := 'Hello'

a printNl.

=>'Hello'

b := 5

b printNl.

=>5
``````

### Precedence and parenthesis are very important...

```				```
'Hello' size + 3 printNl.

=> 3

('Hello' size + 3) printNl.

=> 8
``````

## Data Structures

### Let's start with Arrays

```				```
| myArray |

myArray := Array new: 3.

myArray at:1 put: 1.

myArray at:2 put: 2.

myArray at:3 put: 3.

myArray printNl.

=>(1 2 3)
``````

```				```
myArray := #(1 2 3).

myArray first.

=>1

myArray last.

=>3

myArray size.

=>3

myArray at:1.

=>1
``````

```				```
myArray := #('Smalltalk' 'Fortran' 'Haskell').

myArray includes:'Python'.

=>false

myArray reverse.

=>('Haskell' 'Fortran' 'Smalltalk')
``````

## Sets

### Similar to arrays but unordered and without limits

```				```
| aSet |

aSet := Set new.

aSet add: 'Smalltalk'.

aSet add: 'Fortran'.

aSet add: 'Haskell'.

aSet printNl.

->('Smalltalk' 'Haskell' 'Fortran')
``````
```				```
aSet remove: 'Smalltalk'.

aSet printNl.

->('Smalltalk' 'Haskell' 'Fortran')
``````

### Dictionaries

```				```
| aDict |

aDict := Dictionary new.

aDict at:'Peru' put:'Spanish'.

aDict at:'Canada' put:'English'.

aDict printNl.

=> Dictionary(

'Canada' -> 'English'

'Peru' -> 'Spanish'
)

``````
```				```
| aDict |

aDict := Dictionary new.

aDict := Dictionary from: {'Peru' -> 'Spanish'.

'Canada' -> 'English'}.

aDict at:'Peru'.

=> 'Spanish'

aDict keys printNl.

=> Set('Peru' 'Canada')

aDict values printNl.

=> Set('English' 'Spanish')
``````

## Blocks

### Something like functions or methods...but that are objects as well...

```				```
| myBlock |

myBlock := [:name |

Transcript show: ('Hello ' , name , '!').

].

myBlock value: 'Blag'.

=> Hello Blag!
``````

## Conditionals

```				```
| myVar |

myVar = 'Blag'.

(myVar = 'Blag') ifTrue: [

'Blag rocks!' printNl.

] ifFalse: [

'Hey!, where is Blag?' printNl.

].

=> 'Hey!, where is Blag?'
``````

## Repetitive controlling

```				```
| num |

num := 1.

[ num < 11 ] whileTrue: [

Transcript show: (num asString , ' ').

num := num + 1.

].

=> 1 2 3 4 5 6 7 8 9 10
``````
```				```
1 to: 10 do: [:x |

Transcript show: (x asString, ' ').

].

=> 1 2 3 4 5 6 7 8 9 10

1 to: 10 by: 2 do: [:x |

Transcript show: (x asString, ' ').

].

=> 1 3 5 7 9
``````

## Classes and objects

```				```
Object subclass: Person [

| name |

setName: newName [

<category: 'accessing'>

name := newName.

]

getName [

<category: 'accessing'>

^name

]

speak [

<category: 'accessing'>

'Programming is fun!' printNl.

]
]
``````
```				```
blag := Person new.

blag setName: 'Blag'.

blag getName printNl.

blag speak.

=> 'Blag'

=> 'Programming is fun!'
``````

### Strings

```				```
| aString |

aString := 'My name is Blag.'.

aString := aString , ' I like Smalltalk'.

aString printNl.

aString reverse asUppercase printNl.

aString size printNl.

=> 'My name is Blag. I like Smalltalk'

=> 'KLATLLAMS EKIL I. GALB SI EMAN YM'

=> 33
``````

## Fibonacci List

### Name your file "Fibonacci.st"

```				```
| number fib result |

result := ''.

fib := [:num :a :b |

a > 0 & (num asNumber > 1) ifTrue: [

result := result , (a + b) asString , ' ' ,

(fib value: (num asNumber - 1)

value: (a + b) value: a).

] ifFalse: [
``````
```				```
a = 0 ifTrue: [

result := a asString , ' ' , b asString ,

' ' ,  (a + b) asString , ' ' ,

(fib value: (num asNumber - 1)

value: (a + b) value: b).

].

].

].

Transcript show: 'Enter a number: '.

num := stdin nextLine.

Transcript show: (fib value: num value: 0 value: 1); cr.
``````

## Making an LED Number App

### Name your file "LED_Numbers.st"

```				```
| led line lines counter getLine number digit |

led := Dictionary new.

lines := Array new: 3.

line := ''.

counter := 1.
``````
```				```
led := Dictionary from: {0 -> ' _  ,| | ,|_| '.

1 -> '  ,| ,| '.

2 -> ' _  , _| ,|_  '.

3 -> '_  ,_| ,_| '.

4 -> '    ,|_| ,  | '.

5 -> ' _  ,|_  , _| '.

6 -> ' _  ,|_  ,|_| '.

7 -> '_   , |  , |  '.

8 -> ' _  ,|_| ,|_| '.

9 -> ' _  ,|_| , _| '. }.
``````
```				```
getLine := [:digit :dline |

1 to: ((led at: digit) size) do: [:x |

(((led at: digit) at: x) asString ~= ',')

ifTrue: [

line := line , ((led at: digit) at: x)

asString.

] ifFalse: [

lines at: counter put: line.

line := ''.

counter := counter + 1

].

lines at: counter put: line.

].
``````
```				```
Transcript show: ((lines at: dline) asString).

line := ''.

counter := 1.

].

Transcript show: 'Enter a number: '.

number := stdin nextLine.

1 to: 3 do: [:y |

1 to: (number size) do: [:x |

digit := ((number at:x) asString) asInteger.

getLine value: digit value: y.

].

Transcript cr.

].
``````

## Random Names

### Name your file "Random_Names.st"

```				```
| names last_names full_names counter |

full_names := Array new: 100001.

counter := 1.

names := Array new: 16.

names := #('Anne' 'Gigi' 'Blag' 'Juergen' 'Marek'

'Ingo' 'Lars' 'Julia' 'Danielle' 'Rocky'

'Julien' 'Uwe' 'Myles' 'Mike' 'Steven'

'Fanny').
``````
```				```
last_names := Array new: 16.

last_names := #('Hardy' 'Read' 'Tejada' 'Schmerder'

'Kowalkiewicz' 'Sauerzapf' 'Karg'

'Satsuta' 'Keene' 'Ongkowidjojo'

'Vayssiere' 'Kylau' 'Fenlon' 'Flynn'

'Taylor' 'Tan').

1 to:100001 do: [:x |

full_names at:x put:((names at:(1 to: 16)

atRandom) , ' ' ,

(last_names at:(1 to: 16)

atRandom)).

].
``````

### How this behaves in Python? ### And in Julia? ## Decimal to Romans

### Name your file "Decimal_to_Roman.st"

```				```
| number roman_Table roman_keys result flag |

roman_Table := Dictionary new.

roman_keys := Array new: 13.

result := ''.

flag := 0.

roman_Table := Dictionary

from: {1000 -> 'M'. 900 -> 'CM'. 500 -> 'D'.

400 -> 'CD'. 100 -> 'C'. 90 -> 'XC'.

50 -> 'L'. 40 -> 'XL'. 10 -> 'X'.

9 -> 'IX'. 5->'V'. 4 -> 'IV'. 1 -> 'I'.}.

``````
```				```
roman_keys := #( 1000 900 500 400 100 90 50 40 10

9 5 4 1 ).

Transcript show: 'Enter a number: '.

number := stdin nextLine.

[ number asNumber > 0 ] whileTrue: [

flag := 0.

1 to: (roman_keys size) do: [:x |

(number asNumber >= (roman_keys at: x) asNumber

& flag = 0)

ifTrue: [
``````
```				```
result := result , (roman_Table at:

(roman_keys at: x)).

number := number asNumber -

(roman_keys at: x) asNumber.

flag := 1.

].

].

].

Transcript show: result; cr.
``````

## Count Letters

### "This is a text file that we're going to read using Smalltalk"

```				```
| file contents letters |

letters := Dictionary new.

file := FileStream open: 'readme.txt'

mode: FileStream read.

file linesDo: [ :c | contents := c ].
``````
```				```
1 to:contents size do: [:x |

(letters includesKey:((contents at:x) asString))

ifTrue: [

letters at:((contents at:x) asString)

put:((letters at:((contents at:x)

asString)) + 1)

] ifFalse: [

letters at:((contents at:x) asString) put:1.

].

].
``````
```				```
letters keysAndValuesDo: [:aKey :aValue | Transcript

show: aKey printString; space;

show: aValue printString; cr

].

file close
``````