It's been a long time since the last post! In previous posts, we already discussed some strategies for making our code easier to reason about by looking at Functional Programming concepts and integrating them in our own workflow. In this post, we go at the problem from a more traditional perspective and look at a few small things that can make our lives a lot easier (as well as the lives of the other people that need to check out our code)!

🍍 πŸ™…β€β™‚οΈ πŸ• Make invalid state impossible to represent

Let's say we are building an app that lets people order coffee from a local coffee shop. They pick the product they want to order from a list, and they have to put in the number of items they want to order (the quantity) per product that they picked.

You could write something like

$cart->add(new ProductId('001-esspresso'), 3);

If you wanted to buy three Espressos.

The problem with this, is that we can easily pass a faulty value to that function:

$cart->add(new ProductId('001-esspresso'), 0);

or

$cart->add(new ProductId('001-esspresso'), -2);

or even

$cart->add(new ProductId('001-esspresso'), 3.14);

This can become a problem later on, for instance when we are calculating the price of the order. This means that our method needs to guard against faulty input values here, but it's impossible to know from the outside of the method if it does it or not. This will throw an exception:

$cart->add(new ProductId('001-esspresso'), -2);

But you don't know that. You need to go and look inside that method to know for sure. Also, you don't know when it will throw...

PHP's type system could be of help in some cases (e.g. to prevent the float value, we could typehint for an integer), but in this case, we're missing a concept: Quantity which is a Value Object that represents the exact value that we need, a positive integer that's bigger than zero.

The method now only accepts instances of that object, which means it doesn't need to do any additional checks.

public function add(ProductId $id, Quantity $quantity): void
{
    // ...
}

What's more, every time we pass a Quantity around, or when we are passed one, it's guaranteed to be a verified correct value:

final class Quantity
{
    private $quantity;

    public function __construct(int $quantity): Quantity
    {
        $this->assertBiggerThanZero($quantity);

        $this->quantity = $quantity;
    }

    private function assertBiggerThanZero(int $quantity): void
    {
        if ($quantity <= 0) {
            throw new InvalidArgumentException('Quantity should be bigger than zero');
        }
    }
}

πŸ€– ➑️ 😁 Using annotation and static analysis to our advantage

It's good to know that the Quantity object is a Value Object, because this makes it easy to reason about: it behaves like a value, it's immutable. Knowing this, you can forget about passing by reference and other headaches. It's even better if you can let other developers know:

/**
 * @immutable
 */
final class Quantity
{
    // ...
}

You can get even more out of it, if you use psalm. You can let psalm guard this property for you: if someone would add a method to the Quantity class that made it mutable, your tests would start failing:

/**
 * @psalm-immutable
 */
final class Quantity
{
    // ...
}

At this point, you can be pretty sure that no mutation is going to happen. You can also annotate functions/methods like this to let others (and psalm) know that the function is "pure":

/**
 * @psalm-pure
 */
public function addOneFreeCoffee(Quantity $quantity): Quantity
{
    return new Quantity($quantity->toInt() + 1);
}

This annotation makes it impossible to do anything in the body of this method that changes state, or even generates output. It becomes a lot easier to reason about this function: if you give it input a, it will always return output b. It won't magically pull out some random value, or a record from a database. It's transparent.

βœ… ➑️ πŸ“– Your tests are domain expectations

Tests are often used as "a way to make sure our code works". While I don't disagree with that, I think good tests are way more valuable than that. If you're working in a Test-Driven manner, they provide confidence and flow during development. They help you to do safe refactors. But also, they document your code. Let's look at an example, would you rather find this:

/**
 * @test
 */
public function shippingIsFreeWhenYouOrderThreeOrMoreProductsAtLeastOneBigLatte()
{
    $cart = new Cart();

    $cart->add(new ProductId('001-esspresso'), new Quantity(2));
    $cart->add(new ProductId('002-lungo'), new Quantity(3));
    $cart->add(new ProductId('003-latte-big'), new Quantity(1));

    $cart->checkout();

    $this->assertTrue($cart->freeShipping())
}

or this:

/**
 * @test
 */
public function shippingIsFreeWhenYouOrderThreeOrMoreProductsAtLeastOneBigLatte()
{
    $cart = new Cart();

    $cart = $this->givenTheCartContainsThreeOrMoreProducts($cart);
    $cart = $this->andTheCartContainsOneOrMoreBigLattes($cart);

    $cart = $this->whenTheCartIsCheckedOut($cart);

    $this->thenShippingShouldBeFree($cart);
}

