Skip to main content

Proposals for adding method support to Java?

26 replies [Last post]
coxcu
Offline
Joined: 2003-06-11

Hi,

Near the end of this presentation Graham Hamilton discusses the possibility of adding method support to Java for Dolphin.

The Next Releases of the Java Platform by Graham Hamilton
See 35. Many other Dolphin candidates...
http://wiki.javapolis.com/confluence/display/JP05/The+next+releases+of+Java

Does anybody have any information about what options are being considered? Would anybody like to share a proposal?

Thanks,
Curt

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
leouser
Offline
Joined: 2005-12-12

one reason I would want the method to be tied to a specific class is that you operate with the method's contract, not just the method itself.

because methods share a name and a list of parameters doesn't tell us what its contract is. You need that information to do sensible programming.

That doesn't preclude using higher level classes in my mind. So instead of needing to do stuff like:
ArrayList.iterator you could have the reference be
List.iterator.

My guess is your (int, int, int) may be a way to deal with which method is being referenced.

method Thing.doSomthingImportant(int, int, int) a = AThing.doSomethingImportant;

I suppose that would be enough information for the compiler to determine which method is being referenced. Since so much info is in the reference, maybe just having the object would do to get the method:
method Thing.doSomethingImportant(int, int, int) a = AThing;

then Id hope the calling the method would be a simple manner of:
a(1,2,3);
//probably need some way of controlling what was called in this situation if there was a conflicting method called 'a'. You could force it to use 'this', in this case.

I suppose you could drop the method keyword, or would that confuse the reader into thinking he was reading a method declaration?

Thing.doSomethingImportant(int, int, int) a = AThing;

hmm, this is kinda fun isn't it? :D
leouser

rizzix
Offline
Joined: 2004-08-21

i.c. So you want it tied to denote a constraint, something similar to Haskell's => notation?

In that case.. lets revert back to my example for a second here..

(int, int):int min = Math.min;

Here we can assume if no constraint is explicitly specified then, it's of type Object. By this I mean, the above is actually:

Object.(int, int):int min = Math.min;

So your iterator example could be written as:

List.(void):Iterator it = ArrayList.iterator;

leouser
Offline
Joined: 2005-12-12

if I'm reading your line right:
(int,int) expresses parameters
List expresses parent interface
:Iterator expresses a return type of Iterator

this though is still vague in the face of an interface that has multiple methods that take the same parameters and return the same type. If Im passed a method like:

Thing.(int):void

I have almost no idea what the method name is. Which leaves me clueless as to what Im calling. Thing could have lots of methods like this. I fear that not being able to peruse what the method name is without resorting to reflective voodoo will hurt its usage. Im not going to like the feature if to feel confortable using it I always have to do stuff like this:
void something(Thing(int):void a){
if(a.getName().equals("doit")){

}

leouser

rizzix
Offline
Joined: 2004-08-21

Do you realise that what you are asking for is really the equivalent of C's typedef (but specialised for methods) and not really references?

rizzix
Offline
Joined: 2004-08-21

nvm i see what you mean.. =/ Although i got to say, it's very limiting.. There's a whole lot of stuff yout cannot do if you fix the method names.

On the other hand why would you care which method is called?

Consider: if you require a method that returns an interator, does it really matter that the method given is an overriden version of List.iterator specifically? I don't see the point.

Message was edited by: rizzix

leouser
Offline
Joined: 2005-12-12

I care because I compose my functionality out of contracts, not out off a series of vague method calls.

I found myself wondering last night after outlining stuff Id like to know with a method reference, what the heck would be the gain for me? If I want all the stuff why not just pass in a regular reference to an object? Im fairly convinced that one of the reasons people like java is that you can look at some code and get a good bearing on what is happening.

If I saw a sequence of calls to method references that with just this info:
(int, int):int a;
(String, String):void b;
(Runnable):void c;

If Im handed this things in my parameter list, how the heck am I to know what is even happening?

ughh...
int x = a(1,2); //I wonder what x refers to?
b("I Hope this works", "whats this param do");
c()//I guess I should call this...

what did I just do!?! :D

leouser

leouser

leouser
Offline
Joined: 2005-12-12

one idea Ive played with today is to try simplifying the creation of interfaces for listeners with annotations and dynamic proxies.

The idea Ive looked at is:

say you have a method with this signature:
public void doSomething(MouseEvent me){

}

if I add this simple annotation:
@Intent(class=MouseListener.class, methodname="mousePressed")
public void doSomething(MouseEvent me)

and pass it to a factory method:
generateProxy(Object o)

your able to use the annotation info to generate a proxy and have it map mousePressed on MouseListener to doSomething.

The rules are simple:
1. The parameter list of the doSomething method must match the targeted proxy method.

So I guess a sequence of the whole shebang is:
@Intent(class=MouseListener.class, methodname="mousePressed")
public void doSomething(MouseEvent me){}

public static void main(String ... args){

SomethingParent sp = new SomethingParent();
MouseListener ml = (MouseListener)Proxier.generateProxy(sp);
JButton jb = new JButton("Hi!");
jb.addMouseListener(ml);

}

------
I haven't decided if I like this yet. :D

leouser

soupdragon
Offline
Joined: 2006-01-07

>Neither does it
> overlap in functionality with anonymous inner
> classes.

Can you name anything you could do with delegates that you can't do with inner classes? Nor can I see any reason why an anonymous class instance should be less efficeint that a delegate. Both require a definition to be loaded. Both involve a heap object. Both need to contain a reference to the primary function and must manipulate the call stack to put that address together with the parameters passed.

And such a class is just as capable of invoking either static or instance methods.

> Use an Anonymous Inner class when you want
> to transfer "state" along with "actions" and use
> these Functions when you only want to transfer
> "actions".
>

Why have two constructs when one will do?

leouser
Offline
Joined: 2005-12-12

I have to agree with soupdragon, don't cruft up the language so you can have 10 ways of expressing things.

After dorking around with annotations/Proxy for targeting methods and listeners I found myself saying, the machinery for doing simplified listener creation appears to be here in this one instance. I assume there are going to be other ways of simplyfing besides my little experiment. Those avenues should be explored before reaching for language extensions.

leouser

mpocock
Offline
Joined: 2006-02-13

I guess we need to show that a) adding method references doesn't break Java type-safety, b) adding extra syntax for it increases clarity and c) it is actually useful.

