Await, there’s more!

This week I gave a talk at my local JavaScript meetup on the history, use, and future of Promises and I thought that you, dear reader, might be interested as well. Here’s the blurb:

JavaScript is an asynchronous language; it is designed to react to events and to trigger jobs that take an unknown amount of time to complete. While there is a fairly standard way to call functions when something happens, until recently there had been no standard way to chain these functions together, nor an easy way to handle failures inside the chain. Promises provide the solution. This talk will guide the group through the motivation for Promises, how they work, and what comes next (async/await and beyond).

My slides for the talk are at the following link:

https://sirbrillig.github.io/js-promises-slides/

During research for the talk I discovered that Top Level Await is already available in Chrome Devtools (not in Chrome itself). So if you’re just experimenting, you can run both of the following snippets. The first one uses the native Promise methods to fetch some data (try it!).

fetch('https://jsonplaceholder.typicode.com/todos/1') 
  .then(response => response.json()) 
  .then(json => console.log(json))

The following one is the same, but uses async/await.

const response = await fetch('https://jsonplaceholder.typicode.com/todos/1');
const json = await response.json();
console.log(json);

If you’re not familiar with the syntax of await, the new thing here is that with the proposal, you can use it outside of an asynchronous function. Otherwise, you can only use the await keyword in a function declared with async.

Writing a function with the async keyword actually just guarantees that the function will return a Promise object. If it does not, its return value is wrapped in a resolved Promise automatically. So in actual code today you’d need to write something like the following in order to use await.

async function getDataFromServer() {
  const response = await fetch('https://jsonplaceholder.typicode.com/todos/1');
  const json = await response.json();
  return json;
}

async function main() {
  console.log(await getDataFromServer());
}

main();

Just for completeness, you’ll need to know that while we can handle Promise rejections (and thrown Errors) with the catch() method on a Promise, you’ll probably want to use the regular try/catch syntax to handle rejections when using await.

When using await, if the Promise is rejected, the await expression throws the rejected value.

async function main() {
    try {
        await fillKettle();
        await boilWater();
        await addLeaves('green');
        await steepTea('1 minute'));
        drinkTea();
    } catch (error) {
        console.error('There was a problem making tea.');
    }
}

main();

If none of that makes sense to you and you’d like to start from scratch learning about Promises in JavaScript, check out the whole slide deck. A big thanks to everyone who came and especially to those who asked questions!

Alternatives to Else

One of the first imperative programming concepts I ever learned was if/else. With this relatively simple power tool I could make decisions in my code based on any number of factors.

Of course, my early programs were… a little hard to read. I hadn’t yet learned one of the maxims of programming that I try to live by today: write code first for humans to read, then for computers.

Using if for conditions is pretty important. There’s other ways to code, but as a concept it’s usually extremely readable. On the other hand, the seemingly harmless else can add a world of problems. I’d like to talk a bit about why I feel this way, and explore some alternatives.

(note: these examples are in PHP, but the concepts are the same for javascript and other languages.)

Cognitive Load

The biggest issue I have with else is… “what’s the condition?” An else statement prefaces an arbitrarily large block of code, but unless I happen to have just written the code, I have to read upward past another arbitrarily large block of code before I can figure out the conditions on which that block will execute.

Many if/else statements start off with each block holding just one or two lines, and surely that’s not an issue, right? Who could complain about this innocent code?

if ($wantSomeToast) {
  butterBread();
} else {
  makeASandwich();
}

The problem arises when those code blocks grow. And they will grow. Without careful pruning, code only gets bigger. Perhaps not every if block will get to be 300 lines long, but at least some of them will, and in my opinion there’s really no need to take that risk.

