Functional programming

Much ado about null

Submitted by Larry on 13 May 2022 - 11:24am

null has a controversial history. It's been called "the billion-dollar mistake" by its creator. Most languages implement null, but those few that do not (such as Rust) are generally lauded for their smart design by eliminating a class of errors entirely. Many developers (myself included) have argued that code that uses null or nullable parameters/returns is intrinsically a code smell to be avoided, while others (also myself included, naturally) have argued that is too draconian of a stance to take.

Anna Filina has a very good three-part series (properties, parameters, and returns) on how to avoid null in PHP generally. Alexis King has a related post (excuse the Haskell) on how to avoid needing edge cases like null in the first place.

However, I want to go a bit deeper and try to understand null from a different angle, and tease out the nuance of why one would really want to use it, and thus what we should be doing instead. To get there we'll have to go through a tiny little bit of type theory, but it will be quick and painless, I swear.

Continue reading this post on PeakD.

Advent of Functional PHP: Review

Over the last few weeks, I've been following Advent of Code 2021, using Functional PHP as an approach. It's been a fun and educational process, at least for me and apparently for a few other people, at least given how popular the articles have been.

For reference, the full list of articles in this series is here:

Larry 29 December 2021 - 7:10pm
Advent of Functional PHP: Day 10

For the 10th Day of Advent of Code, we're asked to solve a matching braces problem. This is a common parser exercise, but it's made a bit more complex in this case by using multiple types of braces. Specifically, we're handling a series of lines that contain ( and ), but also < and >, [ and ], and { and }.

The story jazzes it up as being the code of our submarine's navigational computer, which consists entirely of braces in a sort of eldritch horror version of brainfuck, but that's mostly just a distraction.

Larry 24 December 2021 - 7:14pm
Advent of Functional PHP: Day 9

Day 9 of this year's Advent of Code revolves around grid interpretation. Specifically, we are given a grid of numbers and want to find the low points, that is, the numbers that are smaller than any of their orthogonal neighbors. (We're told to ignore diagonals in part 1.)

After finding the low points, we need to do a bit of math on each one, and add them up. As usual, this last step is mostly just to produce a single verification number at the end. That part is easy as usual, but how do we find the low points?

Continue reading this post on PeakD.

Larry 23 December 2021 - 11:21am
Advent of Functional PHP: Day 8

Advent of Code Day 8 was, to put it mildly, a pain in the ass. There's a couple of reasons for that. It's a naturally tricky problem, it's hard to genericize, and it's explained fairly badly. It took a while but with some help from others I was finally able to figure out (and refactor to) a good, functional solution to it. So let's dive in.

The problem boils down to one of encryption. Our input is several lines that all look like this:

acedgfb cdfbe gcdfa fbcad dab cefabd cdfgeb eafb cagedb ab | cdfeb fcadb cdfeb cdbaf

Where each letter corresponds to one segment in an LED display for a number. Each number appears once on the left side, which is enough for you to figure out what letter corresponds to what segment. Then we need to use that knowledge to decode the numbers on the right and figure out what the number is.

Larry 20 December 2021 - 10:06am
Advent of Functional PHP: Day 7

Advent of Code Day 7 this year is another problem that's more about the math than about the programming, so we won't see much in the way of new functional techniques. Still, there's some interesting bits in there.

Today we need to calculate the fuel costs of moving a bunch of crabs in submarines all into a line. (Don't ask. Really, don't ask.) Essentially we want to center-align a series of points using the least "cost" possible. Crab positions are represented by a single number, as crabs can only move horizontally. (Because crabs.)

The trick for today is realizing that the crabs don't matter; it's a distance-cost calculation. In part 1, the cost for a crab to move one space toward whatever alignment number we want to pick is 1.

Continue reading this post on PeakD.

Larry 7 December 2021 - 3:38pm
Advent of Functional PHP: Day 6

Day 6's challenge is a little fishy. Given what we've already done so far, it's pretty simple. The only catch is making sure you do it in an efficient way.

Specifically, we're asked to model the growth patterns of fictional lantern fish. In this silly model, we start with a list of fish at various ages. Each fish spawns a new fish every 7 days, and a newborn fish takes an extra 2 days before it starts spawning new fish. Fish also never die. (Someone warn the AI people that we've found the paperclip optimizer.)

Part 1 asks us how many fish there are after 80 days, all around the world, given the start data. Let's find out, but let's do so efficiently.

Continue reading this post on PeakD.

Larry 6 December 2021 - 12:43pm

Advent of Functional PHP: Day 5

Submitted by Larry on 5 December 2021 - 9:23pm

After the last two days, Day 5 of Advent of Code is almost mundane in comparison. Today we're asked to read in the definition for a series of lines and compute how many times they intersect.

The process is much the same as the previous days: Parse the incoming data into some sort of data model, then run some computations on it. And both parts will consist primarily of `pipe()` operations, since we're really just shuffling data from one form to another.

Our input data looks like this (albeit with a much larger range of coordinates):

Continue reading this post on PeakD.

Advent of Functional PHP: Day 4

Submitted by Larry on 4 December 2021 - 7:41pm

Day 4 of Advent of Code has us playing bingo against a giant squid. (Don't ask; I don't understand it either.) More specifically, we want to take an input file that consists of a series of numbers that will get called, followed by a series of boards. We then need to compute which board will be the first to win, following the standard rules of bingo (although with no free space in the middle, the cheating squid...).

This sort of problem is inherently very stateful, and thus, frankly, not a good fit for functional code. It absolutely can be done in a functional way, but it's not the best fit. We're not interested in the best fit in this series, though, just how it could be done functional-style. So let's do it functional style just to say we did. Along the way we will really exercise the function composition concept, and show a few other tricks along the way.

Onwards!

Advent of Functional PHP: Day 3

Submitted by Larry on 4 December 2021 - 6:15pm

The third challenge in this year's Advent of Code is all about bit manipulation. We're asked to read in a series of binary numbers and interpret them in various entirely illogical ways as a form of diagnostics. (Incidentally, if you ever write a system that requires this kind of logic to debug its output, you're fired.)

In any case, we're given a file with a list of 12 digit binary numbers and asked to compute various values. In the first part, we are asked to find the most common bit (0 or 1) in each position, and the result is known as "gamma." Then we have to find the least common bit in each position, and the result is known as "epsilon." (I don't know why you would want to do this; it's all Greek to me.)