dave^2 = -1

A software development blog by some bloke called Dave

Design via minimum code

Being a bit of a realist (;)), I find it much easier to find problems with my design ideas than I do finding designs I’m really happy with. I am always cognisant of this and make sure to balance the needs of doing a good job and getting the job done. One technique I find useful for this is thinking about the minimum amount of code required.

Whenever I find myself evaluating different design patterns or counting responsibilities to work out where the feature should go or which areas I should refactor, I stop and work out the minimum amount of code I’d need to write to solve the problem, ignoring design considerations. Once I’ve starting thinking about the problem in that light, working out where to put that code becomes a bit easier. If the code violates my sense of design aesthetics, it could just be because it is a messy problem, and no matter how hard I try to abstract or design my way out, the fundamental messiness still remains.

Working out function types: map map

One of the exercises in Introduction to Functional Programming by Richard Bird and Philip Wadler is to work out the type signature of map map (i.e. calling map with map as its first argument). I’ve generally struggled to deal with all but the simplest of partial function application, but I found a great thread on the Lambda the Ultimate forums that really helped me out with this. Two commenters suggested different approaches: going through the maths, and understanding the abstraction.

Associativity

One of the nice things about pure functional programming is that we can use mathematical properties and axioms to reason about, simplify and derive functions. A property that I’ve seen crop up a few times is associativity.

Function strictness

I’m currently reading Introduction to Functional Programming by Richard Bird and Philip Wadler, and it contains a really nice explanation of function strictness, a topic that came up in my last post.

Bird and Wadler describe a strict function as one that is undefined when its input is undefined. The symbol, or bottom, is used to represent ‘undefined’, so f is strict if f ⊥ = ⊥, otherwise it is non-strict.

Folds Pt 3: Left fold, right?

This post is part 3 of a series on folds, which is my attempt to understand the topic. The examples are in Haskell, but hopefully you can follow along even if you’re not familiar with the language. If you find yourself getting lost in the syntax, I’ve written a Haskell quick start that goes through all the bits we’ll use.

In part 1 we found that a fold is a way of abstracting recursive operations over lists. In part 2 we saw that we could also express loops using recursion, which we could extract into a different type of fold. We learned that the loop-like fold is called a left fold (it accumulates its values on the left of the expression), and that our original fold was called a right fold (which accumulates to the right).

foldLeft :: (a -> b -> a) -> a -> [b] -> a
foldLeft f acc (head:tail) = foldLeft f (f acc head) tail
foldLeft _ seed [] = seed

foldRight :: (a -> b -> b) -> b -> [a] -> b
foldRight f acc (head:tail) = f head (foldRight f acc tail)
foldRight _ seed [] = seed

We saw we could implement several functions using both left and right folds (like sum, length, and mapFn). As both folds abstract away explicit recursion, they seem capable of producing the same results, just with different orders of evaluation. It turns out these differences in evaluation have some important implications, so in this post we’ll take a closer look at them.

Folds Pt 2: From loops to folds

This post is part 2 of a series on folds. Folds seem to crop up quite often in functional programing, and this series is my attempt to learn a little about the topic.

In part 1 we found that a fold is a way of abstracting recursive operations over lists. In this post we’ll look at a different way of folding; one that traverses lists in a similar way to a for/foreach loop.

Goals for software developers

Most software developers I know are really keen to improve their skills. But how do we know we’re improving? How can we tell if our efforts are effective? Without feedback on our progress, it is easy to feel swamped and demoralised by the rate at which stuff we want to learn piles up, compared with the rate at which we feel we’re improving. Setting and working towards goals can help address this.

Yet when I’ve asked other devs, most have great personal, work and non-tech goals, but have something to the effect of “become a better developer” thrown in as well. I’ve been thinking about this a bit recently, so thought I’d jot down a couple of thoughts about goals specifically related to software development.

Haskell newbie attempts a Haskell quick start guide

I recently posted an attempt to explain folds using Haskell, and I got some feedback that the code samples were quite hard to follow for people that hadn’t played with Haskell before. Now the best way that I know of to quickly get started with Haskell is to go through the excellent Learn You a Haskell for Great Good guide. I heartily recommend leaving this post right now and reading it. The whole guide is available free online, but you can also buy print copies of the fantastic reference. Here’s the link again in case you missed it the first time.

Are you still here? Oh. Well, seeing as you don’t seem to want to listen to my advice, you deserve the rest of this post. It features a complete Haskell-n00b sharing his ignorance and misinformation with a reckless disregard for your quest to understand the basics of Haskell in a way that may permanently impair your ability to learn Haskell, understand functional programming, operate heavy machinery, socialise with other humans or be trusted with the weighty responsibility of goldfish ownership.

The aim of this post, despite your reticence to go through an extraordinarily helpful Haskell tutorial, is to get going with the very basics of Haskell insanely quickly and with a minimum of understanding about what’s actually going on. Because that’s just the way I roll. And let’s face it, you deserve it for not taking my advice. ;) (Last chance for redemption.)

Folds Pt 1: From recursion to folds

I’ve recently been trying to learn some functional programming, and one of the first things to trip me up was the idea of folds. Folds crop up all over the place in both functional and imperative languages, so they’re worth understanding. At their simplest, folds seem to be a short-hand for defining recursions over lists, but I find I start getting lost somewhere between fold types and optimising for languages with lazy evaluation.

This series on folds is my attempt to pull together the little bits and pieces I’ve managed to pick up into a form I can understand. If you’re not familiar with folds, hopefully it will help get you started. If you already know about folds then you probably won’t get much out of this, but if you do read through it I’d love to get corrections via the comments or via email so I can update the post.

In this first post of the series we will try to work out what folds are. We’ll start by looking at some problems we can solve using recursion over lists. We’ll then try and work out what these solutions have in common, and factor that out. Finally we’ll see how this relates to folds, and how we can use folds to solve these problems more succinctly.