The Resistance War of Computer Science

Object Lessons of History 29 Dec 2016, Hanoi

If the hardest thing in Computer Science is naming things, then a corollary rule is that misnaming things must be the easiest.

One of the more evocative similes in my field is Ted Neward’s notion that “Object/relational mapping is the Vietnam of Computer Science.” It’s an analogy for the mismatch between the representation of data in object systems (in terms of OOP languages) and relational systems (i.e., relational databases) and the hazards of translating between them.

The thrust of the metaphor is that the O/R-M problem, like the Vietnam War, is a quagmire that might have started as planned but quickly got bogged down in complications with no solution and no exit strategy in sight.

Vue du Petit Lac de hanoi

It’s rueful to think on this problem from Hanoi, where the real Vietnam War was experienced from the opposing side, and known by another name entirely, as Kháng chiến chống Mỹ, or the Resistance War Against America.

Neward later acknowledged that his analogy might seem strained and even offensive. I don’t wish to defend it, or dismiss it. Nevertheless, an analysis of his argument, like the War itself, would benefit from a similar shift in perspective.

Neward’s stance on the O/R-M problem takes an object-oriented approach for granted, rather than deconstructing it; much like his metaphor of the Vietnam War assumes its name and meaning in an American context.

It has been over a decade since The Vietnam of Computer Science was published. In that time the industry has had a chance to learn its own lessons from history, such as the advantages of message-passing, share-nothing, process-oriented architectures (like Erlang) which make better object systems than OOP does; and functional languages which manipulate lists and sets of data in a way that is aligned with the operators of relational algebra.

Neward proposes one solution to the O/R-M problem that he can’t accept in the end, to give up on objects entirely. Ironically, it is the same conclusion that the U.S. came to in its prosecution of the war effort in Vietnam: abandonment.

articles programming


Match All the Verbs

Phoenix is not your App. Is it even MVC? 26 Dec 2016, Hanoi

It turns out that Elixir’s popular MVC web framework doesn’t need Models, Views, or even Controllers.

I’ve never been an adherent of the MVC pattern in web applications, even though it has been a productive concept for full-featured server-side software. I might use Webmachine or an equivalent program in Erlang, Ruby, or Clojure; or I might not require an HTML template engine or a database wrapper. I often prefer building up a web app piece by piece, instead of committing up-front to an opinionated framework.

When working in Elixir, Plug suffices for the piecemeal approach. Nevertheless, it is tempting to use Phoenix Framework, which adds many features without sacrificing flexibility or performance.

Although I can generate a Phoenix project without Models, or else encapsulate them in a separate OTP application from my web app; and although I can avoid Views by sending responses directly using Plug; I didn’t think I could escape from Phoenix’s Controllers (without completely replacing the Router). Soon I would find a way.

Spelling W-E-B with M-V-C

Model–View–Controller (MVC) is a software design pattern that developed out of early (desktop) graphical user interfaces but was later adapted to describe web application frameworks, such as Ruby on Rails and, more recently, Phoenix.

For server-side web software, MVC denotes the components that manage data (Models), media representations (Views), and HTTP request/response behavior (Controllers). Nevertheless, the MVC pattern does not name its central component, the Router, which dispatches each request to the code that will handle the response.

Take a basic request line such as:

GET /some HTTP/1.1

In Phoenix, a GET request for /some resource is matched using a router macro:

get "/some", SomeController, :index

This get macro call is equivalent to:

match :get, "/some", SomeController, :index

Here, the arguments comprise an HTTP verb, a URL path, a Controller, and an action function. These four terms together determine a “route” in Phoenix. But do they have to?

The Controller Pattern

The match macros in Phoenix Router are not limited to using a Phoenix Controller. Instead, the routes will accept any module that follows the Plug specification.

match :get, "/plug", SomePlug, []

So, if a Phoenix route does not require a Controller, does that mean we can drop the last letter of MVC?

Not necessarily.

Because the role of the Router is often elided when we talk about Web MVC, it’s easy to miss its significance. The Controller part of MVC is not just a Controller module that includes one or more action functions. Rather, it is a particular contract, enforced by the Router, for matching a request with the code that will handle the response. We have already seen this contract in the API for Phoenix’s match macro:

# Generates a route match based on an arbitrary HTTP method
match(verb, path, plug, plug_opts, options \\ [])

I argue that the real Controller pattern in Web MVC matches a verb and path, and executes a module/function in the context of a request.

For most CRUD apps, the Controller pattern suffices. But it does not work for resource designs such as:

  1. An echo server that replies to all requests for a path (for any HTTP method)
  2. A REST-based framework where the HTTP methods supported by each resource are encoded in the connected Plug, and not the Router; e.g., PlugRest