When you’re debugging some issue and a diff or your editor only shows something like the following, who knows what’s really going on here?

  // ...
  bakeCake();
  $frosting = new Frosting();
  engageFroster($frosting);
} else {
  drillHole();
  $jam = Jam::fetchStrawberry();
  $result injectJam(new JamInjector(), $jam);
  if ($result !== 'ok') {
    throw new \Exception('Jam is jammed');
  }
  //...

Parsing this means scrolling up until you find the if condition, and then holding that in your head while you work on the else block. And what if there’s else if statements, or nested conditions?

Alternatives

In short, I think that when else is used it needs to be as close to the if as possible. Within a few lines, really. Because, again, this is not a problem:

if ($wantSomeToast) {
  butterBread();
} else {
  makeASandwich();
}

But this is a problem:

//... many lines...
} else {
  makeASandwich();
//... many lines...

To that end, any time you can easily avoid else, I’d argue that it’s worth the effort. Here’s some ways to do that:

The first thing I see a lot is a simple boolean return.

function isTostValid($toast): bool {
  if (empty($toast->grain)) {
    return false;
  } else {
    return true;
  }
}

I know that this models the original developer’s thought process, but look how large it is, and remember that it’s far too easy for later developers to come in and add unrelated code to those blocks. What if we did this instead?

function isTostValid($toast): bool {
  return ! empty($toast->grain);
}

Much easier to read. Another alternative is an early return. This set of conditions could grow very large after a while:

function getFavoriteJam($name): string {
  $jam = null;
  if ($name === 'joe') {
    $jam = 'marmalade';
  } elseif ($name === 'jane') {
    $jam = 'raspberry';
  } else {
    $jam = 'strawberry';
  }
  return $jam;
}

But it could be easily turned into a version without else, by using early returns. The first conditions will still override later ones, but any time we follow code and see return we know that we can stop reading. It becomes a set of simple decision making tools rather than one complex multi-decision machine.

function getFavoriteJam($name): string {
  if ($name === 'joe') {
    return 'marmalade';
  }
  if ($name === 'jane') {
    return 'raspberry';
  }
  return 'strawberry';
}

Sometimes you can turn an if/else into two if statements by repeating and inverting the first if condition. This may seem to violate the DRY (Don’t Repeat Yourself) principle, but in practice it grants a lot of clarity.

if ($name === 'joe') {
  $jam = 'marmalade';
} else {
  $jam = 'raspberry';
}

That else can just have its condition repeated to become:

if ($name === 'joe') {
  $jam = 'marmalade';
} 
if ($name !== 'joe') {
  $jam = 'raspberry';
}

Another common pattern which this demonstrates is a condition being used to set a variable. In those cases, we can use null coalescing (or logical OR in Javascript), ternaries, or even function calls to make the assignment less likely to grow out of control later. Here’s a ternary version of the above.

$jam = ($name === 'joe') ? 'marmalade' : 'raspberry';

In this version it’s immediately clear that the whole line is about assigning $jam based on a condition, and the condition is the very next thing. In the first version it would take reading five lines and then drawing some conclusions to be able to be sure that’s all that’s happening, and just imagine how hard it would be when twenty other statements get added to those blocks!

If there’s a lot of computation or multiple decisions needed before the variable assignment, put all of that into its own small function and you end up with this, which is even more clear:

$jam = getJamFlavor($name);

There’s a lot of other ways we can avoid else in our code, and even if you’re skeptical, I’d like to recommend you give it a try! There’s no one best option, and it might just change how you think about coding entirely.

(Photo by Jens Lelie on Unsplash)

How do we deal with dependencies in PHP

Generally what we want to do when we’re coding something is to call a function.

do_the_thing();

While some of the functions we call could stand alone and some could be methods on an object, they’re all just function calls.

So why does most PHP code have so many classes? I don’t think code organization is a good answer, since we have access to namespaces which can do that just as well. I believe the only valid reason apart from value objects is because of trying to manage dependencies.

Let’s say you are writing code which wants to refund a purchase through a billing system. You call something like refund_purchase($purchase) and you expect to get back a receipt id for the refund. From most caller’s perspectives, that’s all we should need to worry about.

However, let’s say the refund function needs to do the following things:

  • Contact the payment processor to initiate the refund.
  • Create and save a new receipt to the database.
  • Queue webhooks for the refund.

In order to do any of those things, it requires references to other systems. What if we want to switch out those other systems? Perhaps we want to test our function without a database, or we want to change the payment processor. This is where dependency injection comes into play.

Dependencies as Arguments

In order to use dependency injection in the simplest sense, we need to pass interfaces for each of the dependent systems into our function as arguments.

function refund_purchase($purchase, $processor, $database, $webhooks) {}

This is not scalable, though, because as the number of dependencies increases, so does the number of arguments, making it very confusing to call the function in the first place. In addition, when a developer wants to add a new refund call, they also have to figure out how to get each one of the dependencies, each of which may have their own dependencies!

Wrappers

The alternative to passing dependencies as arguments is to use a wrapper function to pre-inject our dependencies before they are needed. In PHP (and other Object-Oriented languages) the most accepted way to do this is using a class constructor as that wrapper. (In some other languages we might use a Higher Order Function, but this is much more challenging in PHP).

class Refunds {
  public function __construct($processor, $database, $webhooks) {
    $this->processor = $processor;
    $this->database = $database;
    $this->webhooks = $webhooks;
  }

  public function refund_purchase($purchase) {}
}

But now we are stuck with another problem: were do we call the wrapper? Since we might want to ask for a refund in any number of places, generally we must force the calling code to call the wrapper as well.

$wrapper = new Refunds($processor, $database, $webhooks);
$wrapper->refund_purchase($purchase);

That’s not a whole lot better than putting the dependencies into the function arguments, though; it’s confusing and annoying for the caller. Also, any time we want to add new dependencies we would have to change every single caller.

Factories

A solution to the issue of where to call the wrapper is to put it into a stand-alone function.

function create_refund() {
  global $wpdb;
  $processor = new DefaultProcessor();
  $database = $wpdb;
  $webhooks = new Webhooks();
  return new Refunds($processor, $database, $webhooks);
}

The calling code must still create the wrapper before it uses the function it wants, but at least that can be broken down to a one-liner.

create_refund()->refund_purchase($purchase);

In practice, these wrapper calls are often put into static functions, and can even be functions attached to the classes they are meant to wrap, which puts them close to the function call we want and so makes them easier to discover.

Forwarding Functions

It’s also possible to wrap the wrapper call into its own forwarding function to remove any need for the caller to know about our wrappers.

function refund_purchase_with_defaults($purchase) {
  return create_refund()->refund_purchase($purchase);
}

This may seem like an extreme level of redirection, but it provides the best of both worlds: as long as the forwarding function does not do anything apart from call the wrapper and its method, most callers can ignore dependency injection entirely. This only works if we make sure never to use the forwarding functions inside other wrappers, though.

Containers

Eventually we end up with tons of wrappers, as there are many functions that have dependencies and they can’t always be grouped easily. This presents two new problems: it can be hard to locate the wrapper you need, and in order to keep everything as simple as possible for the caller, we end up creating and re-creating the wrapper class many times within a single execution of the code. This can immensely bloat our memory usage since each one of those instances keeps its own state and references.

Therefore many projects end up with a Dependency Injection Container which puts all the wrapper functions into one place and also caches the instances it creates, making it very easy for callers to keep their one-liners without having to worry about memory issues.

class Container {
  public function create_refund() {
    global $wpdb;
    if (! $this->refunds) {
      $processor = new DefaultProcessor();
      $database = $wpdb;
      $webhooks = new Webhooks();
      $this->refunds = new Refunds($processor, $database, $webhooks);
    }
    return $this->refunds;
  }
}

Having these wrappers creates a new problem for our functions themselves, though, which I mentioned above: it’s now so easy to call other wrapped functions that it’s tempting to use the wrappers to make calls to other systems rather than using injected references. Doing this defeats the purpose of our wrappers entirely and we end up right back where we started. Therefore we must have some mechanism, usually just code review, which prevents anyone from using wrappers within a wrapped function.

Do we need all this?

All of this work is built on the premise that dependency injection is good and a necessary thing to have. The counter-argument is that without that premise, our code is so much simpler. So let’s examine the concept a bit more.

In any given project there will probably be functions for which the dependencies are relatively trivial. Let’s say a function needs to log events for analysis, but we don’t want to log anything while running automated tests. Rather than injecting a logger, we could just have the logger function itself detect if we’re running inside a test and if so, do nothing. If more special cases are needed, those can be added directly to the function as well.

function log_message($message) {
  if (! defined('ARE_TESTS_RUNNING')) {
    write_log_message($message);
  }
}

This technique has the advantage that it’s more foolproof than relying on callers to substitute dependencies, so we might be doing it anyway to protect our data. Even though it relies on global variables and constants, a PHP process is bounded in both time and scope so in many projects this reliance on globals creates fewer problems than it solves.

It’s also likely that in any given project there are at least a few functions which have very complex dependencies, and therefore are hard to test without running them in isolation. These functions probably benefit from using a wrapper approach as described above.

So when exactly do we need dependency injection and when is it just needless work? Even though to me the elegance of separating dependencies is a reason in itself, to be honest I can only think of two real needs. I think that we must ask these questions of each dependency we find.

Questions to ask

  1. Is a dependency large or complex enough to require mocking during testing, or do we need to test the interaction with a dependency itself?
  2. Is it likely that a dependency will need to be changed now or in the future because it represents some system that has more than one implementation?

As soon as any dependency in a project answers “yes” to one of the above questions, I think that it’s worth including a Dependency Injection system of some kind. Even if the answers are “no”, it might be a good idea if the project is a library which itself is used by other systems, because it’s often hard to predict how a library might be used. It can be a pain to be forced by your libraries to adopt specific other libraries.

And if you do have a Dependency Injection system, if any given dependency does not answer “yes” to the above questions, then perhaps you can ignore injecting it. The purist in me rebels against the idea of a single function including both injected dependencies and non-injected dependencies, but given the large amount of code needed to use a wrapper in PHP, it may just be the better choice.

(Photo by John Carlisle on Unsplash)

Legend of the Whale

As has become tradition, every year I design and run a one-shot Dungeons & Dragons game for my co-workers at our annual gathering. This year I was heavily inspired by my experiences playing Breath of the Wild and I wanted to try to re-create that particular “Zelda” feeling in D&D. I’d love to have done more but there’s only so many puzzles you can fit into a 3 hour game!

The adventure is a one-shot adventure for a group of 2nd-level characters and runs in just about 3 hours. It was designed to be fun for brand new players and experienced gamers alike. Myself and several wonderful volunteer DMs ran the game seven times over the past few weeks and I think it runs pretty smooth.

Here is the teaser text:

One hundred years ago the realm of Dunelin built four magical monuments in the shapes of giant animals to concentrate their power and defend against a demon’s attack. Sadly, they did not account for the cunning of their adversary. The demon took control of the monuments, turning them against their creators, making him nearly unstoppable.

Though it cost her life, the realm’s most powerful wizard was able to bind the demon in a magic circle, buying her people some time. All of the demon’s rage is now focused against his prison, and after a hundred years he is close to breaking free.

Time to to recover the monuments is running out.

You may download the adventure yourself here: http://bit.ly/legend-of-the-whale

Photo by Roberto Lopez on Unsplash

Safely coding with constants

In PHP there is a tendency to assume that the code we are working on is the only code that is running. The global and transactional nature of the language’s past has made this easy to do.

This tendency naturally leads us to use global state, and while there does seem to be a resistance to using global variables, I’ve only seen increased usage of constants created using define(). I would like to suggest that constants created in this way are actually just global variables by another name. Worse, perhaps, they are global variables whose values cannot be changed during runtime. If that last bit seems like an advantage rather than a disadvantage, read on.

First let’s briefly cover the risk of global state. As I’ve seen in my experience over and over again, the nature of code is to proliferate over time and when code starts to have complexity, global state becomes a liability. Anything the programmer cannot see directly when coding is something they have to keep in their head. And there is only so much we can keep in our heads, especially when large periods of time pass and when many different people are involved. A local variable (local state) is much easier to reason about, because it’s “right there” in front of us and less likely to be affected by things “somewhere else”.

There’s more to it than just making code more readable, though. Another way we learn about and protect code from bugs is by testing, both automated and manual. The nature of testing is to try some code, then change the state and try it again to see what the effects are. Remember how I said that constants created by define() cannot change? Let’s look at an example,

function getGroceries(): string {
  if (defined('LIKES_PEAS')) {
    return purchasePeas();
  }
  return purchaseCarrots();
}
// ...
echo "I will buy some " . getGroceries();

How would we write a test case for this function? The risk of having a condition on a defined constant is that apart from manual testing it is impossible to test it. Constants by their very nature cannot change, and defined constants are global in scope so there is nowhere they will not be. Once we define it, we cannot change it during the same runtime and most PHP test runners execute all their test cases in the same runtime.

That’s not to say that all constants are problematic. It’s more an issue of how we use them. Essentially, if we just stop writing if (defined())… in our code, the problem goes away.

But it’s not that easy, is it? The argument that I’ve heard most often to keep checking for defined constants is that they already exist in most large projects and so we have no choice. But this is not quite true.

The values stored in these constants are not themselves constant, and can be injected into the code that uses them. Here’s that previous example, written a different way,

function getGroceries(bool $likesPeas): string {
  if ($likesPeas) {
    return purchasePeas();
  }
  return purchaseCarrots();
}
// ...
echo "I will buy some " . getGroceries(defined('LIKES_PEAS'));

Suddenly it’s very easy to test the function! We just change its input. This is called dependency injection.

This technique is a time honored way to isolate dependence from logic. It may be less convenient because we must admit that when we need to check a constant we are actually adding a new dependency. However, noticing this gives us information, not penance. It may force us to find other ways of structuring our logic to avoid those dependencies altogether.

There is no doubt in my mind that the isolation of dependencies is critical to write code that is easy to reason about, and that doing so will reduce bugs, stress, and confusion as the code grows. When we recognize that constants created using define() are just another dependency, we can use them sparingly and isolate their usage in the same way we would for any other global or remote state which we cannot control.

(Photo by Simon Matzinger on Unsplash)

Giving more time to each thing

Lately a lot of my dharma practice has been revealing restlessness. Even when I think I’m being calm and slow and contemplative, I still am giving more thought to my Instagram-mind, or my what-do-I-need-to-do-next mind. Most of all I’ve noticed that my inclination toward efficiency in all things leads me to always be doing more than one thing at once, and this is the source of many small sufferings (Buddhist philosophy speaks of “suffering” a lot, but the word is loaded in English and perhaps better translations would be “dissatisfaction” or “stress”).

Let’s say I’m cooking dinner. I may be carefully frying onions, trying not to burn them, but I also realize I want to prepare some (vegan) sausage, so I pull that out and start to chop it up, figuring that it’s relatively little effort to do that and watch the onions at the same time. And it is, but inevitably there’s another thing; I realize that the cutting boards are not where I want them to be; someone has left them dirty in the dish washer. Ok, no problem, I can wash one off pretty quick. And I can, but then another thing; my wife is texting me asking about some papers she needs for her work, can I go find them real quick? Of course I can, but then another thing… you see how it goes.

While I tell myself that I can handle juggling all these things – and I can, and I even take a certain pride in my ability to push each thing onto a mental stack, constantly sort and re-sort their priority, and pop off what needs to be done at each and every moment – each item on the stack takes a mental toll.

It’s a tension in my belly, a furrowing of my brows, a tendency to snap at others if I’m interrupted. It’s unhappiness at the way things are. It’s stress. It’s Dukkha.

I’ve started to feel this toll in so much of my day. Microscopic things, mostly. Wanting to sip some tea while listening to a podcast. Wanting to wash some dishes while cooking. Even wanting just to think about something, perhaps a future event, when I’m busy doing something else. The thinking might be the hardest one of all.

And the solution that I’ve come to? It doesn’t require a lot of thought to figure out. Pay attention to each thing that is going on. Give it my full attention and, if I need to do something else, then totally stop doing the first thing and move on to the other. Switching isn’t the problem, it’s my resistance to stopping, my resistance to switching that is causing the suffering.

That makes it sound so easy, though. “Just do one thing at a time.” It’s cliché. For cooking onions it might indeed be easy. The hard ones are the thoughts, the emotional reverberations, and the conversations that require some time to digest (and which ones don’t, I wonder?). It’s hard for me to treat needing to think about something as worth pausing in my activity.

I’m starting to look for the feeling of that tension arising, or for the thought of “I just need to…”, and to say a resounding “no” when it appears. Well, maybe not so harsh an expression, but certainly a firm one is needed, because it’s insidious. “Oh, just this thing, it’s not really that bad” is so hard to deny, to see through the illusion of the thought. And one reason, I believe, is that I worry that I’ll be judged for it, for being slow or inefficient, or that things that matter to me or to others will not get done.

But what’s more important? Getting things done or being at peace? That’s not a trick question, or meant to be rhetorical; that’s the question that I need to ask each time I encounter these feelings. In general, when I really force myself to look at it, my answer has been “being at peace”. So my practice has become trying to find ways to just do one thing. I’ll let you know if I still manage to get things done.

What it comes down to is that the experiences in my life demand more time than I want to give. It’s challenging to stay with one experience even when others are calling. I suppose that’s the point of formal meditation, and perhaps a significant part of the recipe for a contented life.

 

Photo by Murray Campbell on Unsplash

 

Creating Sniffs for a PHPCS Standard

As a follow-up to my summary of using phpcs to lint your PHP code, this post will explain how to create, modify, and test a phpcs standard.

As a quick refresher, phpcs organizes its linting messages (warnings and errors) into “sniffs”, then into “categories”, then into a “standard”.

The official tutorial for creating a standard is here, but it doesn’t go into much detail and some parts of it are out-of-date. There’s additional useful information in the 3.0 upgrade guide but I’m going to try to do a better job here of explaining how it all works.

Continue reading “Creating Sniffs for a PHPCS Standard”