I was trying out 8.5a5 thinking that it's new compiled
switch feature would improve Tcl's detection of syntax
errors in switch arms, but instead found not only
is it unchanged, but that the basic error detection of
"if" is now gone. For example the following script
causes 8.3 and 8.4 to barf, but is perfectly legal
in 8.5:
proc bar var {
if {$var == "acorn"} {
set a b c
}
}
bar a
Ditto for
proc bar var {
if {$var == "acorn"} {
set a [b c
}
}
The "no errors til you execute it" policy means
you need nearly perfect code coverage testing
to use Tcl with any confidence.
Logged In: YES
user_id=79902
Because you can do some horrible hacks like this now:
rename if if_
proc if args {
foreach a $args {puts $a}
}
bar var
rename if {}
rename if_ if
OK, that's rather odd code, but it's legal. If you want
static syntax checking, use a third-party tool like Nagelfar.
Logged In: YES
user_id=190660
Wonderful, Tcl will have even less checking.
Any idea how hard it would be to optionally
disable this lazy compile?
Logged In: YES
user_id=190660
Originator: YES
I understand a little better now whats going on.
Compilation is not being deferred but rather errors are
being ignored.
The main change seems to be in TclCompileScript() which
no longer provides a return code.
I looked at the two simple test cases in 8.5a5 and in both
cases it is TclCompileScript() that is ignoring the compile
errors.
(Case 1):
# set a [badcall c
Line 1006:
if (Tcl_ParseCommand(interp, p, bytesLeft, 0, &parse) !=
TCL_OK)
Just compiles a returnCmd which the invocation chain
ignores. This is a syntax error which I think should be
reported.
(Case 2):
# set a b c
Line 1183:
code = (cmdPtr->compileProc)(interp, &parse, envPtr);
...
/* Restore numCommands and codeNext to their ... */
Not sure what's the goal here. If you just wanted to
redefine 'if' you can do that in 8.4 so long as 'proc if' is
defined before this code is compiled.
Oh, and Donal I think your code example is invalid.
Did you mean:
if bar var
Also, static code checkers aren't really an option. On
the second module I tried them on, frink core dumped and
nagelfar generated an error for every 10th line of code.
Logged In: YES
user_id=190660
Right. But we could already do that as long as 'proc if' is define before compiling bar. eg. the following works
in 8.3:
proc bar var {
if {$var == "acorn"} {
set a b c
}
}
catch {bar acorn}
rename if if_
proc if args {
foreach a $args {puts $a}
}
bar var
rename if {}
rename if_ if
I wonder if you didn't mean the following (which
also works in 8.3)?
proc bar var {
if {$var == "acorn"} {
set a b c
}
}
catch {bar acorn}
rename set set_
proc set args {
foreach a $args {puts $a}
}
bar acorn
rename set {}
rename set_ set
Logged In: YES
user_id=80530
> # set a [badcall c
> Just compiles a returnCmd which the invocation chain
> ignores.
No, it compiles to bytecode that reports the
syntax error at runtime.
Logged In: YES
user_id=190660
Hence: no errors till you execute it.
Logged In: YES
user_id=148712
Originator: NO
This is per design. Tcl's has string interpretation semantics, the bytecompiler has to respect that. Tcl8.5 has fixed a number of bugs in that area.
If we checked for syntax errors you couldn't run the following "perfectly valid" code. Tcl8.4 will return an error, which is a bug.
proc foo bar {
if {$bar == 0} {
set a [badcall c
} else {
set a $bar
}
}
foo 1 ;# returns 1
proc if args {return $args}
foo 0
Not arguing that you would *want* to run code like that, only that a string interpretation language will run it.