Breaking the Pattern

I brought up method-agnostic Phoenix routes again in a closed issue on the GitHub project page. After some discussion, Chris McCord offered that Phoenix already supports this behavior by way of a catch-all verb:

match :*, "/any", SomePlug, []

The feature exists for use with the forward macro, but had not been publicly endorsed for use with match. Fortunately, it seems this feature may be documented in the next release of Phoenix. This finally allows us to drop the Controllers from our “MVC” web app.

Doing It Wrong?

I was curious about the initial reluctance to fully support a catch-all match macro in Phoenix Router, and how it could be “abused” or “introduce bad behaviors”. I have a hunch it stems from a decision in Rails to deprecate “match” without an explicit method (resolved in this commit).

Rails warns about the danger of unintentionally putting “state-changing” code that manipulates resources on GET-accessible routes. The documentation advises that “You should not use the match method in your router without specifying an HTTP method.” Egor Homakov is even more blunt, writing:

You always know which HTTP Verb is used for specific “controller#action”! If you don’t - you are doing it wrong.

This assumes, of course, that we are using the Controller pattern. This may be a fair assumption for Rails, but it shouldn’t be for Phoenix.

It’s still possible to match all HTTP methods in a Rails route using an explicit via: :all option. Fortunately, Phoenix offers us the same escape hatch.

Game, Set, Match

Phoenix’s flexibility and openness to multiple, co-existing patterns for structuring web applications is just one more thing to recommend the framework.

Phoenix is only MVC if you want it to be.

articles programming


Go to the Source

Linking each webpage to its code 02 Dec 2016, Taipei

I recently wrote about why I use static site generators. Approaching blogging as a coder inspired another feature that makes this site easier to use and share.

You may have noticed I include a [ source ] link at the bottom of every page. Since this is a static site hosted on a web-accessible Git repository, it is simple to link each page to its counterpart source file.

I’ll explain how I do this using Jekyll, but the same technique should work with any static site generator that can output the path of the current file relative to the root directory, and with any Git web host that preserves this path for viewing.

For example, the page.path for the current file is _posts/2016-12-02-go-to-the-source.md, and its corresponding page on GitHub is here.

First, I add the repo URL to the config file. For GitHub, this takes the form:

# _config.yml
source_url: "https://github.com/USERNAME/REPO_NAME/blob/BRANCH/"

Then, in the layout, I build and render the source link:

<!-- _layouts/page.html -->
<a href="{{ page.path | prepend: site.source_url}}">
  source
</a>

These source links are the very definition of free software, to let you use, study, change, and share this work. They also serve as shortcuts for the lazy or forgetful!

articles programming


New Router features in Plug 1.3

Calling All Plugs 28 Nov 2016, Taipei

Plug v1.3.0 has just been released. Read on for a couple of interesting new features.

Plug is a simple specification and powerful library for writing composable web modules in Elixir. While it underpins the popular Phoenix Framework, it also tends to get over-shadowed. And yet, Plug is very capable on its own, and has a couple of new features that are helping it to pull even.

Here is an example of a module that satisfies the Plug spec. It only needs to export two functions: init/1 and call/2.

defmodule HelloPlug do
  import Plug.Conn

  def init(opts) do
    opts
  end

  def call(conn, _opts) do
    send_resp(conn, 200, "hello")
  end
end

Routers

The centerpiece of most web frameworks is the router. It provides the bridge between the framework’s code and the user’s by dispatching each request (identified by a URL path) to a designated resource implementation. In most Elixir web frameworks, the router provides an approachable DSL for defining the routing structure. Plug is no exception here.

Since version 1.0, Plug’s Router has had a DSL reminiscent of Sinatra. It defines a macro for each HTTP verb, which matches a URL path and executes a body of code operating on the connection.

defmodule MyApp.Router do
  use Plug.Router

  plug :match
  plug :dispatch

  get "/hello" do
    send_resp(conn, 200, "world")
  end
end

In contrast, Phoenix’s Router is more in the style of Ruby on Rails. It dispatches each request to an action function in a Controller module.

defmodule MyApp.Router do
  use HelloPhoenix.Web, :router

  get "/hello", HelloController, :show
end

Underneath, both Plug and Phoenix’s routers implement the Plug module specification. However, in the case of Phoenix, an extra bit of cleverness lurks behind its MVC facade: Controllers are Plugs! In fact, the router macros will accept any Plug module. We could, for example, change the route to:

get "/hello", HelloPlug, [an_option: :a_value]

Plug’s Router has been deprived of a feature like this, until now. Starting in v1.3.0, you can dispatch requests directly to a Plug module:

get "/hello", to: HelloPlug, init_opts: [an_option: :a_value]

