Chapter 2 Language tour
2
Chapter 2

Language tour

This chapter expands the first program into the source shapes you will read most often: explicit bindings, functions, branchy control flow, optionals, and a small result-style return type.

Make values readable

Use explicit types at useful boundaries and mark mutation where it happens.

src/tour.slk
package tour;

fn accumulate (limit: int) -> int {
  let mut total: int = 0;
  let mut i: int = 0;

  while i < limit {
    total = total + i;
    i = i + 1;
  }

  return total;
}

Use small functions for decisions

Return types make the boundary visible even when the body is simple.

src/tour.slk
fn classify (score: int) -> string {
  if score >= 90 { return "excellent"; }
  if score >= 70 { return "steady"; }
  if score >= 50 { return "watch"; }
  return "blocked";
}

Model absence with an optional

T? is the right shape when missing is normal and no extra error detail is needed.

src/tour.slk
fn env_label (name: string) -> string? {
  if name == "prod" { return Some("production"); }
  if name == "dev" { return Some("development"); }
  return None;
}

fn label_or_default (name: string) -> string {
  return env_label(name) ?? "unknown";
}

Check the module

Keep using the same quick feedback loop as the first chapter.

Terminal
silk check src/tour.slk
silk test src/tour.slk

The point is not to memorize every construct here. The habit is to read the boundary first: package, imports, function signatures, return types, and optional/result shapes.

What changed

  • let mut made mutation visible.
  • Function signatures carried the important type information.
  • string? represented absence without inventing an error path.
  • ?? handled the optional fallback at the call site.

Chapter complete

Next, split useful code into package modules and import it deliberately.

Continue to modules and packages