Lowent Manual←↑→

Appendix C — Common mistakes and how to fix them

These are the places people often trip when writing Lowent with habits from other languages. The meanings of diagnostic codes are in Appendix B, and explanations are in the chapters named in the tables.

The surface#

MistakeDiagnosticFix
Writing output before inputE-CLAUSE-ORDERFollow the clause order table. Clauses other than inputs are moved by --fmt (chapter 3)
Opening a block with a period or line break, as in struct p .E-STMT-NODOstruct p do … end (--fmt fixes it)
Closing with ; or ,E-VOCAB-REMOVEDThe detached period .
Reading a field with p.xE-FIELD-GLUEDfield p x
for x in xsE-VOCAB-REMOVEDfor x xs do … end
let x f64 be .5 .E-LET-NOVALUE0.5
Naming a local the same as a parameterE-NAME-SHADOWPick a new name
Using names like count, text or lenE-NAME-BUILTIN and othersBuiltins and heredoc words cannot be names
A module name equal to an op nameE-NAME-DUPRename the module
expr a lt b and b lt cE-TYPE-LOGICALexpr (a lt b) and (b lt c) (chapter 8)
type pct be u8 .E-TYPE-DECLtype pct u8 .

Table 50.1 — Mistakes on the surface

Values and flow#

MistakeDiagnosticFix
set on a letE-IMMUTABLEMake it with var
Using an integer as a conditionE-TYPE-CONDWrite the question, as in gt n 0
Expecting overflow to wrap as in CE-VM-OVERFLOW (at run time)Choose the outcome with wrap_add, sat_add or chk_add
Expecting narrow u8 x to truncateE-VM-CAST (at run time)narrow_wrap, narrow_sat, narrow_try
guard’s else does not leaveE-GUARD-FALLTHROUGHreturn, break, continue, panic, or use if
No return on some pathE-RETURN-PARTIALReturn on every path
Using if as a valueE-IF-VALUEMake a var and set it in each branch
Missing cases in matchE-MATCH-INEXHAUSTIVEThe missing case or case _ .
Writing enum variants one per line without periodsE-ENUM-DOTred . for each variant
Extracting with some_value without checkingE-VM-NONE (at run time)guard is_some · value_or · match
array u8 4E-TYPE-ARRAYarray 4 u8

Table 50.2 — Mistakes with values and flow

Effects, capabilities and memory#

MistakeDiagnosticFix
Printing from a fnE-EFFECT-CALCproc with effects io
Writing effects none on a fnE-EFFECT-REDUNDANTDelete the clause
A fn writing to the caller through a mut parameterE-EFFECT-PURITYMake it a proc
effects io without receiving a capabilityE-EFFECT-NO-CAPinput out cap io .
Receiving a capability but not passing it to the builtinE-CAP-MISSINGAs the first operand, as in write_out out 1 …
The entry point receiving dataE-ENTRY-PARAMSThe entry point receives only capabilities. Arguments via cap args
Writing to a slice without mutE-TYPE-MUTmut slice
Writing through refE-TYPE-REFmut_ref
Borrowing the same value for writing twiceE-EXCLSplit the borrows or split the order
Returning a reference to a localE-ESCAPEReturn a value or store it in the caller’s storage
mut ref sliceE-MREF-SLICEReturn a new slice
Carrying a region’s bytes outsideE-REGION-ESCAPEWiden the region or carry out only values
Not closing a file or bufferE-OWN-INCOMPLETECall close or finish. To discard, drop
Using a moved value againE-OWN-MOVEDUse it before handing over, or get it back
Using the heap on a target without an operating systemE-HEAP-NOHOSTA fixed window (cap allocator) and alloc

Table 50.3 — Mistakes with effects, capabilities and memory

Abstraction and concurrency#

MistakeDiagnosticFix
Writing fn or proc in a trait signatureE-TRAIT-SIGarea input s self . output u64 .
Satisfying a pure signature with a proc without an effects lineE-TRAIT-EFFECTUse fn, or write effects
A type argument not satisfying the traitE-BOUND-UNSATAdd satisfies and the op
Giving a run-time value where comptime is requiredE-COMPTIME-ARGA literal or module constant
spawn <op> outside a task_groupE-SPAWN-SCOPEWrap it in task_group do … end
Writing an accumulator in a split loopE-PAR-CARRYreduce <place> <op> .
Using a stage like sorting in pipeE-PIPE-STAGEUse only the seven stages and five terminals
Calling an effectful attached op with method inside a fn(not rejected in this edition)Call it directly as <type>.<name> (chapter 23)

Table 50.4 — Mistakes with abstraction and concurrency