4 ms·
The typo had to do with accidentally naming a variable in a let binding to the same name as a built-in function. It happily compiled but when that code actually
by hellofunk 10y ago
The typo had to do with accidentally naming a variable in a let binding to the same name as a built-in function. It happily compiled but when that code actually ran in one particular use-case, it crashed due to the way the binding and the scoping worked in that case.
- kazinator 10y ago> accidentally naming a variable in a let binding to the same name as a built-in function. Not even a problem in a Lisp-2 like ANSI CL! (let ((list '(1 2))) (list list list)) -> ((1 2) (1 2)) Facepalm. We could argue you were burned by the stupid Lisp-1 namespacing. Under the separate function and variable namespace of a Lisp-2, you would have to bind a local function in order to shadow a global one. Even without a compiler, we can implement a warning for this. The code walker which expands macros is aware of lexical environments and can issue diagnostics when suspicious-looking shadowing is going on, or unbound variables are referenced and such. Not only is this not the fault of the language being dynamic, but the problem could exist in a static language, like, oh, C: #define DECLARE_MY_PRINTF int (*printf)(const char *, ...) = my_printf; { DECLARE_MY_PRINTF: printf("hello, %s\n", "world"); // goes to my_printf via shadowing local var } ISO C does not require a diagnostic for this. Gcc has -Wshadow. ISTR -Wshadow is not turned on by -Wall or -Wextra; you have to use it explicitly. Of course, the above depends on the local printf pointer actually having the right type so that the call is well-formed. If we just have "int printf" or whatever, the type system will catch it.