11 ms·
How to Design Programs 2nd Edition
- ChicagoDave 3y agoI would not follow any of this book anymore. Abstractions lead to coupling and complexity. So many outdated principles I can’t enumerate them all.
- Hypergraphe 3y agoIn fact, that could be useful to ellaborate a bit.
- ChicagoDave 3y agoPrimarily this book completely ignores communication with subject matter experts and the business. This is fundamentally more important than any language, process, or platform.
- deleted 3y ago[deleted]
- Ligma123 3y ago>Primarily this book completely ignores communication with subject matter experts and the business. Probably because this isn't an advanced book on Software Engineering, but an introductory book to programming.
- sussmannbaka 3y agoThis is wrong, it’s a core part of the design process as described in the book.
- geokon 3y agoI also found the outside-in way they solve problems (using stubs for inner calls) very bizarre. I could be wrong.. But I don't think anyone codes like that
- regularfry 3y ago"Using stubs for inner calls" is literally a top-level description of London-style TDD.
- kmac_ 3y agoOnly Detroid school! Mocks should be banned (unless they mock external system). London-style tests cargo culting is one of the reasons why OOP got bad name.
- regularfry 3y agoLeaving mocks in place once you're done should be banned, I agree with that. I think they're fine as an exploratory tool to figure out what an interface should look like.
- kmac_ 3y agoMocks means that there's a side effect neccessary (and that's quite rare) so the use is justified in such a case. If a stub is needed, then mostly it's gone when the code is refactored to a more functional style. Unfortunately, most OOP developers bury side effects at the bottom of the stack, instead of passing an object that describes the side effect to happen (which it's executed at the shallow and simple application layer). Said result object can be tested as any other function result and no mocking is required.
- segfaltnh 3y agoI love this sort of approach for one-shot externalities but what about when your entire program is a conversation with external components? My current project coordinates software repositories and services within AWS and I find myself using a lot of mocks in testing. I can return a tree of lambdas but then I have to resolve them against something and that's just replacing mocks with lambdas, really. Not sure it's any better in practice.
- atoav 3y ago> Abstractions lead to coupling and complexity. So you write everything in assembly and rewrite it completely for every new target system? Seems a bit tedious to me /s Just kidding abstraction serves it's function and the right amount of abstraction makes things better, more transferable, easier to maintain etc. I think for example about hardware abstraction layers (HAL) in embedded programming. But abstraction in programming is never a value in itself and its use needs to be weighed carefully. I think it is best to teach people to stick to the data and to think about transformations between said data. If they don't know abstraction (aka beginner's spaghetti code) it is worth telling them about it.
- SanderNL 3y agoI think ORMs fit that bill. For some reason they were (are?) incredibly popular, but I don't think they stood the test of time. In the case of SQL, it's already an abstraction. No need for elaborate wizardry to hide the fact you're about to JOIN a table or two. Just write the damn join. Every. Single. Project. I see using ORMs resulted in a baseline 20+ queries being fired under the hood for every screen. They are not bad in and of themselves, I think that they attract or are amenable to a certain type of development mindset that ends in bad results. I have a very hard time thinking of any kind of object oriented abstraction that turned out to be a very good idea.
- ChicagoDave 3y agoRelational databases are an operational anti-pattern. ORMs have proven that.
- barrkel 3y agoRelational databases have shown, and will continue to show more longevity than object orientation. Facts and the relationships between facts is a deeper foundational principle than the concept mashup of modularity, hidden [mutable] state, dynamic dispatch and interface subtyping that object orientation is formed from. Databases are more long-lived than applications, so applications tend towards adapting to the form of the data rather than the other way around.
- stinos 3y agoAbstractions lead to coupling and complexity. The wrong abstractions can lead to coupling and complexity. The right ones on the other hand are all about reducing coupling and complexity.
- ChicagoDave 3y agoWe have a history of abstraction-based code that’s turned applications into frozen balls of mud. We have so many tools to help write good code that the short-term savings of shared libraries is superseded by having distinct codebases that can be modified without those dependency concerns. Same is true for finding bugs in many places and easily setting those up for maintenance releases.
- kaba0 3y agoThere is no going around complexity. We are absolutely standing on the shoulders of huge giants; even if you think you don’t have any dependency, behind the scenes you use many decades-old libraries dealing with the complexity of floating point arithmetics and such. Also, Brooks paper is still true, the only real, significant productivity boost is reusing existing code. Even if you rewrite everything from scratch, you will still have to carry the exact same amount of essential complexity. Managing complexity is pretty much the most important part of CS.
- DanielHB 3y agoopen any network communications protocol RFC or any CPU design architecture or operating systems memory tables or operating systems filesystems with journaling or hardware I/O it is crazy that society hasn't collapsed yet
- DanielHB 3y agoSome engineer from Netflix once said something along the lines: "Microservices, not too many, mostly alongside team boundaries". Meaning most microservices should be wholly owned by a team and a team should ideally own only one microservice (but exceptions are allowed under special circumstances) Like microservices, I feel code abstractions should be thought in a similar way, mostly a thing we use in our team, not company wide In my own team I have to fight very hard to keep dependencies to external code down, the amount of entangling people are willing to put their code through is just crazy. An argument I often put is: "Why should we use lib X from team Y from my company if they don't even feel it is good enough to open source?". Any external code that my team imports into our project should be good enough it could be open sourced (given IP-rights allowing)
- oslac 3y agoHaving read through the old version I cannot recommend that one either.
- ericjmorey 3y agoWould you care to elaborate?
- ericjmorey 3y agoCould you share a few examples of what you consider outdated principles?
- favadi 3y ago> Abstractions lead to coupling and complexity. Without abstractions, we would still programming using punched cards.
- mumblemumble 3y ago> Abstractions lead to coupling and complexity. If you're in the habit of programming in anything other than machine language, I think you'll have to agree that the real story is more nuanced than that. I haven't actually read this book so I'm not prepared to defend it. But I would happily run my mouth and say that the truth is more that abstractions are a double-edged sword. They can be very effective in skilled hands, but they are dangerous in the hands of the untrained. Unfortunately, what makes a good abstraction (IMO it's algebras or GTFO) is not something in which most of us receive sufficient training.
- Joker_vD 3y agoIf an "abstraction" leads to coupling, then it's not an abstraction.
- kqr 3y agoRichard Gabriel coined a word for those things: compressed definitions. When a thing looks like reuse or abstraction because it implicitly pulls in something else in a coupling way, it's really about exploiting shared context in a way that allows the new definition to be much briefer than it otherwise would have been. However, it still relies on full knowledge of the context, so in terms of conceptual load, there's no difference. Just as with other types of compression, the shared context becomes the global coupling across definitions.
- kaba0 3y agoCould you give an example of that?
- kqr 3y agoI have come across a codebase where there was an "Import data from HTTP" functionality that extended the "Import data from file" functionality in such a way that the HTTP calls were grafted onto and around the file operations. This probably made the HTTP class quicker to write, but - Anyone wanting to make changes to the HTTP import functionality needed to also fully understand the file import functionality since basically all of it was used to import from HTTP, and - Many changes to the file import functionality also broke usages of the HTTP import functionality. (Fortunately these breakages were always revealed by automated tests before they made it into master.)
- qumpis 3y agoThis might not be a perspective of a programmer, but the code I've reviewed and tried to understand from academics is always easier to manage when it's not abstracted too deeply. Especially when reading the code is the main reason for trying to understand the underlying idea. Unless you have an extensive (visual?) representation of how the code flows, abstracted code for beginners might be a hindrance towards understanding what's happening at the lowest level while still maintaining the contours of the whole thing. Of course when everyone's on the same page and has similar understanding, this is no longer a concern.
- taeric 3y agoWould be nice to see at least a few of the principles called out. What makes them outdated? And coupling/complexity are a touch on the weasel word space for our domain. They can mean things, sure, but they are often used for the emotion attached more than anything else. Worse, as programs grow, they probably should be coupled heavily. Loser coupling is almost always more complex to maintain and of diminishing returns. Is why the tires on your car can't be used on another vehicle. We probably could engineer the "one true wheel", but it would be done at the expense of capability. Not in pursuit of it.
- adamors 3y agoPosted just 3 weeks ago by the same user no less https://news.ycombinator.com/item?id=35478871 https://news.ycombinator.com/item?id=35478871
- activitypea 3y ago[flagged]
- hazn 3y agoHow did you come to that conclusion? Seems like a pretty tame post and submission history.
- medo-bear 3y agoi found out about it today
- jmnicolas 3y agoNot in vain since I just saw it today.
- avinassh 3y agoWhy one should read this book? If you have read this book, what were your big takeaways from this?
- soegaard 3y agoIt's all about systematic program design. The authors has the following to say in the Preface. PREFACE Many professions require some form of programming. Accountants program spreadsheets; musicians program synthesizers; authors program word processors; and web designers program style sheets. When we wrote these words for the first edition of the book (1995–2000), readers may have considered them futuristic; by now, programming has become a required skill and numerous outlets—books, on-line courses, K-12 curricula—cater to this need, always with the goal of enhancing people’s job prospects. The typical course on programming teaches a “tinker until it works” approach. When it works, students exclaim “It works!” and move on. Sadly, this phrase is also the shortest lie in computing, and it has cost many people many hours of their lives. In contrast, this book focuses on habits of good programming, addressing both professional and vocational programmers. By “good programming,” we mean an approach to the creation of software that relies on systematic thought, planning, and understanding from the very beginning, at every stage, and for every step. To emphasize the point, we speak of systematic program design and systematically designed programs. Critically, the latter articulates the rationale of the desired functionality. Good programming also satisfies an aesthetic sense of accomplishment; the elegance of a good program is comparable to time-tested poems or the black-and-white photographs of a bygone era. In short, programming differs from good programming like crayon sketches in a diner from oil paintings in a museum. No, this book won’t turn anyone into a master painter. But, we would not have spent fifteen years writing this edition if we didn’t believe that everyone can design programs and everyone can experience the satisfaction that comes with creative design. Indeed, we go even further and argue that program design—but not programming—deserves the same role in a liberal-arts education as mathematics and language skills. A student of design who never touches a program again will still pick up universally useful problem-solving skills, experience a deeply creative activity, and learn to appreciate a new form of aesthetic. The rest of this preface explains in detail what we mean with “systematic design,” who benefits in what manner, and how we go about teaching it all. For more details on "System Program Design" means in practise, see the last section of the preface. https://htdp.org/2018-01-06/Book/part_preface.html https://htdp.org/2018-01-06/Book/part_preface.html
- revskill 3y ago[flagged]
- rileymat2 3y agoWriting a sentence is simple, yet there are many skills to learn to do it well.
- revskill 3y agoCorrect. But it didn't disaproove the original statement.
- vsnf 3y agoCan you provide an example of something you consider to be complicated? I’d like to know how to calibrate your comment.
- brbrodude 3y ago`In fact, if treated properly, most programming things are hard, even things that might seem simple. That is because you have complex pieces that you have to put together and to make them work. And the hardest part is when one has to write the complex pieces from scratch. Things only seem easy because you have people with 5, 10, 20 years of experience doing things that are easy to them because they did them many times before, because they made all the possible mistakes or thought about them and made sure they don’t fall in those traps.` https://dorinlazar.ro/2021-02-programming-is-hard/ https://dorinlazar.ro/2021-02-programming-is-hard/
- lincpa 3y ago[dead]
- JustSomeNobody 3y agoI love the look of scribble docs. I don't really use Racket though. Are there alternatives that anyone knows about that have this look?
- vrglvrglvrgl 3y ago[dead]
- wodenokoto 3y agoThe copyright says 2014, the foreword says they spent 15 years on the 2nd edition since 1995-2000. It also says it was released the 6th of March 2023 So is it new or not?
- tjr 3y agoI remember the 2nd edition coming out in printed form years ago. Perhaps there was some update in March of 2023, or perhaps this particular set of HTML files was published in March, but overall, the book has been out for a while.
- marai2 3y agoThere is a version number at the top: "v8.8.0.8". I believe they keep making updates to the book probably to fix typos/errata. The original link I had bookmarked https://htdp.org/2018-01-06/Book/index.html https://htdp.org/2018-01-06/Book/index.html and this one look mostly the same - content wise. But it would be nice if there was a CHANGES file or description about what does change between these versions.
- soegaard 3y agoThe version number matches the latest version of Racket. It's simply the tool used to generate the book site that inserts the version number. It's more relevant in the Racket docs than in the book though.
- photochemsyn 3y agoI think this approach to the issue of 'what language to start with' has a serious flaw for basic programming instruction: > "Our solution is to start with our own tailor-made teaching language, dubbed “Beginning Student Language” or BSL." The only time the use of a toy language makes sense is if you're learning how to create a programming language in the context of understanding compilers, e.g. https://llvm.org/docs/tutorial/MyFirstLanguageFrontend/index.html https://llvm.org/docs/tutorial/MyFirstLanguageFrontend/index... Otherwise it's doing the students a disservice as they'll never use the language again and will have to relearn a whole new syntax later on. It's also far better to learn in a widely used language because there will be a wide variety of resources that can help you solve simple problems (and this is even more true in the era of ChatGPT). The argument that a simplified language makes it easier for students to grasp high-level concepts doesn't work either: instead just use a restricted well-defined subset of a language like C, C++, Java, Python, Javascript - and explain to the students the rationale for doing so.
- Athas 3y agoI thought BSL was a subset of Scheme, so it avoids most of those problems you mention. Or do I misremember?
- soegaard 3y agoIt's not one "toy" language. It's a series of languages that becomes gradually larger. It has the exact same syntax and semantics as the "real" Racket. If a language is small, the compiler can give very precise beginner friendly error messages. I'll call someone who has programmed one or two weeks for a beginner. As an example, in the beginner language all function calls begins with a name, so `((foo) 42)` gives an error message, that says function calls must start with a name. Note that beginners often use too many parentheses. Later on when first order functions are introduced, the call `(foo)` might return a function, so `((foo) 42)` is okay. The beginner friendly "function call must start with a name" message is now no longer true. There are four language levels used in the book - and they follow the progression in the book.
- todd8 3y agoThere's a lot of speculation about the approach used by this book to teach programming. It's the book that my own daughter used as a freshman in college. It was her first programming class, and she ended up deciding to major in CS. The programming language taught in this book is Scheme. Students are introduced to programming concepts and language features gradually and the assignments are intended to be implemented using a growing subset of Scheme features as the students learn the language. By the end of the semester my daughter was familiar with much of Scheme and was comfortable with subjects like recursion, lambda functions, list handling, map functions, and closures. I'm not sure but I don't believe that she learned about continuations or macros. Some comments mention the "toy" languages used in the book, but these aren't really toys, just subsets of Scheme that provide guard rails to keep the students from wandering into parts of Scheme that they haven't yet learned. Another notable feature of the How to Design Programs 2nd Edition is its introduction of a defined sequence of steps for breaking a problem down into parts that are implemented as collection of functions that make up the solution.