Re: [Java] Function Binding Redux (long post)
John Moeller <[email protected]>
| Newsgroups | gmane.comp.lib.boost.langbinding |
|---|---|
| Message-ID | <[email protected]> |
David Abrahams wrote:
> on Fri Jul 20 2007, John Moeller <fishcorn-AT-gmail.com> wrote:
>
>> 2a. Generate a Java source file where the methods wrap the function
>> dispatcher.
>>
>> Not entirely appealing, because it's a build-time solution, not a
>> runtime solution.
>
> Not necessarily. If Java can compile and load source files
> dynamically (it can, can't it?), I don't see any reason why you can't
> generate this source file on demand at runtime. I guess that's where
> the "special class loader" you meantion below would come in.
It can only load and link classes dynamically. The source is compiled
to bytecode as a separate build step.
> [snip]
>
> I don't know what you mean, or anything about what's involved here.
> That's not a criticism; I'm just letting you know I'm not even a Java
> n00b, much less an Xpert.
That's fine, you're an expert in plenty else. :) Here was where I was
hoping that Rene or his business partner would weigh in (when they had
time, of course).
>> ...
>> API. It's pretty gross. If the class can implement an
>> interface though, (I'm referring to the Java kind of
>> interface), then you could just cast it, because a class can
>> implement an interface that's already been loaded by another
>> class loader with no problem.
>
> I don't see how the "implement an interface" thing helps you very
> much. You'd still need to generate Java code for the interface,
> right?
Right, but not necessarily in the context of the classes that you are
using. As I'm sure you know, a Java "interface" is essentially just a
pure virtual base class. Because of that abstraction, you can
polymorphically use a class that you generate that implements the
interface. It doesn't matter *how* you load the class or define it.
So you can use the interface to help protect yourself from the vagaries
of class loading, implementation, the Reflection API, etc. That's
mostly what I was getting at.
>> ...
>> I thought of another alternative. If we're willing to compromise on
>> natural syntax,
>
> I don't recommend that.
Ok, this is where I wanted your (Dave's) input. That is, I wanted to
know how far I could push the usage model. Say I had a Langbinding
class definition (C++):
class_<X>("X") [
def("isFoo", &X::isFoo),
def("getBar", &X::getBar)
];
In Python, it's straightforward to *use* it naturally, i.e. (and you'll
have to forgive me, I don't speak Python):
X x;
if (x.isFoo())
return x.getBar("stuff");
Whereas in Java, it would require some gymnastics and/or extra
installation (both on the client's part) to get such a thing to compile.
The alternative is to use a wrapper API or Reflection.
>> [snip]
>> WrappedClass x = new WrappedClass("X");
>> Runnable r = x.asInterface(Runnable.class, ctorArg1, ctorArg2);
>>
>> new Thread(r).start();
>
> Is this just a compromise on the construction syntax, or something
> more/worse?
If you had an interface FooBarable defined as:
public interface FooBarable {
public boolean isFoo();
public Object getBar(String request);
}
[Note: I'm assuming here that FooBarable is an interface *not*
generated by Langbinding; that the client creates this interface or uses
another provided by a library because it matches a subset of the method
interface of X, which the client must be familiar with to use X in the
first place. I'm beginning to suspect that I didn't communicate this
clearly.]
In Java code, you could "inform" the Java backend of Langbinding that X
really did implement FooBarable, and get an X as an instance of the
class. This would prompt the internals of the Java backend to crank out
a bytecode representation of X that implemented FooBarable:
Class XClass = WrappedClass.asInterface(FooBarable, "X");
FooBarable fb = WrappedClass.construct(XClass, ca1, ca2);
if (fb.isFoo())
return fb.getBar("stuff");
So, getting to your question, it would be a compromise of the
construction syntax, but probably no more. Additionally, Java
programmers are generally used to "interface programming."
As for iterator/collection support, I was thinking of offering an
interface that just hotwired the iterators into a Java Collection. That
way, it could be used with a "foreach" loop in Java. This could be done
without the aforementioned user gymnastics, as Collection is an
interface provided by the Java API.
However, not all of the binding "goodies" available in Python or Lua are
available in Java. As an example, overriding field/property access as
you do in Boost.Python would be impossible in a Java binding. You'd
have to settle for getters/setters. I was going to bring this issue up
in a different post, though.
--
John Moeller
[email protected]
-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems? Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/