This article gives examples of some mysterious error messages, how they arise, and what they mean. Hopefully this can save some debugging time.
Usually Arc doesn't provide any indication of where the error occurred. In the cases where Arc does provide location information, the location is a byte offset, not a line number, which is hard to interpret:
arc> (load "t.arc")
Error: "t.arc::720: read: expected a ')'"
If you're loading a file, how do you find byte offset 720? One way is dd if=t.arc bs=1 skip=720
which will display the file from the 720th character onward.
Similar errors can be generated from REPL input. In this case, the unexpected parenthesis is at character 910 that's been typed to the REPL (although that's unlikely to be useful):
arc> )
Error: "UNKNOWN::910: read: unexpected ')'"
arc> (def foo (x) (prn x))
#<procedure: foo>
arc> (foo 1 2)
Error: "procedure foo: expects 1 argument, given 2: 1 2"
This error message is straightforward - too many arguments were given to the procedure..
arc> (def (bar (x) (prn x)))
Error: "#<procedure>: expects at least 2 arguments, given 1: (bar (x . nil) (prn x . nil) . nil)"
In this case, the expected arguments error is more mysterious. Misplaced parentheses generate this error from the depths of the interpreter.
arc> (+ 1 ("s"))
Error: "car: expects argument of type <pair>; given ()"
You probably have extra parentheses, attempting to index into a string. For a number, the error message is much clearer:
arc> (+ 1 (42))
Error: "Function call on inappropriate object 42 ()"
arc> (def foo (a (b c)) (prn a))
arc> (foo 1 2)
Error: "car: expects argument of type <pair>; given 2"
Destructuring bind fails because argument format doesn't match function definition.
arc> (def f (o x (table)) (prn x))
arc> (f 42)
Error: "car: expects argument of type <pair>; given ()"
You need two sets of parentheses in the def
, one around the arguments, and one around the optional argument:
arc> (def f ((o x (table))) (prn x))
arc> (+ 1 "s")
Error: "+: expects type as 2nd argument, given: \"s\"; other arguments were: 1"
Straightforward: wrong type to +
.
(= t 42)
Error: "Can't rebind t"
The atoms t
and nil
can't be changed. Don't use t
as a variable.
arc> (map (prn) '(a b c))
Error: "Function call on inappropriate object nil (a)"
You need to pass a function to map
, such as prn
or [prn _]
rather than (prn)
arc> (car "abc")
Error: "Can't take car of \"abc\""
Car
and cdr
don't work on strings. You'll also get this error if the function erroneously uses car
on a string internally:
arc> (counts "abc")
Error: "Can't take car of \"abc\""
arc> (with a 4 (+ a 1)) Error: "Can't take cdr of a"The mysterious "can't take cdr" error shows up if you don't have parentheses around the variable assignments. You may be thinking of
let
, which doesn't use the parentheses and assigns a single variable.
Let me know if you have any other candidates for mystery errors.