3. Shapes in tiny labelled boxes
Run 03-shapes.bend. Expect 25.
type Shape is Data:
Circle{r: U32}
Square{s: U32}
This is an algebraic datatype: a Shape is either a
circle carrying a radius or a square carrying a side length.
Circle and Square are constructors, not
subclasses. Square{5} constructs a value.
is Data says values of this type may be copied. It does
not make every binding automatically reusable.
To inspect a shape, use pattern matching:
def area(x: Shape) -> U32:
match x:
case Circle{+r}:
(3 * r * r : U32)
case Square{+s}:
(s * s : U32)
Each pattern opens one kind of box and names its contents.
+r and +s let the selected numeric field be
reused. The circle formula deliberately uses a crude approximation of
pi: this is a datatype lesson, not a geometry certification.
Haskell companion:
data Shape = Circle Word32 | Square Word32 area :: Shape -> Word32 area (Circle r) = 3 * r * r area (Square s) = s * sBoth languages describe alternatives with constructors and handle them with patterns. Bend adds a kind (
Datahere) and explicit reuse annotations. Constructor braces in Bend are construction/pattern syntax, not Haskell record-update syntax.
A small but important matching fence
Current Bend has no if syntax: branch by matching
True{} and False{}. It also restricts the
thing you match on: use a parameter or a pattern-bound variable, in
binder order. You cannot directly write match area(shape):,
nor introduce a local computation before matching a parameter.
For a computed decision, pass the computed value to a helper that
matches its parameter. Haskell's unrestricted
case expression of is not a safe syntax guide here.
Try it: change main to
area(Circle{4}). Expect 48. Then add a
Rectangle{w: U32, h: U32} constructor and its matching
branch.