When you look at the first example, the domain rule is expressed in the name of the test only, the test code itself doesn't help you in understanding the actual rule that we're testing. You can see how the Cart is used, but you'll have a harder time finding out or validating what the actual rule is that's being tested. In the second example, there's no chance of missing the domain rule. The domain language is used to express the problem as if you were talking about it. It's a bit harder to see how the Cart is used, but it's easy to click through to the implementation of those methods to see the actual implementations.

Conclusion

Using three simple concepts, we can give our brains a bit of rest when looking at the code because they don't need to keep as much information in "working memory" to understand it. I hope these tips will help you to make your code easier to grasp for yourself and your coworkers! Hope to see you for the next post!

Tags:

As you could already read in one of our previous posts, we started working in pairs some time ago. Now there's also some Mob Programming being done from time to time, and we started automatically doing some things to make our own lives easier. Some examples:

πŸ›‹ πŸ“Ί Make yourself comfortable

Keyboard Switcher in macOS

Make sure everyone has a good chair and good visibility of the screen you're working on. If you're pairing, this means that you should work on an external screen of some kind, instead of on a laptop. Make sure there's enough light, not too much noise, and that everyone has drinks and food if they need it.

You can work best if you're not focussing on something else. Taking away small distractions like restlessness or poor visibility of the screen can do wonders!

βŒ¨οΈπŸ’» Set your machine up for everyone

Make sure the machine you're working on is set up so that you can switch drivers often and so that every driver is working comfortably on it. Of course, it's mostly impossible to all agree on the same set of shortcuts and keyboard setups, but we found a great compromise:

Keyboard Switcher in macOS

  • On macOS you can make the keyboard settings available from the top bar so that you can really quickly switch keyboard layouts
  • In PhpStorm or other editors, there are options to export your settings and import other ones. I just created a backup of my settings by exporting them and I ask everyone at the beginning of the session to send me their configs. When they start, they can select their own config from my desktop! After the session I can easily restore my own settings.
  • On macOS it's also possible to connect multiple Bluetooth keyboards, mice, etc. We have an AZERTY and a QUERTY keyboard available, as well as a trackpad and a mouse. They are easily passed on and ready to use by the next driver!

These three small changes come a long way to make you feel as if you're working on your own machine!

β›”οΈπŸ“± Only allow one screen

Being distracted already came up in the previous tip, but here we go again! Ask everyone in the room to put their phones on silent and put them in their pockets. Ask them to close their laptops, they're not going to need them. If you need to look something up, or if you're unsure about what a given piece of code does, ask the driver to put it on the big screen.

This way, nobody dives off into their own cocoon and let their minds escape the group's focus.

πŸŽ¨β—»οΈ To the drawing board

Try to find a way to make things visible. If you have a whiteboard available, great! Do you have a wall? Use stickies or put up big pieces of paper. As a last resort, there's still just pieces of paper that you can draw on. Just make sure that you can make something visible so that you have something to talk about when a discussion is in order.

😰 ➑ 😁 Keeping everyone engaged

Two rules:

  • Switch drivers often
  • Take breaks often

We use this simple app to notify us when to switch and when to take breaks. If the app doesn't tell you to take a break but you feel like it anyway, just do it. You'll be more productive after the break.

πŸ’»πŸ‘ Remote work and mobbing

  • Make sure both parties have a perfect internet connection
  • Make sure the setup for audio is working properly. We use a Jabra kit that picks up less ambient noise and makes everything clear to understand
  • Use e.g. Slack screen sharing features to your advantage: you can draw on the screen and you can switch drivers easily!

Hope these takeaways can help you as well! Happy Mobbing!

Tags:

Starting tomorrow until October 20th, it's EU Code Week 2019; that time of year to get young adults excited about programming.
Just as last year, several members of our team are taking part in one of the initiatives for that European Code Week; we'll be giving a workshop to 11 year olds by building a little robot with them next Thursday.
This blog post puts a spotlight on these initiatives and explains how you can help.

πŸ‡ͺπŸ‡Ί European Code Week

During 15 days hundreds of activities happen all over Europe that want to celebrate creativity, problem solving and collaboration through programming and other tech activities.

You probably need little convincing that digital literacy is super important in today's world. Getting young adults interested in programming is one way of driving that.

"It's about Pia, who felt like she had to study law, even though she always enjoyed maths and playing with computers. It's about Alice, who dreams about making robots because her parents don't allow her to have a cat." - codeweek.eu/about

