SUBMISSION : A second look on "named parameters"

Reinier Zwitserloot reinier at zwitserloot.com
Sat Apr 18 17:14:16 PDT 2009


Your proposal is very incomplete. Three major nits:


A. Did I miss something, or did you totally forget to include an  
example of calling a method with named parameters? Something like:

doLogin(user: "foobar", password: new char[] { 'a', 'b', 'c' });

B. Why static? You might as well have picked 'strictfp' - it's a total  
non-sequitur choice. Re-use of existing keywords is not really a  
panacea; it waters down the anchoring ability of a keyword to  
virtually nothing. I'm not sure if context-sensitive keywords are any  
better, but java7 is already going to have at least one ('module'), so  
don't beat around the bush and just call it 'named'). Could be just  
me, but introducing a change which is not backwards compatible IF you  
have a type that's called 'named' (written just like that, all-lower  
case), is not something I find troublesome in the least. That's very  
ugly code, and a migration tool can fix this easily.

C. You don't mention having default values for parameters, which is  
sort of the point of this exercise (otherwise you really still need  
builders  ; any method that has so many parameters that they need  
names probably needs a builder, and without defaults, not providing  
one and instead relying on named params is just an inferior bandaid to  
your ugly API; to get it right you STILL need to provide a builder.  
If, however, parameters can have defaults, then you no longer need to  
make builders at all).

I suggest you look over the coin-dev mailing list; I entered a rough  
sketch of a named parameters proposal near the end of coin. I never  
wrote it up because I thought of it far too close to the deadline, and  
it's still of such high impact that I doubt it would pass muster for  
coin.


  --Reinier Zwitserloot



On Apr 19, 2009, at 00:15, Jean-Baptiste Bugeaud wrote:

