[patterns] Redefinition of pattern variable is allowed by javac in some cases

Mark Mahieu markmahieu at gmail.com
Mon Jan 6 12:28:20 UTC 2020


Yes that explained the intent nicely.  Pattern matching looks like it could be a rather enticing fit for Java now that I’m reading a little more deeply into it.

Thanks!

Mark


> On 5 Jan 2020, at 15:02, Brian Goetz <brian.goetz at oracle.com> wrote:
> 
> Heh, was just about to point you to that.  In the table "Scoping of pattern variables", the 6th row covers conditionals -- I suspect it probably covers everything you want.
> 
> On 1/5/2020 3:54 AM, Mark Mahieu wrote:
>> Just to follow up on my own question re future directions, I think I’ll find what I'm after with a more careful reading of https://cr.openjdk.java.net/~briangoetz/amber/pattern-semantics.html <https://cr.openjdk.java.net/~briangoetz/amber/pattern-semantics.html> <https://cr.openjdk.java.net/~briangoetz/amber/pattern-semantics.html> <https://cr.openjdk.java.net/~briangoetz/amber/pattern-semantics.html>
>> 
>> Mark
>> 
>> 
>>> On 5 Jan 2020, at 07:15, Mark Mahieu <markmahieu at gmail.com> <mailto:markmahieu at gmail.com> wrote:
>>> 
>>> Hi.
>>> 
>>> I just bumped into a variant of that one with 14-ea-29, whilst musing on how the ? : operator might take further advantage of pattern matching.  My example actually used the pattern variable inside a branch, but I expect it’s the same apparent discrepancy between javac and the draft spec.
>>> 
>>> That draft also suggests that more sophisticated rules may be considered in future for some conditional statements (e.g. the last sentence in 6.3.1.4).  I imagine this was discussed at some point (and I guess, parked for now) but I’ve had no luck searching the archives - any pointers would be gratefully received :)
>>> 
>>> Mark
>>> 
>>> 
>>>> On 26 Dec 2019, at 11:34, Tagir Valeev <amaembo at gmail.com> wrote:
>>>> 
>>>> Another shadowing case:
>>>> 
>>>> class Test {
>>>> static void test(Object o1, Object o2, Object o3) {
>>>>   boolean b1 = o1 instanceof String s ? o2 instanceof String s : o3
>>>> instanceof String s;
>>>> }
>>>> }
>>>> 
>>>> Also happily compiled by javac. If I understand correctly the spec
>>>> draft, 6.3.1.4 [1], this should be rejected:
>>>> 
>>>> The following rules apply to a conditional expression a ? b : c:
>>>> ...
>>>> A pattern variable is introduced both by a when true, and by c when true.
>>>> ...
>>>> A pattern variable is introduced both by b when true, and by c when true.
>>>> 
>>>> Am I missing something?
>>>> 
>>>> With best regards,
>>>> Tagir Valeev.
>>>> 
>>>> [1] http://cr.openjdk.java.net/~gbierman/jep305/jep305-20191021/specs/patterns-instanceof-jls.html#jls-6.3.1.4 <http://cr.openjdk.java.net/~gbierman/jep305/jep305-20191021/specs/patterns-instanceof-jls.html#jls-6.3.1.4>
>>>> 
>>>> On Thu, Dec 26, 2019 at 5:10 PM Tagir Valeev <amaembo at gmail.com> wrote:
>>>>> Hello!
>>>>> 
>>>>> Playing with javac 14-ea+28-1366. This code can be successfully compiled:
>>>>> 
>>>>> class Test {
>>>>> static void test(Object o1, Object o2) {
>>>>>     boolean b = o1 instanceof String s && (!(o2 instanceof String s)
>>>>> || consume(s));
>>>>> }
>>>>> 
>>>>> static boolean consume(String s) {
>>>>>    System.out.println(s);
>>>>>    return true;
>>>>> }
>>>>> 
>>>>> public static void main(String[] args) {
>>>>>   test("x", "y"); // prints y
>>>>> }
>>>>> }
>>>>> 
>>>>> Spec draft says for `a || b`:
>>>>> It is a compile-time error if any pattern variable introduced by a
>>>>> when false is already in scope at b.
>>>>> 
>>>>> If I understand correctly, assuming a = !(o2 instanceof String s) and
>>>>> b = consume(s), we already have `s` (from `o1 instanceof String s`) in
>>>>> the scope at b, and a introduces new `s` when false, so this code
>>>>> should be rejected. Please correct me if I am wrong.
>>>>> 
>>>>> With best regards,
>>>>> Tagir Valeev.
> 



More information about the amber-dev mailing list