Mia Liu

I dwell in Possibility 20 Jul 2019, Taipei

Mia Liu

Mia Liu at her first major exhibition at Mind Set Art Center.
(Summicron-M 50mm f/2, Leica M10)

photos portrait link

TJ Hughes

Dimsum Thensum 11 Jul 2019, Hong Kong

TJ Hughes

TJ Hughes is a game designer and artist from Saint Louis, here at his solo exhibition in Hong Kong at Oui.Gallery.
(Summicron-M 50mm f/2, Leica M10)

photos portrait link

Raúl Gasque

Mi Montaña 19 May 2019, Taipei

Raúl Gasque

Mexican artist Raúl Gasque near Yangmingshan.
(Summicron-M 50mm f/2, Leica M6, Ektar 100)

photos portrait link

Beat Streuli

Opening 10 Nov 2018, Taipei

Beat Streuli

Beat Streuli is a Swiss visual artist. (Summicron-M 50mm f/2, Leica M10)

photos portrait link

Naut Humon

Gray Area 26 Jul 2018, San Francisco

Naut Humon

Naut Humon is the Founder and Artistic Director of Recombinant Media Labs. (Nokton 35mm f/1.2 II, Leica M10)

photos portrait link

Christopher Adams

Creative Commons Global Summit 16 Apr 2018, Toronto

Christopher Adams

about portrait link

Lawrence Lessig

Reviving Democracy 15 Apr 2018, Toronto

Lawrence Lessig

Lawrence Lessig is the founder of Creative Commons and a professor at Harvard Law School. (Heliar 75mm f/1.8, Leica M10)

photos portrait link

The Resistance War of Computer Science

Object Lessons of History 29 Dec 2016, Hanoi

The Resistance War of Computer Science

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.

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}}">

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

self source license