Small, Fast, & Simple

May 11, 2015

Muntzing

Small
Fast
Simple

According to Wikipedia, “Muntzing” is the practice of reducing parts in an electronic appliance to the minimum required for it to function. At it’s core, Muntzing is about simplifying by challenging core assumptions. Muntz rejected the assumption that his television sets had to work everywhere. By designing them to work only in areas with a strong signal he could leave out expensive components needed to pick up weak signals. With fewer components, his sets needed less power and didn’t overheat as easily. They were then much cheaper. All this because he challenged one basic assumption.

May 7, 2015

Single-Executable Programs

Small
Fast
Simple

Thanks in part to Go, single-executable programs are becoming more popular. Replacing Ruby or Python scripts with compiled, binary executables makes deployment much easier. Programs can be compiled, copied to the destination server, and run without the need for installing a full runtime platform. Compiling dependencies into the binary also avoids having to install a package manager like Pip or Bundler. Compiled programs are, in sum total, much smaller than scripts, since a full runtime platform and standard library are not necssary. They are also faster since optimizations can also be applied in ways impossible with scripts.

May 4, 2015

The K Programming Language

Small
Fast
Simple

One of the most interesting languages I’ve toyed with is K. K is a vector programming language like APL and J and makes several major departures from mainstream languages. It favors terse expressions with short variable names, forcing the programmer to examine the whole expressions rather than the individual pieces. Compared to API and J, K has very few operators. Higher-order operators provide additional functions. K elides common functions like filter and reduce in favor of highly orthogonal and composable operators. For example, filtering a list to even-valued entries is done as follows:

xs[&0=xs!2]
April 30, 2015

Graphviz

Small
Fast
Simple

Graphviz is a handy tool for visualizing graphs and networks. It uses a graph specification language called Dot. Dot is both readable by humans and generable by machines. The Graphviz toolset includes several executables for rendering Dot code into PDFs or images. Each program renders the Dot code using different layouts. Graphs are extensively customizable. Graphviz is a good platform for quickly mapping out an entity relationship diagram or the structure of a system. It’s much quicker to write out the relationships in code and generate a visualization than to drag shapes and draw the diagram manually.

April 27, 2015

JavaScript

Small
Fast
Simple

There are numerous languages that compile to JavaScript, but sometimes the best option is just to use JavaScript itself. Translating non-JavaScript code to JavaScript adds a compilation process, which can be a nuisance to install and run. Often it can take several seconds to transpile code to JavaScript, slowing the development cycle. It can also be buggy or have unexpected results. Some languages dramatically increase the resulting amount of code and add dozens of layers to the application. Debugging in the browser can become remarkably difficult. Sometimes it’s smallest, fastest, and simplest to use plain old JavaScript.

April 23, 2015

Pipes

Small
Fast
Simple

Unix introduced the concept of chaining program outputs to the inputs of other programs via pipes. For example, the commands cat, grep, and cut are very simple and focused, but using pipes they can be composed together to do non-simple searches.

cat file.txt | grep 2015-04-23 | cut -f5

This example finds the fifth tab-delimed field of lines in file.txt matching the given date. Unix-like systems have a large toolbox of small programs that can be connected together. Often I’ve used pipes to write a program that would have been non-trivial in a scripting language.

April 20, 2015

Laziness

Small
Fast
Simple

One of Haskell’s key features is lazy evaluation. Expressions are not evaluated until they are needed. This is also a valuable technique for writing programs. For example, rather than writing all the lowest-level database code first, start with user-facing code and work down through the layers of the application, writing only the code that has to be written to support the top-level changes.

There are also other ways to consider laziness in programming. Larry Wall considers it one of the three virtues of great programmers. Laziness is also a weapon against the temptation to prematurely optimize.

April 16, 2015

Canvas Element

Small
Fast
Simple

The Flipboard Engineering blog has a nice outline of using the HTML canvas element to create animations and interactions that can’t be done with a plain, DOM-based webpage. Even with HTML5 and CSS3, some transitions and effects still aren’t possible, but you can have pixel-by-pixel control over the canvas element. Compared to the HTML and CSS API for rendering a webpage, the canvas drawing API is incredibly small. Unlike SVGs, which are driven by a DOM structure, canvas renderings don’t retain any information about what’s been drawn to them, which makes rendering to a canvas extremely fast.

April 13, 2015

Make

Small
Fast
Simple

Make is a long-standing build utility. It allows build commands to be specified in terms of the files they depend on. If a dependent file has changed, the commands are run; if none of the files have changed, the output is considered up-to-date. It’s a much faster build pipeline than many modern tools, such as Rake and Grunt. Make has become my preferred way to document what shell commands build, test, and run my code, especially in compiled languages. Make steps can also be parameterized. The basics of Make are reasonably straight-forward, though mastery may take time.

April 9, 2015

cURL

Small
Fast
Simple

cURL is a convenient command line tool for making HTTP requests. While it’s easy to make a GET request from the browser, other request types are more difficult. cURL only requires a flag:

curl http://localhost:3000/items -X POST

