6 ms·
In the "things learned from Ruby" section: Focus on strong object oriented programming What I've learned from Ruby is to favor functional programming concep
by tcopeland 8y ago
In the "things learned from Ruby" section:
Focus on strong object oriented programming
What I've learned from Ruby is to favor functional programming concepts - minimize side effects, isolate state mutation, etc. Ruby is definitely OO, but when my Ruby code is more functional it's less buggy, easier to understand and move around, and generally less convoluted.
- dzuc 8y agoLike Gary Bernhardt's notion of a "Functional Core, Imperative Shell" — https://www.destroyallsoftware.com/screencasts/catalog/functional-core-imperative-shell https://www.destroyallsoftware.com/screencasts/catalog/funct...
- faitswulff 8y agoDamn, I knew I got this idea from somewhere, I just totally forgot where. Thanks for posting this link - I'll have to rewatch it.
- aardvark179 8y agoBrian Goetz has talked about this as well - see FP is Dead - Long Live FP (https://youtu.be/ROL58LJGNfA https://youtu.be/ROL58LJGNfA).
- always_good 8y agoI watched that video in my earlier 20s and it changed how I wrote code.
- yxhuvud 8y agoAs someone stated, good OO and good functional is approaching the same goal from different sides. Your code being functional doesn't really make it less OO.
- joncampbelldev 8y agoExcept if you're using immutable data, pure functions and explicit state there's a lot less room for OO which (as presented by ruby, java etc) involves mutable data accessed/changed via methods that conceal their state.
- yxhuvud 8y agoNothing in the concept of OO enforces mutability. The paradigm doesn't enforce anything at all there. You want immutable objects that never changes once created? Fine, go for it.
- mikekchar 8y agoI'm literally writing a blog post about this now (I'm building an objects system from scratch using only FP techniques in JavaScript... slightly eclectic ;-) ). The very interesting thing about this exercise is that immutability solves a huge host of problems in OO systems. As a very small example, even the diamond inheritance issue just goes away because nothing is ever updated. If B and C both have the base class A, you can safely instantiate A twice because it doesn't matter which one you use. I'm about half way done. When I'm done, I'll post it on HN, but if you are interested here is what I've got so far: https://github.com/ygt-mikekchar/oojs/blob/master/oojs.org https://github.com/ygt-mikekchar/oojs/blob/master/oojs.org If anyone ends up reading it, I'm very happy to receive criticism, so feel free to leave an issue.
- cutler 8y agoSure, you can simulate immutability in Ruby or Python but it's not real immutability. It's just shallow freezing. The real point, however, is that immutability is not idiomatic in OOP languages. Objects are intended to store state and have it modified. It's not what a language can be made to do that matters. It's what is idiomatic.
- joncampbelldev 8y agoAnd yet 99% of code written in Java, Ruby, <Generic OOP language here> is based on mutable objects. Its not about what is possible, we're all familiar with the turing completeness of everything. It's about what is: the default + easy + encouraged in the ecosystem.
- bitwize 8y agoI've learned to think of objects as not exactly monadic, but monad-like in their pattern of use: whenever there's a bit of state that I need to track and isolate from all other state in the system, wrap that in a class. The allowable state transitions then become methods.
- yxhuvud 8y agoRight, and most of the times, if state have different life times, then it should be in different classes.
- deleted 8y ago[deleted]
- blunte 8y agoRuby used functionally is great, but it takes an already time-inefficient language and amplifies that weakness (lots of creating new collections and returning them, whereas normally in Ruby you would modify elements within the collection).
- mullsork 8y agoIsn’t there something called LazyEnumerator that deals with this? In terms of chained .map at least
- djur 8y agoLazy enumerators don't make each individual step of the iteration any more efficient. They just let you stop the iteration partway through without traversing the entire original enumerable. Given this contrived example: a = (1..1000).lazy.select(&:even?).map{|i| i*2 }.map{|i| i + 1 }.map(&:to_s).map(&:reverse) There is no benefit from lazy if you do `a.join(",")`, since that iterates over the entire sequence. But if you do `a.take(10)` or `a.detect{|s| s == "14" }`, the chain will only be executed for each item in turn until 10 elements are produced or an element is the string "14", respectively.
- bbatha 8y agoThere is absolutely a benefit to lazy if you're doing more than one combinator even if you ultimately need to iterate over the whole list such as the join case. The lazy version basically turns into a = "" (1..1000).each { |i| next if i.odd? i *= 2 i += 1 a << i.to_s.reverse + ", " # ya ya, trailing comma } Where as the non lazy version turns into: odds = [] (1..1000).each { |i| odds << i if i.even? } doubled = [] odds.each { |o| doubled << o * 2 } incremented = [] doubled.each { |d| incremented << d + 1 } strs = [] incremented.each { |i| i.to_s } a = "" strs.each{ |s| a << s.reversed + ", " } Which means that you have you went from N iterations to 5*N iterations, with 5 intermediate arrays in this case.
- 8y ago
- _sdegutis 8y agoI've always had better luck restricting FP to using things like map, reduce, filter, (etc) inside methods as an implementation detail, but having the structure of the app use OOP.
- scruple 8y agoThis is where I've landed when writing Ruby code, as well, and it's served me really well.
- pjmlp 8y agoIncidently that is how FP in done in Smalltalk as well. All those methods, and reactive patterns (Observer and such) were already present in Smalltalk-80.
- mercer 8y agoElixir, I suppose, would be a 'modern' example too.
- dogweather 8y agoYes - Ruby makes it easy. I'm run into the downside, though, that Ruby isn't optimized for immutable operations - tons of object instances created. I've needed to 'pythonize' my Ruby code in the worst cases - using mutable functions to dramatically reduce memory usage.
- cutler 8y agoCan you say more about this Pythonisation process? How is Python any better at immutable operations? Ruby and Python are both OO languages which can be used in a procedural style. Hell, you can write a whole app in Ruby without creating a single class if you so choose.
- dogweather 8y agoIMO, Python is worse at immutable operations. Ruby makes it easy (but inefficient). Python makes mutable code the easy path.
- wrmsr 8y agoI think what they mean by 'pythonize' is ditching fluent functional style and embracing dumb imperative mutability for the sake of efficiency. Rewriting sequence compositions as stateful for-loops. Idiomatic Python is more pragmatic than Ruby in that regard, stupid=good (yet ironically Ruby's strings are mutable and Python's aren't :p).