7 ms·
On LISP, by Paul Graham. LISP was the second language I learned in college, but only after 6 years programming Java and C# that I came back and really learned L
by jcmoscon 9y ago
On LISP, by Paul Graham. LISP was the second language I learned in college, but only after 6 years programming Java and C# that I came back and really learned LISP. It was when I realized that I was doing everything wrong. For example design patterns exists because OO has serious problems that we don't find in a functional programming language and you only see this when you understand both paradigms.
- gnaritas 9y agoDesign patterns exist because common solutions to problems exist, not because OO has serious problems. I understand both paradigms and Lisp is hardly free of design patterns. Every time you pass a lambda to a higher order function you're using a strategy pattern. If you only see design patterns as problems with OO, you're missing the point of design patterns. All languages have design patterns. Common design pattern in Lisp, with-X macros to deal with scoped resource cleanup.
- sideshowb 9y agoAre Design Patterns really so out of fashion with the youth of today that nobody here mentions Design Patterns as their answer? Because it is mine, for better or worse. It took me from understanding OO to understanding how to build large systems with OO, writing maintainable code and using proper encapsulation. A much deeper work than Code Complete (though the latter is worth reading too). I have used functional languages as well (ML, Lisp; not Haskell yet though I think I get what monads are; plus I write a lot of Python, C++, JS in functional style) but I have yet to use them for any project as big. I hope I get the chance to one day. But for now Design Patterns gets my vote.
- gnaritas 9y ago> Are Design Patterns really so out of fashion with the youth of today that nobody here mentions Design Patterns as their answer? Apparently so; sad.
- deleted 9y ago[deleted]
- jdmichal 9y agoI don't think design patterns went out of fashion. I think the opposite happened -- they gained such mindshare that they became a solution looking for a problem for many people. That is, they forgot that design patterns are meant to solve problems, and that you should also only solve problems that actually exist. Instead we started getting things that resembled "Hello World Enterprise Edition" [0], which has been dubbed "lasagna code" -- lots of layers with a little bit of filling in each one. [0] https://gist.github.com/lolzballs/2152bc0f31ee0286b722 https://gist.github.com/lolzballs/2152bc0f31ee0286b722
- usmannk 9y agoThey meant the book Design Patterns https://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612 https://www.amazon.com/Design-Patterns-Elements-Reusable-Obj...
- jdmichal 9y agoThe person I replied to, sideshowb, explicitly asked about both design patterns and Design Patterns. Regardless, that book was what elevated design patterns into common knowledge within the object-oriented world. Their fate is tied together; the book and the patterns described within are practically synonymous.
- btilly 9y agoI'm nearing 50 so I'm hardly a youth. http://www.perlmonks.org/?node_id=133399 http://www.perlmonks.org/?node_id=133399 does a very good job of explaining why Design Patterns is a book to be careful with. By contrast Code Complete won't steer people wrong. See https://steve-yegge.blogspot.com/2006/03/execution-in-kingdom-of-nouns.html https://steve-yegge.blogspot.com/2006/03/execution-in-kingdo... for a cautionary tale about how a pursuit of OO purity can result in great verbosity, hiding intent behind a barrage of patterns. Resulting in code that I, for one, would rather not work with.
- sideshowb 9y agoAgree on both those fronts, if you're not careful. Still dp influenced my coding more than any other book to date, which was the original question.
- btilly 9y agoAs to that, Design Patterns did not influence my coding style very much. By contrast Code Complete was the first book that I read about how to structure code, and I've gained more from it on multiple rereads. I consider it a much better book. But then again I'm hardly enthusiastic about OO. See http://www.perlmonks.org/?node_id=318257 http://www.perlmonks.org/?node_id=318257 for more on my perspective.
- sideshowb 9y agoThat second link is great btw. I've always felt that aspect of java was odd, and I do like modern fables :-)
- gnaritas 9y agoYegge critiquing OO for verbosity, that's a hoot; talk about the pot calling the kettle black.
- btilly 9y agoBut only a person as verbose as Yegge can really on about Java at sufficient length to do the topic justice.
- hyperpallium 9y ago> build large systems DP are oft misused, but I think the main idea is a pattern language - a way to communicate to other developers what the architecture is. This is especially important on larger, more complex projects with more developers and developer turnover. Understanding the architecture of a project is crucial for grokking it, but usually not well documented. Even just "DPs are naming conventions" is helpful in this regard. I really disagree with the idea that most DPs are particularly clever or helpful - they are just the way you'd end up solving those kinds of problems yourself. If you look at your own pre-DP code, you'll see design patterns. What they give is a standardized terminology ("pattern language"). Sometimes an architecture seems more complex than necessary, but makes sense as you better understand the whole problem. e.g. how curl handles http. e.g. youtube-dl. (for me, when I reverse-engineered mini-versions of them, then studied their source) tl;dr "DPs are docs"
- tonyedgecombe 9y agoI've heard a lot of people saying they were already using these patterns before they read the gang of four book, it just put a label on those patterns for them.
- mattmanser 9y agoI think there are two reasons Design Patterns have disappeared: 1. Being able to use functional programming concepts in OO languages made a lot of design patterns irrelevant (Python, Ruby, C# 3.5, C++11, Java 8). I feel Crockford's The Good Parts really introduced these concepts to the OO crowd with javascript acting as the bridging language for the concepts. 2. Many design patterns were terrible ideas in practice. Factory patterns were a disaster, as were many of the others. Good in theory, utterly useless in practice. There was a blog here recently about TDD that argued TDD is useless because you need to be a great architect to do TDD correctly, and most programmers aren't great architects. Design patterns had the same problem, it was very easy to get them wrong and create an utter mess. Ultimately it's more maintainable to have a complicated monolith method than some crazy pattern no-one understands or dare touch.
- dragonwriter 9y ago> Design patterns exist because common solutions to problems exist, not because OO has serious problems Implementation-recipe design patterns only need to exist (or, rather, only need to be part of the active, day-to-day awareness of more than a small number of programmers per language) when the target language does not support implementing the common solutions as reusable code modules because doing so would require a kind of abstraction the language does not support. This has nothing to do with the OOP paradigm particularly; there's no reason OOP languages can't support powerful abstractions that reduce the need for that type of design patterns; the GoF book just emerged when the most popular industrial languages were both OOP and lacking in those facilities.
- brucephillips 9y agoCan you provide an example of how a language like C++ or Java would require a "design pattern" when another language wouldn't?
- esfandia 9y agoIn early Java versions, functions were not objects, and therefore could not be passed as parameters. So you needed patterns such as Command or Observer. In Javascript, for example, you wouldn't need them. More recent versions of Java, with the introduction of lambdas for example, are also reducing the need for these patterns.
- vram22 9y agoI'm not the person you asked, and not a patterns expert, but will try to answer, using the Template Method Pattern (a GoF book pattern) [1] as an example: - In Java [2] or C++, to implement that pattern, you may have to define an abstract class, or a class with some abstract and some concrete methods, and subclass it, and in the subclass, redefine some of the abstract methods (of the superclass) concretely. (Maybe interfaces can be used here instead of abstract classes/methods - in Java. Haven't used Java for a while, so not sure right now.) - In Python, you can just do: def transform(input, output): # Code here to read data from input, transform it, and # write the transformed data to output. Now let's say the code in the transform function does input.read() and output.write() (with maybe some way to indicate when the end of input is reached, like the null string is used in Python). In other words, methods like those of Python file objects are used for reading and writing. Given all this, you can now pass objects of any types as arguments for the input and output parameters, as long as they implement a read and a write method respectively, and the code will just work. This has been described as "smooth seamless polymorphism" in Python. It's also known as duck typing. https://en.wikipedia.org/wiki/Duck_typing https://en.wikipedia.org/wiki/Duck_typing [1] The Template Method Pattern is one of the ways in which frameworks (as opposed to libraries) are implemented. The abstract methods of the framework are implemented concretely by your code that the framework then calls, using the Hollywood principle - Don't call me, I'll call you, a.k.a. Inversion of Control (IoC). https://en.wikipedia.org/wiki/Template_method_pattern https://en.wikipedia.org/wiki/Template_method_pattern https://en.wikipedia.org/wiki/Inversion_of_control https://en.wikipedia.org/wiki/Inversion_of_control [2] Note that what I wrote is based on knowledge of older versions of Java - newer versions may have features that make the pattern simpler to implement, maybe without abstract classes/methods.
- oskarth 9y agoHere's some old school thought leadership on dynamic languages and design patterns using actual data. Specifically Peter Norvig looked at all the examples in books like Design Patterns and found that: 16 of 23 patterns are either invisible or simpler, due to [...] http://norvig.com/design-patterns/design-patterns.pdf http://norvig.com/design-patterns/design-patterns.pdf
- gnaritas 9y agoHe's talking about the original design patterns book which is a book of OO patterns, it's hardly surprising that many OO patterns are either invisible or simpler in a functional language, functional languages have different design patterns. And yes, I know who Norvig is and I've read that article before.
- btilly 9y agoThe parent comment is a variation of the well-known claim from http://wiki.c2.com/?DesignPatternsInDynamicProgramming http://wiki.c2.com/?DesignPatternsInDynamicProgramming which says that in a more powerful language, a variety of design patterns go away and become invisible. And Lisp in particular renders many common patterns irrelevant.
- kazinator 9y agoThe irony is that the languages which are the targets of design patterns already encode considerable design patterns from a previous generation of language research. Those languages are higher-level languages. A considerable number of design patterns disappears in them already. In Java or C++, you have functions with parameters and local variables. In assembly language, there is a "design pattern" of pushing words onto a stack to generate arguments, and moving the stack pointer to reserve a frame for local variables, and then unwinding these actions when the function returns. Also, saving certain registers and restoring them may be part of the pattern. This pattern can be supported with macros and pseudo-ops to varying degrees. In these higher level language, this pattern disappears. The concept of parameters and local variables doesn't disappear, of course. Those things are just declared in a simple way. The assembly language pattern for calling conventions is in fact a back-formation from higher level languages. It won't even occur to assembly language programmers until they think of their programs at a higher level, and translate from that to machine code. Or: let's look at C++ vs C. In C++, there are declarative mechanisms which generate code that can be understood in terms of C. It captures coding patterns, such as ensuring that a structure is properly initialized when instantiated, and cleaned up on every exit path from a function.
- gnaritas 9y agoAnd yet Lisp, the language that can abstract anything, still has design patterns because there's no such thing as a language without patterns that are useful to solve common problems.
- kazinator 9y agoDesign Patterns is about typing out boilerplate code by hand to solve a problem, because the language doesn't have the expressivity to encode the same solution directly. When it does have the expressivity, the underlying rendering of the pattern hasn't gone away; just the manual boiler-plate for producing it. For instance, if you're working in assembly language, then you might sometimes benefit from a "while loop design pattern" to keep your code clean. The while loop design pattern calls for some test code before a block which jumps past the block when the test is negative, and an unconditional backward branch at the end of the block back to that test expression. The while loop doesn't go away when you use a higher level language. You just indicate that you would like that pattern, and the compiler spits it out for you, invisibly. > Every time you pass a lambda to a higher order function you're using a strategy pattern. Every time you pass a "naked" lambda somewhere, you're potentially missing the opportunity to have a macro there do that for you.
- gnaritas 9y ago> Every time you pass a "naked" lambda somewhere, you're potentially missing the opportunity to have a macro there do that for you. True but equally sad that you must use Lisp to hide ugly Lisp because naked lambda's are so ugly. Yet the point remains, whether hidden behind a macro or not, design patterns still exist in Lisp and every other language and always will.
- kazinator 9y agoLambdas aren't "ugly"; they are sometimes just a mechanism that is not directly relevant to the problem domain: the "how" part of the solution, rather than "what". The point isn't to hide the lambdas, but to hide the "how", which might or might not use lambdas. The "how" could instead open-code the procedure that would have otherwise called the lambdas; then the material just becomes embedded forms in the inline code.
- gnaritas 9y agoLets not kid ourselves, hiding lambda's is one of the primary uses of macros in Lisp (obviously not the only). Yes, you're hiding the "how", we don't disagree there, but my point was that such syntactic abstraction is only necessary in Lisp because it's so ugly to directly use lambda. Compare to Smalltalk which uses naked lambda's everywhere because they're nice looking as is and don't need to be hidden away by special forms in order to feel idiomatic.
- swift 9y agoThat's true. I think the GP's point was probably that some GoF patterns, specifically, just exist to work around language deficiencies. My go-to example for that is the visitor pattern; something that's trivial in Haskell or Lisp is ridiculously heavyweight in C++ or Java.
- gnaritas 9y agoThat is true, some of "those" particular patterns work around language deficiencies, however OP misunderstand and think that means all patterns do that, they don't.
- kazinator 9y agoOO doesn't have serious problems. Crap implementation of OO bolted onto Algol derivatives has problems.
- icebraining 9y agoYeah, OO as commonly used is not the OO as originally envisioned and implemented: http://userpage.fu-berlin.de/~ram/pub/pub_jf47ht81Ht/doc_kay_oop_en http://userpage.fu-berlin.de/~ram/pub/pub_jf47ht81Ht/doc_kay...
- kazinator 9y agoSpeak of the devil; I just got +10 points an a "necromancer badge" for this: https://stackoverflow.com/questions/327955/does-functional-programming-replace-gof-design-patterns/20477117#20477117 https://stackoverflow.com/questions/327955/does-functional-p...
- btschaegg 9y agoThat was also the impression I got on this issue; however nowadays I'm usually less frustrated with what the respective languages provide and more with what people use them for. C++ since 11, C# since ~5 and Java 9 for example have actually introduced very useful tools¹ that would allow people to write much more readable code - yet there's always someone who insists that anything beyond the C++98-style is somehow evil and inherently unreliable. ¹Yes, they're by no means perfect, but they introduce are a lot of low-hanging fruit when it comes to improving code quality - if one decides to use them...