Paul M. Jones

Don't listen to the crowd, they say "jump."

Moving Away From Google

In an effort to extract Google's tentacles from my life, and to give them as little feedstock as possible, I am no longer using my Gmail account as a primary contact address. Contact me at my pmjones.io address instead. Likewise, my paul-m-jones.com address is no longer being hosted by Google.

It was surprisingly time-consuming to find a reasonable alternative host that would support some other functionality (more on that later). After some preliminary attempts, I settled on Namecheap. Believe it or not, I am using a shared hosting plan, which supports another effort I am trying out (more on that in another post).



Immutable Objects for PHP

The new immutablephp/immutable package provides truly immutable value objects and an immutable value bag, along with base Immutable and ValueObject classes for your own objects. It helps to prevent against the oversights described by my earlier article Avoiding Quasi-Immutable Objects in PHP. (Of course, it cannot prevent you from deliberately adding your own mutable behaviors, or from using reflection to mutate an object from the outside. If you do those things, you get what you deserve.)

Its base Immutable class protects against common oversights in PHP regarding immutables:

  • It defines final public function __set() and final public function __unset() to prevent adding and mutating undefined properties.

  • It defines final public function offsetSet() and final public function offsetUnset() to prevent adding and mutating values via ArrayAccess.

  • It prevents multiple calls to __construct() to re-initialize the object properties.

Further, the base ValueObject class with() method checks the types of all incoming values to make sure they are themselves immutable. It does so via static methods on the Type class.

The Type class recognizes scalars and nulls as immutable. All other non-object values (such are resources and arrays) are rejected as mutable.

When it comes to objects, the Type class recognizes anything descended from Immutable as immutable, as well as DateTimeImmutable. To allow Type to recognize other immutable classes, call Type::register() with a variadic list of fully-qualified class names that you want to treat as immutable.

After installing immutablephp/immutable via Composer, you can use it to create your own immutable Value Objects, or consume one of the provided Value Objects:

There is also an immutable value Bag for an arbitrary collection of immutable values; it can be useful for immutable representations of JSON data.

If you need truly immutable objects for your PHP project, give immutablephp/immutable a try!


Read the Reddit commentary on this post here.


Clarifications to a review of Action Domain Responder

Herberto Graça, as part of his Software Architecture Chronicles, saw fit to review the Action-Domain-Responder pattern that I have written so much about. It’s a good writeup, and you should read the whole thing, but it is off in a couple of places. I sent Herberto a followup email with some minor corrections and clarifications; I repeat it below (with light editing) for posterity.


The ADR pattern was created by Paul M. Jones

I prefer to say, not that I “created” the pattern, but that I “recognized and named” it in 2014. Slim, for example, already had single-action controllers at that time, and the various Domain Logic patterns previously existed as well. If I “created” anything, it was the idea of the Responder; that is, of treating the Response-building work as a completely separate concern. But even that is just an application of Separated Presentation.

to adjust MVC to the context of web REST APIs.

APIs were one aspect, but the origin was more in the typical HTML page-based interface. For example, the word “Action” in Action Domain Responder was inspired both by “action” methods in Controllers, and by the “action” attribute on <form> tags in HTML interfaces.

because the idea is to adapt the MVC pattern to the context of an HTTP REST API, the Action (Controller) names are mapped to the HTTP request methods so we will have Actions with names as Get, Post, Put, Delete

Well, you can do that, but it’s not strictly necessary. I think it would be more accurate to say that it’s typical for an Action to be mapped to a route, and for the routes themselves to be mapped to GET/POST/PUT/DELETE etc.

As an organization pattern, all Actions on a resource should be grouped under a folder named after the resource.

That is one reasonable approach, but it’s not dictated by ADR. Alternatively, instead of grouping Actions by resource, you might organize them by Use Case, or by the intended Interactions with the underlying application.

This pattern was thought of specifically for REST APIs, so in this form it is not refined enough to be used in web applications with an HTML interface (ie. what would be the name of the action to show a form, prior to creating a resource?) … I think the pattern can easily be extended so that it is fully usable with an HTML interface: We can emulate some extra HTTP methods specifically to handle the HTML requests that a REST API does not have.

