5 ms·
Serious question about this line: "Reusing code via inheritance is fragile. Inheritance also couples interfaces to implementations, which makes reuse more diff
by wmccullough 8y ago
Serious question about this line:
"Reusing code via inheritance is fragile. Inheritance also couples interfaces to implementations, which makes reuse more difficult. This is its own topic, but even OO programmers will tell you to prefer “composition over inheritance”."
Isn't the goal to have implementations of interfaces so that you can inject implementations around in order to reduce tight coupling? Implementing an interface is not the same thing as inheritance. It's adhering an implementation to a contract. Are interfaces in ObjC different than what I'm used to from Java, C#, and others?
I mean this with sincerity, what am I missing? Is this a short-coming of my knowledge because I come from a strict OOP background? I've always used implementations of multiple interfaces to achieve composition.
- brightball 8y agoIn my experience, a practice that requires training to implement rather than enforcement by the language itself will become messy. Every OOP server side project that I’ve dealt with in the last 16 years eventually becomes an entangled mess. That’s across Java, Python, Ruby, PHP and C#. Probably the biggest advantage Ruby has over the rest is the easy of monkey patching far up the inheritance tree where needed rather than having to work around everything below. All that said, functional/compositional approaches avoid these issues at the language level by default. They are a huge win for maintenance long term. It’s one of the big reason I got interested in Go and Elixir in the first place.
- wmccullough 8y agoThank you for the explanation! If someone such as myself wanted to understand the philosophy of functional languages, do you have any book you'd recommend? Learning the languages is easy enough, but if I ever tried them I'd want to do it using the ideals of functional programming vs. trying to contort the language to be something it isnt't. I'm noticing a trend more and more where developers move to FP over OOP after a decade or so in their career. I feel if I don't give it a look, I could be missing an obvious lesson.
- brightball 8y agoThere are different extremes. Elixir is one that keeps things developer friendly and enforces everything. The new Programming Elixir book is probably a good place to start. It has constructs that definitely smooth the transition...and it’s really just a wonderful language. Plus the runtime is excellent for server side.
- AlexanderNull 8y agoWhile Scala isn't a pure functional language there are some good resources for picking up FP related concepts with it (and it's what I recently moved over to so it's most recent for me). Scala with Cats did a pretty good job for me at describing things in relatable terms. "The Red Book" (Functional Programming in Scala) goes a bit more in depth on these concepts but has a pretty steep learning curve compared to the cats book. Also check out anything Haskell/Eta/OCaml for server side (and probably also a bit of a steep learning curve) or if you're currently a front end developer CHECK OUT ELM NOWWWWWW. Core beginner concepts to youtube would be currying, higher order functions, and composition. Monads will come once you've mastered map/flatMap/reduce/fold chaining.
- lmm 8y agoI would recommend ML for the Working Programmer (available free online on the author's site). Learning ML forced me to write in a properly functional style rather than writing "C in $LANGUAGE" (the book doesn't even mention the possibility of using mutable variables until quite late on); by the same token I'm not sure the language is that usable in the "real world" (I work in Scala these days), but the lessons from it were useful even when I was working in Python.
- sevensor 8y agoI think the first sentence is key, "reusing code through inheritance" is the fragile thing that doesn't work. Pure interfaces do better, but then you're not reusing much code by inheritance. Programming to interfaces lets you reuse the code that uses the interface, but not the code that implements it. That's my take, anyhow.
- throwawayjava 8y agoMore importantly, this forces you to create an explicit interface for any code you'd like to reuse between implementations. Inheritance is fragile for a lot of reasons (see e.g., fragile base class). But the most common failure modes all have the same thing in common: the error happens because a developer fails to realize that there's an implicit interface between two things in the object heirarchy.
- sevensor 8y ago> there's an implicit interface between two things in the object heirarchy I think the tendency to miss this is compounded by fuzzy thinking about class hierarchies. I've lost count of the times I've heard somebody talk about an object of a child class "talking to" an object of the parent class, when calling an inherited method. They think there's actually another object -- their mental model for inheritance is composition. Using pure interfaces helps to quash this kind of thinking.
- naasking 8y ago> Implementing an interface is not the same thing as inheritance. Correct, but typical OO languages implement interfaces via inheritance since that's the only means of extension. The problem with inheritance is that it conflates subtyping with subclassing. These are separable concerns, so with interfaces you get proper subtyping without subclassing, but you can't typically have subclassing without subtyping which is why inheritance should generally be avoided.
- nexys 8y agoWhat is the difference between subtyping and subclassing? It looks confusing to me.
- zwieback 8y agoOversimplifying for this context: subclassing is reusing the implementation of a parent class, subtyping is when a type can be substituted for a (parent) class for some given functionality. It's confusing because it's not always easy to explain what constitutes "substitute", e.g. see "Liskov Substitution Principle". In some languages there might not be any class or interface relationship between subclasses - they just have the right functions that do the right things.
- kroltan 8y agoAs I understand it, subtyping is the actual conflation of interfaces (not necessarily a syntatical `interface`, but in the logical sense of "exposed things") into one type, and subclassing is direct extension, the so-called "is a" constraint. For example, in Rust, there is no subclassing: There is no concrete type that is also another type. But there is subtyping, that is, a concrete type can be used where a interface (in Rust, called `trait`) is required, granted it implements that interface. Additionally, external sources can implement their interfaces unto existing external types. In C#, you have subtyping+subclassing, but only as one. That is, you can have a concrete type B that is an A, and if A implements X, then B implements X. But you can't implement Y for A unless you have access to A's source. So if you want a type that is an A but also does Y, you _have_ to subclass A as a B, and implement Y on B.
- hinkley 8y agoI was responsible for a shared library amongst a bunch of teams that didn’t like each other and one greedy global contractor. The latter in particular wanted more money any time the interface changed (even when there was evidence they hadn’t consumed it yet) What I was handed was slow as molasses and insecure by design (no surprise since I arrived at late POC stage). I spent a considerable fraction of my cleverness on that project to upend the semantics and internal logic of that module with only a handful of changes to the syntax. And most of that came down to massaging the contract and a couple method signatures. Outlawyering that team is still one of my proudest moments, but I’ve lost less sleep after I left over that code than just about anything I’ve done.
- dunham 8y agoA "protocol" in swift is equivalent to an "interface" in Java. "protocol" seems to be the older name (per one of the guys that wrote Java): > I'm pretty sure that Java's'interface' is a direct rip-off of Obj-C's 'protocol' -- https://cs.gmu.edu/~sean/stuff/java-objc.html So "protocol oriented programming" is just advocating the use of swift's equivalent of java interfaces. (It'd be "interface oriented programming" in Java.) Edit: apologies if you know all this already, it just sounded like you were asking "what makes this protocol stuff better than interfaces".
- Someone 8y agoEquivalent, but not exactly the same, mostly in the sense that Java is less dynamic than Swift. Ones I know of: - In Java, you have to declare the interfaces that a class implements when you declare the class. In Swift, you can add conformance of a class to a protocol, even if you don’t have access to the class’s source code. - In Swift, protocol definitions can contain implementations of methods (I think this is being or has already been added to Java recently). For example, a method foo that takes a string argument could call the foo overload taking a character for each character in the string. That way, classes conforming to the protocol need not define the method taking a string. - Even if the protocol definition doesn’t declare that default implementation, you can add one by writing an extension method. All of those are useful, but also can make it hard to understand what code exactly is being called. (More info at https://docs.swift.org/swift-book/LanguageGuide/Protocols.html https://docs.swift.org/swift-book/LanguageGuide/Protocols.ht...)
- saagarjha 8y ago> In Swift, protocol definitions can contain implementations of methods Technically, no, they can't. What you do is write your protocol as usual, then extend the protocol with a default implementation.
- TeMPOraL 8y ago> "protocol" seems to be the older name (per one of the guys that wrote Java) Quite likelym as another Guy (Steele) responsible for Java was also a big name in the Lisp world, including chairing the committee that wrote ANSI standard for Common Lisp. In the Lisp world, protocols were a known concept. In CL nomenclature, a protocol is a set of generic functions and types used by those functions. Which is kind of like a Java interfaces, except with multiple dispach based on any of the arguments instead of the typical single dispatch of Java and friends. For example from TFA, a CL protocol would be a #'draw generic function and a 'drawable and 'renderer abstract types. The particular #'draw methods could be specialized on either argument (or both), and we could also imagine another protocol consisting of (the same) renderer type and some geometry-related generic functions. Point being, protocols are both an old and very useful concept, and like usual, C++/Java-like languages only allow expressing a small subset of it.
- deleted 8y ago[deleted]
- deleted 8y ago[deleted]
- lmm 8y agoThe line is about implementing interfaces rather than doing "extends"-style inheritance, which effectively conflates three different things: implementing the superclass' (possibly implicit) interface, composing in a value of the superclass and delegating method implementations to it.