Monday, October 29, 2018

Why Functional Programming?

Consider the following code.

10 let x = 5;
20 print x;    // prints "5"
30 let x = x + 1;
40 print x;    // prints "6"

Therefore, based on the above program, 5 = 6.

If you just said, "Wait, what??" then you've just stumbled over the difference between functional programming and imperative programming. In high school algebra, we learn that once we've solved for x, we know the value of x and can use it to find other values in the equation. When we try to apply that knowledge to (imperative) programming, we find out that our math knowledge is useless, and the reason is right there in line 30:

30 let x = x + 1;

You can't do that in in math, because there is no value of x that can satisfy both sides of the equation. Imperative programming, though, not only allows you do that, it actually encourages it.

That, in Zen koan form, is the difference between functional and imperative programming. In functional programming, you can find out the value of something, and once you know it, you've found the answer. In imperative programming, by contrast, there's no such thing as the value of a variable, because it's variable. The closest you can come to knowing its value at some particular instant in time, with no guarantee that it will still have the same value even a millisecond later.

Now multiply that by the number of variables in a typical non-trivial program, and maybe you can see the advantage of functional programming. Functional programming is about functions, in the more mathematical sense. Functional programs work with values, not variables, and thereby eliminates entire classes of bugs that arise because some variable changed values when you didn't expect it to. That in turn means you no longer need to write all the defensive code it takes to try and avoid/detect/recover from them.

There's lots more to learn about functional programming, and particularly about how we use it to manage changing state (which is something all code needs to do somehow). But the gist of it is this: in functional programming, we're not issuing commands to bash things together (and possibly break them). Functional programs describe the fundamental relationships between things, the same way 2x + y = 0 describes the relationship between x and y. And that, in turn, lets us write code that is simpler, more powerful, and more reliable.

Saturday, October 3, 2015

Review: Single Page Applications with ClojureScript and Om

I have just finished Eric Norman's interactive programming course called "Single Page Applications with ClojureScript and Om," and I have to say I am very pleased with the course. The pacing is good, the examples are clear, and the hands-on exercises are both helpful and doable. The one complaint I had was that I had trouble reading the lighter font against the light background, but since the course is made of locally-stored HTML files, it was easy to get in and tweak the CSS to improve the contrast.


Tuesday, August 4, 2015

Users and Roles (Part 3)

In Part 2, I talked about how an almost trivial data simplification can turn a difficult-to-maintain system into a system with a surprising amount of power and flexibility. In this third and final post, I want to discuss a design principle that could help us to design simple, flexible systems without having to go throw a painful, labor-intensive set of iterations first.

Sunday, August 2, 2015

Users and Roles (Part 2)

In Part 1 I described the kind of situation you get into with a naive access control system based on tying everything to a user ID: it starts out easy, but then gets harder and harder to change as the business needs evolve.

In Part 2, I want to look at how we can create a more robust and flexible system by "de-complecting" the separate ideas of user identity and access control.

Monday, July 27, 2015

Users and Roles (Part 1)

In my last post, I pointed out that complexity is the reason why good programmers sometimes write bad code. Complexity, however, can be difficult to recognize at the time you are creating it. Let me give you an example from my own experience as someone who has written code they later regretted.

Sunday, July 19, 2015

Why do good programmers write bad code?

One of the things that annoys me the most about programming is bad code, especially if I'm the one that wrote it. And I know I'm not alone, because I work with other programmers, good programmers, and I hear them say, "Who wrote that crap?" knowing good and well they wrote it themselves.

It happens to all of us. If we write a lot of code, sooner or later, we're going to write code that embarrasses us because we know better than to do what we just did. And I don't believe it's simply a matter of being rushed, or being tired, or just having a bad day. I think there's a fundamental problem that makes bad code difficult to avoid unless and until we address it.


Tuesday, July 14, 2015

Over-engineering

One of the lessons I've learned all too well over the years is the cost of over-engineering. It's an easy trap to fall into, because once we start to get into a particular problem, and start breaking it down into smaller tasks, it's easy to see other problems that could also be solved using the same tools. Complication ensues, because we try to write code that covers every possible use case. This violates the agile programming rule of YAGNI (you ain't gonna need it), which is a good rule for avoiding over-engineering. But there's an even broader principle that also applies here, and that's the principle of doing more by doing less.