Let’s find out what other languages have by way of run-time evaluation and exception handling.
The Tcl interpreter
follows the typical shell syntax: each statement is a command
followed by a bunch of arguments. If the command is known at
compile-time, it generates byte-codes and executes it subsequently,
but if it is a variable, the interpreter waits until run-time to
compile and execute that statement. (Earlier versions of Tcl always
treated the program as strings and parsed a statement every time it
was hit, even if it was within a loop. As this book goes to press,
the Tcl interpreter has just recently taken some steps toward
becoming a byte-code interpreter.) Tcl supports a user-level
eval
call, which recursively calls the parser and
interprets the contents of the string as a command followed by a
bunch of parameters.
For error handling, Tcl provides the error
and
catch
statements, equivalent to
die
and eval
in Perl.
Python’s
eval
function allows a string to be evaluated and
executed, but the string cannot contain newlines. An
exec
statement allows newlines, but since Python
relies on leading whitespace instead of an explicit block structure,
it is important that you get the whitespace correct in a dynamically
constructed string to be given to exec
. This is
quite a bit more painful than getting the block scoping right in
Perl.
Python goes through a compilation and execution stage similar to Perl, and for every module called module.py, it stores the intermediate byte codes in a file called module.pyc. The next time the module is used, the intermediate byte code file is automatically picked up. Perl is likely to see this kind of facility in the near future, considering that Malcolm Beattie’s Perl compiler is in the alpha stage as of this writing.
For exception handling, Python supports the notion of exception
classes as part of the language, like Java and C++. You raise
exceptions with raise
and trap them with a
try
/except
/finally
syntax. (try
and except
are
equivalent to the eval
BLOCK
form. The finally
keyword indicates a default
except
block that is invoked if none of the other
except
statements is able to trap the exception.)
I especially like how the interpreter and the Python library make
consistent use of this facility.
There is no run-time evaluation, but there are a number of public domain and commercial interpreters that can be linked in with your C application to support C or C++-like interpreted languages. Look for C-Interp or XCoral in the free compilers list available from http://www.idiom.com/free-compilers.
C has no keywords for exception handling. C++ has a
try/catch/throw
syntax identical to Java’s.
Exceptions can be user-defined objects and can have their own private
data as well as behavior.
Java goes through the same two phases
as Perl: (1) compilation to an intermediate byte-code form, and (2)
execution of this intermediate code. What it doesn’t allow,
however, is the production and evaluation of new code
on the fly. There is really no reason why this isn’t
technically feasible, because the javac
compiler
itself is written in Java, and it should be possible to package it as
a library instead of a standalone program without violating new
security constraints.
For error handling, Java has a try/catch
syntax
that is equivalent to the eval BLOCK
approach in
Perl, in that all the code is known at compile-time. Exceptions are
true first-class objects in Java, so you can discriminate between
them much better than the string comparison required in Perl. Java
has the throw
keyword to raise a user-defined
exception, similar to Perl’s die
.
Java does strict type-checking and requires that a function enumerate the exceptions it might throw (this is considered part of the signature of the function). So if you call a function that throws an exception, Java either requires your function to either not rethrow it or, if you want to pass it on, you have to include that exception as part of your function’s signature. This way, when you see a function, you know the exact list of exceptions you have to deal with, which is very important for big applications written by a team of people. Depending on your viewpoint, Perl doesn’t have any such feature or restriction.