The Pragmatic Programmer: Your Journey to Mastery, 20th Anniversary Edition
Rate it:
Open Preview
20%
Flag icon
Here are some specific areas you may want to look for in the architectural prototype: Are the responsibilities of the major areas well defined and appropriate? Are the collaborations between major components well defined? Is coupling minimized? Can you identify potential sources of duplication? Are interface definitions and constraints acceptable? Does every module have an access path to the data it needs during execution? Does it have that access when it needs it?
20%
Flag icon
Before you embark on any code-based prototyping, make sure that everyone understands that you are writing disposable code. Prototypes can be deceptively attractive to people who don’t know that they are just prototypes. You must make it very clear that this code is disposable, incomplete, and unable to be completed.
20%
Flag icon
If you feel there is a strong possibility in your environment or culture that the purpose of prototype code may be misinterpreted, you may be better off with the tracer bullet approach. You’ll end up with a solid framework on which to base future development.
21%
Flag icon
We always try to write code using the vocabulary of the application domain (see ​Maintain a Glossary​). In some cases, Pragmatic Programmers can go to the next level and actually program using the vocabulary, syntax, and semantics—the language—of the domain.
21%
Flag icon
Why Don't Many Business Users Read Cucumber Features?
Alexander Bandukwala
It doesn’t actually read like English and still requires programmatic thinking to understand in most cases
22%
Flag icon
They employ some fairly devious code, including metaprogramming and macros, but ultimately they are compiled and run as regular code.
22%
Flag icon
The downside of internal domain languages is that you’re bound by the syntax and semantics of that language. Although some languages are remarkably flexible in this regards, you’re still forced to compromise between the language you want and the language you can implement.
Alexander Bandukwala
Make the host syntax flexible
22%
Flag icon
Finally, there’s a cheat for creating internal domain languages if you don’t mind the host language syntax leaking through. Don’t do a bunch of metaprogramming. Instead, just write functions to do the work.
25%
Flag icon
If you come across a situation where you feel your current tools can’t cut it, make a note to look for something different or more powerful that would have helped.
25%
Flag icon
Many new programmers make the mistake of adopting a single power tool, such as a particular integrated development environment (IDE), and never leave its cozy interface. This really is a mistake. You need to be comfortable beyond the limits imposed by an IDE.
Alexander Bandukwala
What can we do about this
25%
Flag icon
And we believe that the best format for storing knowledge persistently is plain text.
Alexander Bandukwala
Sigh.
25%
Flag icon
Human-readable forms of data, and self-describing data, will outlive all other forms of data and the applications that created them. Period. As long as the data survives, you will have a chance to be able to use it—potentially long after the original application that wrote it is defunct. You can parse such a file with only partial knowledge of its format; with most binary files, you must know all the details of the entire format in order to parse it successfully.
Alexander Bandukwala
I'm more convinced about self describing atomic pieces of data. We need stronger primitives than plaintext can afford but we cant divorce interpretation and content. A composble protocol of some sort is necessary.
26%
Flag icon
Virtually every tool in the computing universe, from version control systems to editors to command-line tools, can operate on plain text.
Alexander Bandukwala
And therefore not much else
26%
Flag icon
Unix is famous for being designed around the philosophy of small, sharp tools, each intended to do one thing well. This philosophy is enabled by using a common underlying format—the line-oriented, plain-text file.
Alexander Bandukwala
What an anemjc choice for the main building block of composability for computing
26%
Flag icon
Plain text is also easier to search.
Alexander Bandukwala
This is interesting. Reminder to look into searching structured data
26%
Flag icon
You won’t be able to automate common tasks, or use the full power of the tools available to you. And you won’t be able to combine your tools to create customized macro tools. A benefit of GUIs is WYSIWYG—what you see is what you get. The disadvantage is WYSIAYG—what you see is all you get.
Alexander Bandukwala
Failure of our primitives and toolkits. Theres also a point about wysiwyg and its relation to algebraic reasoning. The visual representation and discoverability need to be divorced from automation or composability.
27%
Flag icon
text is the basic raw material of programming.
Alexander Bandukwala
:'(
27%
Flag icon
over the course of a year, you might actually gain an additional week if you make your editing just 4% more efficient and you edit for 20 hours a week.
27%
Flag icon
When editing code, move by various syntactic units (matching delimiters, functions, modules, …).
29%
Flag icon
It doesn’t really matter whether the bug is your fault or someone else’s. It is still your problem.
29%
Flag icon
If your first reaction on witnessing a bug or seeing a bug report is “that’s impossible,” you are plainly wrong.
29%
Flag icon
We routinely set compiler warning levels as high as possible. It doesn’t make sense to waste time trying to find a problem that the computer could find for you! We need to concentrate on the harder problems at hand.
29%
Flag icon
Artificial tests (such as the programmer’s single brush stroke from bottom to top) don’t exercise enough of an application. You must brutally test both boundary conditions and realistic end-user usage patterns. You need to do this systematically (see ​Ruthless and Continuous Testing
29%
Flag icon
Read the Damn Error Message
30%
Flag icon
The OS is probably not broken.
32%
Flag icon
But Pragmatic Programmers take this a step further. They don’t trust themselves, either. Knowing that no one writes perfect code, including themselves, Pragmatic Programmers build in defenses against their own mistakes.
35%
Flag icon
Points to ponder: If DBC is so powerful, why isn’t it used more widely? Is it hard to come up with the contract? Does it make you think about issues you’d rather ignore for now? Does it force you to THINK!? Clearly, this is a dangerous tool!
35%
Flag icon
That’s also one reason why each and every case/switch statement needs to have a default clause: we want to know when the “impossible” has happened.
Alexander Bandukwala
Compilers plese
37%
Flag icon
However, many developers have no consistent plan for dealing with resource allocation and deallocation.
Alexander Bandukwala
Use tooling
39%
Flag icon
Deallocate resources in the opposite order to that in which you allocate them. That way you won’t orphan resources if one resource contains references to another.
39%
Flag icon
Use variable scope (for example, stack variables in C++ or Rust)
40%
Flag icon
Take Small Steps—Always
40%
Flag icon
Always take small, deliberate steps, checking for feedback and adjusting before proceeding. Consider that the rate of feedback is your speed limit. You never take on a step or a task that’s “too big.”
40%
Flag icon
What’s a task that’s too big? Any task that requires “fortune telling.” Just as the car headlights have limited throw, we can only see into the future perhaps one or two steps, maybe a few hours or days at most. Beyond that, you can quickly get past educated guess and into wild speculation. You might find yourself slipping into fortune telling when you have to: Estimate completion dates months in the future Plan a design for future maintenance or extendability Guess user’s future needs Guess future tech availability
42%
Flag icon
One way to look at this is to think about responsibilities. Surely the totals object should be responsible for managing the totals. And yet it isn’t: it’s really just a container for a bunch of fields that anyone can query and update.
Alexander Bandukwala
How to represent this responsibility in fp?
42%
Flag icon
This principle says that you shouldn’t make decisions based on the internal state of an object and then update that object. Doing so totally destroys the benefits of encapsulation and, in doing so, spreads the knowledge of the implementation throughout the code. So the first fix for our train wreck is to delegate the discounting to the total object:
Alexander Bandukwala
Is this equally true with immutability?
42%
Flag icon
In every application there are certain top-level concepts that are universal. In this application, those concepts include customers and orders.
Alexander Bandukwala
Domain concepts
42%
Flag icon
Don’t Chain Method Calls Try not to have more than one “.” when you access something. And access something also covers cases where you use intermediate variables, as in the following code:
Alexander Bandukwala
I dont understand how we get out of this other than having the cross product of possible methods
43%
Flag icon
In Topic 30, ​Transforming Programming​ we talk about composing functions into pipelines. These pipelines transform data, passing it from one function to the next. This is not the same as a train wreck of method calls, as we are not relying on hidden implementation details.
Alexander Bandukwala
The distinction bere is lost on me unless it means immutability or certinn functions are more obvious
43%
Flag icon
If It’s Important Enough to Be Global, Wrap It in an API
43%
Flag icon
We discuss Tell, Don’t Ask in our 2003 Software Construction article The Art of Enbugging.
43%
Flag icon
Things don’t just happen; they are made to happen. John F. Kennedy
45%
Flag icon
State machines are underused by developers, and we’d like to encourage you to look for opportunities to apply them.
46%
Flag icon
Pubsub is a good technology for decoupling the handling of asynchronous events. It allows code to be added and replaced, potentially while the application is running, without altering existing code. The downside is that it can be hard to see what is going on in a system that uses pubsub heavily: you can’t look at a publisher and immediately see which subscribers are involved with a particular message.
46%
Flag icon
The current de facto baseline for reactive event handling is defined on the site http://reactivex.io, which defines a language-agnostic set of principles and documents some common implementations. Here we’ll use the RxJs library for JavaScript.
47%
Flag icon
Events are everywhere. Some are obvious: a button click, a timer expiring. Other are less so: someone logging in, a line in a file matching a pattern. But whatever their source, code that’s crafted around events can be more responsive and better decoupled than its more linear counterpart.
48%
Flag icon
Sometimes the easiest way to find the transformations is to start with the requirement and determine its inputs and outputs. Now you’ve defined the function representing the overall program. You can then find steps that lead you from input to output. This is a top-down approach.
53%
Flag icon
​  ​const​ content = File.read(file_name); ​  ​const​ lines = find_matching_lines(content, pattern) ​  ​const​ result = truncate_lines(lines) Many people write OO code by chaining together method calls, and might be tempted to write this as something like: ​  ​const​ result = content_of(file_name) ​  .find_matching_lines(pattern) ​  .truncate_lines() What’s the difference between these two pieces of code? Which do you think we prefer?
Alexander Bandukwala
This is great example of the harm of methods
53%
Flag icon
Do you program in an object-oriented language? Do you use inheritance? If so, stop!
54%
Flag icon
“differential programming” (meaning: various ways to accomplish “this is like that except”).