Yes, sometimes you can't choose a good default, or you hurt users by changing your default. But that's not the common case. The common case is that default values are extremely useful, letting an API designer *allow* a customization without *requiring* it. If you look at the preponderance of (a) telescoping method/constructor signatures and (b) builders, it's quite plain that this is a frequent need. In fact, I'd say that the *best* thing about supporting named parameters is that it allows for parameters to be optional.
Google's codebase is about 743% made up of Builders*, and our interest in a named/optional parameters feature is directly proportional to how many of these builders we think it could eliminate. :-) *figure may be exaggerated slightly On Thu, Nov 30, 2017 at 6:32 PM, <fo...@univ-mlv.fr> wrote: > I will just anwser on the default argument part. > > Java already has a way to specify default argument using several overloads > with a different numbers of argument, it's curbersome but it should not be > too easy to specify default values. > I believe that default argument are evil for two main reasons. > > It's like playing God, it's not the user of an API that specifies the > default value, it's the creator of the API, so it's the creator the API > saying to the world, i know how you will using my API, here are the default > value you want. I tink we should be more humble when developing APIs and > not pretend that we know what the good default are for all our users. > > Defaults are also part of the contract but people tends to think loosely > about that part, defaults are implicit, so a part of the configuration of > an object or a method in not visible at callsite, this leads to > misunderstanding between what a user of a method think the method does and > what the method really do. > > So i'm all for named parameters if it makes a method call easier to > understand, if it makes method call harder to understand by introducing > implicit values, i think i prefer the statu quo. > > Rémi > > ----- Mail original ----- > > De: "Guy Steele" <guy.ste...@oracle.com> > > À: "Remi Forax" <fo...@univ-mlv.fr> > > Cc: "Brian Goetz" <brian.go...@oracle.com>, "amber-spec-experts" < > amber-spec-experts@openjdk.java.net> > > Envoyé: Jeudi 30 Novembre 2017 21:56:27 > > Objet: Named parameters [was: Re: Reader mail bag] > > > Thanks, Remi, this is an excellent start! And it may be where we want > to end > > up. > > > > But when the time comes that we dig into a serious discussion of putting > named > > method parameters into Java, I would like to see a broader exploration > of the > > design space before we settle on a specific design. > > > > I’ve seen a lot of other designs for a lot of other languages, each with > pros > > and cons. > > > > There are at least four more-or-less orthogonal properties a method > parameter > > can have: > > > > (1) May it be specified by name (rather than by position) at the call > site? > > If so, can it be specified _either_ by name or by position? > > > > (2) May the corresponding actual argument be omitted at the call site? > > If so, what happens? > > System-specified default value (such as zero or null) is > supplied. > > Programmer-specified default value is supplied. > > Value is a compile-time constant. > > Value is recomputed at call time. > > Can this computation depend on other > argument values (such as those to the > > left)? > > No value is supplied. > > A separate mechanism allows inquiry as to whether > an actual argument was > > provided. > > The parameter type is actually an option type > (choice; if no value is supplied, > > you get an empty value). > > > > (3) May the corresponding actual argument be duplicated at the call site? > > (This may make little sense for Java, but is used extensively in > Common Lisp, > > where name-value lists may be built dynamically and then fed to > `apply`; > > allowing duplications makes it easy to override a default by just > sticking a > > new name-value pair onto the front of a list.) > > > > (4) May the actual arguments be permuted at the call site—that is, > appear in an > > order other than the order in which they are declared in the method > > declaration? > > (Typically the answer is “no” for positional parameters, but may > be “yes” or > > “no” for named parameters.) > > (If a call contains both positional and named arguments, one can > ask whether the > > named arguments may be mixed in among the positional ones [yech!] > or must be > > kept separate, such as always appearing to the right of the > positional > > arguments.) > > > > For each of the preceding four questions, there are these meta-questions: > > Is the answer to the question the same for all parameters > whatsoever? > > Is the answer to the question the same for all parameters of the > same kind (such > > as named or positional)? > > Is the answer to the question the same for all parameters in a > single method > > declaration? > > Is the answer to the question the same for all parameters of the > same kind (such > > as named or positional) in a single method declaration? > > > > In addition, there is the question of exactly what combinations of > positional, > > optional positional, named, and/or optional named parameters may be used > within > > a single method declaration. > > And there is the question of what combinations of combinations may > appear within > > an overload set. > > > > Many of these questions are in fact answered by specific choices in the > proposal > > below. I’m just looking to seeing (eventually) a thorough discussion of > the > > rationale for each choice. I provide this list of questions as one > possible > > starting point for that discussion. > > > > —Guy > > > >> On Nov 30, 2017, at 3:21 PM, Remi Forax <fo...@univ-mlv.fr> wrote: > >> > >> My note on named parameters: > >> Supporting real named parameters that works with overriding and backward > >> compatibility is hard, but i believe there is a sweet spot. > >> > >> - a method can declare to support named parameters by using a new > modifier > >> 'named'. > >> so - all parameters are named or none are, you can not mix positional > and named > >> parameters like in Ruby. > >> - a method is either support positional parameters or named > parameters but not > >> both at the same time. > >> if there are several overloads, you can only have one named overload > with the > >> same number of parameters, > >> which means that counting the number of parameters is enough to know > which > >> method can be called. > >> a varargs method can not be named. > >> > >> - when overriding a method, a named method can not override a non named > method. > >> overriding a named method with a non named method is allowed to ease > the > >> transition but emit a warning. > >> a named method that overrides another named method need to have the > same > >> parameters with the same name at the same position. > >> > >> - at call site, a named method has to be called using the syntax "name: > >> argument" for each arguments > >> by example: > >> ThreadGroup main = ... > >> new ThreadGroup(parent: main, name: "my group"); > >> if a named method is called with positional arguments, the compiler > emit a > >> warning > >> > >> - at compile time, > >> a declaration site, all parameter named are stored in the Parameter > attribute. > >> a callsite, the compile insert an invokedynamic to the > NamedParameterMetaFactory > >> with a method handle ref on the declared named method and the names > of all > >> arguments in the order of the call. > >> a runtime, the NamedParameterMetaFactory verifies that the number of > named > >> argument is the same and are a permutation of the declared parameters > that are > >> retrieved by cracking the method handle ref as a MethodHandleInfo and > calling > >> getParameters on the corresponding Constructor/Method, once the > permutation is > >> calculated, the NamedParameterMetaFactory returns a ConstantCallSite > on the > >> constant method handle (the method handle ref) permuted using > >> MethodHandles.permuteArguments. > >> > >> To summarize, this let us use named parameters if the API designer want > to allow > >> that, > >> there is a path for upgrading a method that uses positional parameters > to use > >> named parameters, but not in the other way (like varargs), > >> not supporting permutations between overridden methods make thing far > simpler > >> that they are otherwise. > >> > >> cheers, > >> Rémi > >> > >> ----- Mail original ----- > >>> De: "Brian Goetz" <brian.go...@oracle.com> > >>> À: "amber-spec-experts" <amber-spec-experts@openjdk.java.net> > >>> Envoyé: Jeudi 30 Novembre 2017 19:29:41 > >>> Objet: Reader mail bag > >> > >>> We've gotten two submissions to the amber-spec-comments list. > >>> > >>> 1. "Forcing a pattern match", at: > >>> http://mail.openjdk.java.net/pipermail/amber-spec-comments/ > 2017-November/000000.html > >>> > >>> 2. "Named parameters in data classes", at: > >>> http://mail.openjdk.java.net/pipermail/amber-spec-comments/ > 2017-November/000003.html > >>> > >>> > >>> I think the first asks for an alternate form of the "matches" operator > >>> which would fail with a CCE, rather than evaluating to false, if the > >>> match fails. This would be essentially saying, "This should match; if > >>> it doesn't, that's an error." I think that's what's being asked, but > >>> then he talks about an "unnecessary instanceof check", which makes me > >>> wonder whether this is really just about optimization. > >>> > >>> To be clear, the instanceof check is neither expensive nor unnecessary. > >>> (Though we can optimize these away when we know the static type of the > >>> target; if x is a Foo, then "x matches Foo f" can be statically > >>> strength-reduced to "x != null".) > >>> > >>> Note that the "if member.getKind() == VARIABLE" is merely a manual > >>> optimization; you could easily leave that out and just match against > >>> VariableTree. What we'd rather focus on is how to get to: > >>> > >>> switch (member) { > >>> case BlockTree bt: ... > >>> case VariableTree vt: ... > >>> } > >>> > >>> while allowing the pattern to capture the quicker pre-test (kind == > >>> BLOCK) and maintain the performance without making the user worry about > >>> this. We have some ideas here, but I don't think this "forcing" idea > >>> really offers a lot. > >>> > >>> > >>> The second (named parameters) was a question I was expecting. > >>> > >>> I agree that being able to invoke constructors and methods by name can > >>> sometimes result in easier-to-read code, especially when some > parameters > >>> have a sensible default value. (This is also a more complicated > feature > >>> than anyone gives it credit for, so it's not the "gimme" it is often > >>> assumed to be.) > >>> > >>> However, data classes is not the place to cram in this feature; this > >>> should be a feature that stands on its own, and applies to all classes, > >>> data- or not. One of the design goals for data classes is that a data > >>> class should be essentially a "macro" for a class you could write by > >>> hand; this allows easy migration from existing classes to data classes > >>> (if they meet the requirements) and from data classes to full classes > if > >>> they expand to no longer fit the data class profile. The more that > >>> *uses* of data classes or their members are different from the > >>> corresponding use of regular classes, the more difficult this migration > >>> becomes. (This is not unlike the design mandate with default methods; > >>> from the client perspective, they're just ordinary virtual methods, and > >>> you can't tell whether the method was implemented directly or inherited > >>> -- they're just methods.) > >>> > >>> So, while named parameters are a reasonable feature to explore, trying > >>> to staple them onto data classes would be a mistake. They are their > own > > >> feature. We're open to exploring it, but we've got our plate full > for now. > -- Kevin Bourrillion | Java Librarian | Google, Inc. | kev...@google.com