E08110: reassignment not allowed of an incoming argument/parameter
What went wrong
You're trying to REASSIGN a function or method parameter (':=', ':=?' or ':'). A parameter's BINDING cannot be reassigned: the name always refers to the object the caller passed in, and rebinding it to another object is not allowed. That is all this error says - the parameter is NOT read-only.
Worked examples
Compilable examples demonstrating this error and the correct fix:
- ek9 -q 737 (Why does EK9 reject reassignment in pure functions and pa...)
- ek9 -q 2000 (If a parameter cannot be reassigned, is it read-only? How...)
Rationale
Only REASSIGNMENT of the binding is banned. In non-pure code the object a parameter refers to can be mutated in place - a mutating operator such as '+=' or ':=:', or a method like 'list.add(x)' - and the caller sees the change. It can also be aliased ('alias <- counter') and the alias reassigned. Here 'counter += 1' is allowed, and the caller's Integer is one higher afterwards; 'counter := 0' would be this error:
bump() -> counter as Integer //Allowed: the caller's Integer is now one higher counter += 1
Read-only is what 'pure' provides: a pure function or method cannot mutate or reassign (E08100, E08120), and pure code may call only pure code (E08130), so the guarantee carries through everything it calls.
How to fix it
- Declare a local and work on that (the first fix in the [EXAMPLE] section below gives a fallback to a new variable). A local declared from the parameter shares the caller's object, so mutating it still changes the caller's; declare it from a copy ('Integer(counter)') when the caller must not see the change
- Return the new value through the returning variable instead
- If the caller SHOULD see the change, mutate in place ('+=', a copy into it, a merge into it) rather than reassign
- If the caller must be sure nothing changes, mark the function or method 'as pure'
Common causes
- Treating a parameter as a local variable
- Expecting reassignment to hand a new value back to the caller
- Reading E08110 as "parameters are read-only" (only 'pure' gives that)
See also
Examples
Every example is compiled by the EK9 compiler: the first fails exactly as captioned, the others fix it.
Fails with E08110: reassignment not allowed of an incoming argument/parameter
#!ek9 defines module error.e08110.bad defines function greet() -> name as String <- rtn as String? name :=? "friend" rtn: "Hello " + name
Fixed: Give the fallback to a new variable
#!ek9 defines module error.e08110.good defines function greet() -> name as String <- rtn as String? who <- name ?: "friend" rtn: "Hello " + who
Fixed: Mutate the caller's object in place - only rebinding the name is refused
#!ek9 defines module error.e08110.good.mutated defines function bump() -> counter as Integer //Allowed: the caller's Integer is now one higher counter += 1 defines program Count() stdout <- Stdout() tally <- 41 bump(tally) stdout.println($tally)
Questions and answers
These Q&A entries show E08110 and its fix: