SUBMISSION : A second look on "named parameters" / Clarification on the scope
Joseph D. Darcy
Joe.Darcy at Sun.COM
Tue Apr 21 08:36:56 PDT 2009
A few notes on this topic.
Support for retrieving parameter names was removed from the feature list
of JDK 6; there was never any working code to implement this feature.
Implementing this functionality would be nontrivial, for coordination
reasons if no others. Names are stored in the class file at certain
debugging levels. However, there is no Java-level API to return that
information. A new (small) VM interface would need to be written to
retrieve and pass on this information to the libraries. Unconditionally
storing parameter names all the time is unattractive because the names
would take up space. Yes, some people do care about the sizes of their
jar files, (like rt.jar :-), and adding such information that in many
cases would be little used or ignore is not desirable. A further
technical wrinkle, the number of parameters in the source code and the
number of parameters in the class file sometimes disagree, with the
class file having more (outer this parameter for some nested class
constructors, implicit ordinal parameters for enum constructors) and
there is currently no reliable data in the class file to determine
whether or not a parameter is synthetic. For example, constructors for
anonymous classes appearing in a static context, like a static
initializer block, do not need to have an enclosing instance parameter.
These are certainly solvable technical problems, but someone needs to
solve them.
The parameter names are useful when interfacing Java to other language
environments that like sql use nominal rather than position parameter
passing. However, in terms of the overall Java elephant, I don't
perceive this as a prevalent pattern.
Additionally, exposing the parameters names introduces a de facto new
behavioral compatibility constraint; that is, you can no long change the
parameter names of your methods and constructors without regard for the
compatibility consequences because users can be relying on the names.
I encourage people interested in this feature to develop a prototype.
-Joe
Reinier Zwitserloot wrote:
> Ah, now I understand.
>
> I've got a much simpler proposal to address this issue.
>
> NB: Joe, I know coin's long gone, but perhaps consider this one anyway
> - it seems to me that some sort of named parameters proposal is likely
> to be accepted in the future, and adding names now should ease
> transition. As part of the effort I've listed all possibly
> complication I can come up with, at the end.
>
> Proposal:
>
>
> Starting from the new class file format introduced in java7 (due to
> module support, the class format is definitely getting a version
> bump), all compilers MUST put the names of the parameters in the class
> file (javac -g style), and obfuscators/compressors/whatever MUST NOT
> remove this; a class file with version v50 (or whatever number its
> going to end up being) won't even pass the verifier without the names
> in place.
>
> Add an API call on the java.lang.reflect.Method object to obtain the
> names of the parameters (returns a String[], or 'null' if they aren't
> there. Calling this on a param-less method returns an empty array, not
> null). Having the names is an all-or-nothing situation: Either the
> names are all there and this call works, or some/all are missing, and
> then this call does not work. I'm not sure if you can even have just a
> few names defined in the .class file format, but even if you can, that
> situation should be so extremely rare, its not worth writing up a
> complicated rule for). It is guaranteed that if the array exists (is
> not null), then each array element is not null.
>
> Voila. No need to turn in a proposal that's more complicated than most
> just to solve this simple problem.
>
> Complications:
>
> A) It would no longer be possible to rewrite a v49 and below class
> without debug info into a v50 and up class file without having the
> source file, but I don't actually know of any tools that attempt to do
> this.
>
> B) Code that generates class files on the fly (like proxy generators
> and the like) will need to consider the names of method parameters
> if/when they update the class file format they generate to v50+. A
> proxy generator has issues when it is trying to generate a v50+ proxy
> where its input object's class spec AND the input interface to proxy
> on are both v49- without debug info, for example.
>
> C) A (bad) quick-fix for either of the above issues is to just use
> 'arg0', 'arg1', 'arg2', analogous to what e.g. eclipse does when
> showing method signatures for methods in classes where there is no
> source, no debug info and no javadoc. This is not at all the right
> idea. A small risk that the class file format documentation should
> mention as not being appropriate unless there is absolutely no other
> option.
>
> D) Most code these days ships with source, or javadoc, or debug info,
> so that auto-complete shows the proper names for each parameter, but
> this certainly isn't true for /all/ java code out there. After this
> change, method param names become visible to all. This may not be a
> desired side-effect for programming shops that export libraries to
> clients where their method parameter names are inappropriate (swear
> words, or 'x', 'y', and 'z' and this creates deserved but nevertheless
> unexpected ridicule for sucking at programming style). I think this is
> an acceptable price to pay. Parameters are method-local which are
> extremely easy to rename with your friendly neighbourhood IDE's
> refactor tool.
>
> E) While technically the names are NOT part of API, and you CAN freely
> change names around without breaking any code, old or new, the names
> still do become a little more enshrined as at least almost part of the
> public API. This is already the case to some extent (param names show
> up in various tooling support such as javadoc and auto-completing
> IDEs) but this change would move parameter names a little more towards
> a complete member of public API. This is an issue, but its also the
> point of this proposal: Move towards a java world where parameter
> names are universally available and are meaningful. I don't think this
> is a serious problem, because A) names already have a flavour of
> importance right now, and B) While they become more important with
> this proposal, they still aren't true public API, and changing names
> even after this proposal is accepted is not backwards incompatible.
>
> F) Confusion may arise when these names are unintentionally taken as
> being either part of public API, or being hierarchical; they are in
> fact neither. For example, this proposal makes no attempt to harmonize
> name conflicts; if interface A has void foo(int bar), and interface B
> has void foo(int baz), you can still of course write a class that
> implements both of these. You can even name your foo's parameter
> 'floobargle', of course. The aim of this proposal does not involve
> making parameter names inherit sensibly.
>
>
> --Reinier Zwitserloot
>
>
>
> On Apr 20, 2009, at 10:18, Jean-Baptiste Bugeaud wrote:
>
>> Hello Reinier, Hello Joe,
>>
>> Thanks for your feedback.
>>
>> 2009/4/19 Reinier Zwitserloot <reinier at zwitserloot.com>:
>>> 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' })
>>
>> Reiner, I think my submission name is misleading everybody. This is
>> not the same thing you debate some times back. My mistake ... I should
>> have clarified from the start : I do not look at adding direct call by
>> parameter name into the language (say "à la" ObjectiveC). But simply a
>> reliable way access to parameter name and name a parameter's name in
>> static way thru time. See bug 6444738 for differences.
>>
>> Parameter names are very usefull information in most cases, and at
>> this time, either implementers use duplicate annotation (dummy
>> annotations storing again the same name) or they use tools such as ASM
>> to workaround the lack of API in the JDK.
>>
>> At the begining, I thought this requirement did not required a small
>> synthax language change : a new API would be enough. But soon I
>> realized that introducing name parameter that are static thru time,
>> introduce anyway a new paradigm in the language that developer should
>> be able to control directly : do I want this parameter name to be
>> static thu time ? or do I want to let the compiler decide as usual ?
>>
>> A compiler option is not the suitable tool for this.
>> If this is a global switch, it will not offer the fine grain required.
>> If this is a per class/per package option, it will clutter the
>> command line.
>> And in both cases, it will not offer paradigm separation with the
>> legacy. Thus you can not rely on the parameter name because you never
>> know if developper has stored the name accidentaly or for purpose.
>>
>>> 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.
>>
>> Because of the definition a dictionary gives of it : something like
>> "showing little change" is exactly what I meant for this paradigm. And
>> no "strictfp", as well as "const" and "goto" are not matching, you see
>> ;-)
>>
>> If you think that this worth integrating a new keywork, then there is
>> room for debate. I think static fits perfectly and is clear enough.
>> AFAIK, we already have final that is contextual? why not static too ?
>> final is already stretched between two things : do not overload member
>> and do not reasign variable.
>>
>> With the proposed language changed static modifier will be stretched
>> between static thru instances for members and static thru time for
>> variables.
>>
>>> 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).
>>
>> This is because I am not asking for named call of method ... simply
>> for a way to access name of parameter. Just a completely different
>> topic.
>> I don't see why a parameter on an EJB is not meanfull for the external
>> ? same for an webservice ? why a parameter name could not be meanfull
>> ? I don't get your point.
>>
>> My design decision is the kind of decision that led to erasure based
>> genericity : it has some drawback, loss of real parametrics instances
>> that could be usefull while reflection. But was the right decision at
>> the right time or either we would have lots binary compatibility or we
>> would still be debating wether or not implementing generics.
>>
>> My proposition on parameter name is analog, it is just meant to be
>> used ASAP but does it does not fully solve all the possible
>> expectations from this topic scope. Namely, should we call "by
>> parameter name" in the language ? and how ?
>>
>> Room is let for the coming decade ;-) But the propopsition does not
>> close doors to anything.
>>
>>> 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.
>>
>> Yes I've followed the debate :) But, again its my mistake "call by
>> parameter names" is a much more complex topic with lots of
>> performance/plaform impact. This is not a small language change IMHO.
>> Again, I do not look for calling a direct method call using named
>> parameters .... just a way to retreive them.
>>
>> -- --
>>
>> Joe, yes "late I am" ;-)
>>
>> FYI, I got this proposition cooking for several months I was not able
>> to find time to write & post it to you (pittyfull isn't it).
>>
>> If we remove the "language change" part (static named parameter) and
>> only keep the getParameterNames() API part (keep the regular parameter
>> name), do you think this can be pushed to JDK7 even if out of scope of
>> coin ? This is a very small change to the API and would solve lot of
>> time from lot of people.
>>
>> I mean, this API (along with the rest of the named parameter spec) was
>> removed from JDK6, skiping this in JDK7 means years again to wait for
>> it ? I think we are too much getting dependent on tools such as ASM in
>> lots of places (JavaEE implementation stacks for instance). And we
>> have a good opportunity to remove the dependency for a clean/simple
>> solution IMHO.
>>
>> Best Regards,
>> JB
>
More information about the coin-dev
mailing list