# V0016 keyword_binder

URL: /docs/errors/V0016
Markdown: /docs/errors/V0016.md

> A parameter, a lambda parameter, a let or var name or a pattern binding is named error (design §17.297 (2)).

An error from the `parse` phase. `sakura explain V0016` prints this explanation offline.

A parameter, a lambda parameter, a `let` or `var` name or a pattern binding is named `error`
(design §17.297 (2)). `error` is a keyword: it names a field (`{ error: String }`, `r.error`)
and declares an error tag at item position, but a body cannot refer to a binding by that name,
because `error` in an expression is still the keyword. Choose another name.

Wrong:

```sakura
fn describe(error: String) -> String { "failed: {error}" }
```

Fixed:

```sakura
fn describe(reason: String) -> String { "failed: {reason}" }
```

## Wrong program [#wrong-program]

[`compiler/tests/ui/V0016_keyword_binder.sak`](https://github.com/icantcodefyi/sakuralang/blob/main/compiler/tests/ui/V0016_keyword_binder.sak), which the compiler's ui suite runs through `sakura check`:

```sakura
// `error` is a field name, so the lexer reads it as a name before `:`; as a binding it would
// parse with no way to use it (a use in a body is still the keyword), so a parameter, a lambda
// parameter, a `let` pattern and a `var` named `error` are each one `V0016`. A field named
// `error` stays valid.
pub fn describe(error: String) -> Int { 1 }

pub fn handlers() -> Int {
  let f = fn(error: Int) { 2 }
  let error: Int = 3
  var error: Int = 4
  f(0)
}

pub type View = { error: String }

pub fn read(v: View) -> String { v.error }
```

`sakura check --json` reports this record (pretty-printed; `$DIR` is the fixture's directory):

```json
{
  "schema_version": "1.0",
  "kind": "diagnostic",
  "id": "d:4bf5b04fe313e629",
  "code": "V0016",
  "severity": "error",
  "phase": "parse",
  "message": "`error` is a keyword: it names a field, not a binding; choose another name",
  "snapshot": "sha256:$SNAPSHOT",
  "symbol_id": "main::V0016_keyword_binder::describe",
  "spans": [
    {
      "uri": "file://$DIR/V0016_keyword_binder.sak",
      "content_hash": "sha256:1cbf0c2efb7ff407cddf66b907197a175b12ae879265607626ea6bd0415fe838",
      "start_byte": 445,
      "end_byte": 450,
      "role": "primary"
    }
  ],
  "related_ids": [],
  "expected": null,
  "actual": null,
  "obligation": null,
  "counterexample": null,
  "explanation_uri": "sakura://explain/V0016",
  "fixes": []
}
```

## Fixed program [#fixed-program]

[`compiler/tests/ui/V0016_keyword_binder.fixed.sak`](https://github.com/icantcodefyi/sakuralang/blob/main/compiler/tests/ui/V0016_keyword_binder.fixed.sak), which `sakura check` accepts with no diagnostics:

```sakura
pub fn describe(reason: String) -> Int { String.len(reason) }

pub fn handlers() -> Int {
  let f = fn(code: Int) { code + 2 }
  let failure: Int = 3
  var count: Int = 4
  count = count + failure
  f(count)
}

pub type View = { error: String }

pub fn read(v: View) -> String { v.error }
```
