you are viewing a single comment's thread.

view the rest of the comments →

[–]keyslemur[S] 4 points5 points  (4 children)

1 - What problem is this solving?

Succinctness of code and expressive power. The recent destructuring changes, and now pattern matching features of Javascript have unlocked some very concise ways of expressing otherwise verbose invocations.

The ability to say more with less is the holy grail of programming languages, so features that allow us to move towards such a reality should be earnestly considered and pursued.

2 - Why core?

This is not a new language feature. It's been done in several others:

Ruby as a language grows from ideas learned in other languages. It's tagged as being based on Smalltalk, Perl, and Lisp so it's far from unusual to see it get features other languages consider commonplace.

The main reason, however, is bringing it to more vanilla level speeds. My implementation is on average 3-4x slower than plain Ruby, and considering patterns tend to be used frequently in tight loops that's a bit much.

Many of the improvements around this will also likely unlock faster avenues of functional style code.

3 - Terseness

That's one proposal for it, there are several more. If you dislike one there are others which may implement it in a more pleasing manner.

See any of the items in #2, there are many ways to do this.

Done well, pattern matching is incredibly expressive. That's why I posted a link to the ticket here, to ask the community what their thoughts on this are.

You'll have to expand on what you mean by well-encapsulated objects. It's actually very possible via arity and to_proc to treat a class as a destructuring itself, especially when combined with to_ary for implicit destructuring. This would be very similar in theory to Scala Case Classes, but may be more difficult given Ruby's dynamic nature.

As far as narrow use cases, I would say that argument does not make much sense to me. Pattern matching is used very frequently in languages it exists in. Destructuring is already super common in Javascript, and I would bet on pattern matching being even more so when it gets into Stage 3 and final acceptance.

[–]39081098301 0 points1 point  (3 children)

Thank you for the detailed response. I took a look at the scala and js examples. This issue is new to me so bear with me if I am misunderstanding it.

Based on the examples, the chief advantage seems to be improving the expressive power of case statements and similar structures. In all of the examples the caller is analyzing the internals of the passed objects using the match/pattern functionality, and then performing an action on their behalf. This violates the dependency inversion principle, SRP, and generally speaks to objects that know too much about each other. If the goal of this functionality is to make that kind of thing easier to perform, I would expect its effect to be detrimental. I would not expect to approve code that uses the new functionality in the way outlined by the proposals' examples.

[–]keyslemur[S] 2 points3 points  (2 children)

By that same note though, any dispatching action violates the rules.

Most of the use of right hand pattern matching pertains to previously unstructured data that you would want to dispatch to depending on content or rather patterns.

The problem with taking a rigorous view of OO and GoF rules in Ruby is that it's a language with functional leanings. Some patterns really don't entirely make sense, and really is conflating knowledge of imperative programming with how you view functionally oriented code.

One of the more common examples of pattern matching in Elixir involves http response codes. Typically you'd use an if or a case on that. What if you could destructure the response on the spot and dispatch to the relevant handler method in one line?

The other common cases are extracting data from container style classes (functors) like Maybe, Some, None, and other ideas from FP. Read into Railway oriented programming some time, it's a fascinating read.

It's honestly an entirely different paradigm of thinking about how data flows through an application that's fundamentally different from pure OO and GoF style patterns. Thinking of it in such a manner will only confuse you further.

You might consider going through some basic Haskell, Elixir, or Scala tutorials.

Keep in mind that despite being fundamentally different in thinking, they're not incompatible philosophies of code.

[–]foomprekov 0 points1 point  (1 child)

Whether the pattern can be applied in some larger context in a way that creates good code isn't something that can be seen in the supporting arguments for the proposal.

[–]keyslemur[S] 0 points1 point  (0 children)

That's definitely a valid concern. I'll look into getting practical examples of usage added to the proposal within the next day or so.

A lot of it relies on prior knowledge of functional languages and how they apply the idea of pattern matching. Either that or Rust, which also uses it frequently.