4 ms·
Java getting better pattern matching is a great change. Id really like more of the functional features to make it into Java. I would love if Java pattern match
by ecshafer 3y ago
Java getting better pattern matching is a great change. Id really like more of the functional features to make it into Java.
I would love if Java pattern matching could at least get to the level of ruby pattern matching. Ruby pattern matching will allow you to deconstruct arrays and hashes to get pretty complicated patterns, which is really powerful. Right now it seems like Java might have that with a lambda in the pattern, but its not going to be as elegant as ruby where:
case {name: 'John', friends: [{name: 'Jane'}, {name: 'Rajesh'}]}
in name:, friends: [{name: first_friend}, *]
"matched: #{first_friend}"
else
"not matched"
end
#=> "matched: Jane"
But the big change here is virtual threads which should be a game changer.
- unregistereddev 3y agoPattern matching is a neat tool to keep in the toolbox. When it's the right tool for the job, it is really cool and is a lot cleaner than a bunch of conditional checks. However, I rarely reach for it. Maybe my use cases are unusual? I am genuinely curious how often other developers find pattern matching to be the best tool for the job.
- bcrosby95 3y agoIt probably depends on the language you're using. Pattern matching is awesome in Erlang and Elixir. In most other languages it ranges from "nice" to "bleh".
- nayuki 3y agoPattern matching is awesome in Rust. It carries the stellar legacy of Haskell.
- Jtsummers 3y agoWhen available, I pretty much always use pattern matching. It tends to shorten code while not reducing clarity (often increasing it) which means fewer opportunities for errors to creep in. Statically typed languages that can detect incomplete case handling also reduces the chances for some errors (as long as you don't make a catch-all case) but also helps when you change something so that a new case is needed. It also tends to shift the code to the left, reducing the indentation. So shorter, clearer, less unnecessary indentation. Generally a positive.
- weatherlight 3y agoIn languages that have strong support for pattern matching, whether it be on values or types, I find myself reaching for it instead of conditionals. It's all about the explicitness for me. You have to list out all the cases you care about, so there's no room for ambiguity. Plus, the compiler will usually warn you if you've missed a case, which is like a built-in bug catcher. It's also great for working with immutable data, less state to worry about. And let's talk about readability; the code basically documents itself because you can see the shape of the data right in front of you. You can even destructure data on the fly, pulling out exactly what you need. If you're using a statically-typed language, pattern matching adds an extra layer of type safety. And, not to forget, it nudges you toward a more functional style of coding, which I find leads to cleaner, more modular code. So yeah, I reach for pattern matching quite a bit; it often feels like the right tool for the job.
- ecshafer 3y agoI think that you can replace almost any If else with pattern matching. Pattern matching makes type checks easier, which if you are really heavily using types through your program, makes pattern matching even better.
- hibikir 3y agoPattern matching is what makes sum types ergonomic enough to be used. Many a Java design doesn't use said interface-based sum types because it's so cumbersome to use them. But whena language has pattern matching, then suddenly designing with sum types in mind is done a lot, and therefore you see examples of good pattern matching everywhere. When I teach Scala, a very high percentage of the teaching time is ultimately down to re-introducing how to design business domains, because seasoned devs just reach for large classes with a million optional fields, which not only can represent valid systems states, but thousands of invalid ones.
- grumpyprole 3y agoOne example for you: anytime you needed to use the "Visitor pattern" to do a transformation from one representation to another - you don't need it now. Sealed classes and pattern matching will be more succinct and easier to reason about.
- owlstuffing 3y agoPatterns are somewhat nice to have, but for me they’re difficult to read, and not because my brain isn’t used to them. The simple identifier instanceof is about all I’ll use _most_ of the time. Otherwise, yes they are more concise, but lose too much information in the process. I’d rather see a boatload load of other features before patterns. I’ve been experimenting with project manifold[1]. _That_ is the path Java sb on. Just my take. 1. https://github.com/manifold-systems/manifold https://github.com/manifold-systems/manifold
- frou_dh 3y agoI really like that Ruby throws NoMatchingPatternError if none of the patterns match. It's a bit like the much-acclaimed exhaustive pattern matching in static languages (though at runtime rather than compile-time, obviously) and better than just silently falling off the end, which IIRC is what Python's pattern matching does.
- rusk 3y agoIn Python you can terminate a for loop with else, which will be run whenever the loop runs to the end without breaking
- specialist 3y agoNeat. Will check it out. I recently spotted a (new to me) foreach / else construct in a templating language (sorry, forget which one); else is invoked if the list is empty. Nice sugar for common outputs like "no items found". I appreciate modest syntactic sugar. For instance, my #1 sugar wish is for Java's foreach is to do nothing when the list reference is null. Versus tossing a NPE. Eliminates an unnecessary null check and makes the world a little bit more null-safe.
- rusk 3y ago> else is invoked if the list is empty. for / else should do that too …
- frou_dh 3y agoThat's not particularly relevant to the nice pattern matching property I mentioned. If you need to manually write supplementary code to get the exhaustiveness safety then that's back into the realm of bog-standard defensive programming. Here's what I mean. The Ruby will throw NoMatchingPatternError and the Python will silently do nothing. x = [10, "figs"] case x in [n, "apples"] :foo in [n, "oranges"] :bar end # --- x = [10, "figs"] match x: case [n, "apples"]: ... case [n, "oranges"]: ...
- brightball 3y agoSimple solution: JRuby. Virtual threads are going to make Ruby fibers work properly for JRuby so that’s going to be huge as well. Charles Nutter gave an update in August. 45 minute mark he talks about virtual threads. https://youtu.be/pzm6I4liJlg?si=vKVICrola4OmJIal https://youtu.be/pzm6I4liJlg?si=vKVICrola4OmJIal
- munificent 3y agoWe recently added pattern matching to Dart [1], so I'm always keen to see how it compares to similar features in other languages. In case it's interesting, here's that Ruby example ported to Dart: print(switch ({'name': 'John', 'friends': [{'name': 'Jane'}, {'name': 'Rajesh'}]}) { {'friends': [{'name': var firstFriend}, ...]} => "matched: $firstFriend", _ => "not matched" }); Pretty similar! The main differences are that Dart doesn't have symbols, so the keys are string literals instead. Also, variable bindings in patterns are explicit (using "var") here to disambiguate them from named constant patterns. [1]: https://medium.com/dartlang/announcing-dart-3-53f065a10635 https://medium.com/dartlang/announcing-dart-3-53f065a10635
- brabel 3y ago> We recently added pattern matching to Dart [1] I've been using that and I love it, in general... but can I ask you why do we need to name a variable in a pattern like this: switch (p) { Person(name: var name) => ... } That's the only thing that feels a bit annoying as you have to rename the variable... In Java, this would be something like: Person(var name) -> ... EDIT: I guess it's to support `Person(name: 'literal')` matches. > Dart doesn't have symbols That's weird, as I actually use sometimes `#sym` (which has type `Symbol`)?? print((#sym).runtimeType); This prints `Symbol` :) I know you know Dart in and out, but could you explain why this is not actually a symbol in the way Ruby symbols are?
- munificent 3y agoWe require "var" before variable patterns because we also allow named constants in patterns (which match if the value is equal to the constant's value): const pi = 3.14; // Close enough. switch (value) { (pi, var pi) => ... } This case matches a record whose first field is equal to 3.14 and binds the second field to a new variable named "pi". Of course, in practice, you wouldn't actually shadow a constant like this, but we didn't want pattern syntax to require name resolution to be unambiguous, so in contexts where a constant pattern is allowed, we require you to write "var", "final", or a type to indicate when you want to declare a variable. Swift's pattern syntax works pretty much the same way. > > Dart doesn't have symbols > That's weird, as I actually use sometimes `#sym` (which has type `Symbol`)?? Oh, right. I always forget about those. Yes, technically we have symbols, but they are virtually unused and are a mostly pointless wart on the language. It's not idiomatic to use them like it is in Ruby.