3 ms·
I don't like it. Lots of the examples seem forced e.g.: var _ = q.remove(); This is just stupid. We can write: q.remove(); We don't need to save the return v
by invalidname 4y ago
I don't like it. Lots of the examples seem forced e.g.:
var _ = q.remove();
This is just stupid. We can write:
q.remove();
We don't need to save the return value in Java. The only case where this makes sense is:
instanceof Point(_, int y)
But that makes sense because the original code is so bad. A better solution would be type inference like we have in lambdas:
instanceof Point(x, y)
- illiarian 4y ago> We can write: q.remove(); If that method returns, many tools will complain that the returned value is ignored
- invalidname 4y agoThat's a bug in the tools. IntelliJ doesn't and neither does Sonar Cloud.
- brabel 4y agoIntelliJ complains if you don't check certain values (e.g. `file.delete()`). It's not a bug, it's extremely helpful.
- invalidname 4y agoInteresting. It does do that for file.delete() but not for remove(). That's because it's smart enough to know which values are important. In the case of delete() you would want to check the result. So the warning is good and using an underscore to ignore it would actually be a problem. In the case of remove() we don't really need the result.
- kaba0 4y agoThere is type inference, like ` instanceof Point(var x, var y)`. The real winner here is obviously the used example, `instanceof ColoredPointer(_, var color)`, here every other solution would be plain ugly. The other examples are just there to make the feature intuitive - for example I quite like the `catch (SomeException _)`, making it exact that this exception is deliberately not used up in the catch block.
- invalidname 4y agoExactly. That's what I said in the end of my answer but this is no benefit since instanceof ColoredPointer(x, color) is even shorter and it's really not hard to come up with a variable name. In this case some tools might mark x as unused but that's just nonsense. The catch example is interesting but how often do you completely ignore the exception and should you ever do that? Is that behavior the language should encourage? I feel that this is a solution to a very minor inconvenience that is pretty redundant.
- kaba0 4y agoOkay, what about `instanceof ColoredPoint(3DPoint(_, _, _), var color)`? ColoredPoint’s first field now takes some subtype, and you try to handle only the case where it is a 3DPoint. Now you have to explicitly mention that in the pattern, but it’s possibly long and recursive inner patterns have to be named again. It can quickly get out of hand, so _ is a pretty well-known and widely used approach here in ML-like languages, and its usage causes no harm at all.
- invalidname 4y agoI get that it exists elsewhere and saw it in other languages. I think it looks a bit weird and doesn't convey the intention properly. One of the nice things in Java is that we don't automatically copy ideas from other languages but deliberate on them first. Personally, I think the instanceof syntax for Records is terrible and you're showing off exactly why. It breaks encapsulation entirely. What we need to do is fix records so they will have more OOP related principles. instanceof is a patch and switch should be an anti-pattern. If records allowed inheritance we could just add polymorphic APIs to them and then write more elegant code without the instanceof's.
- kaba0 4y ago> One of the nice things in Java is that we don't automatically copy ideas from other languages but deliberate on them first Sure, but I’m sure it was not an automatic copy, but a well thought-out design by the very competent design team. > It breaks encapsulation entirely Records are almost by definition open. They are only the sum[1] of their constituents. They are part of a more data-oriented approach. Of course the “old” OOP concerns may apply, and there is an escape hatch — one can make a class from a record, and with the coming destructors it won’t need any recompilation, every existing pattern match can work, yet its inner workings can be encapsulated. But this is not the primary purpose for them — they are just plain old data. EDIT: though now that I thought a bit about it, hopefully with `withers` we get an alternative syntax for pattern matching on records, like `ColoredPoint { point: 3DPoint { x } }`. That way pattern matching won’t be tied to the order of the fields. Surely records don’t change often, but still. [1] if we are being pedantic, they are the product of their constituents, they are named product types.
- HiJon89 4y agoA common example is try-with-resources where you don't actually need the resource and are just using it for the closing effect. For example, let's say you have a metrics library that allows you to time code blocks like so: try (Timer ignored = Metrics.newTimer("getOrders")) { return db.getOrders(); } Another common example is when you are implementing an interface method or overriding a superclass method, and your implementation doesn't need all the arguments. Would be great for the programmer to have a way to express this intent (to the compiler and to the reader) This JEP would allow stronger static analysis rules like "every declared parameter and variable MUST be used", and _ would serve as the canonical escape hatch for edge cases. One datapoint: searching our codebase for variables named "ignored" produces >1,000 hits. And probably an order of magnitude more unused variables that aren't named ignored.
- invalidname 4y agoWouldn't the try with resources example be better served by allowing this syntax? try (Metrics.newTimer("getOrders")) { return db.getOrders(); } > Another common example is when you are implementing an interface method or overriding a superclass method This doesn't seem to be supported and could cause many issues e.g. if a base interface adds an overloaded method with a similar signature. Suddenly we will have a conflict and compilation issues. > This JEP would allow stronger static analysis rules like "every declared parameter and variable MUST be used", and _ would serve as the canonical escape hatch for edge cases. This is a good point. I'm not sure if it's worth the odd syntax and potential misuse but it is interesting.
- HiJon89 4y ago> > Another common example is when you are implementing an interface method or overriding a superclass method > This doesn't seem to be supported and could cause many issues e.g. if a base interface adds an overloaded method with a similar signature. Suddenly we will have a conflict and compilation issues. I think this is already a risk when modifying interfaces or superclasses. For example, if you add a method to a superclass, a subclass might already have a method with the same name/arguments but different return type, which would break compilation.
- pdevr 4y agoYes, some of the examples are weak. However, the case of unused variables is a well-known problem. Caught but unused exceptions is one common use case, and they have some code snippets of that in there too. Using _ is a neat solution. For those who don't face that issue, life continues as before.