Given my notes above, I think it’s fair to say that new HTTP methods are not really needed. What is needed, as Herberto already points out, is a way to “show a form prior to creating a resource” (among other things).

Because the Actions do not necessarily map one-to-one with HTTP methods, it’s easy enough to specify that GET /{$resource}/new (or something similar) routes to an Action that gets default values for that resource from the Domain, then hands off to a Responder that builds the form HTML. You can see an example of that here:

You might route the first as GET /blog/new and the second as POST /blog. (That idea appears to originate from Ruby on Rails and has been imitated elsewhere.)


Aside from those notes, Herberto’s article is a fair summary and description of ADR. I’m glad he put it together.

You can read more about Action Domain Responder at http://pmjones.io/adr.


Open Source and Squeegee Men

Originally published at https://24daysindecember.net/2018/12/11/open-source-and-squeegee-men/.

I.

It is the Christmas season, and Christmas is a time for giving gifts: to family, to friends, and to colleagues. Some even give gifts to strangers they may never meet, as an expression of charity or of generosity, or in thankfulness for their own abundance.

Does the recipient of a gift owe the giver anything in return? Some might think the answer is “no” — it was a gift, after all. Others might think that the recipient now owes the giver a gift of their own, perhaps one of comparable value — but if the giver expects a gift in return, doesn’t that take away from the generous nature of the gift, making it more like a business transaction?

I would say that both responses are close to the truth. When someone receives a gift, they do well to return something to the giver … but the return is not primarily a material one. The recipient does the right thing to compensate the giver, not first with money or merchandise, but most importantly with gratitude and good will.

Granted a sense of appreciation, then, sometimes a further expression of that thankfulness is a gift in return. But note that it does not come from a sense of obligation or indebtedness “for services rendered.” We may exchange gifts, but we do not pay for having received them. To pay for something in that way is not to have received a gift; it is to have made a purchase.

II.

I think open source software is a little like the giving and receiving of gifts.

To be clear, I don’t mean the production of open source software. The actual work of developing a program, with others, is not a series of gifts being exchanged. It is a cooperative/competitive activity with its own implicit order of criticism and acceptance.

But the open source software product itself, when presented, is a little like offering a gift to strangers. When you publish your work, you don’t know in advance who will find it useful, or even if anyone will find it useful at all. And yet, when someone does accept your offering, you get that good feeling of having been helpful.

In accepting an offer of free software, as with any gift, the recipient does best to regard the giver with gratitude and good will. That is to say, the user of open source software should have an internal feeling of appreciation for the gift they have been given.

If that appreciation is expressed in some outward and visible manner, so much the better. But that expression cannot be required by the giver of the open source gift. Really, it cannot even be an expectation on their part.

III.

What would we think of someone who, on offering what appeared to be a gift, immediately demanded a gift (typically money) in return? And then harbored resentment and ill-will for not receiving one? I think it would be fair to call such a person disingenuous at best; a swindler or a con-man at worst. It’s like the squeegee-man scam: someone runs up to your car at a stoplight, sprays and wipes down your windshield to clean it, starts yelling at you to pay them back for having served you, and finally (if you drive away) curses at you.

A person who offers a gift, then demands a gift in return, is attempting a sort of emotional jiujitsu to turn your own good will against you. Having received a gift, you may feel the giver’s demand is somehow justified; is it not the normal expectation to exchange gifts? And yet the initial act was not that of giving a gift: it was more like priming a pump, so that you would feel guilty, and then pay in cash to soothe your own self-imposed guilt.

Of course, the proper emotional reaction to the squeegee man should be indignation, not guilt, followed by refusal to concede anything to a “gift-giver” who expects money as payment in return.

As such, if you present your open source offering as a gift, you can have no expectation of anything in return. You cannot expect that anyone will use it; that anyone else will write the documentation for it; that anyone will write up issues or pull requests; that anyone will give you money for it. You can hope for these things, but to expect them (especially money!) is to be like the squeegee scammer. You gave a gift of your own volition; you have no cause to be resentful if people don’t offer you money for it.

