<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  </head>
  <body>
    <font size="4"><font face="monospace">We've gone around and around a
        few times on "unnamed variables" (underscore), starting with JEP
        302 (Lambda Leftovers).  We reclaimed the underscore token in
        Java 9 with the intention of using it for unnamed variables and
        "any" patterns.  Along the way, we ran into some hiccups, and it
        has sat on the shelf for a while.  Let's take it down, dust it
        off, and see if we have any more clarity than before.  <br>
        <br>
        There are three syntactic productions in which we might want to
        use underscore as a "don't care" indicator:<br>
        <br>
         - Unnamed variables.  Here, underscore stands in for a variable
        name.  When we declare a local variable, catch formal, pattern
        variable, etc, whose name is `_`, which has the effect of
        entering no new names in scope.  It becomes an "initialize-only"
        variable.  <br>
        <br>
            try { ... }<br>
            catch (FooException _) { throw new BarException("foo"); }<br>
        <br>
         - Partial inference.  Here, underscore stands in for a type
        name.  Today, we can infer type variables for generic method
        invocations and constructor invocations, but it is
        all-or-nothing.  Being able to denote "infer this type" would
        allow us to do partial inference:<br>
        <br>
            foo.<String, _>m(...)<br>
        <br>
         - "Any" patterns.  Here, underscore is a pattern, which matches
        everything, and binds nothing.<br>
        <br>
            case Foo(var s, _): ...<br>
        <br>
        We don't have to do all of these; right now we're not
        considering partial inference, but the other two are reasonable
        options.  Unnamed variables have been a long-standing request;
        any patterns will likely be a common request soon as well.<br>
        <br>
        For a match-all pattern, there is little to say other than "_"
        is one of the alternatives of the Pattern production, it is
        applicable to all types, it is unconditional on all types, and
        it has no bindings.  The specification already has a concept of
        "any" patterns; this is just making it denotable.  <br>
        <br>
        <br>
        I think there is little controversy about using unnamed local
        variables (local variable declaration statements, catch formals,
        foreach induction variables, resources in try-with-resources)
        and unnamed lambda parameters.  What is common to all of these
        is that these are _pure implementation details_, where the
        author has elected to not give a name to a variable that is
        entirely implementation-facing.  This seems eminently
        reasonable.  Unnamed parameters can help eliminate errors by
        capturing design assumptions and make life easier for static
        analysis tools that like to point out unused variables.  <br>
        <br>
        Where we stumble is on method parameters, because method
        parameter names serve two masters -- the implementation (as the
        declaration of a variable) and the API (as part of the
        specification of what the method does.)  Among other things, we
        like to document the semantics of method parameters in Javadoc
        with the `@param` tag, but doing so requires a name (or
        inventing a new Javadoc mechanism like `@param #4`, likely a
        loser.)  Secondarily, sometimes parameter names are retained in
        the MethodParameters attribute, though that attribute (JVMS
        4.7.24) already supports parameters without names by using a
        zero CP index.  <br>
        <br>
        With `var`, we drew a clear line of "implementation only" -- you
        can't infer a method return type, even for a private method, you
        can only use it for local variables and lambda formals.  This
        has been pretty successful.  <br>
        <br>
        We've explored a number of intermediate points on the spectrum
        with varying degrees of stability:<br>
        <br>
         A) Implementation only -- local variables, catch formals,
        for-loop induction variables, TWR resources, pattern variables,
        lambda formals <br>
         B) "A++", where we add in method parameters of anonymous
        classes<br>
         C) Adding in method parameters _for non-initial declarations_
        -- allow unnamed parameters only for methods that override a
        method from a supertype, ensuring that there is a real
        specification of what the parameters mean.<br>
         D) Anything goes, any method parameter can be unnamed, throwing
        specification to the wind.<br>
        <br>
        A is a stable point, and has the advantage of mostly lining up
        with where we can use `var`.  But users will surely grumble that
        they can't use it for implementations of methods from
        supertypes.  As this feature request predates lambdas and
        patterns, giving it to lambdas and patterns but not ordinary
        methods might feel a bit mean.  <br>
        <br>
        The motivation for B is obvious -- to support smooth refactoring
        between lambdas and inner classes -- but is not a very stable
        point, as one will immediately ask "what about refactoring to
        named classes".  <br>
        <br>
        C feels attractive, though there would surely be complaints too;
        it excludes constructors and static methods (which might
        sometimes want unnamed parameters when a parameter is no longer
        used, but stays around for binary compatibility), and even some
        initial declarations.  But, these cases are likely to be
        somewhat more rare, so I don't object to leaving these aside. 
        The main concern is that this might feel arbitrary.  There is
        also the possibility for some confusion; it is not obvious what
        it means when you override a method that already has an unnamed
        parameter.  Can you give it a name and use it?  It is a little
        weird that the lack of name applies only to the implementation
        of the method, but somehow bleeds into the specification.  There
        is also some impact on Javadoc, as well as lingering concerns
        that there are other shoes to drop other than Javadoc and
        MethodParameters.  <br>
        <br>
        D is also stable, but feels like it makes the language less
        safe, by making some methods unspecifiable.  On the other hand,
        the people who might use it for initial declarations, static
        methods, etc, are also the sort of people who probably don't
        write specification anyway (otherwise they would realize that
        they are depriving their callers of useful information.)  <br>
        <br>
        In (C), Javadoc could insert an `@implNote` that says something
        like "this implementation ignores the value of parameters
        <x> and <y> from declaring method Foo::bar".  In
        (D), it could say "ignores its 3rd and 4th parameter", or insert
        synthetic @param tags for parameters whose name is something
        like "<unnamed>".  <br>
        <br>
        Past discussions seemed to gravitate toward either A or D, which
        are also the simplest / most stable points.  I guess it becomes
        a question of getting over the "makes the language less safe"
        concerns.  <br>
        <br>
        Regardless, I'd like to see if we can quantify the "lingering
        concerns about other shoes to drop."  <br>
        <br>
      </font></font>
  </body>
</html>