Type-safe method references can be fully simulated using little invoke/lambda interfaces, which could be implemented by inner classes. This shows that adding method references doesn't make Java less type-safe than it is already, and makes it more type-safe than using bare Method instances.

A clean syntax for manipulating type-safe method references would drastically reduce the obfuciation of code that relies upon reflection, particularly when a Method, or an instance of invoke/lambda needs to be aquired and then passed through.

There are inumerable ways that these things could be useful. Let's just chose factory methods. When implementing design patterns, the concrete name of the classes and methods are decided by the circumstances. Java allows us to abstract over the class name, but not the method name. So if Factory.makeInstance() was the general plan, we could have WigetFactory.makeInstance() but not WigetFactory.makeWigetInstance(), which is anoying. A generalised client to Factory would be unable to discover that makeWigetInstance() was the method it should be invoking on a WigetFactory. Using method references, we could rewrite the client as:


invokeFactoryMethod(
FACTORY f,
FACTORY.():BUILDS makeInstance)
{
return makeInstance.invoke(f);
}

Assuming there are some @Annotation guys for marking up factories, then we could implement the WigetFactory as:

public class WigetFactory
{
@FactoryMethod
public Wiget makeWiget() { ... }

@FactoryMethod
public Wiget makeSpongle() { ... }
}

Then, later on in the end-user code:

