3 ms·
Keywords are of course secondary. Did you miss the "or direct expressions of those concepts" part? I was implying the existence of some boilerplate reducing syn
by loup-vaillant 9y ago
Keywords are of course secondary. Did you miss the "or direct expressions of those concepts" part? I was implying the existence of some boilerplate reducing syntax behind them. With the right features, most patterns vanish. For instance:
// C++98
class Adder {
public:
Adder(int inc) : _inc(inc) {}
int const operator+(int n) { return n + _inc; }
private:
int _inc;
};
// C++11
std::function(int(int)) adder(int inc) {
return [=](int n) { return x + n; };
}
(* Ocaml *)
let adder inc n = inc + n
-- Haskell
adder inc n = inc + n
Assuming currying is a good fit for your problem, you probably don't want to bother with factories, if you can use a language that supports currying directly. Same goes for other patterns: whichever you need suggest what language features you want.
Or you could be content with repeating the same kind of code over and over, but I'm not going to accuse you of such obvious stupidity.
- geezerjay 9y ago> With the right features, most patterns vanish. For instance: The thing is they don't. For example, a function pointer does not fill the need that strategy patterns fill. You look at a function pointer and you have no idea where and how and why it is supposed to be used, there is no type constraint, and there isn't even any way to track where how many different instances there are. A function pointer alone says nothing. Yet, specifying a common interface does, as well as implementing any concrete strategy. That's the whole point of using patterns. Furthermore, design patterns help clarify technical discussions as they communicate clear concepts as well as solutions to particular problems they solve. You get a clear idea of how a data access module is designed if the designer states that he used active records or repositories, and if classes are named appropriately you can already form a clear mental model of what to expect and, more importantly, what you will can or may need to do to fix a bug or implement a feature.
- loup-vaillant 9y agoWho ever said "the right features" were limited to function pointers? Who ever even talked about function pointers? My example didn't even use function pointers! Are your imagination so limited that you cannot think of language features that would reduce the need for any specific pattern? I just showed you one, dammit! Let's step back a little: > 9 out of 10 patterns are nothing more than specific uses of inheritance and polymorphism. Of course, inheritance and polymorphism are the only thing Java has! Or had, back in 1995. Hammer & nail. There are other ways of expressing those patterns, other ways of solving the same problems that do not require those patterns at all. You just need to wake the fuck up and realise OOP is not the only game in town. > design patterns help clarify technical discussions as they communicate clear concepts as well as solutions to particular problems they solve. I have yet to witness a single instance of that in my job, and I've seen loads. On the contrary, naming patterns often clouds the underlying concepts. A pet peeve of mine is the Singleton. It's overused for sure, but that also makes it one of the most widely understood patterns. Yet few seem to realise that singletons are nothing more than global variables with a couple bells and whistles. And since the thing is not called "global variable", it doesn't trigger the appropriate mental warnings. What good are pattern names when programmers can't think clearly to begin with? It's not just the conversations. Every time I saw a pattern name in real code, I could find a simpler way. I also saw misapplied patterns, like factories that actually were memory pools. Whoever did that didn't know what they were talking about, and patterns didn't save them.
- mikekchar 9y agoI've read lots of your postings and I like them. I think you are a smart person and I realise that this topic is getting a bit frustrating. But because I think we're all talking past one another, I'll hopefully be able to clear up a few things. Patterns of code exist. It's a mistake to look at the GoF pattern catalogue and think that it represents patterns that you should use in every situation (or even at all!). I remember hearing someone say one time that all programming should be made up of GoF patterns (touring complete??? ;-) ). Yes, it's absurd. Going all the way back to the original poor article, that's really the problem. People latch on to these ideas; they hear something and it sounds attractive; whatever. Poor programmers are poor programmers. I personally don't think they get worse having learned about patterns. It can help, but it's not the only thing you need by a long shot. In FP there are lots of patterns. A Functor could be a pattern if anyone bothered to write it up in that fashion. It would make a very nice pattern. Applicative is a great example of a generated pattern -- it's a thing you would never actually design up front, but just pops out. Maybe/Option, Either, etc monads.... awesome patterns (again, if anyone decided to write them up in that fashion). Let's go back to GoF patterns, maybe the Singleton. The Singleton is not a global variable with a couple of bells and whistles. That's a very popular, but misconstrued view. It's actually the bells and whistles that are the point of the Singleton. A Singleton is a method to ensure that something occurs at most one time in your system (potentially scoped). You use it when you have a piece of hardware that will crash if you initialise it twice. Or when you have to initialise a communications protocol exactly once. Or when you have a very expensive operation and you want to ensure that it only gets called once in a particular scope. Usually people use a global scope for their singletons -- because that's what they actually want. But it's not uncommon to scope singletons at a module level, or other kinds of scope. How do you usually implement a singleton? By providing a function in the scope you want that memoises a piece of data. Yeah, it's not rocket science. It's not supposed to be. It's just a technique. And if you don't write essentially the same code in non-object based langues to achieve the same result, I'll eat my hat (or at least I'll ask you how you would do it differently and then suggest that it might make a good pattern). One of the weaknesses of the GoF book was that it wrote all the examples in similar languages. At the time, those were the languages that were relevant. Those were the languages that the authors were proficient in. It might surprise many people to know that the GoF was not the first publication on software patterns (not by a long shot). In fact the GoF was only interesting because they attempted to make a pattern catalogue -- a set of patterns that would be relevant to a certain kind of programming. That this is not the kind of programming you enjoy is completely irrelevant. There are other patterns. You can make other catalogues. That is the whole point. And, you are correct. Patterns don't make a good programmer. But good programmers know programming techniques that are relevant to the style of programming that they use. How do they learn those techniques? How do they communicate where they are appropriate and where they are not? Back in my day we just said, "Here's a keyboard. Don't suck!" And then we'd look at their code and say, "You suck. Why can't you write code like mine?" I'm not really so happy to go back to those days.