cURL can also send custom headers. One of its most valuable features is the ability to interact with other programs over pipes. The body of a request can come from standard input, and the HTTP response can be piped into another command. Browser web inspectors often have an option to copy a network request to the clipboard as a cURL command.

April 6, 2015

The Io Programming Language

Small
Fast
Simple

The Io programming language is small in size (in order to be embeddable) and simple in syntax. Like Smalltalk, objects in Io pass messages to each other. Unlike Ruby’s syntax for message-passing, Io’s is not disguised as C-like method invokation. For example,

signal send("Hello World")

Like JavaScript, objects in Io are based on prototypes rather than classes. Like LISPs, Io code is able to inspect itself and control its evaluation. Io has built-in support for concurrency, and its syntax can be extended at runtime. Bruce Tate’s Seven Languages in Seven Weeks has a good introduction.

April 3, 2015

Single-Layer Applications

Small
Fast
Simple

A typical software project in a professional setting has layer upon layer upon layer of code. For instance, CoffeeScript compiled to JavaScript 6 code compiled to JavaScript 5 code packed into a single file. All those layers of languages and frameworks inflate the size of the project, increase its complexity, and slow its execution. If a developer working on the project isn’t familiar with how all those layers work, it also slows their productivity. When working alone, I prefer to write single-layer applications. There’s less code, it runs faster, and making changes is more straight-forward.

March 30, 2015

Vim

Small
Fast
Simple

Judging by the Lindy effect, Vim will be around for another quarter century. Vim’s keyboard-based navigation, reliance on editor commands, and various different modes makes learning the editor difficult but pays dividends to those who stick with it. I’ve used Vim in a terminal without mouse integration for several years, and find I’ve learned how to move through the text and make changes faster than I would with a mouse. Fingers on a keyboard builds muscle memory in a way that pinpointing pixels with a mouse never can, and editing text anywhere else feel incredibly limited.

March 26, 2015

Virtual DOM

Small
Fast
Simple

Facebook’s React introduced the pattern of using a virtual DOM to construct and update a webpage. The solution is elegant, but the implementation is tightly integrated into React’s core. Instead, use virtual-dom, a minimal library that does DOM diffing without need for the much larger React. Using virtual-dom is as simple as creating a virtual DOM tree, attaching it to an actual DOM node, then when changes are needed, generating a new virtual DOM tree, diffing against the old one, and applying only the changes that are needed to the actual DOM.

March 23, 2015

Effort and Value

Small
Fast
Simple

The Pareto principle is popularly known as the 8020 rule—that is, 80% of the effects come from 20% of the causes. It’s useful to remember that not all tools or tasks are equal in value and effort. Often an easy task can be disproportionately valuable while a small improvement takes a surprising amount of effort. The relationship between effort and value is non-linear. An old joke states that the first 90% of a project takes 90% of the time and the last 10% of a project takes the other 90% of the time.

March 19, 2015

Git Bisect

Small
Fast
Simple

Git includes the bisect command, which performs a binary search between two commits to find when a problem was introduced.

git bisect start bad-commit good-commit

Git then updates the working directory to a revision between the given commits. Tell git whether the current revision is good or bad with git bisect good or git bisect bad. Git will then update to another commit and repeat the process. Git can run the search automatically using a script that returns particular exit codes for good and bad revisions.

git bisect start bad-commit good-commit
git bisect run test-script arguments
March 16, 2015

Tmux

Small
Fast
Simple

Tmux has allowed me to structure my terminal sessions and move between them more quickly than using plain terminal tabs or separate windows. Instead of having a series of top-level tabs, I can create separate, named Tmux sessions for separate workspaces. Each session has namable windows, for me usually one for command line operations, one or two for Vim, and one for long-running daemons. Each window can have panes or splits for side-by-side viewing of processes. Using keyboard commands also speeds switching windows and sessions.

March 12, 2015

d3.js

Small
Fast
Simple

D3.js—for “Data-Driven Documents”—is designed to ease the building of XML documents based on data. Because SVGs are XML, it’s common to see D3 used to create data visualizations with SVG. D3’s creator, Mike Bostock, has created bl.ocks.org to demo example code sourced from GitHub gists. D3 is one of the best-designed JavaScript libraries I’ve used. It makes extensive use of functions rather than class hierarchies, and provides keyword argument-like methods for parameterizing functions. The biggest conceptual hurdle to using D3 is the concept of selections. Fortunately, Mike Bostock writes well and extensively, and has published a large body of examples.

March 9, 2015

Scalable Vector Graphics

Small
Fast
Simple

Vector graphics are an efficient way to draw simple images, such as charts and diagrams. A common and web-supported format for vector graphics is the XML-based SVG (Scalable Vector Graphics). The free and open source vector editor Inkscape saves files directly as SVG; other vector editors like Illustrator and Sketch can easily export files and elements to SVG. Because SVGs are XML, they can be embedded in a webpage’s HTML and modified using JavaScript. SVGs can also be natively animated. SVGs are supported by all modern browsers, including Internet Explorer 9 and up.

March 5, 2015

The Lua Programming Language

