6 ms·
I think it's really interesting to contrast this with Stroustroup's advice on concepts: "My rule of thumb is to avoid “single property concepts.”". He gives an
by seertaak 7y ago
I think it's really interesting to contrast this with Stroustroup's advice on concepts: "My rule of thumb is to avoid “single property concepts.”".
He gives an excellent example leading to this dictum: single property interface "Drawable". Let Shape implement drawable with widely expected results. But: let Cowboy implement Drawable -- now with disastrous consequences. The solution to this dilemma is as stated above, not to allow concepts/interfaces/{wave hands} to refer to a single object -- for example, a number is a concept which refers to multiple operations (i.e. methods).
To my mind, this feels right, albeit initially surprising. It makes me think that e.g. the "Neg" interface in Rust is wrong.
See: http://www.stroustrup.com/good_concepts.pdf http://www.stroustrup.com/good_concepts.pdf
- loopz 7y agoFor golang, single method interfaces are recommended as preferable. The problem with huge interfaces or classes is they can always become larger! While if you compartmentalize single responsibility into separate components (may be several methods if applicable to the domain and design), each reason to change may be restricted to that bounded context only. If not, it's a signal design might need revisit. The problem with "Drawable" is that it is property/data, and not messaging-based, thus breaking encapsulation, even if it was behaviour-based.
- seertaak 7y ago> The problem with huge interfaces or classes is they can always become larger! That's definitely a good reason to prefer small interfaces; I hadn't thought of that but it certainly makes sense. That said, I think we may be referring to different things when we use the word "property". Stroustroup is talking about properties in the mathematical sense, i.e. he's talking about the properties of the operation "draw()" in the concept Drawable. Am I misunderstanding you? To my mind that's an operation and closer to "message" (emphasis on the verb aspect) rather than data or property.
- loopz 7y ago"Drawable" as a name is pretty bland, like patterns. Do we ever really say "drawable" out loud? So I suspect if we seek more meaningful objects and models, they become more active, have better names, improved design, etc. If you ask a janitor about Drawable, will he say it's all about draw()? So I think it's kind of a dreary default that we need to avoid and focus on who the actors are, what messages they will pass, and the hidden treasures they encapsulate (don't show, but tell!).
- throwaway894345 7y agoFrequently in Go I find that single-method interfaces are easier to work with when made into a closure. Instead of `type Foo interface { Foo() }`, I often find `type Foo func()` easier to work with. There are probably exceptions to this; I'm mostly just voicing my own observation.
- steveklabnik 7y agoNeg is used to implement operator overloading for unary minus; it's unclear how you would implement this functionality without only doing one thing.
- seertaak 7y agoThanks for clarifying that; I was actually aware of the link to syntactic sugar and it's probably true that you want to control that independently. After all, who doesn't want to hijack unary minus for the purpose of as hackneyed rendering of EBNF? C++ certainly does it :) Anyway a serious answer to your comment would be to create a field or ring concept. This would unify some or all of the arithmetic operations. A neat bonus would be the ability to overload the one and zero literals for the set. So in field of nxn matrices on real numbers 0 is the zero matrix and 1 is the identity.
- steveklabnik 7y ago> After all, who doesn't want to hijack unary minus for the purpose of as hackneyed rendering of EBNF? Ha! > Anyway a serious answer to your comment would be to create a field or ring concept. Yeah, this is true. We really, really struggled to create a set of traits for numerics, even regardless of these more advanced ideas... so it's unclear this would work. But it's certainly closer than I had thought :)