WigetFactory wf = new WigetFactory();
for( WigetFactory.():Wiget fMeth : Factories.findFactoryMethods()
{
Wiget w = Factories.invokeFactoryMethod(wf, fMeth);
}

Agreed - it's overkill in this case where we statically know the type of WigetFactory and friends, but in large, dynamically agregated applications, it is common not to know anything about WigetFactory when writing the code to manipulate it - the interactions are at the level of patterns. First-class method references give us one more powerful tool for pattern-level application development.

soupdragon
Offline
Joined: 2006-01-07

>
>This shows that adding
> method references doesn't make Java less type-safe
> than it is already, and makes it more type-safe than
> using bare Method instances.

I don't thing there's and dispute that delegates for instance methods and method pointer for static could be made type-safe.

>
> A clean syntax for manipulating type-safe method
> references would drastically reduce the obfuciation
> of code that relies upon reflection, particularly
> when a Method, or an instance of invoke/lambda needs
> to be aquired and then passed through.

I thing very little code needs to rely on reflection as it is.

Personally my hobby-horse extension wish is for some kind of class template that provided a contract for static methods and constructors the way an interface does for instance methods, that would, to my mind, eleminate most of the remaining need for reflection.

>
> There are inumerable ways that these things could be
> useful. Let's just chose factory methods. When
> implementing design patterns, the concrete name of
> the classes and methods are decided by the
> circumstances.

I believe this is called "programming", which I realise some people regard as rather old-fashioned.

>Java allows us to abstract over the
> class name, but not the method name. So if
> Factory.makeInstance() was the general plan, we could
> have WigetFactory.makeInstance() but not
> WigetFactory.makeWigetInstance(), which is anoying.

Just about every factory class used in a factory/interface application has a different set of required parameters etc.

>
>
> invokeFactoryMethod(
> FACTORY f,
> FACTORY.():BUILDS makeInstance)
> {
> return makeInstance.invoke(f);
> }

And you thing this is clearer and simpler?

mpocock
Offline
Joined: 2006-02-13

> >
> > invokeFactoryMethod(
> > FACTORY f,
> > FACTORY.():BUILDS makeInstance)
> > {
> > return makeInstance.invoke(f);
> > }
>
> And you thing this is clearer and simpler?

This code lives in a library. The tradeoffs for developing re-usable library code vs disposable user code are very different. The library code opens the possibility of the end-user writing

Wiget w = Factories.makeWithFactory(new WigetFactory());
Bobbin b = Factories.makeWithFactory(new BobbinFactory());

This is obviously more clear than the alternative. Inside the library, first-class methods as outlined above make this sort of thing both introspectable and type-safe.

soupdragon
Offline
Joined: 2006-01-07

As far as I'm concerned anyonymous classes make the delegate concept completly redundant. What's the difference between a class creating a delegate on one of it's fuctions and createing an anomymous class instance that defines a method which [i]calls[/i] that method?

leouser
Offline
Joined: 2005-12-12

My next questions before trying to evaluate this is:
1. What's a good syntax for expressing a Method Reference
2. How does a Method Reference affect the reference to the parent widget? Does it up the reference count by 1 or does it function not in this manner? Similiar to that I find myself wondering how much clarity will be sacrificed by having references to Methods... how would you tell who the parent object is?

I know in python that you can pass methods around and such.

Say in jython you can do this:
a = swing.JButton("Hi")
a.actionPerformed = self.methodThatPrintsHi

methodThatPrintsHi would be a method in this case. I think you can use functions as well. When I did Tk programming, the passing of a function was the way to do it.

leouser

coxcu
Offline
Joined: 2003-06-11

Since Java already has method references, I'm guessing that a more typesafe way of constructing them is being considered.
http://java.sun.com/j2se/1.5.0/docs/api/java/lang/reflect/Method.html

There are several methods on java.lang.Class like this one:
http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Class.html#getDeclaredMethod(java.lang.String,%20java.lang.Class...)

So, code like this is already quite possible:

Method method = null;
try {
method =
Foo.class.getDeclaredMethod("setBar",Bar.class);
} catch (NoSuchMethodException nsme) {
// do whatever
} catch (SecurityException se) {
// do whatever
}

Whether or not the exceptions will be thrown can often be determined at compile time, which would enable something like this:

Method method = Foo.setBar(Bar bar);

I have no information if this bears any relation to what is being considered. I just would like to know what is being considered. Perhaps this already published somewhere. If so, I'm asking for a pointer. If not, I'm suggesting it should be published.

If you go read Neal Gafter's blog, you may come to the same conclusion that I did. It can be really hard to get community support for the final product even if you're relatively open all the way. The sooner Sun can involve the community the better.
http://gafter.blogspot.com/

ryandse
Offline
Joined: 2005-09-06

Assuming such is even necessary, here is how I propose adding function pointer (a.k.a. delegate) support to Java:

Say that we would like to have "fptr" be a function pointer to the method MyClass.staticMethod(int x, int y):

MyClass.staticMethod() fptr;

Now fptr(1, 1) would be equivalent to MyClass.staticMethod(1,1)

Another Example:

myInstance.method() fptr;

fptr() would be equivalent to myInstance.method().

Now for a more interesting variation:

given: interface foo {
public boolean bar();
}

We could do this:

foo.bar() fptr = new foo() {
public boolean bar() {
return true;
}
}

which would allow us to invoke fptr() (instead of ftpr.bar()).

The definition above would allow us to do the following:

foo.bar() fptr2 = fptr;
fptr3.bar() fptr2;

One final consequence of this syntax is the following:

foo.bar() fptr4;
fptr4; <<-- Would throw NullFunctionPointer Exception
since foo.bar() has no implementation.

As far as I can see, this syntax should not create any inconsistencies with the language, as the Java language presently contains no valid mapping for " ". Furthermore, the JVM can make this happen simply by replacing these function-pointers with the actual method calls (which may or may not be calls into anonymous classes).

So, for those of you who are arguing "But Java already supports function pointers via anonymous classes!": I agree completely. What I have shown here is that function pointers could be implemented simply as "syntactic sugar" and compliment Java's anonymous class support.

As far as the question of whether such an addition is really necessary or not, is concerned: Well, I leave that up to the pragmatists and idealists to argue amongst themselves.

Ryan

rizzix
Offline
Joined: 2004-08-21

Not only does this make things safer (type-safe), it makes things more efficient (since most of the type checking is done at compile time). Also this makes Java functions, first-class entities (to some extent), which basically means we can do a whole lot of cool stuff that was not efficiently possible before.

Hint: functionalj.sf.net

And NO, this does not make things more complicated, in fact it makes coding simpler. Neither does it overlap in functionality with anonymous inner classes. Use an Anonymous Inner class when you want to transfer "state" along with "actions" and use these Functions when you only want to transfer "actions".

Now all that's missing are Tuples and multiple dispatching functions (methods). It would make OO development a whole lot easier, and not to mention a whole lot more fun.

leouser
Offline
Joined: 2005-12-12

one concern I have at this moment is that if you have a method reference how will you be able to tell what it is? Obviously you will need a special type for it, but I hope it wont be something as generic as Object.

The gizmo Im envisioning is something like:
method List.iterator li = //somehow get the method reference

this is more verbose than regular declarations, but how else can you convey everything you'd want to know?

thoughts folks?
leouser

leouser
Offline
Joined: 2005-12-12

hmmm, one problem with this:

method List.iterator it =//get a method reference somehow

is that it doesn't make overloading clear. If we have 2+ methods that are iterator in some sense, which of those does it call? One potentially, screwy, way of dealing with this is having the overload determined at call time, so method references could function as some form of pointer to groups of functions. yeash... :D

leouser

rizzix
Offline
Joined: 2004-08-21

Why should the method be tied to a specific class?

Why not..:

(void):Iterator it = List.iterator;

where (void):Iterator denotes a method that takes no arguements and returns an Iterator. =/

similarly..

(int, int):int min = Math.min;

"min" takes two int's as arguments and returns an int.

I dunno.. i guess it's just a possibility..

rizzix
Offline
Joined: 2004-08-21

I guess its best to not leave it half baked.. So we need anonymous method/functions,, aka lamda expressions or closures..

(int, int):int add = (int a, int b):int {return a + b;};

now... get rid of the semi-colon if it's the only statemen t and add a little type inferrencing to make it cleaner:

(int, int):int add = (int a, int b) -> {return a + b};

probably even better written as:

(int, int):int add = (int a, b) -> {a + b};

(if only one statment, return is implied)
where (int a, b) is a tuple of two int's... the -> is an inject/binding operator. any tuple bound to a block is basically an anonymous method notation.. :P

ok so maybe i'm taking this too far.. but to whatever reasonable level this can be implemented and in which ever manner.. we'd appreciate it.. right? :)