This is equivalent to:

get "/hello" do
  HelloPlug.call(conn, HelloPlug.init([an_option: :a_value]))
end

While a seemingly small change, this feature will make it both easier and more likely for us to build Controller-like patterns directly on top of Plug Router. With it you can factor out the code that handles each route into separate modules, rather than filling up your router with function bodies.

Path Params

Plug Router’s routes have always supported dynamic path segments, such as:

get "/hello/:name" do
  send_resp(conn, 200, "hello #{name}")
end

The :name parameter can be used directly as a variable in the function body passed to the match macro. In order to make these values available generally in the connection, Plug 1.3 has added a conn.path_params map to hold them. They will also be saved in conn.params, a behavior which will be familiar to Phoenix users.

The Plug Router docs have all the details.

P.S. The reason I decided to blog about these new Plug features is because I wrote them!

articles programming


What happens when you blog as a coder?

The spark of static site generators 25 Nov 2016, Taipei

What would happen if I approached blogging from a software development perspective?

—Tom Preston-Werner

The Dynamic, Static Web

I made the website where this post is published using Jekyll, a static site generator written by Tom Preston-Werner. Jekyll is probably the most commonly-used software in its class, since it drives GitHub Pages.

Although the very first website comprised plain hypertext documents, today much of the Web runs on dynamic software and data stores. This makes the recent renaissance of static websites look like little more than a novelty.

(This graph charts the Google search interest in “static site generator” since 2008.) source

There are very real, practical advantages to making websites static, specifically in terms of increased performance, security, and ease of deployment and maintenance.

For these reasons, static websites make eminent sense from a business or operations perspective. However, I do not believe this entirely explains the popularity of static site generators. The best justification, in my mind, is the one that announced Jekyll.

Blogging Like a Hacker

Tom Preston-Werner introduced his new static website generator in 2008, in a post titled Blogging Like a Hacker. At the time he wanted to improve his personal writing and publishing practice, but found that the contemporary blogging engines and services were too complicated or encumbered.

Instead of giving up or giving in, he figured out an approach to the activity of blogging as an author not just of prose but of code. To this end he created a tool that worked the way he did, namely:

  1. write with a text editor
  2. manage from the command line
  3. do not repeat yourself
  4. make things customizable and extensible
  5. store and distribute using version control

Finally: release it all and let others hack on it.

The upshot is to treat the blog as source code, using the same tools and techniques. I believe this is the real reason that static site generators have become and remain popular (if niche). They allow hackers to write the way they work best: with code.

articles programming


Jailing Bassel

Activists in Syria 10 Oct 2016

every so called activist in #Syria who was jailed for a month or two is now trying to make a hero of him self. I'm sick of that #Syria

— Bassel Safadi (@basselsafadi) January 31, 2012

Bassel sent this tweet just weeks before his own arrest. It would read like dramatic irony if not for the real tragedy that Syria has suffered.

Of course, Bassel’s arrest did not last months, but rather years. He was detained on March 15, 2012. Then one year ago he was taken from Adra Prison in Damascus and disappeared for good.

Bassel did not want to be a hero. But for us he became one.

the people who are in real danger never leave their countries. they are in danger for a reason and for that they don't leave #Syria

— Bassel Safadi (@basselsafadi) January 31, 2012

Our efforts to find and free Bassel continue at freebassel.org.

articles freebassel


Joi Ito

Director of the MIT Media Lab 24 Jan 2016, Tokyo

Joi Ito

Joi Ito is the director of the MIT Media Lab, an accomplished photographer, and long-time friend. (Ilford HP5 Plus 400, Nokton 35mm f/1.2 II, Leica M6)

photos portrait link


Fred Benenson

At Kickstarter HQ 12 Jan 2016, New York

Fred Benenson

Fred Benenson was employee №2 at Kickstarter and is now at Y Combinator. Fred is a long-time friend, copyright activist, and emoji expert. (Ilford HP5 Plus 400, Nokton 35mm f/1.2 II, Leica M6)

photos portrait link


Philipp Schmidt

MIT Media Lab 11 Jan 2016, Cambridge, MA

Philipp Schmidt

(Ilford HP5 Plus 400, Nokton 35mm f/1.2 II, Leica M6)

photos portrait link


Saravuth Inn

Odysseus' Gambit 20 Dec 2015, New York

Saravuth Inn

Saravuth Inn is originally from Cambodia. You can often find him playing chess in Union Square. The man is a scholar but has had a very trying life, and was the subject of a documentary titled Odysseus’ Gambit. We shared a smoke and a game and he beat me handily, but let me make a portrait in return. (Arista Premium 400, Nokton 35mm f/1.2 II, Leica M6)

photos portrait link



self source license