IV.

Then comes the question, “Don’t I deserve to get paid for my work?” Certainly you do. But you don’t “deserve” to get “paid” for your gifts. It may be true that one good turn deserves another, but if anything, it is to be in kind, not in cash. If someone opens a door for you, you don’t tip them; you open a door for them in return.

The open-source “in kind” equivalent is Github stars, fair reviews, issues and PRs, and other work — given as a gift! — on your offering. Or recognition, or being cited as an ispiration. Or it might be new software offered as a gift to new strangers, that you never know about. (That is part of what prompts my own open source work; having received these gifts, I find it fulfilling to offer gifts of my own.)

Is it appropriate to mention the kinds of gifts you might like in return? Of course! Everyone who has ever made a Christmas list knows how that works. Set up a Patreon account, point out your Amazon buy-through link, suggest a donation. But I caution against “advertising” it anywhere other than on the project page itself; going out and announcing in public that you accept gifts is a little too much like panhandling.

V.

It’s normal to want to get paid for doing something you love doing anyway. It’s just not an appropriate expectation when you are giving strangers a gift. Now, it is true that getting money for open source software does happen from time to time, but it is unusual — more often, payment is tied to services around the software, not to the software itself. So if you prefer to get paid for your programming efforts, that’s fine: state the terms of exchange, then (and this is key) do not deliver the software unless those terms are met. Generally speaking, we call this “employment” or “sales” or “business,” not “gift-giving.”

Giving a gift in return may sometimes be good manners, but expecting a gift in return is bad manners. Likewise, it is bad manners to be a scold or a busybody, demanding that others pay money for gifts freely given. And if you feel that others are being “exploited” somehow for giving out gifts, the remedy is not to encourage them to begin demanding payment like the squeegee-man. Instead, consider suggesting that perhaps they should not be giving out gifts when they cannot afford to do so.

So don’t be the squeegee-man. If you want to get paid for your work, great! Ask for your money up front. If what you want is to give a gift, that’s great too — and if money unexpectedly flows your way, be grateful.


Postscript: these are some of the links that informed this essay.


Done With Twitter

I've tried "taking a break" but I always come back. Time to be done with it: account deactivated.


What to Do About The Linux COC

(An open letter to the Linux community.)

You need to decide for yourself how dire your circumstances are now that the Contributor Covenant Code of Conduct (CCCOC) is in place. If you think the Social Justice capture of the Linux kernel is all-well-and-good, you need do nothing. Everything is running right on schedule.

But if you think this heralds the end of Linux as anything resembling a meritocracy (however flawed), as well as the beginning-of-the-end of a project that you love and depend on, then you need to take action. Nobody is coming to save you. You’re going to have to save yourselves.

Whereas the Social Justice Attack Survival Guide is a good defense, playing only defensively leaves the non Social Justice cohort of the Linux community indefinitely vulnerable to attack, individually and collectively. To end that vulnerability, you will need to achieve something very difficult. You will need to drive the rejection of the CCCOC, and demand restoration of the Code of Conflict (or perhaps the outright rejection of anything resembling a Code of Conduct at all).

You may ask, “Why should I have to do anything? They’re the ones who suck! They should do the right thing themselves, I shouldn’t have to make them.” And in a way, that’s all true – but it doesn’t matter. You can’t wait for “the management” to “come to their senses.” They have no incentive to change. You have to motivate them to change.

Here’s one form of motivation:

You go on strike.

Don’t resign. Don’t delete or disable your accounts. Keep them, because you’ll need them when this is over (if it ever is over). But stop volunteering:

  • Stop donating money. Email them and say how much you have given in the past, and why you won’t give any more.

  • Stop donating time and effort to commits. Email the project and list your commits, fixes, and features, and say why you won’t be committing any more.

  • Stop answering questions and writing documentation. Instead, respond along the lines of “I’d love to help … once the CCCOC is removed.”

  • If you are paid to work on the kernel, stop doing that work. Tell them why you are going on strike.

