Hyde

Hyde is a package for the JTcl Interpreter (and Jacl) that allows for easy Tcl-to-Java integration, for instances where the JTcl java package is insufficient. Hyde is similar in concept to critcl - Java code is compiled on-the-fly. Three primary interfaces are available:

  • hyde::jproc simple Java methods, made available as a Tcl procedure
  • hyde::jcommand JTcl command procedures
  • hyde::jclass arbitrary Java classes

For each case, Java is code is compiled on-the-fly via one of several Java compilers. The default Java compiler is Janino [1 ], which is included in the JTcl distribution (and is also used for the TJC compiler.)

Here is an example of using hyde::jproc:

 ::hyde::jproc int fibHyde {int n} {
     if (n <= 0) {return 0;}
     if (n ==  1) {return 1;}
     return (fibHyde(n-1) + fibHyde(n-2));
 }

 puts "computing fibonacci [fibHyde 22]"

Notice that a return type is coded, as well as types for procedure parameters, and the body of the jproc is Java code. This will generate a Java class with a static method, which is defined as a Tcl procedure.

Hyde can be used where speed in necessary. Here are simple benchmark results compared with a pure Tcl version, and a Tcl version compiled with TJC (results on a AMD64 3200+):

Tcl version:

 proc fibJacl {n} {
     if {$n <= 0} {return 0}
     if {$n == 1} {return 1}
     set n1 [incr n -1]
     set n2 [incr n -1]
     return [expr {[fibJacl $n1] + [fibJacl $n2]}]
 }

The TJC compiled version is named fibTJC, but is simply the fibJacl version. The JVM was allowed to warm-up, by executing a number of iteratiosn before actual timing.

 timing 10 interations (fibonacci 22).....
 time Jacl (interpreter) : fibJacl 22: 8344100 microseconds per iteration
 time Jacl (TJC compiled): fibTJC  22: 67300 microseconds per iteration
 time Hyde (Java)         : fibHyde 22: 400 microseconds per iteration

hyde::jcommand is used to define new Tcl commands, using all of the facilities of the JTcl programming interface [2 ]. Here is a simple example that sets the interpreter result:

 ::hyde::jcommand helloworld -body {
        interp.setResult("hello world");
 }

 puts "helloworld = [helloworld]"

The hyde::jclass command has several Java code generation modes, which can create Java bean properties along with getters and setters for each property. Other code generation includes equals(), hashCode(), and toString() methods. In addition, any arbitrary Java class can be coded.

Here is an example of building a Java bean, with an extra method for validation:

 ::hyde::jclass Employee -import java.util.Date -properties {
       {int id -1}
       {String name}
       {Date hireDate}
 } -tostring * -hashequals * -body {
       public boolean isValid() {
             if (id == -1 || name == null || hireDate == null) {
                   return false;
             } else {
                   return true;
             }
       }
 }

 set emp1 [java::new hyde.Employee]
 $emp1 setId 86
 $emp1 setName "Maxwell Smart"
 $emp1 set_hireDate [java::new java.util.Date]
 puts "employee [$emp1 get_id] isValid? [$emp1 isValid]"

Notice that class properties can either be accessed as getXxxx / setXxxx (Java bean style), or get_xxxx / set_xxxx (for easy Tcl access where property names are lowercase).

Hyde is currently available in the JTcl Interpreter distribution.

Hyde is used in the MrPersister database library to build Java objects to match table or result set definitions. Also see Using javamail in jacl for an example of using the Java Mail API with Hyde.

The manual page for Hyde is at [3 ].