Nowości z php.internals – return type hint

W jednym z niedawnych wpisów na internalsach, Felipe Pena przedstawił propozycję wprowadzenia typowania zwracanych zmiennych przez funkcje. Jest to funkcjonalność którą znamy z języków statycznie typowanych, gdzie każda funkcja musi mieć zdefiniowany typ zwracanej zmiennej. Propozycja opublikowana jako RFC zawiera patch, który każdy może przetestować u siebie, jeżeli wie jak kompilować php ze źródeł. Patch jest kompatybilny ze znajdującym się w trunku patchem dotyczącym typowania argumentów funkcji (dostępne są pseudotypy scalar i self bodajże).

Przykład (skopiowany z RFC):

function scalar abc($x = NULL) {
	return $x;
}
 
var_dump(abc(1));  // int(1)
var_dump(abc(1.)); // float(1)
var_dump(abc());
/*
PHP Catchable fatal error:  The returned value must be of the type scalar,
called in ... on line 9 and returning in ... on line 4
*/

Jak dla mnie sam feature może być, natomiast składnia nie do końca mi się podoba, wg mnie jest mało czytelna, wolałbym coś a’la ActionScript3:

function foo($arg):bar {
    return $arg+1;
}

A Wy co sądzicie o tym ficzerze ?

  1. cojack says:

    function scalar? WTF? Imo jak będzie taka składnia to jej w życiu nie użyje. Brakuje chłopakom typu danych? To niech idą sobie programować w czymś innym.PHP Miało założenie że w locie ma typy, to jak ma mieć typy w locie to niech nie zmieniają założenia. Bezsensu…

  2. kilas says:

    Podobnie jak @cojack, tak i ja mam negatywne podejście do takiego rozwiązania. O ile wprowadzanie możliwości typowania argumentów na wejściu funkcji mi się podoba, o tyle na wyjściu jest to zbędne. Za dużo komplikowania, kod staje się brzydszy (składnia też mi nie podeszła).

  3. Popieram przedmówców – po co tworzyć kolejne dziwolągi językowe w tym i tak już zaśmieconym języku? Nawet jeśli chcą dodać ten type hinting przy zwracaniu danych, to czemu nie zapożyczyć jeszcze jednej rzeczy ze składni c++ i po prostu zrobić scalar foo()?

  4. ix says:

    A ja pozwolę sobie nie zgodzić z powyższymi komentarzami – dwoma pierwszymi w sumie.
    ‘Miało założenie że w locie ma typy’ – nie rozumiem zdania, ale domyślam się o co mogło chodzić. Cojack’u gdzie takie założenia można znaleźć? O ile dobrze pamiętam nigdy takowych nie było – to że php miało w nosie typy od najwcześniejszych wersji, wcale nie oznacza, że ma tak robić dalej i że wynikało to z jakichkolwiek założeń – widać z resztą że od wielu wersji to się mocno zmienia… Zmienia się na lepsze. PHP to już nie jest język do programowania liczników odwiedzin, czy ksiąg gości (?!).

    “O ile wprowadzanie możliwości typowania argumentów na wejściu funkcji mi się podoba, o tyle na wyjściu jest to zbędne. Za dużo komplikowania, kod staje się brzydszy (składnia też mi nie podeszła).”

    Również nie można się z tym zgodzić. Przynajmniej nie z taką formą uzasadnienia braku potrzeby deklarowania typów dla wartości zwracanych z funkcji/metody. Czy tylko mnie się zdarza wykorzystywać instanceof/implements/is_string/is_float itd.? Nie uważacie, że przy użyciu typehinting właśnie w tym miejscu spowodowało by to znaczne oczyszczenie kodu z totalnie zbędnych IF’ów?

  5. Wojciech Soczyński says:

    Typowanie na wyjściu ma pewien sens, np przy interfejsach. Tam w sumie oczekujemy, że klasa implementująca jakiś interfejs zwróci nam jakąś przewidywaną wartość. No a składnia tak jak mówiłem, jest obrzydliwa ;P

  6. ix says:

    Osobiście bardziej mi nie odpowiadały separatory w przestrzeniach nazw – do których już się przyzwyczaiłem.. Kwestia dni oraz nastawienia 😉

    Ach, odnośnie zaśmiecenia php jeszcze… Tu również należy zauważyć postęp – kolejne wyrzucanie aliasół/DEPRECATED/czy naleciałości z php4 – vide w 5.3.3 konstruktor. No trzeba od czegoś zacząć, a z wiecznym nastawieniem na ‘NIE’ zupełnie nic się nie zmieni. Niestety, znalezienie kompromisu jest ciężkie, a złotego środka który zadowoli dosłownie wszystkich, jest niemożliwe.

  7. Wojciech Soczyński says:

    ix ma racje, poza tym, zrobienie zbyt dużej rewolucji w składni czy api języka spowodowałoby, że nagle duża część kodu przestała by działać, co z biznesowego punktu widzenia dla każdej firmy tworzącej w php było by strzałem w stopę…

  8. Vokiel says:

    Wprowadzenie tego jako opcji, z której można skorzystać lub nie byłoby moim zdaniem dobrym rozwiązaniem. Taki ficzer, możliwy do zastosowania jeśli jest na niego zapotrzebowanie, domyślnie wyłączony.

  9. Wojciech Soczyński says:

    Ja osobiście byłbym ostrożny w dodawaniu nowych opcji do php.ini, każda nowa opcja zmieniająca zachowanie interpretera znacząco utrudnia development…

  10. batman says:

    Nazwa tak samo chybiona jak separator przestrzeni nazw. Funkcjonalność jednak jak najbardziej potrzebna. Jeśli komuś się nie podoba kierunek rozwoju języka, niech zostanie przy wersji 4…
    Obawiam się jedynie, że wprowadzane zmiany są chaotyczne. Zamiast dopychać język irracjonalnymi słowami kluczowymi, autorzy powinni skupić się na ujednoliceniu składni. Robienie większego bałaganu spowoduje, że z nowych funkcjonalności będą korzystać tylko nieliczni. Reszta nadal będzie siedziała w czwartej wersji, z tą różnicą, że przed metodą pojawi się kolejne słowo kluczowe.

  11. Wojciech Soczyński says:

    Mi tam separator przestrzeni nazw nie przeszkadza, nie wiem skąd tyle negatywnych opinii o nim ? Może dlatego, że w innych językach wygląda on inaczej i niektórzy uważają, że skoro gdzie indziej ma jakąś postać to w php też POWINIEN być taki ?

  12. batman says:

    Separator POWINIEN być, podobnie jak w innych językach, taki sam jak pozostałe separatory. Np w C# jest to tylko kropka. Dlaczego w PHP nie może to być tylko strzałka? Czy twórcy języka są tak słabi, że nie potrafili tego zrobić? Czy język jest na tyle źle napisany, że nie było to możliwe?

  13. Wojciech Soczyński says:

    Jest jaki jest i tyle, nie ma żadnych 10-ciu przykazań projektowania języków gdzie by było napisane, że ma być taki sam jak inne separatory. Poza tym pytanie, czy strzałka jest separatorem czy operatorem ? Moim zdaniem jest operatorem, każdy język ma swoje specyficzne cechy za które się go kocha albo nienawidzi i jest to jedno z kryteriów wyboru języka. To tak jak by powiedzieć, że bloki POWINNY być wydzielane wcięciami albo “{…}” albo “begin … end”, nie ma to zupełnie jakiegokolwiek znaczenia.

  14. batman says:

    Przykazań nie ma, ale konsekwencja powinna zostać zachowana. Jak tak dalej pójdzie, to będziemy pisać:
    Foo\Bar/Baz->Bla::Blex

    A nie lepiej to wygląda w takiej postaci?
    Foo.Bar.Baz.Bla.Ble.x

    Skoro mowa o specyficznych elementach języka, to w przypadku PHP jest to burdel.

  15. Wojciech Soczyński says:

    Moim zdaniem wszystko zależy od indywidualnych preferencji, np w Javie wszędzie separatorem jest kropka, również przy wywoływaniu statycznych metod, ja wole php-owy sposób wywoływania statycznych metod przez “::”, jest to dla mnie bardziej czytelne.

    Można na to spojrzeć też z innej perspektywy, różnorodność separatorów promuje jednoznaczność, wiedząc, że jakiś separator czy operator powoduje tylko pewne działanie czytając kod jest nam się łatwiej domyślić co on robi, zamiast sięgać do manuala i czytać co robi dany “znaczek” w jakimś kontekście…

  16. batman says:

    Masz rację, ale tylko w przypadku PHP. Inne języki mają na tyle dobrze rozwinięte IDE, że nie ma potrzeby sięgania do dokumentacji w celu odnalezienia definicji konkretnego elementu.

  17. Wojciech Soczyński says:

    Z tymi IDE to nie jest tak różowo, może Java i C# mają świetne darmowe ide, ale już np. do Pythona ciężko coś znaleźć, nie mówiąc już o innych mniej mainstream’owych językach. Zresztą przywoływanie IDE tutaj wg. mnie nie jest do końca zasadne, ponieważ rozmawiamy o samej składni języka a nie o całym środowisku. Równie dobrze można by dyskutować o szybkości języka, podczas gdy sam język nie może być ani szybki ani wolny, wszystko zależy od implementacji. Wg mnie, czym bardziej jednoznaczna jest składnia języka tym lepiej. Jak dla mnie jest to ważniejsze od konsekwencji (która jest również bardzo ważna). Będąc zbyt konsekwentnym możemy się zapędzić w kozi róg (vel smaczki Pythona).

  18. deirathe says:

    A mi koncepcja się podoba. Ja jestem za pełnym typowaniem zmiennych. Zwiększyłoby to wydajność języka, zmniejszyło ilość błędów związanych właśnie z typami zmiennych, a tym samym luk bezpieczeństwa w aplikacjach.

  19. Wojciech Soczyński says:

    @deirathe, dlaczego chcesz pełne typowanie zmiennych (jak rozumiem statyczne) ? Wtedy w zasadzie moglibyśmy równie dobrze pisać wszystko w C/C++ i pewnie by nawet szybciej działało ?

  20. batman says:

    Deklarowanie typów w argumentach funkcji oraz w zwracanych danych z funkcji spowoduje, że kod “schudnie” o dziesiątki if-ów. Nie raz musiałem dodawać na początku funkcji if-a z is_numeric, czy is_string lub rzutować na konkretny typ danych. Typizacja pozwoli uniknąć sytuacji, w których funkcja, która powinna zwrócić tablicę, zwraca np 0.

  21. Wojciech Soczyński says:

    Jest faktem że schudnie, ale ja mam wrażenie, że deirathe chodziło o wprowadznie statycznego typowania zmiennych: int $var = 5;

  22. Rodzyn says:

    Wystarczyłoby silne typowanie. I nie spłycajmy programowania w C/C++ tylko do statycznego typowania 😉

  23. Wojciech Soczyński says:

    Ja wolałbym jednoznaczne operatory i silne typowanie, wtedy np mamy operator ‘.’ i on konwertuje obie strony z automatu na string, mamy ‘+’ na “szerszą” liczbę, jakiś tam operator “join” na tablice (zamiast “+” przy łączeniu tablic), w przypadkach wątpliwych powinien lecieć po prostu ekception. Jakie są plusy tego rozwiązania ? Po pierwsze krótszy zapis, a po drugie jednoznaczność, poza tym jeden operator dla jednego rodzaju operacji poprawia czytelność kodu.

  24. Artur Świerc says:

    Dzięki typowaniu możemy się pozbyć na starcie wielu ifów. Wystarczy try/catch i po ptokach.
    Tylko tutaj nie podoba mi się ten scalar, może od razu pozostać przy “mixed”?

    Składnia javowa mi odpowiada :)

  25. deirathe says:

    Typowanie jest uzasadnione: wydajnością, mniejszą ilością ifów i luk w oprogramowaniu wynikających z typowania- w wielu aplikacjach takie istnieją. No i typowanie wcale nie przemieni PHP’a w C czy C++ :). Tak jak tu napisał rodzyn.

  26. Wojciech Soczyński says:

    Śmiem twierdzić, że typowanie nie ma nic wspólnego z wydajnością. Java jest statycznie typowana i co ? Niech mi ktoś powie, że jest demonem prędkości. Wydajność jest rzeczą dużo bardziej złożoną niż tylko kwestia typowania w jakimś języku.
    Jeżeli chodzi o ilość luk wynikających z takiego czy innego typowania to prosiłbym o jakieś konkretne opracowanie, bo bez konkretnych badań takie stwierdzenia są po prostu wyssane z palca.
    Każdy ma oczywiście swoje zdanie i preferencje, ale uważam, że nie należy php na siłę zmieniać w inny język. Dzięki swojemu systemowi typów ma pewne zalety (i również wady) których inne języki nie mają. Dlatego osiągnął sukces w tym obszarze rynku do którego jest adresowany. Jeżeli ktoś potrzebuje innych, specyficznych właściwości języka dla swojej aplikacji powinien się zainteresować inną technologią i tyle, wszak Tao mówi, że jest 10000 języków 😉

  27. cojack says:

    No bez przesady z tym typowaniem, macie od groma funkcji i jakiś gównianch przełączników w php do typowania danych, (bool), (int) itp aż do gettype i settype. Chcecie typowania, no to jazda, używajcie go sobie. A ja się spytam po cholerę? Jest doctype? No jest, można w nim zdefiniować jakiego typu jest zwracana wartość, ustawcie sobie przed nią typ do którego chcecie rzutować wartość i będziecie na 100% pewni że dostaniecie to co chcecie. AMEN. Jestem za tym co pisał batman ( o dziwo ) “Zamiast dopychać język irracjonalnymi słowami kluczowymi, autorzy powinni skupić się na ujednoliceniu składni. ” jestem jak najbardziej za.

  28. Wojciech Soczyński says:

    Cojack, miałeś chyba na myśli PHPDoc 😉

  1. There are no trackbacks for this post yet.

Leave a Reply

Notify me of followup comments via e-mail. You can also subscribe without commenting.