Web Mindset
There’s a common complaint about apps on mobile platforms (namely iOS and Android): you have to download an app. This has led to calls for websites to stop pushing their app equivalent and just let people browse. (We’re looking at you, newspapers.) Why pull a beefy application every month or so when you can just pull the UI, content, and behaviour all at once, on demand, when you need it?
This observation is correct, and, I think, not the main reason why the web’s usability will always triumph over apps.
When I need to do something on my phone, I first …
Pointless work
We leave our mess everywhere.
The demise of LastPass, or at least the beginning of the end
In August, LastPass notified its customers, including me, that there had been a breach in it systems, and some data was leaked. I didn’t worry. After all, “We have no evidence that this incident involved any access to customer data or encrypted password vaults.” The keys to the kingdom were safe.
On 1st December, it got a little murkier. It turns out someone “was able to gain access to certain elements of our customers’ information”. Still, I didn’t worry. …
I shall finish more than I start
Here’s an incomplete list of projects I’m working on right now in my “spare time”, in order from least abandoned to most.
- This very blog you’re reading
- Migrating everything off LastPass, because it seems it’s very overdue
- Setting up NixOS on a new hard drive (this time it will stick, goddamnit)
- Advent of Code 2022 (I’m about half-way through; turns out it’s a lot harder to keep up when you have a tiny child)
- Improvements to my personal Mastodon instance
- Migrating my email and calendar from Google to Fastmail, in my quest to de-Googlify myself
- Shipping …
I'm not fucking about, I'm internalising
I think I’m coming to terms with my procrastination.
A lot of the time, it looks like I’m fucking about, but I’m really just internalising the problem at hand, and clearing space for it in my brain.
It might look like I’m doing 8 other things. I need to do those 8 other things first, because they’re in the way. They’re taking valuable computation power and memory. Once they’re done, I have space to breathe, and then time to really get excited about the task at hand.
And meanwhile, there’s a background thread going on the whole time, …
Twitter's doomed. What's next?
Last week, Twitter got new management.
Now, I’m not a fan of the new management. But then, I wasn’t a fan of the old management either. Nevertheless, this presented an opportunity to reflect on how I engage with Twitter.
About a year ago, I decided I was spending far too much time doomscrolling, and I deleted the app from my phone. I’ve done this before, but this time it stuck. I keep the browser signed out, too. If I want to check what’s going on on the timeline right now, I have to go to a computer. This means that I rarely check out the timeline. And …
Maybe, just maybe, there are other ways
There’s this common trope in startups: “Hire fast, fire fast.”
Every time I’ve heard this, I think, “I could never do that.” And I’ve always wondered if I’m weak, or shouldn’t be in that kind of leadership position. (And, dear reader, I have been in that kind of leadership position, but maybe I shouldn’t have been?)
Recently, I read Rands’ latest article, The Coach and the Fixer. To spoil the article a little (go read it first), at the end, he talks about being unfailingly kind.
And he asks himself, “Is it kind to fire someone?”
Reading this article, it …
#OneEstimate
This started out as a Twitter thread.
#OneEstimate, or, why your estimates suck and why your stand-ups are boring.
Estimates have a pretty bad reputation at this point, at least in certain circles. (I am sure there is a much wider circle of Agile legionnaires or whatever they call themselves, shouting about how you must estimate every story using only powers of 7 or something, so that management can make plans stretching out to 2031. Fortunately, I don’t talk to those people.)
I agree with most of the arguments put forth by the #NoEstimates crowd and …
Camaraderie is helpful, but no substitute for working together
In failing to build a company, I have learned many things. Core to all of them is that a company is not a product. Ideas change, products change, people change. We “pivot”, rapidly, relentlessly, sometimes ruthlessly.
Managed well, change is a catalyst. Managed badly, it can be catastrophic.
In this series, I try to explain the various ways in which I failed to understand this, and how I would endeavour to do better next time. You may notice that the style of these posts is more instructive than usual. Remember that these are mostly addressed to my …
Roles can be fluid, but they must be defined
In failing to build a company, I have learned many things. Core to all of them is that a company is not a product. Ideas change, products change, people change. We “pivot”, rapidly, relentlessly, sometimes ruthlessly.
Managed well, change is a catalyst. Managed badly, it can be catastrophic.
In this series, I try to explain the various ways in which I failed to understand this, and how I would endeavour to do better next time. You may notice that the style of these posts is more instructive than usual. Remember that these are mostly addressed to my …
If you don’t know how to do it, that’s your biggest problem
In failing to build a company, I have learned many things. Core to all of them is that a company is not a product. Ideas change, products change, people change. We “pivot”, rapidly, relentlessly, sometimes ruthlessly.
Managed well, change is a catalyst. Managed badly, it can be catastrophic.
In this series, I try to explain the various ways in which I failed to understand this, and how I would endeavour to do better next time. You may notice that the style of these posts is more instructive than usual. Remember that these are mostly addressed to my …
Until you have traction, money is a trap
In failing to build a company, I have learned many things. Core to all of them is that a company is not a product. Ideas change, products change, people change. We “pivot”, rapidly, relentlessly, sometimes ruthlessly.
Managed well, change is a catalyst. Managed badly, it can be catastrophic.
In this series, I try to explain the various ways in which I failed to understand this, and how I would endeavour to do better next time. You may notice that the style of these posts is more instructive than usual. Remember that these are mostly addressed to my …
Agile methods are tools to try more ideas in less time
In failing to build a company, I have learned many things. Core to all of them is that a company is not a product. Ideas change, products change, people change. We “pivot”, rapidly, relentlessly, sometimes ruthlessly.
Managed well, change is a catalyst. Managed badly, it can be catastrophic.
In this series, I try to explain the various ways in which I failed to understand this, and how I would endeavour to do better next time. You may notice that the style of these posts is more instructive than usual. Remember that these are mostly addressed to my …
Do less, and do it better
In failing to build a company, I have learned many things. Core to all of them is that a company is not a product. Ideas change, products change, people change. We “pivot”, rapidly, relentlessly, sometimes ruthlessly.
Managed well, change is a catalyst. Managed badly, it can be catastrophic.
In this series, I try to explain the various ways in which I failed to understand this, and how I would endeavour to do better next time. You may notice that the style of these posts is more instructive than usual. Remember that these are mostly addressed to my …
Throwaway development environments with Nix
I use Nix a lot.
Nix is a bunch of different things. It’s a programming language, designed for expressing a build pipeline. It’s a package manager. It (well, NixOS) is an operating system based on that package manager.
Today I’d like to talk about the package manager. Specifically, a lovely gateway into the rest of the ecosystem, nix-shell
.
Some people will tell you that the point of Nix is to set up your software so it can be built with Nix, which allows you to tightly control all dependencies and emit something that is as close to reproducible as …
Code is a liability; ship without coding, if possible
In failing to build a company, I have learned many things. Core to all of them is that a company is not a product. Ideas change, products change, people change. We “pivot”, rapidly, relentlessly, sometimes ruthlessly.
Managed well, change is a catalyst. Managed badly, it can be catastrophic.
In this series, I try to explain the various ways in which I failed to understand this, and how I would endeavour to do better next time. You may notice that the style of these posts is more instructive than usual. Remember that these are mostly addressed to my …
Unless someone cares, don't waste your time
In failing to build a company, I have learned many things. Core to all of them is that a company is not a product. Ideas change, products change, people change. We “pivot”, rapidly, relentlessly, sometimes ruthlessly.
Managed well, change is a catalyst. Managed badly, it can be catastrophic.
In this series, I try to explain the various ways in which I failed to understand this, and how I would endeavour to do better next time. You may notice that the style of these posts is more instructive than usual. Remember that these are mostly addressed to my …
Explore the terrain first
In failing to build a company, I have learned many things. Core to all of them is that a company is not a product. Ideas change, products change, people change. We “pivot”, rapidly, relentlessly, sometimes ruthlessly.
Managed well, change is a catalyst. Managed badly, it can be catastrophic.
In this series, I try to explain the various ways in which I failed to understand this, and how I would endeavour to do better next time. You may notice that the style of these posts is more instructive than usual. Remember that these are mostly addressed to my …
Go to therapy with your co-founders
In failing to build a company, I have learned many things. Core to all of them is that a company is not a product. Ideas change, products change, people change. We “pivot”, rapidly, relentlessly, sometimes ruthlessly.
Managed well, change is a catalyst. Managed badly, it can be catastrophic.
In this series, I try to explain the various ways in which I failed to understand this, and how I would endeavour to do better next time. You may notice that the style of these posts is more instructive than usual. Remember that these are mostly addressed to my …
Trust your gut, understand your heart, and open your mind
In failing to build a company, I have learned many things. Core to all of them is that a company is not a product. Ideas change, products change, people change. We “pivot”, rapidly, relentlessly, sometimes ruthlessly.
Managed well, change is a catalyst. Managed badly, it can be catastrophic.
In this series, I try to explain the various ways in which I failed to understand this, and how I would endeavour to do better next time. You may notice that the style of these posts is more instructive than usual. Remember that these are mostly addressed to my …
Your corporate values transcend your product vision
In failing to build a company, I have learned many things. Core to all of them is that a company is not a product. Ideas change, products change, people change. We “pivot”, rapidly, relentlessly, sometimes ruthlessly.
Managed well, change is a catalyst. Managed badly, it can be catastrophic.
In this series, I try to explain the various ways in which I failed to understand this, and how I would endeavour to do better next time. You may notice that the style of these posts is more instructive than usual. Remember that these are mostly addressed to my …
"Do research" is not a corporate strategy
In failing to build a company, I have learned many things. Core to all of them is that a company is not a product. Ideas change, products change, people change. We “pivot”, rapidly, relentlessly, sometimes ruthlessly.
Managed well, change is a catalyst. Managed badly, it can be catastrophic.
In this series, I try to explain the various ways in which I failed to understand this, and how I would endeavour to do better next time. You may notice that the style of these posts is more instructive than usual. Remember that these are mostly addressed to my …
How to drive fast
An incomplete list of the things you need to drive a car at high speed:
- a powerful engine
- high-quality brakes
- power steering
- solid suspension
- tires in good repair
- a clean windshield
- a seatbelt
- an airbag
- enough fuel
- an open road
- good-quality tarmac (asphalt)
- excellent weather conditions
- clear visibility
- quick reflexes
- a solid night’s sleep
- years of experience
Next time someone asks you why you’re wasting time writing tests, or refactoring code, or introducing continuous deployment, consider this list.
If the company goals change, the company should probably change too
In failing to build a company, I have learned many things. Core to all of them is that a company is not a product. Ideas change, products change, people change. We “pivot”, rapidly, relentlessly, sometimes ruthlessly.
Managed well, change is a catalyst. Managed badly, it can be catastrophic.
In this series, I try to explain the various ways in which I failed to understand this, and how I would endeavour to do better next time. You may notice that the style of these posts is more instructive than usual. Remember that these are mostly addressed to my …
Focus on the problem, not the solution
In failing to build a company, I have learned many things. Core to all of them is that a company is not a product. Ideas change, products change, people change. We “pivot”, rapidly, relentlessly, sometimes ruthlessly.
Managed well, change is a catalyst. Managed badly, it can be catastrophic.
In this series, I try to explain the various ways in which I failed to understand this, and how I would endeavour to do better next time. You may notice that the style of these posts is more instructive than usual. Remember that these are mostly addressed to my …
Introduction
In late 2016, I founded a startup named Prodo with a few friends. My job title was “Chief Technology Officer” (CTO). Our mission was to democratise programming by automating away common mistakes, powered by machine learning technology.
Unfortunately, things didn’t pan out. I left Prodo in late 2019, and the company shut down in mid-2020.
In failing to build a product-focused company, I have learned many things. Core to all of them is that a company is not a product. Ideas change, products change, people change. We “pivot”, rapidly, relentlessly, …
A little announcement
A little announcement, in case you’re interested.
My partner and I have lived in Zürich for almost two and a half years now. I love it here, and I am very grateful and privileged that I got to ride out the worst part of this horrible pandemic in a country where people take masks seriously, the supermarket never ran out of basic food, and there’s so much to do outdoors. (Can’t catch a virus if the nearest person is on the next mountain.)
It’s been a rough couple of years, but we count our blessings. And the best one arrived around a month ago, in the form …
Transparent memoisation in Haskell with MemoTries
Last month I participated in Advent of Code, along with a bunch of friends and colleagues. Typically I prefer to use Advent of Code as a mechanism to learn a new programming language, but after not finishing the last couple of years, I wanted to make life easier for myself, so I decided to use Haskell and give myself a little break.
Haskell is a language designed to effectively express computations. As such, functions are “pure”: they may have no side effects. Even I/O is handled by returning a sequence of instructions which are then actually enacted by …
Laziness in Haskell
A precursor, so that I never have to explain this again.
Haskell is often called a “lazy” language. This means that it doesn’t compute anything until it has to.
This allows for a host of interesting behaviour. One of the simplest is infinite sequences. Lists in Haskell are lazy (like anything else, by default). This means that the head of the list can be inspected without computing the tail, or vice versa.
For example, I can define a sequence that is just the value 7
over and over again:
sevens = 7 : sevens
λ sevens
[7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, …
Meeting structure
On Monday, I asked you to review your meeting formats.
Now I want you to look back. Which of those meetings were productive? Which encouraged healthy collaboration, and which had a bunch of people staring into space (or worse, doing other work at the same time)?
Of the unproductive meetings, what was the format like? Did they stick to a specific style, or meander about? Was there someone keeping the discussion on track, or was facilitation left to whoever had the most clout or influence? Was there a clear goal for the meeting?
I can guess the answers to …
What kind of meetings are you having?
Happy Monday, those of you who are reading this as it’s published.
I have a challenge for you this week (or any week), inspired by the Agile Conversations Slack group. If you work in software development, you most likely have a bunch of “meetings” throughout the week. Now, I really dislike the term “meeting”, because I find it very general.
In the interest of improving your skills, I invite you to get better at naming things by being more specific about the meeting in question. Try breaking down the meetings by format. For …
Overcoming writer's block
Sometimes, when attempting to write, or design, or create something new, you’ll get “blocked”. You know where you want to be, but you don’t know the next words to write to get yourself moving.
The trick, as I’ve found it, is to not write (or design, or create) the next thing.
Writing often goes from top to bottom, left to right. But it doesn’t have to be that way. You can start in the middle.
So start in the middle, and write the thing that’s first and foremost in your mind. It doesn’t matter that it …
I miss unconferences
It’s been almost exactly nine years since I attended my first unconference: SoCraTes, in Germany. At the time, it was around 60 people, gathered in the ever-fascinating SeminarZentrum Rückersbach, nestled in a forest, on a hill, about 50km away from any kind of civilisation. A bunch of people, trapped, with very little to do except talk about computers.
SoCraTes is special, even for an unconference. It attracts an incredible mix of makers, educators, connectors, hackers, facilitators, and philosophers. People who work for large companies and small …
Test-driven development in three easy steps
You might have heard that test-driven development, or “TDD”, is as simple as three easy steps. So without further ado, I present them here.
- Write a failing test.
- Delete that test. It was nonsense.
- Write a much smaller test with just an assertion and a couple of extra lines.
- Run the test and observe that the failure message is completely useless.
- Rewrite the assertion for good failure messages.
- Run the test again. Rejoice in your helpful failure message.
- Try to make it pass by implementing a new function in your test code.
- Realise that in …
Truly great CI/CD
Either my standards are too high, or I’ve never seen an excellent CI/CD pipeline. Which got me wondering: what would a truly great continuous deployment (or continuous integration) pipeline look like?
So here’s some ideas.
-
Software developers (programmers, QA, designers, ops, customer liaisons, etc.) can build your entire application (and yes, that includes microservices) in under a minute on their work computers. Offline.
It’s OK if the first run takes a while, but the second time shouldn’t.
Bonus points if attempting to build …
I contain multitudes
Do I contradict myself?
Very well then I contradict myself.
(I am large, I contain multitudes.)Song of Myself, by Walt Whitman
There’s a movement going on, invisible but powerful. I’m not sure how it started, but I’ve been swept up.
I keep hearing, nowadays, that we should be able to bring our whole selves to work. That a sufficiently psychologically safe work environment doesn’t require us to be “professionals”, but to be our raw and honest selves. Only by being ourselves can we unlock the next stage of creativity …
What to refactor
I originally posted this on Twitter. Thought I’d update it and turn it into an article.
I recently spent a couple of weeks refactoring a large chunk of an API we use at work to integrate our software with third-parties. All in all, it was 17 changesets, most of which were refactoring the code to make it easier to switch.
I really enjoyed this work, and I wanted to share how I know what to refactor.
We’re introducing a new (Scala) API (“v2”) to replace an old one (“v1”). For a while, we’ll need both functioning in …
One Weird Trick To Improve Development Culture
If you asked me the one thing you could change to improve your code, I’d tell you you’re asking the wrong question.
If you came to me and asked me how to improve the productivity, happiness, and knowledge of your software developers, I’d tell you that I don’t know. But I do know how you can find out.
Introduce pair programming, with frequent rotation. Pairing has a number of benefits that any XP fan (like me) will happily go into, such as getting very fast feedback on your work, keeping each other motivated, and learning how any …
You Could Have Invented Booleans
Booleans can be confusing.
Note: The original version of this article used a tweet by David Flanagan, but it’s gone missing, so I have replaced it with this screenshot.
Now, let’s first establish that we’re glad the file_diff
crate exists and we appreciate the maintainers for their time. This is not an accusation or criticism of their work, …
Running Agda with Nix
I like to keep even traditionally system-level dependencies isolated and pinned per-project, so I use Nix for that.
I have been playing with Agda for a while now, and it has been a joy to work with a theorem proof assistant for the first time. (I am hoping to write some more on the topic when I am more familiar with it, but for now, I’ll just recommend Wadler, Kokke, and Siek’s excellent and free book, Programming Language Foundations in Agda.)
I found it a bit of a pain to configure Agda with Nix, and I haven’t found this advice …
All Problems Are Hard
I got some praise yesterday. A colleague of mine told me that I never shy away from the hard problems.
It’s hard not to have a big grin on your face when you hear something like that.
Got me thinking though… what’s hard, exactly? And so I’ve been musing. Aren’t all problems hard?
Say a customer reports a bug, and you’ve got to fix it. You can fix it. You know you can fix it. Maybe it’ll take an hour, maybe it’ll take a day, maybe a week. But you’ll narrow it down, figure out the smallest possible increment …
Thirty-two
I had a lot planned for last year.
We’d just moved to Zürich, and were getting to know the place. I’d found the good coffee, and I was on the hunt for decent Thai food. We bought some furniture, we didn’t have ceiling lights (now resolved), we’d figured out how to buy bin bags (it was a challenge) and I missed fish and chips. I planned to work on an open-source project, buy a TV, and jump in the lake a lot. I planned on buying a snowboard, and come winter 2020–21, learning how to use it properly.
Then… well, you know what …
Untriggered traps in zsh
Recently, I had the displeasure of experiencing a few interesting situations in which traps in zsh don’t run. This isn’t the first time I’ve wasted hours or days debugging this problem, so I’m writing it down.
For those of you who may not know, a trap is a catch-all exception handler. Think of it as a finally
block for your shell script.
Try this script:
#!/usr/bin/env zsh
set -e
trap 'echo "Finished."' EXIT
echo 'Started.'
false
echo 'This will not print.'
This script will exit with a failure …
Smoke v2.1 is out!
I’ve just released version 2.1.0 of Smoke, my integration test framework for command-line applications.
The major feature: if your command-line application produces files, you can now test their contents.
The release notes explain all:
What to expect in an Interview Technical Test
Chipo, on the Codebar Slack, asked what they could expect in a technical test. I wrote a pretty long answer, which I thought might be useful to others as a blog post (after a bit of cleanup).
I’d typically expect a “tech test” to be part of an interview for a software development role. It involves implementing a small program, typically on the command line, as well as you can. Often, the interviewer will expect you to write unit tests and practice good design principles (low coupling, good names, etc.)
Sometimes the interviewer will …
Mean Time To Recovery, as a lifestyle
I don’t have a plan, but I have half a dozen outlines for plans.
I recently made an observation about myself that I thought was worth sharing. It’s both an explanation of how I operate and a realisation of the trouble this causes for other people.
I’ve never really been able to collaborate with other people; either I do things on my own or not at all. I’ve managed to get over this to an extent with techniques like pair programming, which enforces a kind of working structure by breaking the work into small, manageable pieces …
Teaching a Machine to Code, at NewCrafts Paris 2019
Last week, I spoke at NewCrafts Paris 2019 on the topic of “Teaching A Machine To Code”, a talk I also gave last year at Joy of Coding.
(If you just want the content, it’s up.)
Before I talk about my talk, something really important: NewCrafts is a wonderful conference. I’ve never seen one run so smoothly. It was marvellous to see. Massive credit to the organisers for making it work so well.
Since Joy of Coding, a couple of things have changed. Firstly, the models themselves have evolved, and we’ve become more focused on the …
Running Swift without Xcode
On Saturday, I finally finished Advent of Code 2018 (and pushed my solutions to GitHub). I did the whole thing in Swift (except for a couple parts which I did by hand), but I tried to avoid Xcode as much as possible, knowing that it would make automating things a whole lot harder. Instead, I ran everything directly in the command line. It took a while to figure out how to do this, with little official documentation on the subject, so I thought I’d explain how I did this so that anyone searching for it would find the information in one place. …
Plz, Respect Ur Data
Last night, I gave a talk at the very first Reproducibility and Productivity in Data Science (“RAPIDS”) meetup on the relative unimportance of code, the state of data management, and what we at Prodo.AI are trying to do about it.
As (almost) always, I wrote the majority of the content ahead of time, so if you weren’t there (and I know you weren’t), please take a look. I think you’ll enjoy it.
It focuses on an open-source tool we’ve been building to help us manage our own data problems, Plz, which I also encourage you …
Functional Reactive Serverless Architecture
Originally posted as a Twitter thread.
I’ve been thinking a lot about serverless architecture and I’ve realised what bugs me about it.
This is gonna be a long one. Not gonna lie, I wrote a draft first. If I hadn’t, this thread would end right before it got interesting because I’d get distracted by a butterfly.
At its heart, serverless/FaaS/lambda/whatever-you-call-it works for me because it ties action to cost. The more I do (or the more inefficiently I do it), the more I pay. More users, more money. Gojko Adzic wrote about this …
Chet Hendrickson, on the craft of software development
I was listening to Ron Jeffries and Chet Hendrickson on the Cucumber podcast, and I heard something that helped me reframe agility and craft in a way that was very meaningful to me.
He was prompted by Sal Freudenberg talking about asking for permission to use techniques such as test-driven development, rather than treating it as part of the job.
Chet Hendrickson: I think you’re right; it seems odd that we ask permission. We believe we have to have permission to do good work. I believe that on the first day of a new greenfield project, the codebase …
Teaching a Machine to Code, at Joy of Coding 2018
On Friday, I gave a talk at the Joy of Coding conference. The topic: “Teaching a Machine to Code”.
In this talk, I explained why we at Prodo.AI are working on next-generation tooling for developers, leveraging neural networks alongside traditional static analysis to find problems faster.
I also gave four (live!) demonstrations of how we can use machine learning and other more “human” techniques to detect and repair defects in code.
But mostly I talked about the difference between humans and machines, and how we can rebalance …
The Five Stages Of Agile Transformation
Every successful agile transformation goes through five stages.
Denial
What are you talking about? What’s this “Agile” bullshit? We don’t need it!
The first stage of an agile transformation is resistance. Perhaps the CEO is convinced, or perhaps there’s a ground-up movement from one of the software development teams, or maybe there’s a solo designer, engineer, tester or other developer pushing for change. Either way, we don’t like it. And we’re not listening.
It’s just another fad, anyway. …
Going Static
I’ve been wanting to get my blog off Tumblr for a while. It’s finally done.
I’m now running on Hugo, which is a pretty shiny static site generator. I like it a lot. It has a bunch of rough edges but I’ve mostly got my head around them now.
A Continuous Flow Of Coffee
I’ve watched software developers (in the broadest sense—programmers, designers, testers, managers, coaches, etc.) struggle with the idea of “one-piece continuous flow” for a long time.
Recently I was reminded of my favourite metaphor for this. I was in Brooklyn Coffee (the best little café in London) and watched the staff (there’s typically 3 people working there at any given time) work. I was waiting to place my order, but there were two people operating the coffee machine and one handling something in the back, so I had to wait …
Amdahl's Corollary, For Teams
The most efficient way to implement a piece of software is to do it all yourself. No time is wasted communicating (or arguing); everything that needs to be done is done by the same person, which increases their ability to maintain the software; and the code is by default way more consistent.
Of course, we don’t make large pieces of software this way. We work in teams.
Turns out “more efficient” doesn’t mean “faster”. When there are more people working on the same problem, we can parallelise—do more at once.
When we …
The Decentralised Web is the Client-Driven Web
I’m getting pretty excited about the idea of a completely decentralised World Wide Web.
Last year I went to the Mozilla Festival. I loved it. I could only make one of the two days, but it was enough for me. The highlight was the Beaker Browser, a browser that’s able to request and serve web pages over a secure peer-to-peer networking protocol called DAT.
Over the holidays, I decided to serve my website over DAT using the Beaker Browser, just to see how it goes. And I discovered something really interesting.
Twenty-Nine
Today, I’m 29.
Here’s what I’d like for my birthday.
I’d like you to ask yourself why you do what you do.
And then I’d like you to post that online somewhere public (even if it’s bloody Facebook), and leave a link in the comments, or email me, or tweet me, or… you get the idea.
That’d be the best present I could ask for.
City Planning
I believe, like all jobs, programming will be fully automated. The question isn’t “if”, but “when”. I believe in specialised AI for this role, not general-purpose AI, because most software problems are caused by incomplete understanding, and only a machine that can fully understand the technical landscape of a given piece of software will be able to meaningfully improve it.
I Promise I'll Call You Back
This post stems from a discussion with Constantina and others on the Codebar Slack team.
In JavaScript, callbacks can be unpleasant to work with. Callback Hell has a great explanation about how to make them work well, but it doesn’t change the fact that a programming style that lends itself to misuse can be problematic, and callbacks are misused all over the place. Even in documentation.
One of the big problems with callbacks is remembering to handle the error. This is the if (err) { … }
pattern you see a lot. If you find yourself copying and …
Public Speaking Is Hard
Last week, I spoke at Computer Science Noobs on the subject of type systems. I’m still in the process of writing up the talk (and make no promises about if and when it will be finished), but I realised something that I wish I’d realised sooner.
It turns out I really don’t like talks.
You Don't Need To Rebase
This post is loosely based on a discussion with Beverley Newing and others on the Codebar Slack team.
You don’t need to rebase.
I think branch-based development is now the most common workflow when using Git: everyone develops on a branch that belongs to them (for some definition of “belongs”, depending on the team), then when they’re done, they merge the branch into a shared branch (often called master
, latest
or develop
), from which they release.
No Computers
On Saturday, I helped run the Cambridge instance of Coderetreat, 2017 edition as part of the Cambridge Software Crafters.
It was a really fun day, and I enjoyed it thoroughly. Today, though, I’m not going to talk about the whole day. (If you want to read about what it’s like, I wrote a post about it five years ago.) This time, I want to concentrate on just the first session.
This one was new to me, but Amelie and Alastair been doing it in Cambridge for a long time. The task is the same as always: implement Conway’s Game of Life. The …
Facilitating Better Code Reviews
Over the weekend, I asked a lot of people a few questions about code reviews.
I have an agenda. We’re working on a product that intends to take the pain out of code review. We want to make the best product possible, and that starts with understanding where the pain is.
The data in my survey is biased towards the sort of people that read this blog. So take it with a grain of salt, and if it doesn’t resonate with you, comment! I’d love to hear from you.
Teach Me BDD
Sensei, teach me BDD.
OK, this whole programmer-fascination-with-Japanese-words thing has gone too far.
Also, OK.
Behaviour Driven Development, or BDD, is the idea that you write user stories that turn into executable test cases.
You’ve probably heard of Cucumber, or Gherkin. Gherkin is a format for doing just this. Cucumber runs the scenarios and tells you if they fail.
WebOps Workshop
Over this year, I’ve been delivering a talk/live presentation/workshop on “WebOps”, or DevOps-style operations for the web.
Here’s the premise:
At lightning speed, this workshop will cover the bits that aren’t code that make up a working web app. These include servers, monitoring, deployment mechanisms, logging, alerting, secret management, recovery mechanisms… you get the idea.
Topics include:
- how to set up a web server on Linux,
- deploying changes to a web server with zero downtime,
- keeping an eye on your server to make …
More like Hask-Hell LOL
I’m not sure how, but a little while ago I got talking to John Cinnamond about an experience of mine with Haskell that didn’t exactly end well.
As some of you may know, I made a terribly-promoted, mostly-unused (except by me) application called Over The Finish Line. It displays open pull requests on your favourite repositories in a dashboard format. I think it’s pretty neat. It doesn’t get much love nowadays… but I’m getting ahead of myself.
<img src=“ …
Player Characters
I was at GameCamp this weekend, learning more about how to design games.
I love the GameCamp community. More than anything, it’s inclusive: if you’re there, you must like games, and we like games too, so let’s talk about games!
So we talked about games. And something came up that I’ve never considered before.
Games, especially video games, provide the opportunity for something special: they allow the player to say and do things they’d never even consider in real life. This is often linked to the violence in many AAA titles, …
I've Got 99 Problems And Asynchronous Programming Is 127 Of Them
On Monday, I gave a talk at Codemotion Berlin entitled… well, it’s a long title. I don’t need to say it twice.
Anyway, I thought you might be interested in reading it. Yes, reading it. My talks are essays first.
Docker, Part Seventeen: Continuous Deployment
Apologies folks. I wrote this ages ago and apparently never published it. Well, late is better than never, so here it is!
You may want to remind yourself of Docker Compose and The Guts Of Docker Compose first.
Once we have a container, we can run it on a server.
$ ssh my-production-server docker-compose up -d
Of course, we need to get the container images there first. This is where continuous integration comes in.
Lean, Reactive Event-Sourcing
a.k.a. ALL OF THE BUZZWORDS.
You know, it’s been so long I forgot how my blog works. Time to remedy that.
I gave a talk last month at DevOps Linz entitled “Staying lean with application logs”. On the day, I came up with the far more click-baity one above.
#SoCraTesUK, Buzzfeed Edition
People came to beautiful Wotton House, the new venue for SoCraTes UK, from all over Europe.
I'm on my way to LGW! And I have wifi onboard #socratesuk pic.twitter.com/3rUWB7Vykq
— Aki Salmi (@rinkkasatiainen) June 2, 2016
The @socrates_uk venue is beautiful. Lot's of interesting discussion for the first night, time to sleep #socratesuk pic.twitter.com/FW6aAEGoec
— Emilien Pecoul (@Ouarzy) June 2, 2016
Docker, Part Sixteen: Logging
This post isn’t really about Docker, except that it is.
It’s generally considered good practice to log everything in your application that might be useful. When you’ve separated parts of the application into different processes, or even worse, distributed it across several computers, logging becomes even more important, as tracing an event through multiple systems isn’t easy by default.
The first thing to remember is that if it’s important, log it. Treat your log as an event stream. Ideally, you’ll be able to …
Isolating Gems With RVM
When working on a Ruby project, it’s tempting to just install the gems with bundle install
and get to work. While Bundler is pretty good at ensuring you only use the gems you specify, and that you get the right versions, you still end up with a ton of gems in one directory with no way to identify which ones you need and which ones exist for projects you don’t maintain any more, or are older versions of gems that you’ve updated.
Too Much Work In Progress
I’m working on a side project to help with a common problem: doing too much at once. I strongly believe that a productive team tries to focus on one thing at a time, and that juggling several pieces of work is the sign of an overloaded, badly-managed or underperforming team.
To figure out useful proxy metrics for too much “work in progress”, I surveyed people on Twitter and the Software Craftsmanship Slack to find out how they measure it. Here’s my distilled results.
Ninja Pairing
I’m sure I’m not the first person to do this, but I’ve never heard anyone else explain it explicitly, so here’s my take on it. This was originally part of a discussion on the Software Craftsmanship Slack organisation.
Ninja pairing: you arrive, you pair, you depart, and no one even realises you were there.
Three Months
It’s been three months since I started this new phase of my life. Time to take stock.
Health
Here were my goals for the year, health-wise, from my post, State of Mind.
- No sweets or processed sugar.
- No bread or pasta.
- No meat.
- Exercise a little bit every day.
- Run, climb or cycle a couple of times a week.
Docker, Part Fifteen: Securing Your Containers
Up until now, we’ve been neglecting security in favour of getting our application working and features delivered. It’s time to look back and ensure that there are no holes in our application containers.
Docker, Part Fourteen: Behave Like A Process
I was going to write a long post on all the different ways in which stopping your container can go wrong, but it turns out Brian DeHamer beat me to it and did a much better job than I could. I’d recommend reading the article, Gracefully Stopping Docker Containers.
But for completeness’ sake, I’d like to apply the advice in that article to my pet project, bemorerandom.com.
Docker, Part Thirteen: The Twelve-Factor App
A lot of the principles and practices I’ve tried to embody in my previous posts on Docker come straight from The Twelve-Factor App, a document spawned from, among many sources, Heroku’s engineering practices. The Twelve-Factor App explains the principles behind creating robust, scalable software that behaves the same in development as it does in production.
Docker makes some of the twelve factors easier, and some of them harder. I want to go through each of them in turn and explain how and why. Before going through this, I strongly encourage …
Language-Agnostic Test Cases
When pairing with @sleepyfox on a kata, we decided to write the code in a shell script. Someone snarkily asked how we were going to test-drive our solution. So, after a second of thought, I remembered my test framework, Smoke.
Smoke is a little different from other test frameworks. It was designed to test code written in any language, so you don’t write the tests in code. You simply specify the input to be provided to the program via command-line arguments and STDIN, and the expected STDOUT, STDERR and exit statuses. To do this, you just create …
The Three Laws of Project Management
-
A project manager may not impede a worker, or through inaction, allow a worker to be impeded.
-
A project manager must further the desires of the business except where such desires would conflict with the First Law.
-
A project manager must further their own goals as long as such goals do not conflict with the First or Second Law.
Making a calculator with bash and sed
Here’s an easy way to make a calculator REPL:
#!/usr/bin/env bash
while read line; do
echo $(($line))
done
Toggling browser elements without JavaScript
I’m having a sleepy weekend, and I feel like the rhythm of one week on Docker, one off is about as much as I can handle. (Those posts take work!) So we’re going to have a week of random stuff before I get back to it. Hope you don’t mind the wait. :-)
Cleanliness
I’ve heard this one from Hindus, Jews and Christians alike:
Cleanliness is next to godliness.
Docker, Part Twelve: Cleaning House
We’ve come a long way, but as they say, you can’t make an omelette without breaking some eggs.
Lets have a look at the mess I’ve made in the last couple of days.
Docker, Part Eleven: The Guts Of Docker Compose
Where were we? Ah yes, DNS resolution wasn’t working.
org.flywaydb.core.api.FlywayException: Unable to obtain Jdbc connection from DataSource
(jdbc:postgresql://database:5432/bemorerandom) for user 'bemorerandom': The connection attempt failed.
Docker, Part Ten: Docker Compose
Yesterday, we wrote a script to spin up all the various containers we need to start our application. Today, let’s take a look at a better way to do all that without worrying too much about the intricacies of Bash scripting.
Docker Compose is a tool for doing this sort of thing in a declarative fashion. You write a specification for what your application looks like, and Compose handles building and running it.
Docker, Part Nine: Scripted Deployment
We left off more than a week ago with an introduction to Docker volumes (amended in part eight and a half), which showed how to persist data across container restarts and upgrades. By the end of it, we could start the bemorerandom.com API service and its database with just a few commands:
Building Is The Job Of The Compiler
A few years ago, Kevlin Henney spoke on the topic of The Programmer at Devoxx UK. In his talk, he mentioned an article by Jack Reeves, What Is Software Design? It’s a long piece, written in 1992, musing on design, building and the job of the programmer. In the article, the author wrote something very striking.[^Thanks to @tomwhoscontrary]
This lesson is that programming is not about building software; programming is about designing software.
…
After reviewing the software development life cycle as I understood it, I concluded that the only …
Why Maven?
Every time I mention Maven, people ask me why I hate myself so much. It’s a (scarily) valid question to ask after seeing a POM file, so I thought I’d go into it a little.
Here’s a POM file. I hope your scrolling finger has been working out.
Finatra and Maven
I was ranting about Finatra’s Maven dependencies last week, and today I figured out why they’re broken.
Unless You Have A $PAGER
I just found a bug in SDKMAN! that you’ll probably never see. It only manifested in my machine when I ran the test cases inside a Docker container.
SDKMAN! is a program that manages, well, SDKs. It started off as the Groovy Version Manager, or GVM, but now it can install multiple versions of Scala, Grails, SBT… you name it in the Java world, and it’s there. You run it with the sdk
command in your terminal.
Docker, Part Eight and a Half: docker volume
I know I said I wouldn’t be writing about Docker this week but I wanted to correct the record. After Friday’s post, Lewis got in touch to ask why I hadn’t talked about the new Docker volumes. (Thanks Lewis!) I have to confess, I hadn’t even heard of them. Like the new networking functionality, docker volume
represents a shift in the way of thinking towards more than just containers. Instead of volumes being an attribute of a container, they’re entities in their own right.
Docker, Part Eight: Turn Up The Volume
(Can you tell I’m enjoying these awful puns?)
Yesterday, we created a container for PostgreSQL, my database of choice in a pinch. This was fairly simple, but had a problem you don’t see with stateless applications: the data on disk needs to be preserved across restarts and even replacements of the container.
Once the PostgreSQL container starts, it checks for a database in its own /var/lib/postgresql/data. If there is no database there, it creates one (and we can tell it how using environment variables which this container is specifically …
Docker, Part Seven: Start Talking
When we left off, we had a Scala web service running inside a Docker container. That’s all well and good, but we usually need a little more than a stateless machine. How about we bring in a database?
I’ve added a feature to bemorerandom.com that’ll make use of a PostgreSQL database. Here’s how it works:
Interlude: The Tiniest Web Service
I don’t have Internet now and I’m tethered to my phone, so I can’t play with databases and Docker like I wanted to today. So instead, let’s talk about a little project I made to demonstrate that you don’t always need your favourite programming language to deliver something useful.
nc
, or netcat, is a program that will connect to a network socket and cat (just like cat
) the result. It’s on basically any Linux or BSD (including Mac) operating system. Let’s try it.
$ nc google.com 80
Docker, Part Six: A Slow Build Is Worse Than No Build At All
A 22-line Dockerfile is all you need to create an image that runs a Java application with Maven.
FROM azul/zulu-openjdk:8
EXPOSE 8080
RUN apt-get update && apt-get install -y curl
ENV MAVEN_VERSION 3.3.9
ENV PATH /opt/maven/bin:$PATH
RUN mkdir /opt/maven
RUN curl -fsSL "http://mirror.ox.ac.uk/sites/rsync.apache.org/maven/maven-3/$MAVEN_VERSION/binaries/apache-maven-$MAVEN_VERSION-bin.tar.gz" > /opt/maven/apache-maven-bin.tar.gz
RUN tar xf /opt/maven/apache-maven-bin.tar.gz -C /opt/maven --strip-components=1 \
&& rm …
Docker, Part Five: Let's Make A Website
OK, the weekend has happened and I can’t remember where we left off. So let’s recap, as much for my sake as for yours.
Skillful Sailing
It is not the ship so much as the skillful sailing that assures the prosperous voyage.
— George William Curtis
Docker, Part Four: Repeating Yourself
Yesterday we made a Docker image that packages a simple Ruby application. However, recreating that image each time the application changed quickly became tiresome. Today we’re going to see how to automate that.
Docker, Part Three: Running Software
We’ve played with “Hello, World!” long enough. Let’s do something useful.
Hello, World is a simple example, but containers can wrap any software you like. This becomes especially useful when creating software that requires a lot of runtime dependencies. For example, your average command-line Ruby program probably depends on a bunch of libraries (gems), and shipping them is a pain. We don’t just have to ship the application, but the gems and the Ruby interpreter too. The alternative is to just ship the code and the Gemfile
, …
Docker, Part Two: Images and Containers
We left off, dear reader, with you running the following:
$ docker run hello-world
That would have resulted in output similar to this:
To generate this message, Docker took the following steps:
1. The Docker client contacted the Docker daemon.
2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
3. The Docker daemon created a new container from that image which runs the
executable that produces the output you are currently reading.
4. The Docker daemon streamed that output to the Docker client, which sent it
to …
Docker, Part One: Getting Started
Note: This article is pretty old. On Windows and Mac, I now recommend checking out Docker Desktop instead.
I’ve been using Docker heavily in development, test and production for almost a year now, and more and more, I’m asked how to get started with it and use it. I thought I’d write a quick guide to Making Things Happen™ on your local machine, and perhaps touch on deploying services inside Docker containers in the future.
Like The Turtle
Try to be like the turtle—at ease in your own shell.
— Bill Copeland
I’ve been re-learning tmux these last two weeks, living happily in my shell, with vim in a pane among a shell or three. It’s been wonderful. I never want to go back to using an IDE.
<img src=“https://assets.monospacedmonologues.com/2016-02-19--tmux.png" alt=“2016-02-19–tmux.png” />
Localised dotfiles
So you followed yesterday’s guide to setting up your dotfiles repository. Now it’s time to get your shell configuration in there.
If you’re using Bash, you’re in luck. Just move your .bash_profile
to dotfiles/bash_profile
and commit. Done and dusted. If you’re using ZSH, well, you have to copy your .zshrc
, .zshenv
, .zlogin
, .zlogout
and .zprofile
. That might take a while. It’s OK. I’ll wait.
dotfiles
I talked about the ramifications of uploading your dotfiles to an online repository yesterday, but I also want to talk a little about the practice.
Assuming you’re not running Windows (and if you are, I have no good solution except to stop right now), you probably have a bunch of files starting with “.
” in your home directory. Here’s mine.
The Worst Kind of Open-Source
There’s a growing trend among software developers which I absolutely love. More and more, people are checking their dotfiles (configuration files, normally starting with “.
”) and other personal scripts into version control and pushing them up to the Internet. It’s mostly selfish—just a useful way to make sure we don’t lose them, to be honest, and perhaps help us set up another computer quickly.
There’s also one massive benefit I’ve found to pushing my configuration files and shell scripts up to GitHub.
Backward Operators
I spent a summer a few years ago learning Clojure. Here’s a thing that confused the hell out of me for a while. It probably won’t affect anyone else who reads this, but I think it’s amusing.
I was coming at Clojure from two different angles: I know Java very well, and I am a Haskell hobbyist, though I’ve never used it for anything too serious. So when I read Clojure, my brain translates the syntax into Haskell, and the execution into Java. Because I’ve never used Clojure for anything in anger either, I’ve never got …
Moore's Law
The fast inverse square root function I talked about yesterday is often attributed to John Carmack. The fact is, no one really knows where it came from, but it speaks to Carmack’s legendary status that such an amazing feat of engineering is commonly assumed to be written by him.
So I thought, for today, I’d muse about something Carmack once said:
Because of the nature of Moore’s law, anything that an extremely clever graphics programmer can do at one point can be replicated by a merely competent programmer some number of years later. …
// what the fuck?
A few days ago, Peter Hilton was talking about the fast inverse square root method on the Software Craftsmanship Slack, which he uses in his presentation, Layout & typography for beautiful code. I love that this function exists, and I decided to blog about it.
First, let me explain what it means. The inverse square root of a number, $y$, is simply $1 / sqrt(y)$, or $y^(-1/2)$. Last week, I explained how to use the Newton-Raphson method for finding the square root of a number. We can use the same method for finding the inverse square root. If you …
What Is A No-Argument Function?
The other day, I was reading Eric Lippert’s blog—specifically the second post in his series on implementing a Z-machine in OCaml—and something he wrote reminded me of a conversation I had with Tom Denley many years ago:
This declares a variable called word, though “variable” is a bit of a misnomer in OCaml. Variables do not (typically) vary. (There are ways to make variables that vary – they are somewhat akin to “ref” parameters in C# – but I’m not going to use them in this project.) Variables are actually a name …
Smalltalk, A Functional Programming Language
I was watching Sandi Metz’s talk, Nothing is Something, recommended to me by Pawel Duda in the comments of my post, Why Couple Data to Behaviour?. In the talk, she said something that I’ve always found fascinating.
In the talk, Sandi compares booleans in Ruby (and other “object-oriented” programming languages) to booleans in Smalltalk. She points out that Smalltalk has six keywords, and if
isn’t one of them. So how do you branch, without an if
keyword?
The Expression Problem
The week before last, I wrote about functional programming and how it relates to object-oriented programming. I asked Ganesh Sittampalam to take a look and he told me that I was mostly right, and to Google “the expression problem”.
So I did. Before I go on, you might want to read the previous posts. Or not. That’s cool too.
- Getters, Setters and Properties
- Why Couple Data to Behaviour?
- The Other Trade-off: Separating Data and Behaviour
- Referential Transparency, And The True Meaning Of Functional Programming
- Moving Parts
I found a quote …
$∀x :$ My $x$ Is Special
An ex-colleague of mine, Pedro Moreira Santos, once made an observation to me that I thought was incredibly insightful. Paraphrasing him:
Every manager says the same thing: “This will never work. My team is special.”
Let's Talk About The Play Framework
A couple of weeks ago, I was experimenting with writing a simple web app in Scala. I’d heard that the Play Framework had got a lot better since v1 a number of years ago, and there’s lots of benefits to sticking to first-party libraries (of which Play is one), so I thought I’d give it a try.
Solving Problems By Trying Over And Over Again: the Newton-Raphson Method
I was re-reading Slash Slash Massive Hack as I wrote yesterday’s blog post, and was reminded of the awesomeness of the Newton-Raphson method. Wikipedia explains it better than I:
In numerical analysis, Newton’s method (also known as the Newton–Raphson method), named after Isaac Newton and Joseph Raphson, is a method for finding successively better approximations to the roots (or zeroes) of a real-valued function.
Naming Things
A couple of weeks ago, I promised to talk about naming.
If you can name a function really well, it probably does one thing and one thing only. This means you’ve figured out a decent way to separate your concerns, which means that often, the name is really all you need to know. (Expect more on naming in a future post.)
A Middle Ground Between Checked And Unchecked Exceptions
I hear a lot of arguments against Java’s checked exceptions. Normally, they run along these lines:
You have to propagate the exceptions everywhere. Too much noise, not enough signal.
And they’re right. It can be very noisy. Personally, I think the noise is worth it so that exceptions are adequately handled, but it’s a bit ridiculous.
Moving Parts
This week, I tried to explain the difference as I see it between object-oriented and functional programming. There are four articles. If you haven’t seen them yet, they’re linked right here:
Referential Transparency, And The True Meaning Of Functional Programming
Programming is compromise. No matter how you design your system, you will be compromising something, whether it’s flexibility in one axis for flexibility in another, or simplicity for the ability to create new features. All designs are “wrong”, for some definition of wrong. The important thing is whether they’re right enough for your purposes.
Before you carry on, I suggest you read the last three articles:
- Getters, Setters and Properties
- Why Couple Data to Behaviour?
- The Other Trade-off: Separating Data and Behaviour
The …
The Other Trade-off: Separating Data and Behaviour
True object-oriented programming brings with it a set of trade-offs: while you couple data to behaviour, you get a large number of advantages as well. Now let’s look at it from the other side.
Yesterday, in our Account
class, we had a Transaction
type, one of the implementations being Withdrawal
. Let’s take a look at that in broader detail.
class Withdrawal implements Transaction {
private final Money amount;
private final LocalDate date;
// constructor, getters (no setters), equals, hashCode and toString.
}
Now, that’s …
Why Couple Data to Behaviour?
Yesterday I posted on avoiding Getters, Setters and Properties, and how to bring the behaviour of your system closer to your data. The more functionally astute of you might have realised that this is, of course, a form of coupling. By making state private, and only allowing access via methods, we need to open up the class each time we want to modify the behaviour. This makes it look like proper object-oriented programming must violate the open-closed principle:
Software entities (classes, modules, functions, etc.) should be open for extension, but …
Getters, Setters and Properties
The last rule of Object Calisthenics is:
No getters, setters or properties.
Last week, I was at eXtreme Tuesday Club (a.k.a. XTC) for a beer and a conversation, and something happened that hasn’t happened there in a while. Someone new to the industry came along. (I can’t remember their name, but if it was you, post a comment!) For ages, XTC has been dying because no new blood, but due to stellar leadership and fantastic marketing, things are starting to pick up again.
In our discussion, something came up. Some people will tell you that …
The Boy Scout Rule
The Boy Scouts have a rule: “Always leave the campground cleaner than you found it.” If you find a mess on the ground, you clean it up regardless of who might have made the mess. You intentionally improve the environment for the next group of campers. Actually the original form of that rule, written by Robert Stephenson Smyth Baden-Powell, the father of scouting, was “Try and leave this world a little better than you found it.”
Slash Slash Massive Hack
I generally dislike code comments. I’ve heard good arguments for and against, and many, many bad arguments for them. Let me sum them up, and I’ll present a slightly different take on them at the end.
Custom Web Apps… In A Bookmarklet
A couple days ago, I demonstrated how to use a bookmarklet to automate the time-consuming process of discovering a link to an RSS or Atom feed and subscribe to it. Today I want to do something a bit weirder.
I once wrote a JIRA plugin to reformat the Agile board (how I hate that it’s called “Agile”… it’s nothing of the sort) to something more useful for a project manager. It reformatted it so that every box was very small and colour-coded by discipline (front-end, back-end, infrastructure, design, etc.), making it easy to see …
Working Hours
Everyone on Twitter has their opinion on working hours. Here’s my story. There’s very little data, but the nice thing about self-experimentation is that you can be fairly sure you’ve found something that works for you.
The current standard for office work in Europe is eight hours per day, including time for lunch, five days per week. This has been fairly common in many jobs for over a century now, down from 12–14 hours, 6–7 days per week in the worst case.
Many people would say that the current status quo is fine, but increasingly there …
Feed Me With Bookmarklets
If you’ve been reading this blog since the start of the year, you may have noticed that posts go up at 08:00 UTC (…ish) every weekday. This is intentional, and I hope to keep it going all year.
I use Tumblr as my blogging engine, which lets me schedule posts. I then use IFTTT to push a link to Twitter, which it does within minutes. If you follow me, you’ll see them. However, I know a lot of people, especially techies, prefer to use a feed reader. Personally, I use Feedly, mostly because when Google Reader shut down, Feedly allowed me to …
Surround Yourself With Good Examples
It is practically impossible to teach good programming to students that have had a prior exposure to BASIC: as potential programmers they are mentally mutilated beyond hope of regeneration.
Line Breaks: A Ruby Style Guide
I don’t mean “style guide” as in a full guidebook, but rather a guide to styling Ruby with regard to two very specific circumstances: when to use parentheses on function and method invocation, and whether to use braces or do … end
for blocks.
This is my personal recommendation and the style I try to follow. I couldn’t really care less what you use as long as you’re consistent inside a single project.
Anti-Pattern: Bending The Framework
Wolfram Kriesing and Jim Suchy were talking about frameworks on Twitter. I thought I’d get involved.
Specifically, they were talking about what happens when you come up against the walls of the framework. Because of the nature of frameworks, implementing certain pieces of behaviour is often unreasonably difficult, usually because the framework itself was not designed with capabilities for that particular functionality.
Your People Shouldn't Have To Know
I remember being in an airport a few years ago, siting near the gate, about to embark on a domestic flight across the USA. I was watching people file through the neighbouring gate. When the last one was through, one of the staff turned to the other and said something I found amusing.
Why do people keep showing me their passports? We don’t need ’em!
Viewed from the lens of the airline, this is completely reasonable. It’s a domestic flight. All they need is your boarding pass. You’re not going abroad. Isn’t it obvious?
Casting Lambdas in Java
I love Java 8. It’s so much better than Java 7. Not as nice as a properly functional language, of course, but beggars can’t be choosers, am I right?
It’s a bit odd for a language that’s trying to be functional, though. Functions are objects, and often a lambda can be one of many types. This is usually fine:
Stream.of(1, 2, 3)
.map(x -> x * 2)
.forEach(System.out::println);
// prints:
// 2
// 4
// 6
Start Simple
Continuing in the theme of fresh beginnings, I wanted to talk about a famous quote:
A complex system that works is invariably found to have evolved from a simple system that worked. A complex system designed from scratch never works and cannot be patched up to make it work. You have to start over with a working simple system.
— John Gall (Systemantics: How Systems Work & Especially How They Fail, 1975)
State of Mind
On 30th December, I started a diet and exercise plan, because what the hell, it’s New Year’s and I’d been pigging out for the entire month on barbecue and beer Down Under. It’s really simple, but there’s a bit of a twist.
The plan is as follows:
- No sweets or processed sugar.
- No bread or pasta.
- No meat.
- Exercise a little bit every day.
- Run, climb or cycle a couple of times a week.
Next Level Git
It’s no secret to anyone I’ve ever worked with that I essentially run my working life with an ever-growing, ever-changing set of shell scripts.
It is, however, somewhat of a secret that all of these are hosted on GitHub.
Some of them, I use every week or so, like up
, which updates basically everything on my machine using Homebrew, apt-get
, RVM, NPM… you name it. Some, I’ve completely forgotten about, like whitespace
, which I’m pretty sure converts tabs to spaces… I don’t even remember why I wrote it. Today, though, I’d …
Automating The World
It’s official. I’m going to automate everything.
One bit at a time.
I’m currently available for work in London or remotely, automating everything and teaching others how to do the same. Allow me to explain.
(Or, if you’re impatient, get in touch immediately.)
A New Start
Until a week ago, I was sunning myself in New Zealand, enjoying a December barbecue, wandering up and down volcanoes, and pretending I was a hobbit. It was a great way to forget about things for a while and reset. Now I’m back from holiday, caught up with sleep, 2016 is here, and January is traditionally the time to decide what to do with the rest of your life. So here I go.
Time To Go
I’m writing that blog post I never thought I’d write.
When I joined Codurance, I knew I was joining something special.
I was right.
Conversations About Conversations at SoCraTes UK 2015
OK, brain dump time.
Using the Right Language
What do we prioritise? What do we sacrifice? Every single product ever released has had trade-offs baked in, from the set of features to the implementation of the networking code. There were many independent discussions on and around this, all asking different questions, but arriving at similar answers: there is no right answer. Instead of trying to find one, we should respect the fact that there will be trade-offs, and spend our energy gathering as much knowledge as we can in order to make the right ones.
Crank Up The Volume And Forget Your Pomodoros
Together, Steve Lydford and I came up with a way to work that we don’t think has been put to paper before.
The Pomodoro technique is a great way to keep you focused, alone, in a pair, in a mob or in a meeting room. By setting a 25-minute timer and a goal, you can help ensure you’re keeping on the right track and taking frequent breaks.
It works pretty effectively, but it’s not as fun as we’d like. Our substitute doesn’t work in a pair, but when you’re on your own, try this:
Design Patterns in the 21st Century: Conclusion
This is part five of my talk, Design Patterns in the 21st Century.
Over the past week, we’ve seen three examples of design patterns that can be drastically improved by approaching them with a functional mindset. Together, these three span the spectrum.
Design Patterns in the 21st Century: The Chain of Responsibility Pattern
This is part four of my talk, Design Patterns in the 21st Century.
Here’s a thing you might not see a lot.
@Test public void hungryHungryPatrons() {
KitchenStaff alice = new PieChef();
KitchenStaff bob = new DollopDistributor();
KitchenStaff carol = new CutleryAdder();
KitchenStaff dan = new Server();
alice.setNext(bob);
bob.setNext(carol);
carol.setNext(dan);
Patron patron = new Patron();
alice.prepare(new Pie()).forPatron(patron);
assertThat(patron, hasPie());
}
It might look odd, but the idea is …
Design Patterns in the 21st Century: The Adapter Pattern
This is part three of my talk, Design Patterns in the 21st Century.
The Adapter pattern bridges worlds. In one world, we have an interface for a concept; in another world, we have a different interface. These two interfaces serve different purposes, but sometimes we need to transfer things across. In a well-written universe, we can use adapters to make objects following one protocol adhere to the other.
Design Patterns in the 21st Century: The Abstract Factory Pattern
This is part two of my talk, Design Patterns in the 21st Century.
This pattern is used everywhere in Java code, especially in more “enterprisey” code bases. It involves an interface and an implementation. The interface looks something like this:
public interface Bakery {
Pastry bakePastry(Topping topping);
Cake bakeCake();
}
Design Patterns in the 21st Century, Part One
I’ve been having a bit of trouble blogging recently. In an effort to get back into it, I thought I’d take a talk that I presented at JAX London last year, split it up into blog-sized posts as it’s pretty long, and post them all week. If you haven’t read it before or seen the talk, I hope you enjoy it.
Oh, and if you’d rather just read the whole thing in one go, flick through the slides (which are almost entirely code), or watch the recorded version as a video, head to my talks page.
Too Many Cooks
Last week, Sandro and I flew to Bucharest to meet Alex and Adi Bolboaca, Aki Salmi and Peter Kofler. We didn’t know what to expect: the agenda was to try a “hardcore coderetreat”, in which the constraints would be incredibly difficult, but when you have six headstrong, opinionated people in a room, you really have no idea what’s going to happen.
So it was surprising, but not, when we decided as a group to try and mob on a real project. We started on a website for people to find pair programming partners (which we still plan to …
Highly Strung
This blog post is way overdue.
A couple of months ago, I wrote a talk entitled Highly Strung for the Virtual Java User Group (vJUG) on when and how to use strings in your code.
Spoiler: don’t.
So this blog post is really just to ask you to check it out if you’re interested. The link’s up top, and has the talk in essay form, the slides and the video, lovingly recorded by the folks who run the vJUG.
Go on, check it out. I want to tell you something else, but afterwards.
Mob Programming, and the importance of fun at work
It’s been a few weeks since SoCraTes UK 2014, and I’ve had some time to reflect on the event and my learning experiences. Today, I want to talk about the biggest things that stood out for me.
Rekord: Java Beans must die
In programming, duplication is the enemy.
We see it everywhere. Code, copied and pasted because “we have no time”. Entire pieces of infrastructure lifted from one project to the next, rather than extracted and shared. Domain objects scattered through applications, every one slightly different. API connection layers written again and again, each one in a different style, doing the same, exact thing with new and interesting bugs.
A software craftsman is
Someone who aspires to quality.
Someone who considers the means as well as the ends. Alternatively, one who realises that everything has more than one outcome, and that as many of them as possible should be considered.
Someone who does not build unnecessary things.
Pairing without programming
Pairing is often associated with programming. There’s a Wikipedia article about pair programming, but nothing on pairing in general. And yet, it’s a fantastic technique for getting anything done well, especially when neither of you really know exactly how to approach a problem.
For a week and a half now, I’ve been working with Sandro on the business side of Codurance. From next week, I’ll be heading to a client to do some actual programming, but in the mean time, I’ve been working on recruiting, promotion, client relations, …
Check your I/O
In Haskell, there’s something known as the IO monad. The way it works is this: if you have it, you can do I/O. If you don’t have it, you can’t. You can pass it around, but you can never produce it from nothing. (Haskell aficionados, the comments are open for flaming in 3, 2, 1…)
Before we continue, I should elaborate a bit on what I/O is. It’s basically anything that reaches out of the safe confines of your executable and touches the system in which it lives. For example:
- reading and writing files
- printing to the command prompt …
Time for change
On the 31st of January, 2014, I will be leaving Palantir Technologies and a job I love. I’ll be leaving some of the best people I’ve ever met, a really cool set of products, some awesome customers and (not least) an absolutely beautiful working environment. I’ll be leaving a job that’s taught me about client relations, server administration, requirements gathering, large-scale data management, integration and sanitisation, but also how to work with people on different continents and how to deliver outcomes, not services or …
Go make a sandwich
I was originally planning on writing something about the Cake pattern here, but after reading a lot more about it, I’ve decided it’s not as bad as I thought. I mistook one variant of it (which involved essentially having all methods of all classes available to you) with something a little more sophisticated. If you want to know about the pattern, I recommend Real World Scala: Dependency Injection (DI) by Jonas Bonér.
Complicit Implicits
Imagine we have a calculator, written in Scala.
class Calculator {
def run() {
val printer = new Printer
printer.print("The answer is always ")
printer.print(7)
printer.newLine()
}
}
object Calculator extends App {
new Calculator().run()
}
It does one thing and it does it well. (Not the thing it says on the tin, but we’ll get there.) It makes use of a Printer
, which is a type of object that knows how to print things.
import java.io.PrintStream
class Printer {
def print(value: Int)(implicit out: PrintStream) = …
New Year's Resolution
At work, we run monthly coding workshops to give people an opportunity to hone their development skills. The idea is to provide an environment in which the results don’t matter, letting people take their time and try different approaches to the same problem without worrying about deadlines. This was an initiative started by Joe Lea and massively encouraged by me. Every month, a different person facilitates the workshop, letting people learn from each other as well as giving the facilitator a chance to practice their teaching and training skills. …
Outside your comfort zone
I’ve shied away from the word “programmer” for a long time because I don’t think it accurately represents what I do. It implies that the most important thing about the job is the magic words that come out of our fingers, and not where those magic words came from. This couldn’t be further from the case.
It’s been said by many that in order for programmers to improve, they should focus on communication. When you communicate more effectively with other people with aligned interests–that is, members of your project and …
Self-awareness, existentialism and personal responsibility.
We kicked off SoCraTes UK 2013 with lightning talks, and it was then that the theme of the conference was set. They all influenced the coming days in some ways (especially Chris’ five-minute rant on bad code and terrible naming, accompanied by a bottle of Jack Daniels), but the one that stood out the most, especially me, was Erik’s. He spoke about the process we go through when we make a mistake, and he gave me two words that had been missing from my software development vocabulary: personal responsibility.
Richard Feynman, TDD Master
For Richard, figuring out these problems was a kind of a game. He always started by asking very basic questions like, “What is the simplest example?” or “How can you tell if the answer is right?” He asked questions until he reduced the problem to some essential puzzle that he thought he would be able to solve.
What is an interface?
Interfaces are my favourite part of programming. They’re the part that makes me stop for a second (or a minute, or an hour, or a day) and actually think about my job. Because my job isn’t really about writing code.
Before we get into what is about though, I want to define “interface”.
What is an interface, anyway?
As you probably know, I’m a big fan of the mentality driving specification by example. So let’s think about examples.
Letter to a Lead
Dear Developer,
Thank you for taking the time to review my pull request. I have to admit, it made my heart sing when you accepted it. The lack of a human touch did not diminish the sweet joy I felt when I received an automated email telling me that you had judged my code worthy to be folded into your most noble of pursuits, to be treated as a brother to the code you wrote with your own hand, to be respected as though you yourself had crafted it.
Functions are Objects: the other point of view
There’s a feature in Java 8 which nicely embodies one of the differences between the class-oriented structure of Java and functional languages. It lies in the way you implement lambdas.
You might have seen the syntax already. It looks something like this:
List<Integer> numbers = ImmutableList.of(2, 9, 8, 3);
List<Integer> squares = numbers.stream()
.map(x -> x * x)
.collect(toList());
assertThat(squares, contains(4, 81, 64, 9));
It’s quite pretty, and means there’s …
SoCraTes 2013
Note: This is an article about SoCraTes, an unconference in Germany. It is not about SoCraTes UK (wich is based on SoCraTes), which I’m helping to organise as part of the London Software Craftsmanship Community, although I hope to be able to write a similar article about that unconference very soon.
SoCraTes 2013 was a lot of fun, and the discussions, just like last year, were top-notch. There are a few topics that were covered that I want to highlight as food for thought.
Dysfunctional Programming
There’s a problem with learning a new programming paradigm: you often have to learn a new language simultaneously. So at SoCraTes 2013 in Germany, I decided I’d run a couple of sessions designed to teach functional programming without having to learn Haskell (when I wasn’t sitting out on the terrace explaining monads with a beer in one hand and a folding whiteboard on my lap). The first time, it was a simple two-hour workshop, and the second time, it was part of the code retreat, in which people applied the concepts to implementing the …
Dependency Inversion, and how to get it wrong
I’ve been building a new application in Clojure over the last week or so, and it seems to be going quite well. I like the syntax, using a functional language has been great, and it’s got enough gold in it that I can ignore the small pockets of “wat”.
Delete Your Code
That was my battle cry at Palantir’s first ever code retreat.
Last weekend, we spent two and a half days out in the beautiful English countryside on some of the hottest days of the year so far. The agenda was as follows: Friday afternoon was to be dedicated to TDD, a code retreat was held on Saturday, and on Sunday, we held our least hacky “hackday” ever.
Thanks so much to Adrian Bolboaca for helping plan the first two days of this event, and to my colleagues Huw, Joe and Michael for organising the event and the venue.
Building software as a hobby
I want to make things for everyone.
I haven’t done that in a while. The last big project I did was eventual.ly, my event notification service, similar in ideas to Facebook Events. It was really fun, but doesn’t work so well any more. (It still works, but there’s some serious problems with editing events. Use at your own peril.) Since then, there’s been a bunch of stuff appearing on my GitHub account, but hardly any of it is for the general public. Most of it is just me dicking about.
Define your Subset
Every tool you use will be inadequate. Every design you create will be inaccurate. Everything you do will be imperfect.
I’ve spent a lot of time experimenting with a lot of languages, and none of them meet 100% of my needs. Java is too clunky, Ruby has too many edge cases, Python is not well-supported enough, C# is too commercial, and Haskell is too academic.
But I’m becoming increasingly happy with Scala, which perhaps encompasses all of those downfalls at once, in some form or another. And I’m fairly convinced that this is because …
Refactoring to Feature
A note, while I’ve got you: I’ve decided I will be posting a new article every Wednesday for the forseeable future. Hopefully I can hold this up. Writing one per week is going to be hard, but I think I can handle it.
Now, onto the meat.
I’ve observed four main ways that people refactor.
The first, and most common, is not at all. This is usually because there’s a new feature that they just have to get done now, or is so complicated that refactoring “wouldn’t help”. It’s also often scheduled to be done …
Simplifying your Design with Higher-Order Functions
That was the name of the talk live-coding demonstration I gave at I
T.A.K.E., a conference in Bucharest, Romania.
My last blog post was on why I was pretty scared of doing this. This one (which is late) is going to be talking about what I covered in the talk. A written version of it, if you will.
Live Coding at a Conference, and why it is Scary
<img src=“https://assets.monospacedmonologues.com/2013-05-27--i-speak-at-itake-unconference.png" alt=“2013-05-27–i-speak-at-itake-unconference.png” />
In less than a week, I’m giving my first ever professional talk at the I.T.A.K.E. Unconference in Romania. The topic: the four elements of simple design, and how functional programming is absolutely necessary to achieve them.
I’m quite excited.
I’m also quite terrified.
You see, I don’t like giving talks. I like showing people code and letting them …
The Social Networking Kata
Last week, Sandro and I had a lot
of fun running our monthly hands-on
session
for the London Software Craftsmanship
Community. We
decided to make things more difficult for ourselves (and the attendees)
by combining two of our favourite sessions: testing with
BDD, and
object
calisthenics.
The victims lucky people had a choice of solving the problem using
BDD/ATDD, object calisthenics, or both. Of course, if they opted for
just the latter, TDD was still mandatory.
Quality, Revisited
Wow, that was a lot of great feedback in a few hours.
So let’s talk about it.
The first thing I want to talk about is the tone of the piece. It’s kind of idealistic. Of course, things didn’t always go that smoothly, but we aspired to meet the standards we set for ourselves. And things were definitely improving everywhere you looked. syl commented on how the TV screens were mostly red. This is actually true at a lot of places that measure build breakages, because keeping all 200 builds green at all times is an absolute nightmare. …
Quality
Update: I’ve answered a few comments I had in another post, entitled Quality, Revisited. Please check it out after you’ve read this one.
“Tests take too long. We don’t have time for that.”
Good one, Bob.
Let’s talk about TIM Group, a company for which I used to work.
Don't Call Us. We'll Call You.
I’ve been thinking about why I dislike Ruby on Rails for over a year now. It’s not the much-touted “convention over configuration”—that’s actually quite lovely. It’s not the ever-increasing rate of zero-day security vulnerabilities: while that’s worrying, it’s not going to stop me from using it to knock out a web site over a weekend. Security is only necessary when you have a product and some customers. It’s not even because DHH is a bit of a tool. I don’t think I’d get along with him at a …
Hiring Engineers, another Process
This post was prompted by Eran Hammer’s excellent article on hiring what he describes as “non-conforming great talent”. It’s part rebuttal, part agreement. It’s not about how Palantir or TIM Group hire—they both diverge from this on a number of things, but simply my thoughts on the interview process.
Pair Up
This post is a result of a long discussion on the London Java Community mailing list on the value of pair programming. After explaining my own feelings and reading the opinions of everyone else, I wanted to get my thoughts down on paper (that’s right, online, virtual paper) so I could be sure they actually make sense.
Here we go.
Diving In
Starting a new job is hard. My first few weeks at Palantir were no different. There was training… of a sort. Things really got interesting, though, when I was given my first real piece of work: take a humongous, incomprehensible script, clean it up and make it work. I could have dived straight in and started to rewrite it, adding features as I went, but I didn’t. I want to explain my reasons.
First things first: there were no tests. None. Zip. More than that, the paradigm used made it very hard to simply wrap tests around the script. It needed some …
Querying the web with ScraperWiki
A few weeks ago, a friend of mine, Michael Cook, retweeted a request for up-to-date discounts on the Steam store:
I want to pay someone to help me automatically scrape steam for all the data here, and then format it correctly. bit.ly/dSvuvx
— Lewie Procter (@LewieP) November 8, 2012
I was interested, so I tweeted back. As part of the deal, though, I asked Lewie if I could open source both the code and the data using ScraperWiki. He was all for it.
What I learnt at youDevise
Today is my last day at youDevise (or TIM Group, as it’s now known). I’ve loved it here, but it’s time to move on and do something a little different. With that in mind, I made a list of all the things I’ve learnt in my two years here. Here it is:
The Brutal Refactoring Game
Let’s play a game.
The rules are simple: write some code. Oh, and you have to do it right. That means if you break one of the following rules, courtesy of the brilliant Adrian Bolboaca, someone will be there to slap your wrist.
- Lack of tests
- Name not from domain
- Name not expressing intent
- Unnecessary
if
- Unnecessary
else
- Duplication of constant
- Method does more than one thing
- Primitive obsession
- Feature envy
- Method too long (> 6 lines)
- Too many parameters (> 3)
- Tests: not unitary
- Tests: setup too complex
- Tests: unclear action
- Tests: more than …
Solidifying your Design
When someone asks me how to design and build a system full of interlocking, moving parts, I just point them at SOLID. These bad boys don’t just apply to your code. They should be an integral part of your architecture too.
Here’s how.
SoCraTes 2012
Or, how I learned to stop worrying and love the weizenbier.
I kid. I didn’t just drink German beer for the whole four days. In fact, there were periods of several hours where I didn’t touch the stuff. Instead, I sat, listened and absorbed as much information as I could, and occasionally contributed some of my own ideas back.
So, what did I learn?
Legacy Code Retreat part two: knock it out of the park
Part one was about understanding the code. Part two is all about changing it.
So after a tasty lunch, we cracked on. Throughout the first half, I was constantly asking people if they had written enough test cases. After lunch, I encouraged them to crack on with the refactoring. We started by extracting classes in session four. It’s something we do all the time, but I think it’s very important to formalise the method so we understand when we’re doing something slightly different.
Legacy Code Retreat part one: get it under test
It’s been a while, but people have convinced me that I need to crank this one out.
A little while ago, Sandro and I ran the UK’s first Legacy Code Retreat. Essentially, it works like a regular code retreat, where people come together to solve a problem again and again in a multitude of different ways. The difference with this one is simple: we don’t start from scratch. You don’t implement Conway’s Game of Life over and over again, but instead start with a terrible piece of code. Your task is to understand it and clean it up. …
Small Minds
I had the opportunity on Sunday to help mentor kids at a one-off CoderDojo in Shoreditch. After a head count, we realised we had as many mentors as kids, so we got to pair up one-on-one. After drawing straws to find out who was going to help the eight-year-old boy with deploying a PHP and MySQL webapp—not one of us could remember how on earth PHP worked—we sat down and got cracking.
The Beast
About a week ago (give or take a few months1), we killed a couple of nulls. If you want to know why, go ahead and read the first of this three-part series, Pinocchio, and then the second, Fairy Godmother. However, there’s one of those evil little buggers left, and I want to slay it with extreme prejudice. So here he is, in all his terrifying glory.
Books books = (Books) cache.get("books", new Supplier<Object>() {
@Override public Object get() {
Books defaultBooks = readListOfBooks(); …
Global Day of Coderetreat
Here’s what you do. On Saturday morning, at ridiculous o’clock (i.e. around 8), you walk into a room which has a delicious breakfast all laid out. There are some people running about shouting at each other about “sessions” and “calls”, but you ignore them in favour of the sweet pastries, fresh fruit and hot coffee sitting on the counter. When you’re done, you take out your laptop, and someone with a funny haircut floats over to remind you that you should have a test environment set up for your language(s) of …
Functional Poker Hands in Java
A few weeks ago, I wrote about a workshop I ran at Skills Matter and posed the question to you guys. If you haven’t seen it, I encourage you to go check it out—everybody had a lot of fun. What better way to spend a weekend than writing interesting code, right?
So. I figured it was my turn. And, being a bit of a masochist, I decided to do it in Java. So I fired up Eclipse and started writing some tests. I started by testing the FunctionalList class as I’d neglected to provide any straight off, and then wrote my first acceptance test: …
Fairy Godmother
In our last installment, we looked at a piece of code and removed some of the nulls. At the end of it, it looked like this:
Books books = (Books) cache.get("books");
if (books == null) {
books = readListOfBooks();
downloadBookIsbnsFor(books);
}
cache.set("books", books);
for (Book book : books) {
String isbn = book.getIsbn();
if (isbn == null) {
isbn = "[not found]";
}
System.out.println(isbn);
}
There are still two null checks in there. In this episode, I’m going to explain how to get …
Pinocchio
Continuing in the vein of forbidding things because they are BAD, here’s another one that I hope will leave you scratching your head a little.
Brace yourself. Here it comes.
Don’t use null
.
I realise that at this point, I’ve either lost you, or you’re a Haskell
programmer. So to the first group, I ask you, why doesn’t the Haskell
developer use null
(or nil
, None
, undefined
or their brethren)?
The simple answer is that they’re not necessary: the various catch-all
representations for “nada” can be elegantly …
Workshop: Functional programming in OO languages
As I mentioned on Wednesday, I recently ran a session on functional programming in object-oriented languages. By that, I really mean “languages that weren’t designed with functional code in mind”. This ranges from Java, which doesn’t let you treat functions as first-class objects at all, to Ruby and Python, which have all sorts of cool functional features but puts them in the corner so you don’t have to play with them if you don’t want to. The idea of the workshop was to get people thinking in terms of functions …
Function<Lisp, Java>
If you read the last blog post through the eyes of a Java developer, you
may wonder exactly how you toss functions around willy-nilly like we did
for our implementation of map
. You can’t pass functions around like
they’re values in Java! This is ridiculous. Someone call a lawyer.
Well, hold on, give me a second to explain. First of all, here’s map
again, for your viewing pleasure:
List.map (f) = if this.isEmpty
then []
else f(this.head) : this.map(f, this.tail)
So we have a class called List with a …
Comprehending Lists
Today I ran a workshop on functional programming in object-oriented languages at a London Software Craftsmanship Community meetup. I’ll post up the problem I asked people to solve in the next couple of days, but as I’m currently physically incapable of sleeping, I thought I’d take some time and talk to you about lists.
Lists are one of the most powerful and versatile constructs we have in our day-to-day toolkits. We use them everywhere. I can probably count the number of times I’ve implemented anything even slightly complex …
Stringly Typed
At the first FP Day on Friday, I attended a talk by Don Syme on F# 3.0. There were a number of useful features, but to the functional programmer, the most revolutionary one was type providers. They’re a way to use strong, static typing for data structures beyond those coded into libraries. The most prominent use of these are for data sets so large that the entire set of types necessary to understand all of it is too much to include in your application. However, they’re also useful as an alternative to code generation. Take for example, …
No Comment
Unless you have a damn good reason, don’t write comments.
And if you see a comment, you should probably delete it.
I didn’t come up with this—it’s the policy in the office, as well as various tech shops all over the planet. I thought I’d start with a fun one though. Half the people that read that will think I’m an idiot. The other half will shrug and say, “We taught you this, boy.” (The latter don’t need to keep reading.)
I actually did it.
I made a blog. Now I just need to write some posts. Expect code. Pretty pretty code! And some not-so-pretty code. And lots of ANGRY SHOUTING. I’m good at that.