July 2019, rev. September 2019

I have a testcase where the IR generated for indirect assignment without GC and no syntax generates a bad error message.

The root cause is that the left-hand-side used in indirect assignment must be able to accept more than one parameter, even if this is a semantic error for some variables. Indirect assignment must defer catching errors.

Example:

(= v (list 1 2 3))
(= (v 1 2) 7)

Using (v 1 2) here is a semantic error because it uses more than one index to access a list. It would be useful to generate a correct error message:

(error "parameter count mismatch in indirect set" (= (v 1 2) 7))

The reason not to generate this error message is that passing more than one parameter in indirect assignment can be valid for other expressions. In such cases the error message would be confusing instead of useful. Indirect assignment must allow at compile-time for an expression that looks similar but is semantically different:

(= somefn (fn (a b c) (list a b c)))
(= ((somefn 10 20 30) 1) 200)

Using (somefn 10 20 30) here isn't a semantic error. It's a valid function call that returns a list. The outermost object of the left-hand-side in indirect assignment can be expressed as a list instead of an atom — expressed as the outermost object (somefn 10 20 30) in the left-hand-side ((somefn 10 20 30) 1) instead of the atom v in (v 1 2) — and as a list it must be able to accept more than one parameter. Here it accepts three: 10 20 30. Whereas the atom v should accept only one parameter instead of two: only 1 instead of 1 2.

This example reduces to (= 20 200) which leads to a different type of run-time error. It would be useful to generate the correct error message for it at run-time:

(error "can't reassign primitive type" (= ((somefn 10 20 30) 1) 200))

But to be able to show this type of error message, the previous type of error message shouldn't be shown. (= (v 1 2) 7) shows the same, slightly confusing error message:

(error "can't reassign primitive type" (= (v 1 2) 7))

To fix this, when this type of ambiguous error is detected, inspect the source code at run-time to show the right error message.