Paul Prescod <[EMAIL PROTECTED]> writes:
> Gavin Sherry wrote:
> >
> >..
> >
> > By introducing another layer of abstraction we will most probably decrease
> > the performance of all languages[1].
>
> Some bindings require high performance and some don't. Python's binding
> to Tk still goes through intepreter Tcl strings and complaints about the
> performance are few and far between. Sure, your Oracle driver is going
> to be language-native, but your binding to some weirdo OODBMS might be
> shared and jointly developed with someone interested in another
> language. Given the choice of using a loose, low-performance binding and
> none at all, you might choose the loose binding.
>
> And if the loose binding was easy enough to implement, the PHP-Sablotron
> programmer might just decide to implement both the native binding and
> the loose binding just to be nice.
>
> I'll include a strawman but keep in mind that this is a very rough first
> cut. I use some C++ language features to keep it syntactically simpler
> than using plain structs and function pointers but that's just for
> expository purposes. A cross-lang API would have to be ANSI C.
I certainly agree that most bindings can be expressed fairly well
in a cross-language fashion, and that a way of doing so could
be extremely valuable without being extremely complex. But I'm not sure
that it could be quite as simple as your strawman.
The prominent characteristics of your interface seem to be:
A) Simplicity of implementation: everything is completely portable simple
C function calls.
B) Common subset - the exposed language features are
ones that are found in almost any language.
C) All typing is dynamic
If you don't mind, let me attack those three points in sequence :-)
A) The success of such an interface is completely in how widely
it is adopted. If it is widely adopted, people won't mind
spending a few days implementing a binding onto their
language, since they will save vastly more time in writing
individual bindings.
While simplicity is certainly one big factor in gaining
adoption, if the solution is too slow or not sufficiently
expressive, all the simplicity in the world doesn't do
any good.
B) It's important to make everything possible to express in some
way, but the smaller set of features you expose, the less
natural the bindings become. Some examples:
- If you don't expose exceptions, then you can't use the
language's native exception-handling facilities, and
the programmer sees error codes.
- If you don't expose structures, then all structures
must be represented as objects, which prevents efficient
remoting.
- If you don't have events/callbacks, then you can't
uses closures / anonymous functions for callbacks
if a language has them.
Clearly, you have to choose where to draw the line ... maybe
callbacks is going to far. But languages have sets of idioms
that go far beyond what is expressely in the language -
every language will have _some_ way of expressing an
exception, a structure, or a callback. And if you omit
these from your type system, then you lose the ability
to map to the language's native idiom.
C) While dynamic typing is a wonderful thing at times, I don't
think it is appropriate for an inter-language interface.
- It excludes statically typed languages from participating.
- Static type information is important for coercing between
different type systems.
In Perl, there is essentially no difference at all between "1" and 1
as far as a programmer is concerned (**). But this is not the case in Python.
So, if I make a call foo("1") in Perl, and foo() is a python function,
the translation layer need information about whether foo() takes
an integer or a string.
While writing down a competing header file is more than I can
do here, basically I'd want to:
- Use something similar to the CORBA set of types
- Package the interface for a library/component together with
the library/component as a "typelib".
- Use either:
a) platform native C++ ABI
or:
b) an efficient in-memory marshaled form.
for invoking methods
Regards,
Owen