Go on strike, and speak up about having gone on strike, until the CCCOC is reverted and the Code of Conflict is put back in place. The longer you keep volunteering, the longer it looks like you are OK with the CCCOC.

They cannot survive (at least, not as easily) without your volunteer efforts. Stop volunteering, and speak out as to why you are stopping. Be prepared to do it for longer than you think you’ll have to.

Threats to their cash flow, to their free-resource flow, will be a serious motivator for them to listen to you.

That’s a starting point. If they need further motivation, their actions between now and later will make the followup approach more obvious.

Do it today. Not tomorrow, not next week, not “later” – today. The longer you wait, the more inertia will build up against you.

Now, I have to warn you: the consequences for you going on strike might be overwhelming. You are likely to find yourself the target of Social Justice, with all that entails. Each of you has to decide for yourself if you want to deal with that kind of fallout, and I’m not kidding when I say it is psychologically and emotionally draining. But you also have to decide for yourself if you want to just sit back and let Linux be co-opted in this way. The choice is yours.

And if you see someone else going on strike with you, support them.

Good luck.


Social Justice Attack Survival Guide

With the recent Social Justice capture of the Linux kernel, many in the open source world may find this guide from Vox Day to be useful. I present it here as a public service; you can find the original PDF here. If you are interested in how to resist the introduction of the Contributor Convenant and other Social Justice derived Codes of Conduct, you may wish to watch this presentation or see the slides for it.


This survival guide is intended for the use of the individual who finds himself under attack by Social Justice Warriors for standing up against them and their ever-mutating Narrative. It may be freely distributed so long as it is correctly credited to SJWs Always Lie: Taking Down the Thought Police by Vox Day.

The eight stages of the SJW attack sequence are as follows:

  1. Locate or Create a Violation of the Narrative.

  2. Point and Shriek.

  3. Isolate and Swarm.

  4. Reject and Transform.

  5. Press for Surrender.

  6. Appeal to Amenable Authority.

  7. Show Trial.

  8. Victory Parade.

The rest of this guide consists of the correct way to respond to an SJW attack once it has been identified, ideally at the earliest stage possible. Please note that the eight stages of response do not correspond directly to the eight stages of the SJW attack sequence.

Read more


Atlas ORM Integration with Symfony

Are you using Symfony 4? Do you want to use Atlas with it? We now have a Symfony bundle and Flex recipe that makes installation and integration a breeze. Two commands and one .env file edit, and you’re ready to go:

composer config extra.symfony.allow-contrib true
composer require atlas/symfony ~1.0

Build out all your mapper files from your database tables with a single command:

php bin/console atlas:skeleton

Then let Symfony inject the Atlas ORM object in your controller or application service constructors automatically (no further configuration needed):

<?php
namespace App;

use Atlas\Orm\Atlas;
use App\DataSource\Thread\Thread
use App\DataSource\Thread\ThreadRecord;

class ApplicationService
{
    public function __construct(Atlas $atlas)
    {
        $this->atlas = $atlas;
    }

    public function fetchThreadById($thread_id) : ThreadRecord
    {
        return $this->atlas->fetchRecord(Thread::class, $thread_id);
    }
}

That’s it – you can now use Atlas for all the heavy lifting of your database work:

If you’re looking for a good persistence model data mapper, give Atlas a try!


Atlas.Orm 3.0 ("Cassini") Now Stable

I am delighted to announce the immediate availability of Atlas.Orm 3.0 ("Cassini"), the flagship package in the Atlas database framework. Installation is as easy as composer require atlas/orm ~3.0.

Atlas.Orm helps you build and work with a model of your persistence layer (i.e., tables and rows) while providing a path to refactor towards a richer domain model as needed. You can read more about Atlas at the newly-updated project site, and you can find extensive background information in these blog posts:

If you want a data-mapper alternative to Doctrine, especially for your pre-existing table structures, then Atlas is for you!


Read the Reddit commentary on this post here.