I'm happy to announce the first release of the First Class Methods (FCM) java prototype. This prototype anyone who is interested to find out what FCM really feels like.
Standard disclaimer: This software is released on a best-efforts basis. It is not Java. It has not passed the Java Compatibility Testing Kit. Having said that, in theory no existing programs should be broken. Just don't go relying on code compiled with this prototype for anything other than experimentation!
FCM javac implementation
The FCM javac implementation is hosted at Kijaro. The javac version used as a baseline is OpenJDK (the last version before the Mercurial cutover).
The prototype includes the following features:
- Method literals
- Constructor literals
- Field literals
- Static method references
- Bound method references
- Constructor references
- Anonymous inner methods
The following are not implemented:
- Method types
- Instance method references
- Named inner methods
- Inner method non-final local variable access
- Inner method exception inference
- Inner method exception/completion transparancy
- Conversion to single abstract method classes
The download includes a README with many FAQs answered, including more information on how the types work.
The biggest outstanding area is getting generics working properly. This is a complex task however, and I took the view that it was better to release early than spend any more time trying to get generics working properly.
Nevertheless, even without full generics, you can get a really good feel for how Java would look and feel with FCM. In addition, the FCM enabled code just falls off my fingers very nicely. Now if only we could get Eclipse or Netbeans support...
Summary
One of the key requests for considering FCM as a viable proposal has been having a prototype to play with. Now the prototype is out there, it would be really great to hear some feedback, including any bugs. Comments welcome here, at kijaro-dev mailing list or scolebourne-joda-org.
I'll send crashes and programs that don't compile directly to you, but please help me out here: I could not figure out how to get exception transparency or completion transparency working. Also, the prototype does not appear to allow an inner method to access a non-final variable.
ReplyDeleteStephen:
ReplyDeleteWRT the code falling off your fingers nicely, I guess you don't have a Mac with a UK keyboard then - # is not the easiest character to type ;-)
Good to have prototypes of BGGA, CICE and FCM available though. Bug reports on their way shortly...
Also, I'd really recommend looking into using jtreg for your tests (if you haven't already) - it's very useful.
Great, good job.
ReplyDeleteI hope to be able to test it soon.
I'll do the jtreg tests like I did for Remi's property implementation, and hope to have time to integrate the bound method reference with property.
@Neal: Is it possible to have a link to the source code of BGGA prototype? It will be nice to integrate different language proposals together to see how they fit.
Anyway, Let's play ;-)
Just a question:
ReplyDeletehave you considered another syntax for methods like what is already used in C or C++? Something like this one (looks more natural to me):
ref = &JButton.setPressed;
Neal: All three items are on the 'not implemented yet' list.
ReplyDelete88.70.83.241: Having used C very little, I don't find myself constrained by its syntax. Nevertheless, your syntax would probably be a valid alternative.
Cool, i will try testing the implementation. And hey, JSR-310 needs some TLC too!
ReplyDeleteThat C syntax is very nice. I was looking for an alternative to # myself. Despite the use of it in Javadoc, I can't think of any other language in which the # is an actual operator. The & seems much more natural, and having it at the beginning of the expression is much more indicitive, imo, of the intention.
ReplyDeletei also liked the & symbol.
ReplyDeleteSemantics. The # is actually closer than &, after pressing shift. Neither compares to the awesome that is . since that doesn't need two key to type.
ReplyDeleteHow about using '\' ?
ReplyDeleteAn updated version 2008-02-25 is now available with a few bug fixes.
ReplyDeleteHi Stephen!
ReplyDeleteDo inner methods only support single method interfaces? Is this likely to change later?
Thanks
kodeninja
Great,
ReplyDeleteas for me, i think i will be able to release an updated spec and prototype of the properties in one or two weeks.
Rémi
kodeninja: Yes, currently only single method interfaces are supported. Do you want method/function types? Or Single abstract method classes?
ReplyDeleteRemi: Thats good to hear!
Are there any plans for an example library using FCM? (i.e. something like the fork-join library with bgga http://www.javac.info/jsr166z/jsr166z/forkjoin/package-summary.html)
ReplyDeleteGregory: This proposal is usable with the fork-join library as is. Oh - except that generics don't work properly yet, so you'll find things very limiting...
ReplyDeleteYou can't get a function pointer in C/C++ by using the address-of (&) operator. You simply mention its name. For instance:
ReplyDelete/* Declare the type of pointers to functions with the signature "int main(int argc, char* argv[])" */
typedef int (*FPMAIN) (int argc, char *argv[]);
/* Declare a variable that can get a function reference" */
FPMAIN fpmain;
/* Assign the reference to the "main" function to the "fpmain" variable */
fpmain = main; // there's no "&" operator here.
/* Call the "main" function using its reference - C syntax */
char *argv[] = {"argument 1", "argument 2"};
(*fpmain) (10, argv);
/* Call the "main" function using its reference - alternative C++ syntax */
fpmain (10, argv);
I prefer using the # operator instead of the & operator to get function references - if you are inspired by C/C++, don't be mislead by the "&" operator.
I'm still getting verify errors for the simplest programs.
ReplyDeletepublic class Test5 {
interface Block {
int invoke();
}
public static void main(String[] args) throws Exception {
Integer j;
Block[] a = new Block[10];
for (int i = 0; i<10; i++) {
j = i;
a[i] = j#intValue();
}
for (int i = 0; i<10; i++) {
if (i != a[i].invoke()) throw new AssertionError(a[i].invoke());
}
}
}