> Hi everybody,
>
> Here is an late submission, sorry I missed the initial deadline. If
> you think (as I do) that this is a key small change for lots of
> improvement, maybe there is still a very small gap to go for JDK7;-)
>
> A proposition including the same goal was introduced in JDK6 JSR but
> withdawn in final version. So legacy impact, issues ... should be
> already well known by the JDK core team. This second look has tried to
> solve all the problems.
>
> Let's go ....
>
> Author(s): Jean-Baptiste BUGEAUD, Paris, France
>
> OVERVIEW :
>  FEATURE SUMMARY : Introduce named parameter on methods into the  
> language
>  MAJOR ADVANTAGE : Integration with the legacy, fully backward
> compatible. Clear paradigm separation.
>  MAJOR BENEFIT : Consistent way of naming the parameter help to unify
> existing APIs, remove boiler plate core thus simplify object
> marshaling and reflection usage (WS, JMX, EJB ...).
>  MAJOR DISADVANTAGE : Semantic of static keyword on parameter might
> not be clear for beginers
>  ALTERNATIVES : Usage of existing bytecode handling lib can expose
> the parameter names already, but this leads to dependency [5][6] and
> potential security issues. Usage of APT[7] to store parameter names
> constraint to a prequirement : apply it to all the code you target.
> This is unlikely to happen for JARS you have not created, thus
> reducing the potential benefits.
>
> EXAMPLE
>
> SIMPLE EXAMPLE :
>
> (1a) :
>
> class OrderManager{
> public void order(String product, int amount){
>  // do the login
> }
> }
>
> (1b)
>
> class OrderManager{
> public void order(static String product, static int amount){
>  // do the login
> }
> }
>
> (2a)
> void displayOrderCriteria(){
> Method[] methods = OrderManager.class.getMedthods();
> for (Method m : methods){
>  System.out.println("To call :"+m);
>  for(String n : m.getParameterNames[]){
>   System.out.println("\tYou must provide :"+n);
>  }
> }
> }
>
> (2b)
> void displayOrderCriteria(){
> Method[] methods = OrderManager.class.getMedthods();
> for (Method m : methods){
>  System.out.println("To call :"+m);
>  for(String n : m.getStaticParameterNames[]){
>   System.out.println("\tYou must provide :"+n);
>  }
> }
> }
>
> ADVANCED EXAMPLE :
>
> (3.1)
> package java.lang.annotation
>
> @Documented
> @Retention(value = RetentionPolicy.SOURCE)
> @Target( { ElementType.METHOD, ElementType.ANNOTATION_TYPE })
> public @interface StaticParameterNames {
> };
>
> (3.2)
>
> @Retention(value = RetentionPolicy.RUNTIME)
> @Target( { ElementType.METHOD })
> @Inside(WebService.class)
> @ValidWebOperation
> @StaticParameterNames
> public @interface WebMethod {
> String operationName() default "";
> String action() default "";
> };
>
>
> (3.3)
>
> @WebService
> class LoginManager{
> @WebMethod public void doLogin(String user, char[] password){
>  // simply log the user
> }
> }
>
> DETAILS
>
> SPECIFICATION :
>
> Historicaly, method's parameter names can be stored in the Java
> bytecode using appropriate compiler switch [2]. Although, no standard
> API is available to benefit from them they aready. But when compiler
> optimisation is set or an obfuscater is enabled, then are no more
> available. This is not reliable.
>
> Such inconsistency, along with some other problems, have prevented the
> inclusion for JDK6 of previous proposition [3][4].
>
> This proposition of small language change, introduce named parameter
> on methods into the language thru the add of a new language paradigm :
> static named parameter. At source level, this new kind of parameter is
> simply a regular parameter with the modifier static set on it.
>
> As a summary, we will get two kind of parameters in the language :
> - regular named parameter (see method on (1a)) : the legacy, we "keep
> the good-old way", parameter might be stored in bytecode depending on
> compiler option, no change on language/semantic/compilation
> - static named parameter (see method on (1b)) : a regular named
> parameter with a static modifier added, whatever happens (compiler
> option, obfuscator, etc) parameter name will always be kept at
> bytecode level.
>
> At Java API level, on java.lang.reflec.Method, two new method will
> help API implementer to leverage both kind of parameters.
> - String[] getParameterNames()
> - String[] getParameterStaticNames()
>
> IDE would be most interrested into calling the first one. But API
> implementer (such as JAXWS for instance) requiring a consistent
> behavior could rely on the second. But they could downgrade on the
> first one for legacy JAR if they wish so.
>
> Introduction of an annotation StaticParameterNames could also be
> leverage by API implementer to include automatic parameter name
> storage. This one alone will ease lots of library code. For instance,
> in JAXWS (see example 3.3), WebParam are now optional to get a web
> service working : WebMethod would be enough as long as JAXWS
> implementer apply StaticParameterNames on the WebMethod annotation
> (see example 3.2).
>
> COMPILATION :
>
> Static named parameters are compiled the same way of regular named
> ones but with addition of the static modifier set on the reference at
> the bytecode level and the parameter name parameter kept in the table.
> No compiler/optimizer/obfuscator should remove/change the parameter
> names at bytecode level on a static named parameter.
>
> Thus, at a higher level, although not taking part of the method
> signature (and call resolution), the static named parameter could now
> be seen as part of the method contract: changing a static named
> parameter's name could have the same impact as renaming a method. This
> is the developper resposability to analyze impact of such a change.
>
> If a method is tagged with the annotation (or an inherited annotation)
> StaticParameterNames, all its method parameter should be compiled as
> if they were static named parameters.
>
> TESTING :
>
> Compile test classes (such as examples 1a & 1b) using compiler with
> the feature enable with and without optimization enable (the one that
> remove the parameter names on regular named parameters).
>
> For each scenario (with & without optimization) :
> Call the reflection API for listing regular named parameters, and
> check according to the names that should be returned as per the test
> class.
> Call the reflection API for listing static named parameters, and check
> according to the names that should be returned as per the test class.
>
> LIBRARY SUPPORT :
>
> Two methods must be added to java.lang.relfect.Method :
>
> String[] getParameterNames()
>
> List the parameter names as existing in the bytecode. No guaranty of
> reliability is made : can be renamed, removed, added, ...
> Array is of the same size of getParameterTypes(), for a given index,
> if the corresponding name is not found a null value is returned.
>
> String[] getParameterStaticNames()
>
> List the static parameter names as existing in the bytecode. Those
> named are reliable. Any change impact the contract.
> Array is of the same size of getParameterTypes(), for a given index,
> if the corresponding parameter is not tagged with static modifier, a
> null value is returned.
>
>
> StaticParameterNames (see example 3.1) annotation must be introduced
> to indicate to the compiler all parameters of a tagged method are
> meant to be static nammed parameters although not tagged with the
> static modifier. This anotation can tag other annotation.
>
>
> OTHER CHANGES:
>
> Any existing API willing to benefit from this feature, could inherit
> from StaticParameterNames but this is out of scope of this proposal.
>
> COMPATIBILITY
>
> MIGRATION :
> Manual migration is done adding static modifier on parameters.
> Automatic migration could be done by APIs leader using the
> StaticParameterNames annotation, thus all the existing code base would
> be migrated at the next build automatically.
>
>
> COMPATIBILITY :
>
> BREAKING CHANGES: no, this is the reason of using static modifier.
> EXISTING PROGRAMS: code using legacy class can benefit from the
> getParameterNames(). But getParameterStaticNames() will always return
> an array of null values.
>
>
> REFERENCES
>
> EXISTING BUGS
>
> http://bugs.sun.com/view_bug.do?bug_id=6444738
>
> URL FOR PROTOTYPE
>
> None at this time. Early feasibility check in the native VM coden plus
> pure Java code is feasible [5].
>
>
> [1] http://paulhammant.com/blog/parameter-names-for-java6- 
> question.html
> [2] http://java.sun.com/j2se/1.4.2/docs/tooldocs/windows/javac.html
> [3] http://weblogs.java.net/blog/mreinhold/archive/2005/12/mustang_release.html
> [4] http://blogs.sun.com/mr/entry/java_se_6_public_review
> [5] http://paranamer.codehaus.org/
> [6] http://www.jroller.com/eu/entry/using_asm_to_read_mathod
> [7] http://weblogs.java.net/blog/emcmanus/archive/2006/06/using_annotatio.html
>




More information about the coin-dev mailing list