Small
Fast
Simple

The Lua programming language is designed to serve as an embedded scripting language for larger, compiled applications. Where LISP languages use lists as the universal data structure, Lua uses tables. All other data structures can be built from tables and meta-tables. Unlike the Python or Java virtual machines, which use stack-based instructions, Lua uses register-based instructions. Lua supports first-class functions, lexical closures, tail call optimization, and coroutines. The base language is designed to be easy to adapt to specific purposes. The reference interpreter is only 180 kilobytes.

March 2, 2015

Function Currying

Small
Fast
Simple

An interesting feature of Haskell is that all functions take only one argument. Multi-argument functions are an illusion. Whenever a two-argument function is needed, Haskell instead defines a function that takes a single argument and returns another function. The returned function takes the second argument and returns a result. All multi-argument functions are extensions of this pattern. When doing the final computation, all the arguments that have been passed in are in scope thanks to function closures. Haskell thinly hides this behavior in its syntax. Closures enable Haskell to have multi-argument functions while technically only supporting single-argument functions.

February 26, 2015

Algebraic Data Types

Small
Fast
Simple

One of my favorite features of Haskell and other ML-inspired languages, such as Elm, is their support for algebraic data types (ADTs). ADTs are, in part, small data structures, but they can be combined, unpacked, and dispatched on in ways most statically typed languages don’t offer. For me, it took hands on usage of ADTs to really appreciate them. They provide a very natural way to express what various values are, without resorting to heavy-handed or over-sized classes.

February 23, 2015

Communicating Sequential Processes

Small
Fast
Simple

Tony Hoare’s concept of communicating sequential processes (CSP) is heavily used by the Go programming language and has been adopted by Clojure under the name core.async. CSP is a remarkably simple pattern for handling multiple things at once. As the name implies, it’s formulated on separate, co-running processes that communicate and coordinate with each other over synchronous channels. CSP allows a language to break out of being either synchronous or asynchronous and be both. CSP is the feature I miss most in languages without it.

February 19, 2015

The Go Programming Language

Small
Fast
Simple

Among other things, the Go programing language was designed to compile and run very fast. A lot of new server software is taking advantage of its performance. Critics argue it’s missing some important features, such as generics or memory management. I, however, feel Go’s designers have chosen the 36% of functions that meet 96% of the needs, and not tried to meet the last 4% of needs by complicating the basic conceptual architecture.

February 16, 2015

Long Levers

Small
Fast
Simple

Developers often laud some tool or other for giving them a lot of leverage. The focus of Small, Fast, & Simple is not just tools that give a lot of leverage, but tools that provide extreme leverage. Screwdrivers offer leverage, quite a bit, but it isn’t extreme leverage. Many of the features offered by modern programming languages and frameworks are not long levers, but marginal offerings that make the tool a little easier to use. SFS is about Archimedes-style move-the-world length levers; techniques, structures, and paradigms that—all on their own—offer the wide range of capabilities needed.

February 12, 2015

Stow

Small
Fast
Simple

GNU Stow is listed as a package manager, but I’ve been using it as a simple way to stay on top of my dotfiles, both system-wide dotfiles in my home directory, as well as project-level dotfiles scattered throughout the filesystem. Rather than commit project dotfiles to the project repo, I prefer to keep them in a central location where they can all be version controlled together. The command

stow -t ~/code/project project-dotfiles

symlinks files and directories in project-dotfiles into the ~/code/project directory. The Stow executable is 28 kilobytes, and doesn’t depend on any Ruby or Python installation.

February 9, 2015

The Lindy Effect

Small
Fast
Simple

Nassim Taleb describes the Lindy Effect in his book Antifragile, which states that the longer a technology or idea has been around, the longer it’ll probably be around. The Lindy Effect is a statistical consideration about where in the life of a thing we’re likely to be. In short, the younger a technology is, the sooner it’s likely to become irrelevant; the older a technology is, the harder it will be to displace. Some specific examples: JavaScript will probably be around for another couple decades; TypeScript and Dart probably only have another year or two of relevance.

February 5, 2015

Hugo

Small
Fast
Simple

Hugo has become my de facto static site generator. It’s written in Go, so it’s a single executable and recompiles very quickly. In development, Hugo automatically refreshes browser windows. Setting up a new project is easy (hugo new site such-and-such). Make sure to include a theme or a layout template, or you’ll get 404s. Hugo uses Markdown and Go’s HTML templating language, and abstracts HTML out of your content using shortcodes. Hugo compiles your static site to a single public directory, which can be pushed to GitHub Pages without all the source files using

git subtree push --prefix=public origin gh-pages
February 2, 2015

Functions

Small
Fast
Simple

I’ve come to prefer first-class and higher-order functions with closures in place of classes and objects. Nothing will stop you from writing large functions, but you’ll face more resistence than you will writing large classes. The interface for a function is well-defined and battle-tested: values are passed in, values are available from the enclosing scope, and a value is returned. By contrast, every class in an object-oriented system tends toward being a snowflake whose interface has to be studied each and every time. Many common OOP design patterns can be replaced by functions.