6 ms·
Interesting to see Java copy modern languages good ideas. The footgun of 'break' in switch statements has always bothered me, I strongly prefer the kotlin/swif
by on_and_off 9y ago
Interesting to see Java copy modern languages good ideas.
The footgun of 'break' in switch statements has always bothered me, I strongly prefer the kotlin/swift way of doing this.
- ajkjk 9y agoThey've been doing that for a long time. Just... slowly.
- tigershark 9y agoSlowly is an euphemism.. Lambda Expressions were introduced in c# in 2007, Anonymous delegates exist in c# since 2005, Java introduced closures in 2014...
- ajkjk 9y agoI didn't mean slowly as a euphemism. It's just slowly. They're extremely methodical about changes to the core language. And, yeah, it's slower than many would like, but they do it right and the language remains stable and reliable. Anyway, Lambda expressions have been around in, like, Lisp for at least 40 years and in mathematics for, what, 80? So everyone's slow by that account.
- tigershark 9y agoI emphasised the “slowly” because c# has the reputation of being “a bad copy of Java”, while apparently the opposite is true given how long it took Java to copy closures and to produce a bad copy of LINQ.
- dtech 9y agoThey want to prevent another half-baked implementation of a feature like they did with generics. C# is much faster and has much more features, but because of that it's also a bit of a mess sometimes. For example regarding closures/anonymous functions it has delegates, lambdas and anonymous (inner) classes which all have overlap but aren't fully the same. Java only has anonymous inner classes, and a convenient syntax and good support for anonymous inner classes with only 1 method (which they call lamdbas)
- pjmlp 9y agoLambdas are a bit more than that, because on standard JVMs they are implemented with specific bytecodes (via an invokedynamic specialization). The only variant of Java that desugars lambas into anonymous inner classes is Android, because Google.
- chrisseaton 9y ago> Java introduced closures in 2014 Java has had closures since 1997 hasn’t it? Don’t anonymous classes close over local state? Just the syntax was verbose. Do you mean the lambda syntax? Well that isn’t thue only thing in Java that forms a closure. ‘Closure’ and ‘anonymous function syntax’ are orthogonal.
- int_19h 9y agoJava anon classes couldn't capture non-final locals back when they were introduced. So they were closures, but not full-fledged. In contrast, C# anon delegates could capture any local, including writeable ones.
- dtech 9y agoThey still can't, captured variables need to be "effectively final" since Java 8, meaning they aren't allowed to be written after the capture. I think that's reasonable though, capturing mutable state is a recipe for disaster, and if you really want/need to you can wrap it in a properly synchronized container (e.g. AtomicReference in Java)
- int_19h 9y agoIn most cases, lambdas that capture mutable state effectively take ownership of it, so there's no issue there.
- tigershark 9y agoAnonymous inner classes are not proper closures as the other comment explained. And as you noted the syntax is so abhorrent that their use is actively discouraged by the guava developers for example. And all the source code pre-Java 8 that use anonymous inner classes to pass functions around was pretty unreadable.
- chrisseaton 9y agoWhy do you think they aren’t proper closures? Because they don’t allow you to mutate captured locals? Neither do closures in Haskell, and neither do lambdas in Java 8, so by that argument Java still doesn’t have closures. Your arguments are inconsistent because you’ve claimed that Java now has closures, even though they still do not meet your definition of closures. Apart from effective finality and implementation, the semantics of anonymous classes and lambdas is the same!
- Roboprog 9y agoThank “C” for the broken case statement requiring “break”. Pascal, and presumably Algol, had no break - following the guard condition was “a statement” (either just a single one, or an explicitly bounded block / compound statement) Nice to see plans to act something like Lisp’s “(COND ...)” or Ruby’s case statement (et al).
- Ded7xSEoPKYNsDd 9y agoI can somewhat forgive C for picking a syntax that turned out to be a bad idea. (Even if possibly some prior programming language made a better choice.) Java, on the other hand, copied that syntax knowing exactly how many bugs this would result in, for the questionable benefit that Java superficially looks a little bit more like C.
- int_19h 9y agoEven then there was a better way to do it. E.g. C# copied the C switch/case/break also, but with a caveat that all branches had to terminate without falling through. So you have to put a break there (or a return, or a goto, or a throw - basically any statement for which the compiler knows the control flow won't get past it). And in rare cases where you do want fallthrough, they added the ability to "goto case" from the body of one case label to another. Which is kinda nice, because it follows the original C design in treating case labels as, well, labels.
- pjmlp 9y agoThat questionable benefit is what makes many developers adopt or not a language, and the main reason why we had to endure for so long the fashion of curly braces languages. Thankfully this is changing now, with Pascal and ML syntax becoming again fashionable.
- sparkie 9y ago> modern languages good ideas. Lisp introduced 'cond' when? Also, pattern matching in it's slightly more advanced form is as old as ML. It's good to see languages finally admitting that expressions > statements. Still waiting for them to implement proper tail recursion though so I can replace statement based loops with expression based ones.
- aidenn0 9y agoML and Lisp are both more modern than Java. Java was archaic, at least partially as an attempt to win over C++ users.
- bobbyi_settv 9y agoHow is "break" in switch statements a footgun in Java? It is annoying boilerplate to need a "break" after each case, but how can it lead to shooting yourself in the foot?
- on_and_off 9y agoBecause I have seen more than once devs forgetting to add a 'break;', resulting in more or less subtle bugs. The kotlin/swift way of declaring this flow does not let you do this mistake.
- m2ger 9y agoI recommend using ErrorProne in Your projects. There are several problems its compiler will catch and fall through begin one of them: http://errorprone.info/bugpattern/FallThrough http://errorprone.info/bugpattern/FallThrough It might take quite a lot of work to fix (or bypass) all the reported problems in a large codebase but it is worth it.
- jfoutz 9y agoby forgetting it in that one long clause.