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/
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.