Deprecated Behaviour

The inane, sometimes insane, ramblings from the mind of Brenton Alker.

Applying Functional Concepts to OOP: Referential Transparency / Command-Query Separation

I’ve been studying functional programming lately (it’s trendy) and while it’s great to just learn new languages and paradigm, it’s always nice when the principles can be applied to everyday work.

Command-Query separation is probably one of the lesser known principles of object-oriented programming (OOP). Proposed by Bertrand Meyer in “Object Oriented Software Construction”, it states that a function (or method) should perform a Command (do something) or a Query (return a value) but not both. So, any function that returns a value should not modify state. In Martin Fowler’s discussion of the principle he mentions that “it would be nice if the language itself would support this notion”.

If occurs to me that functional languages do indeed grant Mr. Fowler his wish.

Functional programmers aim to compose programs using “pure” functions. In this case, “pure” is used to mean a functions that are “referentially transparent”, that is, they only depend upon their parameters. A pure function, given the same set of parameters, will always return the same result. No external influences, including variables, databases, inputs or outputs can be used or modified by its execution.

Of course, a program that takes no input, can’t access a data store and produces no output isn’t very useful. As such, even the most pure of the functional languages have to allow the nasty real-world into its pristine clean-room. The difference though, is the strict boundaries that are constructed to protect the pure world from the impure. In Haskell, which is often held up as the purest of functional languages, this airlock is provided by the IO Monad. I won’t go into what a Monads are, it doesn’t matter, and I’m not sure I even explain them even if I wanted to. The point is, there are language features that strictly separate functions that alter state with those that “only” perform calculation.

These referentially transparent “pure” functions are revered because they can be reused, re-ordered or parallelized and are guaranteed to always produce the same result. This makes programs more predictable and thus simpler to debug. When you know a function is pure, you need only check its return value; it can’t have changed anything outside of itself.

So, while the languages most of us use daily don’t offer this as a feature, maybe following the principle more often would make for more predictable, bug free code. Wouldn’t that be nice.

Post-fetch Manipulation (Sorting) of ngResources in AngularJS

Just a quick tip that I found useful in a recent Angular.js application.

I was trying to randomize the order of elements within a list retrieved from a ngResource (answers in a quiz or poll application). The naive approach would be to write the code as if the resource fetch is synchronous.

1
2
3
4
5
6
angular.module('myApp').controller('MyCtrl', function ($scope, $resource, $routeParams) {
  var shuffle = function (list) { /* ... */ };
  var repo = $resource('/api/question/:id', {id: '@id'});
  $scope.question = repo.get({id: $routeParams.id});
  shuffle(question.anwers);
});

The problem that will soon become apparent, is that the get is not synchronous. So, when the shuffle(question.answer) is called, the question object is not yet populated.

One approach that I encountered to circumvent the issue is to use the built in orderBy filter with a callback that randomly chooses the order. This works, because the filter is run when the returning data triggers a new digest. This may be good enough in some circumstances. The problem I encountered with this approach however, is the list is re-sorted every digest cycle. So, if there is anything much going on in the scope, the list will re-sort itself causing the bound elements in the page to jump around.

The solution for me, was to sort the list once, after it is retrieved. This can be accomplished by passing a callback, as the second argument to $resource.get, that will be called with the returned data once it becomes available. This allows you to perform any required manipulation on the data before it is assigned to the $scope.

1
2
3
4
5
6
7
angular.module('myApp').controller('MyCtrl', function ($scope, $resource, $routeParams) {
  var shuffle = function (list) { /* ... */ };
  var repo = $resource('/api/question/:id', {id: '@id'});
  $scope.question = repo.get({id: $routeParams.id}, function (question) {
      shuffle(question.anwers);
  });
});

In this instance, the answers to the question are shuffled, but the pattern is useful any time you want to perform an action only after the data if fetched. This may include calculating aggregates or even fetching extra, dependant data.

As an aside, I don’t believe this manipulation belongs in the controller and should probably be encapsulated in a service that the controller consumes. I will have a look at using “fat” services and “lean” controllers in a future post.

Share Tmux Windows Across Sessions

When working in a terminal (the vast majority of the time) I run the terminal multiplexer tmux, with one session for each project I am currently working on. I like to have a window for my IRC client in every session, so I can keep an eye on it. The best way to do this is to share the tmux window across multiple tmux sessions.

To perform this setup, we can create a new session for “shared” applications, opening irssi in a window named “irc”. Either manually create the windows and open the applications in them, or, if you’re lazy and use the same setup regularly. Script it, something like so:

tmux new-session -s shared "tmux new-window -n irc irssi"

You can use the automatically-assigned window names, but since I’m referencing them across sessions, I feel explicitly naming them (with the -n) is more robust.

Once the applications are running, we can link the windows to the working session using tmux’s link-window command, which has the basic form:

tmux link-window -s <src-window> -t <dst-window>

Any time a tmux command requires a reference to a window, we can provide an absolute reference to any window in any session using the session:window format where session is the name of the session and window is the name (or number) of the window in that session.

Using this, we can use the link-window our “shared:irc” window to index “9” in the current session. Which looks like:

tmux link-window -s shared:irc -t 9

The target parameter is optional, without it the window will be placed in the next available index, but I like to place it at the end of the list so they don’t get in the way of my “real work”.