The initiative started in 2013 and had grown to 44000 activities reaching 2.7 million people all over Europe by last year, all run by volunteers. The EU Code Week includes a.o. well-known initiatives like CoderDojo.

Code Week Participants

πŸ€– WeGoSTEM

One of the other organisations taking part in the EU Code Weeks since a few years, has its roots in the hometown of Clarabridge Engage: WeGoSTEM.
(STEM is short for Science, Technology, Engineering & Mathematics, an acronym often used in education to refer to these fields, as part of a curriculum that is interdisciplinary & using an applied approach.)

WeGoSTEM's mission is to organise a fun workshop in as many schools as possible (mainly in Brussels & Flanders) to give as many 11 to 12 year olds as possible a first introduction to programming. Here's the robot we're building:

The Drawing Bot In Action

WeGoSTEM is a project of the NGO's Dwengo & SheGoesICT. Dwengo is organising teaching activities for people who want to experiment with micro-controllers, all around the world, and more specifically in socially-disadvantaged countries. SheGoesICT has as clear goal to advocate gender diversity in IT companies in Belgium.

The NGO's behind WeGoSTEM have diversity and inclusion in their DNA, so it's no wonder that also in the workshops they give, they focus first and foremost on reaching as many girls as boys, and focus on giving workshops in schools with many children from disadvantaged groups and rural schools. (In 2018, 29% of the children who participated in WeGoSTEM had a special socio-economic status (SES), while the average is only 20%.)

I've joined a few workshops that teached programming concepts to kids on Wednesday afternoons or during weekends, but there's no denying these are too often an affair for boys, and for kids from economically advantaged parents. For me personally, WeGoSTEM’s focus on inclusion, is a very big motivation to volunteer for this project.

By the end of the workshop the main goal is to have given every single kid a fun experience. (Not about building the most complex robot, or have the most advanced programming sequence ...) The only goal is to play around with a micro-controller and use the basics of a visual programming language.

βœ‹ How it is to volunteer

So if you sign-up to volunteer, what actually happens? First, you indicate one or more dates you're available to give the workshop in a school, and area of preference. (This year, Jared and me are heading to a school in Bruges.)
There's also several training sessions around Belgium where the core team of WeGoSTEM explain the project, structure of a typical workshop, you get the time to build & play with the robot yourself, and meet the other volunteers.

When you visit the schools, you're a team of 3 coaches (of which almost always 1 has given the workshop previously).

  • πŸ—£ The workshop starts with a little chat with the class to see what they know and like and find exciting about robots. (Ideal place to test our dad-jokes about mowing robots ☺️.)
  • 🎨 In a next exercise it's about trying to show kids what it is to program: one volunteer kid instructs the rest of the class to make a certain drawing. At this point it often shows the importance of clear instructions.
  • πŸ”© And then of course: building the robot (with Knex-like blocks) and a Dwenguino-board (a pre-assembled Arduino with several sensors).
  • πŸ’» Once the whole robot is build you help the kids to program the robot with Blockly. Blockly is Google technology that you can use & embed in other projects. (You can play with an online simulator of the Dwenguino/Blockly software over here: dwengo.org/dwenguinoblockly.)
  • πŸ˜„ By the end of the workshop the goal is to send every kid home with a smile and a drawing.

Oh, and in the afternoon, you do it all over again, for another class.

The whole experience - standing in front of a class room and having kids so eager to experiment with programming - is absolutely wonderful. And also quite exhausting (no need to convince me of the importance of good teachers, after only a single day in their shoes πŸ˜….)

Maybe you helped inspire a kid to choose an education path focusing on STEM? Maybe you gave the teacher of that class the empowerment & tools to incorporate programming in some of their lessons? Maybe you helped show policy makers the importance of digital literacy and drive change?

A class with all their drawings ...

WeGoSTEM is 100% supported by volunteers in all participating countries. Workshops for the code week start next week, but there's definitely some free spots for coaches still. If you want to participate, check out the dedicated websites: WeGoSTEM Belgium and WeGoSTEM Greece.
After the Code Week, all volunteers can also always use the workshop materials needed to give an extra sessions in a school where you have a friend, kid or nephew or niece, so if you want to help us host a workshop, do let us know ...

Although the costs to run this project are very low (probably among the lowest euro-per-kid for STEM projects in Belgium), they can always use some extra help. WeGoSTEM is working with several partners that donate money, laptops, or help source volunteers amongst their employees.

Tags: