Τελεστής Walrus σε PHP

Τον Οκτώβριο του 2019, η Python 3.8 παρουσίασε τον τελεστή Walrus (:=) μέσω ΠΕΠ 572 – και έτσι πυροδότησε μια από τις μεγαλύτερες αντιπαραθέσεις στην ιστορία της γλώσσας προγραμματισμού. Η συζήτηση ήταν τόσο έντονη που ο εφευρέτης της Python Γκίντο βαν Ρόσουμ τον Ιούλιο του 2018 – ακόμη και πριν από την κυκλοφορία – η θέση του ως BDFL (Φιλάνθρωπος Δικτάτορας για μια Ζωή). Από τις αρχές του 2019, η Python διοικείται από ένα εκλεγμένο Διοικητικό Συμβούλιο.


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

Το ρήγμα στη διακυβέρνηση προέκυψε αμέσως μετά τη συζήτηση για τον Walrus—μια σπάνια περίπτωση στην οποία ένα χαρακτηριστικό μιας μόνο γλώσσας είχε δομικές συνέπειες. Στη δήλωσή του, ο van Rossum εξήγησε: «Η σταγόνα που ξεχείλισε το ποτήρι ήταν μια πολύ αμφιλεγόμενη Πρόταση Βελτίωσης Python. Αφού την αποδέχτηκα, ο κόσμος πήγε στα μέσα κοινωνικής δικτύωσης όπως το Twitter και είπε πράγματα που με πλήγωσαν προσωπικά».

Συνέχισε: «Τώρα που το PEP 572 τελείωσε, δεν θέλω ποτέ ξανά να παλέψω τόσο σκληρά για ένα PEP και να διαπιστώσω ότι τόσοι πολλοί άνθρωποι απεχθάνονται τις αποφάσεις μου. Θέλω να αποσυρθώ εντελώς από τη διαδικασία λήψης αποφάσεων». Η κριτική δεν προήλθε μόνο από την ευρύτερη κοινότητα, αλλά και από τους βασικούς προγραμματιστές.

Υποστήριξαν ότι ο τελεστής ερχόταν σε αντίθεση με τις θεμελιώδεις αρχές της Python από το Zen της Python —ιδιαίτερα την προτίμηση για απλότητα έναντι της πολυπλοκότητας. Μετά από σχεδόν τρεις δεκαετίες ως ο αδιαμφισβήτητος σχεδιαστής γλωσσών, αυτό σηματοδότησε το τέλος μιας εποχής. Αλλά ενώ η Python έπρεπε να εισαγάγει έναν νέο τελεστή Walrus, διαιρώντας την κοινότητά της στη διαδικασία, τίθεται το ερώτημα: Πώς χειρίζονται άλλες γλώσσες παρόμοιες έννοιες;

Ο τελεστής Python := (Η έκφραση ανάθεσης με ψευδώνυμο "Walrus") δεν υπάρχει στην PHP – επειδή δεν είναι απαραίτητη. Στην PHP, ο τελεστής ανάθεσης = πάντοτε Δήλωση και έκφραση ταυτόχρονα: Μια ανάθεση επιστρέφει την τιμή που έχει ανατεθεί. Αυτός ακριβώς είναι ο λόγος για τον οποίο λειτουργούν ιδιωματικά μοτίβα όπως η «ανάθεση και δοκιμή» if-συνθήκες χωρίς δικό τους γλωσσικό χαρακτηριστικό.

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() αναθέτει και αξιολογεί στη δεξιά πλευρά. Εάν αυτό είναι «αληθές», εισάγετε το if-Μπλοκ. Φόντο: Σε Python, := (PEP 572) επειδή οι απλές αναθέσεις δεν είναι εκφράσεις. Στην PHP, αυτό ήταν πάντα διαφορετικό, επομένως δεν υπάρχει ισοδύναμη ανάγκη. Δύο πράγματα συχνά οδηγούν σε σφάλματα.: = Η (Ανάθεση) έχει χαμηλότερη προτεραιότητα από τους περισσότερους σχεσιακούς τελεστές. Οι παρενθέσεις καθορίζουν την αξιολόγηση.

Σε πιο σύνθετες παραστάσεις, θα πρέπει πάντα να χρησιμοποιείτε παρενθέσεις για να αυξήσετε την αναγνωσιμότητα και τη σαφήνεια. ?? έχει τη δική του, μάλλον χαμηλή προτεραιότητα. Αυτό εξηγεί τις εκπλήξεις σε εκφράσεις όπως $x ?? null === null. Χωρίς παρενθέσεις, πρώτα null === null αξιολογείται. Είναι καλύτερο να τοποθετείτε πάντα ρητά παρενθέσεις: ($x ?? null) === null. $a υπάρχει και εκτός του if-Μπλοκ – πιθανώς με ψευδή τιμή.

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

Είναι λοιπόν σαφές ότι === 'bar' εφαρμόζεται στην τιμή που έχει ανατεθεί. Οι αγκύλες είναι σημαντικές εδώ για την αναγνωσιμότητα και την προτεραιότητα. Στην πράξη, αυτό το μοτίβο αποφεύγει τις περιττές διπλότυπες κλήσεις (π.χ., του εργαλείου δημιουργίας ερωτημάτων) αποθηκεύοντας το αποτέλεσμα του ερωτήματος και στη συνέχεια ελέγχοντάς το. Σε παραγωγικές εφαρμογές, όπως έργα που βασίζονται σε Laravel, το ακόλουθο μοτίβο μπορεί να παρατηρηθεί πιο συχνά.:

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

&& βραχυκύκλωμα: Το δεξί μέρος αξιολογείται μόνο εάν το αριστερό μέρος είναι αληθές. Αντιστοιχίζοντας την πρόταση ανοδικά, αποφεύγετε την αντιστοίχιση της πρότασης εκτός της πρότασης if. Το αν αυτό αποτελεί καλή πρακτική εξαρτάται από τον κώδικα και τα εργαλεία ανάλυσης της ομάδας σας. Σημασιολογικά, είναι σωστό. Τουλάχιστον, θα πρέπει να γνωρίζετε τι κάνει ο κώδικας εάν τον συναντήσετε σε πραγματικό χρόνο.

Η PHP δεν χρειάζεται έναν "τελεστή Walrus" επειδή οι αναθέσεις είναι ήδη εκφράσεις. Αυτό καθιστά δυνατά ιδιωματικά μοτίβα όπως το "assign-and-test" - αποδοτικά και συνοπτικά. Ταυτόχρονα, οι απαιτήσεις για πειθαρχία αυξάνονται: οι παρενθέσεις, οι αυστηρές συγκρίσεις, η επίγνωση του αληθούς/ψευδούς και οι σαφείς ομαδικές συμβάσεις είναι υποχρεωτικές. Όσοι ακολουθούν αυτές τις οδηγίες αποκομίζουν τα οφέλη της ιδέας του Walrus χωρίς να απαιτούν πρόσθετο γλωσσικό χαρακτηριστικό.

Πίσω