Operator morsa w PHP

W październiku 2019 r. w Pythonie 3.8 wprowadzono operator Walrus (:=) przez PEP 572 – i tym samym wywołał jedną z największych kontrowersji w historii języka programowania. Debata była tak zacięta, że twórca Pythona Guido van Rossum w lipcu 2018 r. – jeszcze przed premierą – jego stanowisko w BDFL (Dobroczynny dyktator na całe życieOd początku 2019 roku Pythonem zarządza wybieralna Rada Sterująca.


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

Konflikt w zarządzaniu pojawił się natychmiast po dyskusji o Walrusie – rzadki przypadek, w którym pojedyncza funkcja języka miała konsekwencje strukturalne. W swoim oświadczeniu van Rossum wyjaśnił: „Ostatnią kroplą była bardzo kontrowersyjna Propozycja Ulepszeń Pythona. Po jej zaakceptowaniu ludzie zaczęli pisać w mediach społecznościowych, takich jak Twitter, rzeczy, które mnie osobiście uraziły”.

Kontynuował: „Teraz, gdy PEP 572 się skończył, nie chcę już nigdy tak zaciekle walczyć o PEP i odkrywać, że tak wielu ludzi nie akceptuje moich decyzji. Chcę całkowicie odciąć się od procesu decyzyjnego”. Krytyka napłynęła nie tylko ze strony szerszej społeczności, ale także od głównych programistów.

Argumentowali, że operator ten jest sprzeczny z fundamentalnymi zasadami Pythona z Zen of Python – w szczególności z preferencją dla prostoty nad złożonością. Po prawie trzech dekadach bycia niekwestionowanym twórcą języków, oznaczało to koniec pewnej ery. Chociaż Python musiał wprowadzić nowego operatora Walrus, dzieląc przy tym swoją społeczność, pojawia się pytanie: jak inne języki radzą sobie z podobnymi koncepcjami?

Operator Pythona := (Assignment Expression alias „Walrus”) nie istnieje w PHP – ponieważ nie jest potrzebny. W PHP operator przypisania = zawsze Oświadczenie i wyrażenie w tym samym czasie: Zadanie zwraca przypisaną wartość. Właśnie dlatego idiomatyczne wzorce, takie jak „przypisz i przetestuj”, działają w if-warunki nie posiadające własnej cechy językowej.

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() przypisuje i ocenia po prawej stronie. Jeśli to jest „prawda”, wchodzisz if-Blok. Tło: W Pythonie, := (PEP 572), ponieważ proste przypisania nie są wyrażeniami. W PHP zawsze było inaczej, więc nie ma takiej potrzeby. Dwie rzeczy często prowadzą do błędów.: = (Przypisanie) ma niższy priorytet niż większość operatorów relacyjnych; o ocenie decydują nawiasy.

W przypadku bardziej złożonych wyrażeń należy zawsze używać nawiasów, aby zwiększyć czytelność i przejrzystość. ?? ma swój własny, raczej niski priorytet. To wyjaśnia niespodzianki w wyrażeniach takich jak $x ?? null === null. Bez nawiasów, najpierw null === null oceniane. Lepiej zawsze wyraźnie ująć w nawiasy: ($x ?? null) === null. $a istnieje również poza if-Bloki – prawdopodobnie z błędną wartością.

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

Więc jest jasne, że === 'bar' jest stosowana do przypisanej wartości. Nawiasy kwadratowe są tutaj ważne dla czytelności i priorytetu. W praktyce ten wzorzec pozwala uniknąć niepotrzebnych duplikatów wywołań (np. konstruktora zapytań) poprzez zapisanie wyniku zapytania i jego sprawdzenie. W aplikacjach produkcyjnych, takich jak projekty oparte na platformie Laravel, poniższy wzorzec można zaobserwować częściej.:

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

&& jest zwarciem: prawa część jest oceniana tylko wtedy, gdy lewa część jest prawdziwa. Przypisując instrukcję w górę strumienia, unikasz przypisywania jej poza instrukcją if. To, czy jest to dobra praktyka, zależy od kodu i narzędzi analitycznych Twojego zespołu; semantycznie jest to poprawne. Przynajmniej powinieneś wiedzieć, co kod robi, jeśli natkniesz się na niego w praktyce.

PHP nie potrzebuje operatora „Walrus”, ponieważ przypisania są już wyrażeniami. Dzięki temu możliwe są idiomatyczne wzorce, takie jak „przypisz i przetestuj” – wydajne i zwięzłe. Jednocześnie rosną wymagania dotyczące dyscypliny: obowiązkowe są nawiasy, ścisłe porównania, świadomość prawdziwości/fałszu oraz jasne konwencje zespołowe. Ci, którzy stosują się do tych wytycznych, czerpią korzyści z idei Walrusa bez potrzeby dodatkowej funkcji języka.

Plecy