TSG-701 Use immut unless the value changes
RecommendedNo tool checks this yet
Declare a variable with immut when it is set once and never changed, and with mut only when the code really assigns to it again. A reader who sees immut knows the value on that line is the value for the rest of the block, without reading the rest of the block.
fn main(): int { immut price: int = 20; immut people: int = 4; mut total: int = 0; for i in 0..people { total += price; } printline(total); return 0;}fn main(): int { mut price: int = 20; mut people: int = 4; mut total: int = 0; for i in 0..people { total += price; } printline(total); return 0;}TSG-702 Write mut and immut, not mutable and immutable
RecommendedNo tool checks this yet
Turf accepts the long spellings mutable and immutable, and they mean exactly the same thing. Use the short ones everywhere, so that one word means one thing in every file.
fn main(): int { mut count: int = 0; immut amount: int = 2; count += amount; return count - 2;}fn main(): int { mutable count: int = 0; immutable amount: int = 2; count += amount; return count - 2;}TSG-703 Write the type unless the value makes it obvious
RecommendedNo tool checks this yet
Turf can work out a variable’s type from its starting value. Let it do that when the value is a plain literal and the type is obvious at a glance (mut count = 0;). Write the type when the value comes from a call, a calculation or a conversion, because then the reader would have to go and look it up.
fn ratio(a: int, b: int): double { return (a to double) / (b to double);}fn main(): int { mut attempts = 0; immut share: double = ratio(1, 4); attempts++; printline(share); return 0;}fn ratio(a: int, b: int): double { return (a to double) / (b to double);}fn main(): int { mut attempts: guess = 0; immut share = ratio(1, 4); attempts++; printline(share); return 0;}TSG-704 Use the short forms for counting
RecommendedNo tool checks this yet
Write i++ to add one and total += price to add an amount, rather than i = i + 1 and total = total + price. The short form names the variable once, so it cannot be misspelled on one side.
fn main(): int { mut count: int = 0; mut total: int = 0; count++; total += 15; return total - count - 14;}fn main(): int { mut count: int = 0; mut total: int = 0; count = count + 1; total = total + 15; return total - count - 14;}TSG-705 Count with for, not while
RecommendedNo tool checks this yet
When a loop counts through a range of numbers, write for i in 0..n. The start, the end and the step are all on one line, and there is no counter to forget to increase. Keep while for loops that run until something happens.
fn main(): int { mut sum: int = 0; for i in 0..5 { sum += i; } printline(sum); return 0;}fn main(): int { mut sum: int = 0; mut i: int = 0; while i < 5 { sum += i; i++; } printline(sum); return 0;}TSG-706 One give / otherwise per expression
RecommendedNo tool checks this yet
condition give a otherwise b is perfect for a quick choice between two values. Chaining several in one line makes the reader keep a stack of conditions in their head. For three or more outcomes, use if / elseif or compare.
fn label(n: int): string { if n > 10 { return "big"; } elseif n > 5 { return "medium"; } return "small";}fn main(): int { immut n: int = 7; immut parity: string = n % 2 == 0 give "even" otherwise "odd"; printline(label(n) + " and " + parity); return 0;}fn main(): int { immut n: int = 7; immut size: string = n > 10 give "big" otherwise n > 5 give "medium" otherwise "small"; printline(size); return 0;}TSG-707 Name every variant when you compare an enum
RecommendedNo tool checks this yet
When you compare an enum or a machine, give each variant its own arm and leave otherwise out. Turf then checks that every variant is covered (E093). The day someone adds a new variant, the compiler points at every compare that needs a new arm. An otherwise would quietly swallow the new variant instead.
enum Light { Red, Amber, Green }fn action(l: Light): string { compare l { matches Light::Red: return "stop"; done matches Light::Amber: return "wait"; done matches Light::Green: return "go"; done } return "";}fn main(): int { printline(action(Light::Amber)); return 0;}enum Light { Red, Amber, Green }fn action(l: Light): string { compare l { matches Light::Red: return "stop"; done otherwise: return "go"; } return "";}fn main(): int { printline(action(Light::Amber)); return 0;}TSG-708 Keep main short
RecommendedNo tool checks this yet
main should read like a table of contents: set things up, call the functions that do the work, and return. Move the work itself into well-named functions, and into modules once a file gets long.