Coming from Python

The biggest change is that everything is checked before it runs, and types are not optional hints. The second biggest is that indentation carries no meaning — blocks are braces. What survives: readable code, interpolation, list and map literals, and a REPL.

ConceptPythonKeal
Bindingx = 1val x = 1
Rebindablex = 1; x = 2var x = 1
Functiondef add(a, b): return a + bfunc add(a: Int, b: Int): Int { a + b }
No returndef log(s): print(s)proc log(s: String) { println(s) }
List[1, 2][1, 2]
Dict{"a": 1}{"a": 1}
f-stringf"hello {name}""hello ${name}"
Nonex = Noneval x: String? = null
Classclass C: def __init__(self, n)class C(var n: Int)
Dataclass@dataclass class P: x: floatrecord P(val x: Float)
Comprehension[x*2 for x in xs]xs.map({ it * 2 })

What will surprise you

Types are not hints

You annotate parameters and fields; everything else is inferred. A mismatch is an error before the program starts, not a surprise on line 400.

There is no self

Methods take no receiver parameter — this is available inside a class, and that is all. (In actor handlers you may see a parameter named self; it is a name the author chose, not a keyword.)

Integers do not grow forever

Int is 64 bits and overflow panics rather than promoting. Float follows IEEE 754.

Reference counting, like CPython

Same model, same blind spot: a cycle. CPython adds a collector; Keal asks you to write weak on the back edge, and explains why in its memory document.