2016-05-12 6 views
1

HHVM 3.9 ist nicht so ein Fan von ternären Aussagen mit benannten Funktionen, auch wenn fun() passiert, aber ≥ 3.10 ist völlig in Ordnung mit ihnen. Es scheint, als ob dies eine der wenigen Fällen ist jedoch wegen 3.9 tut genannten Funktionen von konkreten Funktionen zurücknehmen, sowie die Annahme in andere Funktionen übergeben genannten Funktionen (3v4l):Sind Hack namens Funktionen voll erstklassige Bürger?

<?hh 
echo ((() ==> fun('strlen'))())('Hello'); // 5 
echo (($f, $v) ==> $f($v))(strlen, 'Hello'); // 5 + Notice: Use of undefined constant strlen - assumed 'strlen' 
echo (true ? strlen : intval)('100'); // Fatal error: syntax error, unexpected '(', expecting ',' or ';' on line 3 

Was hat sich verändert zwischen 3.9 und 3.10? Gibt es Fälle in HHVM ≥ 3.10 wo benannte Funktionen nicht referenziert werden können und auf diese Weise verwendet werden?

Antwort

1

Zuerst beim Schreiben Hack, don't write your code at toplevel; the hh_client typechecker can't check anything at toplevel. Und 3v4l führt den Typchecker überhaupt nicht aus, Sie müssen ihn lokal ausführen.

Das sagte, nein, Hack hat nicht wirklich erstklassige Funktionen. Das meiste Verhalten hat es hier von PHP geerbt, das sie auch nicht hat. Damals, als ich im Hack-Team arbeitete, haben wir eine Menge Ideen dafür ausgetauscht, sie in die Sprache zu integrieren. Es ist eine offensichtliche Ergänzung und Notwendigkeit. Aber die Notwendigkeit war nie ziemlich stark genug, so dass wir uns hinsetzten und tatsächlich die Details sowohl für das Typsystem als auch die Laufzeitauswirkungen ausgearbeitet haben; vor allem, wie man einige der Probleme des Scoping ausarbeitet, die die derzeitigen Callables haben. Anonyme Funktionen füllen genug aus, vor allem mit Hack's short lambda syntax, dass es immer etwas dringender zu tun gab.

Also Hack hat nur normale aufrufbare Formen von PHP; fun is one of a few special functions which give information to the typechecker that the string you specified actually represents a function, so kann der Typchecker die Typanalyse durchführen. Aber am Ende des Tages, fun läuft nur auf die üblichen PHP aufrufbaren Formen mit ein bisschen mehr Magie in der Typchecker kocht.

In Bezug auf das Verhalten, das Sie in Ihrem 3v4l-Link angeben. Die Verwendung von strlen und intval würde zu einem Typfehler in Hack führen, da es sich um syntaktische Konstanten handelt, aber Konstanten mit diesen Namen nicht existieren, da Hack keine erstklassigen Funktionen hat - oder wenn der Code nicht vorhanden wäre Toplevel und Sie haben den Typchecker ausgeführt. Warum es einen Parse-Fehler in HHVM 3.9 (der die "Invalid Constant" -Fehler maskiert, die Sie in 3.10 sehen) verursacht, bin ich nicht 100% sicher. Gemessen von this example, die in PHP7 und HHVM 3.10, aber nicht PHP5 und HHVM 3.9 funktioniert, ist es ein PHP7 feature that is backwards compatible and so is always enabled in HHVM.

+0

Ah, also ist das eher eine Frage dessen, was _PHP7_ mit benannten Funktionen unterstützt. Ich bin neugierig, warum die "Notiz ... undefinierte Konstante" durch "Spaß" unterdrückt wird, wenn sie "nur auf die üblichen aufrufbaren Formen von PHP herunter läuft", aber es ist ein kleines Detail, das ich vermute. Zur Klarstellung: Außerhalb von Typfehlern gibt es keine Fälle, in denen 'fun '(' foo ')' und 'foo' anders interpretiert werden, oder? – concat

+0

Die Typfehler sind der gesamte Punkt; sie sind im Typchecker eindeutig nicht dasselbe. Allerdings [zur Laufzeit ja] (https://github.com/facebook/hhvm/blob/cc7f35361e5dfc934631e1e19e2f2b9f66890391/hphp/system/php/lang/fun.ns.php#L31-L67). EDIT: Beachten Sie, dass die Kommentare in dem Code, den ich verlinkt, Code auf Toplevel haben und als solcher falsch sind, aber [die normalen öffentlichen Dokumente] (https://docs.hhvm.com/hack/callables/special-functions) haben Recht . –