Expressions, Statements, and Blocks
The Shim language is built up from a few basic building parts, namely:
- Expressions
- Statements
- Blocks
Expressions
Expressions are the most basic piece. An expression is a chunk of code that can
be evaluated to get a value. A basic example is 13 + 4 or a more detailed
example is (x*x + y*y).sqrt() where you have multiplication, addition, and
method calling.
let x = 3 let y = 4 let hyp = (x*x + y*y).sqrt() print(hyp)
Press the play button to execute
Statements
For the most part, statements are a chunk of code that doesn’t evaluate to a value.
Typically, if a line starts with a keyword it’s a statement. The let x = 3 you
can see in the above code block is an example of this. Additionally, you have
fn declarations, struct declarations, while/for loops, and assignments.
fn greet(name) {
print("Hi \(name)")
}
let names = ["Kate", "Stephen", "Ben"]
for name in names {
greet(name)
}Press the play button to execute
Statements can’t evaluate to a value. As an example, this code block should error out:
let test = (let a = 13)
Press the play button to execute
Some keywords can act as both an expression or a statement, however.
// This `if` is a statement
if true {
print("is true")
}
// This `if` is part of an expression
let a = if true { "is true" }Press the play button to execute
Blocks
You’ve already seen them, but the code contained in curly braces {} is called
a block. A block defines a new scope where variables,
functions, and structs defined in the block can’t be referenced outside of the
block.
{
let a = 12
}
print(a) // <--- This fails since `a` doesn't exist outside of the blockPress the play button to execute
Knowing that the variable a can only be referenced inside the block is great
for keeping code understandable. It means that when you’re looking at code outside of
the block you don’t need to keep a mental record of that variable in your head.
Outside of the block, you can forget that it even existed.
Evaluating Blocks
Like the if keyword that can be a statement or an expression, blocks can also
be used as expressions. The value of a block is the last expression in the block.
Here’s an example:let hyp = {
let x = 3
let y = 4
(x*x + y*y).sqrt()
}
print(hyp)Press the play button to execute
In this example, the last line (x*x + y*y).sqrt() is what the block evaluates
to and what gets assigned to hyp. This is true for functions, where the last
expression in the function body is the return value of the function, and it’s
true for if/else expressions where the last expression of the branch is the value
evaluated for the expression.
let length = 12
let description = if length > 10 {
"long"
} else {
"short"
}
print("It's \(description)")Press the play button to execute