4 ms·
I hope... this is not another feature that is added to Ruby at the sake of the functional programming trend. Rubycop’s author criticized[0] Ruby 2.7 for losin
by pcr910303 7y ago
I hope... this is not another feature that is added to Ruby at the sake of the functional programming trend.
Rubycop’s author criticized[0] Ruby 2.7 for losing a direction/vision where Ruby should go (which sparked controversial operators that were quickly removed).
Most of them looks like, at least to me, trying to fit a functional programming features in an inherently object-oriented language to be ‘hip’. Like... the pipeline operator which had strange semantics.
I hope this isn’t one.
[0] Ruby, Where do We Go Now?: https://metaredux.com/posts/2019/12/06/ruby-where-do-we-go-now.html https://metaredux.com/posts/2019/12/06/ruby-where-do-we-go-n...
- RangerScience 7y agoHmmm. I'm definitely in favor of more functional programming features / capabilities, particularly in a language like Ruby that allows for pretty effective mixing of OOP/functional paradigms. Right tool for the job, where the job is usually "communicating with other programmers what this code should do". I've always found Ruby to be an amazing mix of functional & OOP already, what with blocks, and that class definitions are also (actually?) functions themselves. And don't forget being able to drop parens! I've also always felt like Ruby had mostly clear vision - arguably better than a perfectly clear one, since it leaves more room for play, exploration, and other people's contribution - even if it's not one that's able to be put into words. Every time I came across something surprising in Ruby, once I learned what was going on, it made sense in that larger whole.
- zelly 7y agoRuby blocks are another example of something that looks like a functional programming feature but is actually not. As in Java 8 and C++11, which also added lambdas, it doesn't have much in common with FP lambdas. These are essentially syntax sugar for an ad-hoc function that's too small to factor our and give a name. FP lambdas are the most elementary unit of computation. You're supposed to be doing absolutely everything with lambdas even addition, theoretically (head in the clouds academic BS), and the other syntax (like `do` in Haskell) is sugar for lambdas. So basically Ruby is far from FP. It sticks to OOP, which has actually been proven to work.
- pjmlp 7y agoFrom CS point of view, I miss the point you are trying to make. No mainstream FP language is doing pure lambda calculus.
- foldr 7y agoIIRC the main distinguishing feature of ruby blocks from regular anonymous functions is that you can break out of a containing scope from within them.
- uryga 7y ago> [Java 8 and C++11 lambdas] are essentially syntax sugar for an ad-hoc function that's what a lambda is pretty much anywhere, FP or not :) > [in FP] you're supposed to be doing absolutely everything with lambdas even addition in imperative programming, are you supposed to be doing everything by writing symbols to a moving tape, a la Turing? there's more to FP than pure lambda calculus, even if it was the starting point. sure, natural numbers and other types can be implemented with lambdas. no serious FP language actually does that.
- zelly 7y agoWhy can't pattern matching fit in OOP? It's not really functional, despite being in most functional languages. It's just sugar for more lengthy imperative conditionals and unpacking.
- pjmlp 7y agoIndeed, Objective Caml is a multi-paradigm language with pattern matching.
- totalperspectiv 7y agoAnd Scala. The poster child of oop + functional
- agumonkey 7y agoBecause part of the OOP mindset is to never dig into an object and only interact with a flat interface. From the few that I remember from OO articles in the 00s. Now technically yes all FP idioms are just simple operations below that can be used. And they are.. python, js have destructuring which is a first stage pattern matching.
- zozbot234 7y agoDestructuring ("digging into" a type) makes little sense with open records and sums, which OOP introduced into common use. The "closed" ('final', 'sealed' etc.) case where destructuring makes sense was disregarded for some time because it was thought that extensibility was always the appropriate choice. Today, "open" extensibility mechanisms are considered a bit problematic because it's never really clear what invariants they should preserve, so maintaining correctness is an issue. A "closed" interface makes it essier to specify related invariants.
- verttii 7y agoIt's typical in statically typed functional languages to match against Algebraic data type value constructors. These ADTs have a fixed amount of variants, which makes it suitable to do a clean pattern match. ADTs don't exist in OOP. It gets more complicated to do matches against classes whose abstractions are not really decomposable so easily.
- pjmlp 7y ago> functional programming features What features? Smalltalk-80 already had lambdas and LINQ, they were just called blocks and collection methods instead. Pattern matching in OOP languages was a path pursued by BETA, Simula's successor by the same authors, where even classes are instances of patterns as concept.
- verttii 7y agoYou got any links to share on this? I'm doing a bit of academic study on the subject of pattern matching in OOP.
- pjmlp 7y agoBETA programming language, https://beta.cs.au.dk/ https://beta.cs.au.dk/ Chapter 3, Objects and Patterns Oberon-2 type guards, which are basic but still have the same idea somehow, https://cseweb.ucsd.edu/~wgg/CSE131B/oberon2.htm https://cseweb.ucsd.edu/~wgg/CSE131B/oberon2.htm Modula-3 type case, https://www.cs.purdue.edu/homes/hosking/m3/reference/typecase.html https://www.cs.purdue.edu/homes/hosking/m3/reference/typecas...
- verttii 7y agoThanks!
- bonquesha99 7y agoDefinitely agree regarding the strange semantics recently like the pipeline[0] or `.:` method reference[1] operators. I do think those kind of functional features would be handy if they behaved correctly and had a more Ruby-like syntax instead of introducing foreign looking operators. Luckily this new pattern matching feature appears to behave like expected and feels pretty natural - just a new `in` keyword and some variable binding syntax to familiarize ourselves with (which we already kind of use with statements like `rescue`). Awhile back we experimented with an alternative Ruby pipe operator proof of concept[2] that is "operator-less" and looks just like regular old Ruby blocks with method calls inside of it. Maybe there's still a chance for something like this now that those other implementations have been reverted! # regular inverted method calls JSON.parse(Net::HTTP.get(URI.parse(url))) # could be written left to right url.pipe { URI.parse; Net::HTTP.get; JSON.parse } # or top to bottom for even more clarity url.pipe do URI.parse Net::HTTP.get JSON.parse end [0] Revert pipeline operator: http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/94645 http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/... [1] Revert method reference operator: https://bugs.ruby-lang.org/issues/16275 https://bugs.ruby-lang.org/issues/16275 [2] Experimental "operator-less" Ruby pipe operator proof of concept: https://github.com/lendinghome/pipe_operator https://github.com/lendinghome/pipe_operator