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)