Walrus-operator in PHP

In oktober 2019 introduceerde Python 3.8 de Walrus-operator (:=) via PEP 572 – en daarmee ontketende hij een van de grootste controverses in de geschiedenis van de programmeertaal. Het debat was zo fel dat de uitvinder van Python Guido van Rossum in juli 2018 – nog vóór de release – zijn positie als BDFL (Welwillende dictator voor het levenSinds begin 2019 wordt Python bestuurd door een gekozen stuurraad.


if (n := len(items)) > 10:
    print(f"List is too long ({n} elements)")

De bestuurlijke breuk ontstond direct na de Walrus-discussie – een zeldzaam geval waarin één enkele taalfunctie structurele gevolgen had. In zijn verklaring legde Van Rossum uit: "De druppel was een zeer controversieel voorstel voor Python Enhancement. Nadat ik het had geaccepteerd, gingen mensen op sociale media zoals Twitter dingen zeggen die me persoonlijk pijn deden."

Hij vervolgde: "Nu PEP 572 voorbij is, wil ik nooit meer zo hard hoeven vechten voor een PEP en ontdekken dat zoveel mensen mijn beslissingen verafschuwen. Ik wil me volledig terugtrekken uit het besluitvormingsproces." De kritiek kwam niet alleen van de bredere community, maar ook van de kernontwikkelaars.

Ze betoogden dat de operator in strijd was met fundamentele Python-principes uit de Zen-periode van Python – met name de voorkeur voor eenvoud boven complexiteit. Na bijna drie decennia als onbetwiste taalontwerper markeerde dit het einde van een tijdperk. Maar terwijl Python een nieuwe Walrus-operator moest introduceren, waardoor de gemeenschap verdeeld raakte, rijst de vraag: hoe gaan andere talen om met vergelijkbare concepten?

De Python-operator := (Assignment Expression alias "Walrus") bestaat niet in PHP – omdat het niet nodig is. In PHP is de assignment operator = altijd Verklaring en expressie tegelijk: Een toewijzing retourneert de toegewezen waarde. Dit is precies waarom idiomatische patronen zoals "assign-and-test" werken in if-voorwaarden zonder eigen taalkenmerk.

function get_some_field() {
    return 'foo';
}
if ($a = get_some_field()) {
    echo $a; // foo
}
// Hinweis: $a ist *gesetzt*, selbst wenn die Bedingung falsy wäre.

$a = get_some_field() wijst toe en evalueert aan de rechterkant. Als dit "waar" is, ga je naar de if-Blok. Achtergrond: In Python, := (PEP 572) omdat eenvoudige toewijzingen geen expressies zijn. In PHP is dit altijd anders geweest, dus er is geen equivalente behoefte. Twee dingen leiden vaak tot bugs.: = (Toewijzing) heeft een lagere prioriteit dan de meeste relationele operatoren; haakjes bepalen de evaluatie.

Bij complexere uitdrukkingen moet u altijd haakjes gebruiken om de leesbaarheid en duidelijkheid te vergroten. ?? heeft een eigen, vrij lage prioriteit. Dit verklaart verrassingen in uitdrukkingen zoals $x ?? null === null. Zonder haakjes, eerst null === null geëvalueerd. Het is beter om altijd expliciet haakjes te plaatsen: ($x ?? null) === null. $a bestaat ook buiten de if-Blokken – mogelijk met een onjuiste waarde.

function get_some_field() {
    return 'bar';
}
if ( ($a = get_some_field()) === 'bar' ) {
    echo $a; // bar
}

Het is dus duidelijk dat === 'bar' wordt toegepast op de toegewezen waarde. Haakjes zijn hierbij belangrijk voor de leesbaarheid en prioriteit. In de praktijk voorkomt dit patroon onnodige dubbele aanroepen (bijvoorbeeld van de query builder) door het queryresultaat op te slaan en vervolgens te controleren. In productieve toepassingen, zoals Laravel-gebaseerde projecten, kan het volgende patroon vaker worden waargenomen.:

if ( ($foo = Foo::where('foo', 'bar')) && $foo->count() > 0 ) {
    dd($foo->get());
}

&& is kortsluiting: het rechterdeel wordt alleen geëvalueerd als het linkerdeel waar is. Door de instructie stroomopwaarts toe te wijzen, voorkom je dat de instructie buiten de if-instructie wordt toegewezen. Of dit een goede gewoonte is, hangt af van de code en analysetools van je team; semantisch gezien is het correct. Je zou op zijn minst moeten weten wat de code doet als je deze in het wild tegenkomt.

PHP heeft geen "Walrus-operator" nodig omdat toewijzingen al expressies zijn. Dit maakt idiomatische patronen zoals "assign-and-test" mogelijk – performant en beknopt. Tegelijkertijd nemen de eisen aan de discipline toe: haakjes, strikte vergelijkingen, bewustzijn van waar/onwaar en duidelijke teamconventies zijn verplicht. Wie deze richtlijnen volgt, profiteert van de voordelen van het Walrus-idee zonder dat er een extra taalfunctie nodig is.

Terug