Linux Today: Linux News On Internet Time.
Search Linux Today
Linux News Sections:  Developer -  High Performance -  Infrastructure -  IT Management -  Security -  Storage -
Linux Today Navigation
LT Home
Contribute
Contribute
Link to Us
Linux Jobs


More on LinuxToday


Minotaur for Perl, Python, and Tcl

Jul 10, 1999, 08:41 (0 Talkback[s])

By Jean-Claude Wippler, as posted to comp.lang.python. (Thanks to Rajiv for the tip)

This is the first public announcement of a generalized extension which lets you run Python scripts from Tcl, or Tcl from Perl, or any of the other combinations.

Minotaur works by loading the appropriate shared library into another script language's context. So, for example, running Tcl from Python means that the Python main program imports the Minotaur extension, which in turn loads the Tcl libraries - thus Tcl becomes "embedded" into the Python runtime environment (which is similar to embedding Tcl in a normal C program). As involved as that sounds, performance is already surprisingly good, and the capability is turning out to be quite useful.

Minotaur 0.1 is an alpha level release, meaning: it works, aside from a few quirks (see below), and bugs, but its API and implementation might still change in incompatible ways in future releases.

An example, embedding a Tcl script in Python:

        import Minotaur
        Minotaur.initTcl()
        print Minotaur.Tcl("expr {1111 + 2222}")
        Minotaur.Tcl("""
            set result "Tcl version [info patchlevel]"
            Python "result = '$result'"
        """)
        print result

As you can see, a value is returned either directly (only if it's an integer), or by using a reverse embedding, i.e. executing a Python statement from the embedded Tcl system. Also, this shows how tricky quoting could get once you start mixing languages in this manner. And last but not least, note that the different language contexts are separate: the two "result" variables used above are not related in any way (one for Tcl, one for Python). Also, Minotaur does not yet let you share data, it merely lets you evaluate scripts (and copy things).

Now the gotcha's, quite a list of them right now:

  • You need shared libraries to use Minotaur. Standard installations, especially of Perl and Python, do not always include these. The Minotaur homepage has some info on rebuilds you might need to do.
  • Tcl/Python can call Perl but to get results back, I had to introduce a secondary shared library, dynamically bound to the Perl runtime.
  • There is currently no other interface than evaluating a single string. Passing int/string/whatever args efficiently is planned for later.
  • The Minotaur extension has only been tested for Linux and Windows, but is built in a way which should also work on the Mac, and on all Unix systems, even those which do not support back-linking in shared libs.
  • Minotaur uses some global data; it's not yet re-entrant / thread-safe. As a matter of fact, Minotaur is still totally ignorant of threads.
  • I have not yet succeeded in getting Minotaur working on the Mac, and ran into problems when trying to launch Tk from Python (Win/Linux).
  • The current release does not include any Minotaur binaries, you may have to do quite a bit of tweaking to get this stuff to work for you. One of my plans is to substantially simplify deployment of all this.

And here's the fun part of things:

  • Minotaur uses Forth as low-level "super-glue" language. This offers the ability to deal with all the inevitable "impedance mismatches" which will occur when crossing widely different software designs. Also, this can be done without compilation (and often portably).
  • Timing tests indicate that the overhead of calling through Minotaur is very low, when the necessary symbol lookups are done in advance. The C-based Forth in here uses pForth, and includes quite a bit of standard ("ANS") Forth for now, though this may change in the future.
  • The Minotaur extension is loadable from Perl, Python, and Tcl, 'cause it exports initialization calls for each of them. This is essential, since the embedded language needs to reopen the extension to gain access to the same Forth context as the one which loaded it (this is how each embedded language can call back into its parent context).
  • Forth primitives have been defined which can open, lookup, and locate routines exported from shared libraries. Due to the flexibility and performance of Forth, everything else needed to embed one language in the other is done in Forth, i.e. at run time. Forth has no idea that it is being used to tie scripting languages together, for example.
  • Minotaur, and these shared library access functions have been tested on Linux, Windows, and Mac (partially). The Forth code needed to implement such language bindings differs only in pathnames, so far.
  • But this is only the tip of the iceberg, really. Proof-of-concept bindings have also been created for Java, MS COM, Lua, ICI, and PHP.

Minotaur is a spinoff of my long-term "TinyScript" project and is open source, with a BSD-style license (do whatever you like with it, just leave the copyright attributions intact, and don't sue me). Minotaur was written to see how far one could go in bringing scripting worlds together, and to help me tie my own extensions into a range of languages without having to write a whole range of interfaces. It hasn't met this goal yet, but my hope is that it will be of use to others and that a number of language experts will extend and improve the mechanism so it works well with all of them.

Minotaur has sort of a homepage here:
http://mini.net/pub/ts2/minotaur.html

A mirror copy of my working area is being tracked here:
http://mini.net/pub/ts2/ (a.k.a. ftp://mini.net/pub/ts2/)

And a snapshots of the whole area was recently created as:
http://mini.net/pub/ts2-19990704.tar.gz

There is no documentation, release 0.1 is a "use the source Luke" kind of project, but if you would like to try this out - or better still: participate in whatever way you like - feel free to subscribe to the Minotaur mailing list, by sending an email to minotaur-add@mini.net. There are a handful of subscribers now, with just a few outbursts of discussions of where to take this, so far. Which, at this stage, is still a very open-ended question, IMO.

Comments, suggestions, praise, but especially offering to help with whetever aspect of Minotaur you'd like to improve are most welcome. Language and platform bashing - yawn - will be redirected to /dev/null. If you wish to help lower language barriers, so that more code can be re-used, more interfacing problems can be solved, and perhaps one day even generic extensions can be written which serve multiple contexts, please have a look at Minotaur and consider helping to make it happen.

One interesting option, would be to create a binding in SWIG which generates the low-level glue to Forth, as well as language-specific wrappers. The key advantage is that this could let SWIG be used entirely as a run-time tool, with no compiler/compilation in sight (assuming the target library exists in shared library form, that is).

-- Jean-Claude Wippler (jcw@equi4.com)