Froth, and this site, are pre-alpha. This site is largely OSAI-generated documentation from the Froth repo.

OldFroth used perm to make stack rearrangement regular. Current Froth keeps the spirit of explicit data flow, but the public tools are different:

  • parameters for inputs
  • locals for intermediate values
  • set for mutation
  • top-level Cells for indexed persistent state

You should not need a vocabulary of stack shuffles to read ordinary Froth.

Locals

A block introduces a lexical scope. Inside that scope, bind a local with here:

to scaleKnob with percent, max [
  here bounded is clamp: percent, 0, 100;
  bounded * max / 100
]

The last expression in the block is the value the block yields. Here, the result is the scaled number.

You can also use name is expr inside a block, but here makes the intent obvious in teaching examples. It says “this is local to the current block.”

Mutation

Use set name to expr when you intend to update an existing place:

to countdown with n [
  here current is n;
  while current > 0 [
    set current to current - 1
  ];
  current
]

set does not create a new name. If Froth cannot find an existing mutable place, it is a runtime error. That rule catches a large class of misspellings that stack languages usually cannot see.

Top-Level State

Top-level state is useful when the value is part of the live image:

player.x is 0
player.y is 0

to player.move with dx, dy [
  set player.x to wrap: player.x + dx, grid.width;
  set player.y to wrap: player.y + dy, grid.height
]

Top-level rebinding is persistent-image state, not a temporary local. Use it for things you want to inspect, redefine, save, and restore.

Cells

Cells is the first fixed-size mutable collection. It is intentionally narrow. Elements may hold Int, Bool, Nil, or Text.

Create cells at top level:

scores is cells(4)
set scores[0] to 10
set scores[1] to 25
scores[1]

Cells are good for small tables, board-sized state, and simple buffers. They are not a general heap. In current Froth, cells(n) belongs in a top-level binding so the image can reason about ownership and persistence.

How To Translate Old Stack Thinking

Old style:

3 p[a b a] perm

Current style:

to weighted with value, scale [
  value + (scale * value)
]

The current form is longer only when the data flow was unnamed. Once the values mean something, names win. A reader does not need to simulate the stack to know what is being reused.

Next: Blocks and control flow .