harn-parser 0.10.22

Parser, AST, and type checker for the Harn programming language
Documentation
# HARN-LNT-066 — the result of a pure collection method is discarded

A `list` / `dict` / `set` / `string` method was called as a statement and its
result thrown away, so the call has no effect at all.

Every method on Harn's built-in collections is **pure**. They are persistent,
copy-on-write values: `push` clones the receiver, appends, and returns a *new*
list. It never modifies the receiver.

```harn
const l = []
l.push(1)      // error[HARN-LNT-066]: no effect — `l` is still []
l.push(2)      // error[HARN-LNT-066]
// l == []
```

This reads as a mutation to anyone arriving from Python, JavaScript, or Ruby,
where `push`/`append` modify the list in place. In Harn it is dead code, and
without this diagnostic it is invisible: the program typechecks cleanly, runs
without error, and quietly builds an empty list.

## How to fix

Assign the result back. Because the binding's value changes, it must be `let`
rather than `const` (see the binding rule in the language spec — `const` means
this binding's value never changes):

```harn
let l = []
l = l.push(1)
l = l.push(2)
// l == [1, 2]
```

When building a collection in a loop, the same shape applies:

```harn
let out = []
for item in items {
  out = out.push(transform(item))
}
```

To call a method purely for a side effect inside it — which only a closure
argument can produce — the result is not discarded in the same sense, and this
lint does not fire. Prefer a `for` loop over `map` when you want effects.

## When it does not fire

- The tail expression of a value-producing block (a closure body, `match` arm,
  `if`/`else` branch, `try`, or `block { … }`), where the value *is* the
  block's result rather than a discarded statement.
- A call taking a closure argument (`items.map({ item -> … })`), which may
  perform effects and so is not provably inert.
- A receiver rooted at `harness`, whose methods exist for their effects.
- A method name the file also declares in an `impl` block, which may be a
  user-defined method with effects of its own.