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.
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.