4 ms·
>imagine yourself building UI component without classes or inheritance I see no problem at all. UI development in my opinion becomes much more elegant, concise
by Morgawr 12y ago
>imagine yourself building UI component without classes or inheritance
I see no problem at all. UI development in my opinion becomes much more elegant, concise and easy to follow/reason about in a functional language that does not implement classes or inheritance. As you said, Go has struct inheritance and interfaces, that's how you do things in Go and every Go developer is familiar with the concept, it's clean and elegant. I honestly see no problem whatsoever.
- tormeh 12y agoWell, if what you are doing is inheritance-heavy, then OOP features will make your code cleaner. It's what OOP is made for. You can do it in Go, but it's not as elegant.
- NateDad 12y agoThere is almost never code that requires inheritance.
- jrockway 12y agoInheritance, in practice, is cut-n-paste for people that think they're too smart for cut-n-paste. "Give me an object like Foo, but with this one little thing changed."
- xienze 12y agoSure, you can clone Foo into Bar and change one thing in Bar. But what happens when you need to change functionality common between Foo and Bar? Oh right, you have to change the same thing in two places now. Doesn't seem so smart anymore...
- NateDad 12y agoThis is why Go has standalone functions and interfaces. You can easily share logic between types without having the types be the same thing. The biggest problem with inheritance is that it's a lot like monkey patching (except in production)... the rest of the base class's code expects method X to do ABC, and you've just swapped out the implementation to do LMNO ... and if that never bites you in the ass, you're luckier than most OO programmers I know.
- jrockway 12y agoThis is the big insight. Instead of trying to inherit code, figure out what that code does that interesting, and allow that code to do the interesting things without being inside the class. For example, imagine your class has a "WriteToFile" method. Instead of that, it should just have a method to return its representation, delegating the responsibility of writing to a file to something else. (Of course, the fact that a file can be written to should also be one of those "interesting things", and the thing that writes shouldn't care that it's backed by a file.) Instead of foo.WriteToFile("/tmp/foo") You might write: file.Write(foo.Representation()). I promise that most inheritance in the real world is attempting to reuse something like "WriteToFile". "I wouldn't want to copy-paste the file-writing code, so I'll inherit from something that can write itself to the file." No. Don't do that.
- spopejoy 12y agoMore than just "in practice", it might be worse than copy/paste. Richard Gabriel nailed it in the 90s when he identified inheritance as a form of compression, not reuse, forcing the programmer to have to understand every class under inheritance to understand any part of it: Compression is a little dangerous because it requires the programmer to understand a fair amount about the context from which compressed code will take its meaning. Not only does this require available source code or excellent documentation, but the nature of inherited language also forces the programmer to understand the source or documentation. If a programmer needs a lot of context to understand a program he needs to extend, he may make mistake because of misunderstandings. (from Patterns in Software, which is a really deep if long-winded book)
- dragonwriter 12y agoInheritance isn't a property of what code does, but how the programmer chooses to do it. There is no problem that is inherently inheritance-heavy.
- JulianMorrison 12y agoInheritance is almost always an anti-pattern. It's encapsulation-breaking, dependency-creating, brittle and limited.
- ajuc 12y agoInheritance as taught in OO courses (deep class hierarchies) is bad most of the time. We can save 100 lines of code there by coupling 2 slightly related things forever (and arbitrarily choosing this criteria for division as the most important). I've made game before I knew OO programming. I haven't knew it then, but I used Interpreter Pattern - there was data model, with a list of records, each record had some enums deciding how game logic should handle it. There was main loop updating the model using these enums to choose logic to run on this record. It wasn't pretty but it worked, I was able to modify it however I wanted, to choose logic to run on some record basing on enums, other atributes of given record, attributes of parent records, or of colliding records, on whatever I wanted basicaly. Then I rewrote the game to use OO design (I was enthusiastic- this is exactly what I need - I thought). It turns out that I had to choose arbitrary divisions. I can divide game objects into Solid and non-solid, Static and Movable, Visible and Invisible, and also Smart vs Dumb Objects. Which division should be first in class hierarchy? All the rest would need to be duplicated anyway. SmartMovableVisible, SmartMovableInvisible, SmartStaticVisible, etc... Ugly. Inheritance solves part of the problem and leaves you with inconsistent solution. The real solution is strategy pattern, and composition over inheritance. It can be done just as well in languages without inheritance (but with lambdas).
- vegedor 12y agoI don't agree with the premises. Teaching in higher classes assumes independent study of the reader as enhancement. For me it's making much more sense to look at a consistent implementation of OOP features in C [1] (understanding less and less to the end of the latest paper). It make sense to understand the data structures behind it to reason about the transformation of your game to OOP. For your problem there's Multiple Inheritance, but not every OOP-Language supports it. You have movable, visible, etc as objects and game_objects inherit from them as needed. If you have learned OOP with a toy metaphor and dived straight into Java or Python, you might miss out on some formal fundamentals. Some say Java doesn't implement OOP properly, but at least it's running ;). Naturally most students also want to get practical and don't want to dabble in the dire theory. In C you'd have bitmasks encoding the types and functions called based on that (or how'd you do it? gibe references). If you had your logic wired up to call functions straight away, it might have made sense to encode the functionality as member functions, to have an object being immobile simply by not using the move function. The data would be stored in pools of other objects, like location data, that your functions work on. I'm still learning. If I'm not making sense, tell me, but I think that's what MV* does? For a simple enough problem there are different probable solutions [1] http://ldeniau.web.cern.ch/ldeniau/oopc.html http://ldeniau.web.cern.ch/ldeniau/oopc.html but there are others as well
- platz 12y agoIt's not about imagining what the best UI component would look like removed from any particular framework, but what the practical constraints are working within the already-existing android UI framework. Android APIs were simply designed for inheritance-oo style to work with them, and trying to avoid this will cause pain. A similar situation has occured in ios development where the functional aspects of Swift do not complement the existing design of the coca framework.
- TheDong 12y ago> easy to follow/reason about in a functional language Go is explicitly not functional. Many builtin functions mutate (look at Sort for an example). There's no map. https://groups.google.com/forum/#!topic/golang-nuts/RKymTuSCHS0 https://groups.google.com/forum/#!topic/golang-nuts/RKymTuSC... Functions are only almost first-class. For example... http://play.golang.org/p/WB133vrGKD http://play.golang.org/p/WB133vrGKD Go does have powerful constructs, but to call it "functional" is maligned. I would also argue that it's not always easy to reason about and follow. The reason we build abstractions, which Java allows perfectly, is so that we can ignore the hidden complexity and reason about code more easily. Go explicitly makes it difficult to hide underlying complexity. If I want to make, for example, a Bimap (which Java has many clean implementations of) I get to pick from two poisons in Go: Either I must force everyone who uses it to type-cast on every get (implement the bimap via taking and returning interface{}), or I must surface the implementation details (two maps) and have users directly manipulate those since the builtin uni-directional map is a type-safe generic data-structure which I can't replicate in the language itself. This might look appealing at first, but since I also need to do some Locking my interface for allowing people to manipulate those maps directly rapidly becomes troublesome. Neither of those choices sound appealing to me. Honestly, if you want to avoid java now you have a plethora of options. You can develop for android with Scala and get basically first-class support. You can develop for android via webview+html+js and use something like http://ocsigen.org/js_of_ocaml/ http://ocsigen.org/js_of_ocaml/ to write OCaml and have a wonderful actually functional language. You can wait for Rust to have some android bindings implemented and use a wonderful language that allows powerful features like macros that are excellent for interface-building. I don't mean to bash on Go since it does have a place somewhere, I just feel that it is not the correct language for something UI heavy nor anywhere that suitably complex abstractions and complexity-hiding are a necessity.
- Morgawr 12y agoI never claimed Go was a functional language. Sorry, maybe I shouldn't have placed those two statements on the same line but I was talking about two different things. After all, Go does implement inheritance and OOP constructs using structs (in a way), I thought it was obvious I was talking about a different thing when I said functional languages without inheritance or classes can work well with UI.