Message was edited by: rizzix

fabriziogiudici
Offline
Joined: 2006-01-04

I second soupdragon, we already have anonymous inner classes. If you want you can use introspection too.

I seriously hope that Sun is not going to add method pointers, as Java started it out as a thing that threw away all the unneeded, cluttering and hard-to-control features of C++, but as time goes on it is re-adding them, one by one... :-(

leouser
Offline
Joined: 2005-12-12

It certainly is possible to write a more enhanced version of Method in Java already. I put some classes together over in the Collab project that essentially makes it simple have a Runnable(or Callable) call a method without having to define a new Runnable each time you want to execute a method on say the EDT Thread for example. I suppose another class could be created from the base class and just act as an EnhancedMethod, or a MethodReference class. So I think it is possible already to build machinery out of what exists without adding stuff to the language.

I guess a disadvantage of the reflective class approach is that you probably will get a better compiler check if it was part of the language.

leouser

leouser
Offline
Joined: 2005-12-12

allright, Im intrigued. What do you mean by adding method support to Java? :)

leouser

coxcu
Offline
Joined: 2003-06-11

The presentation talks about some sort of langauge support for method references. The stated motivation is to make it easier to write GUI event handlers, although it is easy to see how just about any language construct added for such a purpose could have other uses.

So, this might mean something like delegates. No matter what it means, I would like to know what options Sun is looking at. I have some ideas about what I would like to see, but I would rather see what Sun is considering than subject everyone to my half-baked proposals.

About Microsoft's "Delegates"
http://java.sun.com/docs/white/delegates.html

The Truth About Delegates
http://msdn.microsoft.com/vjsharp/productinfo/visualj/visualj6/technical...

A Java Programmer Looks at C# Delegates
http://www.onjava.com/pub/a/onjava/2003/05/21/delegates.html

Strongly Typed Java Delegates
http://weblogs.java.net/blog/alexwinston/archive/2005/04/strongly_types_...

jwenting
Offline
Joined: 2003-12-02

oh yes, add function pointers to Java!
Makes it SOOOOO much simpler to understand what you're working with, NOT!