Basic Types
Beamtalk has a small set of built-in types. Everything is an object, so every value responds to messages.
Types covered:
Integer— whole numbersFloat— decimal numbersString— UTF-8 textBoolean— true and falseNil— the absence of a valueSymbol— interned identifiers (#name)Character— a single Unicode codepoint ($a)
Integers
Integers are arbitrary-precision whole numbers (backed by Erlang's bignum).
42 // => 42
-7 // => -7
1000000000000000000 // => 1000000000000000000
Useful messages:
42 class // => Integer
42 isZero // => false
0 isZero // => true
-5 abs // => 5
-5 negated // => 5
5 negated // => -5
Integer predicates:
(3 isKindOf: Integer) // => true
(3 isKindOf: Float) // => false
3 isEven // => false
4 isEven // => true
3 isOdd // => true
Floats
Floats are 64-bit IEEE 754 doubles. Division of integers always returns a Float.
3.14 // => 3.14
-2.5 // => -2.5
Division produces a float:
10 / 4 // => 2.5
10 / 2 // => 5.0
Float-specific messages:
3.7 floor // => 3
3.2 ceiling // => 4
3.7 truncated // => 3
3.7 rounded // => 4
3.14 class // => Float
(3.14 isKindOf: Float) // => true
Strings
Strings are UTF-8 encoded and fully Unicode-aware. Use double quotes.
"Hello, World!" // => Hello, World!
String length counts grapheme clusters (user-visible characters), not bytes:
"hello" size // => 5
"café" size // => 4
Concatenation with ++:
"Hello" ++ ", " ++ "World!" // => Hello, World!
String interpolation with {expression}:
name := "Alice" // => _
"Hello, {name}!" // => Hello, Alice!
Case conversion:
"hello" uppercase // => HELLO
"HELLO" lowercase // => hello
Trimming whitespace:
" hello " trim // => hello
Checking contents:
"hello" isEmpty // => false
"" isEmpty // => true
"hello" includesSubstring: "ell" // => true
Splitting and joining:
"a,b,c" split: "," // => ["a","b","c"]
Converting to/from other types:
42 printString // => 42
"42" asInteger // => 42
"3.14" asFloat // => 3.14
Booleans
There are exactly two boolean values: true and false.
They respond to conditional messages — note that if/else are NOT keywords,
they are messages sent to booleans (chapter 8 covers this fully).
true // => true
false // => false
true class // => True
false class // => False
Logical operations:
true not // => false
false not // => true
and: and or: take blocks for short-circuit evaluation:
true and: [false] // => false
false and: [true] // => false
true or: [false] // => true
false or: [true] // => true
xor::
true xor: false // => true
true xor: true // => false
Checking type:
true isBoolean // => true
(42 isKindOf: Boolean) // => false
Nil
nil represents the absence of a value. It is the only instance of UndefinedObject.
nil // => nil
nil class // => UndefinedObject
nil isNil // => true
nil notNil // => false
42 isNil // => false
42 notNil // => true
ifNil: and ifNotNil: are common patterns for handling optional values:
nil ifNil: ["was nil"] ifNotNil: [:v | "had value: {v}"] // => was nil
42 ifNil: ["was nil"] ifNotNil: [:v | "had value: {v}"] // => had value: 42
Symbols
Symbols are interned identifiers, written with a # prefix.
Two symbols with the same name are the same object (identity equality).
They are commonly used as dictionary keys, method selectors, and enum-like values.
#hello // => hello
#hello class // => Symbol
Symbol equality (symbols with the same name are identical, so use =:=):
#hello =:= #hello // => true
#hello =:= #world // => false
Symbols are often used as dictionary keys:
d := #{#name => "Alice", #age => 30} // => _
d at: #name // => Alice
Converting to strings:
#hello asString // => hello
Characters
A character literal is written with a $ prefix. Characters represent a
single Unicode codepoint and are stored as integers.
$A // => 65
$a class // => Integer
Character predicates work on the integer codepoint:
65 isUppercase // => true
97 isLowercase // => true
53 isDigit // => true
65 isLetter // => true
Type checking and conversion summary
Every object responds to class, isNil, notNil, printString, and respondsTo:.
42 class // => Integer
42 printString // => 42
42 respondsTo: #isZero // => true
42 respondsTo: #unknownMessage // => false
Exercises
1. Type conversion chain. Convert the string "123" to an integer, multiply
it by 3, then convert the result back to a string. What do you get?
Hint
("123" asInteger * 3) printString // => "369"
Use asInteger to parse and printString to convert back.
2. Nil-safe access. Write an expression using ifNil:ifNotNil: that returns
"unknown" when given nil and the value's class name when given a real value.
Test it with both nil and 42.
Hint
nil ifNil: ["unknown"] ifNotNil: [:v | v class printString] // => "unknown"
42 ifNil: ["unknown"] ifNotNil: [:v | v class printString] // => "Integer"
3. Symbol vs String. Create a symbol #hello and a string "hello". Are they
equal with =:=? What about after converting the symbol with asString?
Hint
#hello =:= "hello" // => false (different types)
#hello asString =:= "hello" // => true (asString converts to String)