The Zen of Copy-Paste
There is a tension in computer programming between copy-pasting and abstraction. When we are learning to program we begin by copy-pasting things we find useful and try to figure out how make that thing work for us. We start with text book examples, move on to Stack Overflow answers and advance to blog posts. As we progress in our journey of understanding we see the patterns in what we are copy-pasting and begin to abstract them. We realize that we can figure out something once, put it into a function and reuse it over and over. We start putting everything into functions, abstracting every task whether it needs to be used one hundred times or just once. We swear off copy-pasting as naive, a beginners mistake. We spend hours designing the perfect interface for something we could have done in 5 minutes manually, and then never call that function again.
One day we find ourselves in a time crunch to deliver some functionality that we know how to code. There is a sinking feeling as we realize that setting up the environment, transforming the imperfect data coming from some API and redesigning our current interface to accommodate it will actually take longer than we can afford. We know we need to deliver this fast or something bad will happen, but we also don’t want to go against all we have come to understand of Computer Science. We hold our breath, open a blank new text file, copy paste the relevant parts from some existing code and bang out a script that works for this one API, right now. We know it will break if anything changes, we know it won’t ever work if it gets run again. We know our coworkers would take hours to untangle the copy-pasta we just cooked.
We breathe a sigh of relief. We solved the problem at hand. The script never gets run again, it bit-rots into bit-soil in the depths of a TimeMachine backup never to be restored again. In the meantime, we have triumphed, returning to our enjoyable practice of abstracting.
There is no prescription for when to copy-paste and when to abstract, a balance must be found and the proportion depends on a given situation. This runs contrary to the popular belief that abstraction is the one true way.
We see how powerful abstraction has been throughout history, yet we only see the results of abstraction. We’ve seen assembly turn into C, C into Fortran, C++ into Java. We’ve transcended manual memory management in many environments thanks to abstraction, as well as network communication. We see all of this and we think, I must abstract! Yet we ignore the years and millions of trials that went into evolving these abstractions.
I propose a shift in attitude, one that does not eschew abstraction, on the contrary it assumes that abstraction is the end goal.
By accepting that abstraction is inevitable, we can focus on how to create enough trials to see meaningful patterns.
How do we reduce the friction for copy-pasting? How do we encourage more attempts so that we can make design decisions informed by experience rather than intuition? Err on the side of waste. Moore’s law has provided us with effectively infinite storage when it comes to the code you will write. Copy-paste entire files, search and replace with impunity. Tell yourself that you will clean up the mess of files once you figure out your abstraction, it doesn’t matter if you do anyway.
If you happen to be coding for the web, use services like CodePen and JSFiddle and if you are working with d3.js use Building Blocks. These services may not have all the niceties of your development environment, but they give you an instant, frictionless place to try things with the added bonus that they don’t clutter your hard-drive.
Building blocks in particular reduces friction for copying with it’s `Fork` button. Like what you see but want to try something else with it? Click fork and go for it, if you don’t like it you can always hit the back button. You may recognize this concept from GitHub, and it may come as no surprise that Building Blocks is powered by GitHub gists.
Using one of these in-browser environments has another obvious disadvantage: scope. A reasonable person wouldn’t want to engineer an entire application or complex project in this manner. This can be flipped to an advantage if we set our sites not on building the end goal but proving all of the concepts that will get us there. Every complex project will have smaller parts, components to comprehend, data to decipher and API’s to access. Each of these aspects can be tested, tried, and copy-pasted from existing examples quickly in the browser. Before long you’ll find yourself with a mountain of ammunition and some bonus wisdom from the experience to take on your large project.
Go forth and proliferate!