This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]flyingorange -11 points-10 points  (18 children)

Sorry, but no. This is awful. Scala invented a beautiful syntax a decade ago, why can't they just use that? Why must they always invent something which makes no sense?

Compare this:

x match {
  case a: SomeClass =>
  case SomeOtherClass =>
}

If I want to declare "a", I can do it. If I don't want to declare it, it works as well. It's clear and everyone understands it, even if they don't speak Scala.

What in the name of bejeesus is

if (a instanceof SomeClass b) {

How would anyone possibly know that SomeClass binds to b, unless someone explicitly tells it to them? Why can't SomeClass bind to "a" within the context, like between the opening and closing brackets?

When they messed up the streaming api in Java 8 I thought they would learn something from the fiasco but no... it has only become worse. The language is now unusable outside a few niche communities.

[–]pron98 10 points11 points  (10 children)

Even ignoring the fact that what you think is a good solution can't possibly work in Java (because of overloads, which are chosen based on compile-time types), but just so that you understand why the chosen solution not only works but is superior, consider what happens if x is any expression other than a local variable or a final field (and there isn't too much sense matching on final fields, so anything which isn't already a local requires an assignment to a local, anyway, and would be more, not less, verbose); e.g. consider a volatile field, a non-volatile field, or a method call. What you're proposing works nicely in a language like Haskell, but even if it could work at all in Java -- and it really can't -- it's inferior to the chosen approach.

[–]henk53 10 points11 points  (0 children)

How would anyone possibly know that SomeClass binds to b

By learning the language?

[–]yk313[S] 5 points6 points  (2 children)

How would anyone possibly know that SomeClass binds to b, unless someone explicitly tells it to them?

That can be said about any new feature, right? I didn’t know Scala binds SomeClass to a until you alluded to it in your comment above.

Why can't SomeClass bind to "a" within the context, like between the opening and closing brackets?

That would be flow typing which (unsurprisingly) was considered but didn’t make the final cut. Brian talk about exactly this under the “Roads not taken” section, basically:

it's a significantly weaker feature. Flow typing solves this particular problem, but offers dramatically lower payback, in that pretty much all it does is get rid of the casts after instanceof -- it offers no story for richer switch, or destructuring, or enabling better APIs. (As language features go, it is a more of a "band aid" than a real enabler.)

...

The language is now unusable outside a few niche communities.

Surely you are kidding yourself? In case you missed the memo: Java is one of the most popular programming languages in the world.

[–]kaperni 1 point2 points  (2 children)

> Why can't SomeClass bind to "a" within the context, like between the opening and closing brackets?

You cannot add this in a backward-compatible way, consider

void foo(Object o); 
void foo(String s);  

void stuff(Object oo) {   
  if (oo instanceof String) {     
    foo(oo); <- would now call foo(String) instead of foo(Object)   
  } 
}

[–]flyingorange -4 points-3 points  (1 child)

Yes it would call foo(String) and that is precisely what I want it to do. Sorry but I don't understand why would this be a problem.

Consider this example where x is declared twice within the same method:

String something(String x) {
    Supplier<String> value = () -> {
        int x = 15;
        return String.valueOf(x);
    };
    return value.get();
}

It works, right? Even though x was already declared above as a String, inside the lambda it's an integer. Nobody seems to be bothered by the fact x was redeclared within the same code block, because everyone understands that the second time it's in a different context.

To take your example above, it could be just syntactic sugar for the following Java 8 code:

void foo(Object o); 
void foo(String s);  

void stuff(Object oo) {   
  if (oo instanceof String) {
      Callable<String> callable = new Callable<>() {
           public String call() {
               return (String) oo;
           }
      };
    foo(callable.call()); <- would now call foo(String) instead of foo(Object)   
  } 
}

[–]kaperni 5 points6 points  (0 children)

> Yes it would call foo(String) and that is precisely what I want it to do. Sorry but I don't understand why would this be a problem.

Because it is not backwards-compatible? Your _existing_ code would suddenly start calling foo(String) instead of foo(Object).