Return type hints

php.internals

Terje Slettebø

19 years ago
Hi again. To something different: I've read [1] that return type hints for functions have been considered for PHP 6, possibly even planned. In [1], it says: "We will add support for type-hinted return values." I've searched the archives, but haven't found much on this since about a year ago. Does anyone have the latest on this? Is it planned, dropped, over somebody's "smoking carcass", ;) or what? I've also tried the latest PHP 6 dev-version, a while ago, but it seems it's not in there, yet, at least. If not dropped, have a syntax for this been agreed on? Regards, Terje [1] http://www.php.net/~derick/meeting-notes.html#type-hinted-properties-and-return-values

Marcus Börger

19 years ago
Hello Terje, at some point i might find time to do something. I guess all others who could do something in that area are occupied either by unicode or namespaces. This means we still have this on the todo. We are only open source and all do stuff in our free time.... best regards marcus Tuesday, September 12, 2006, 11:40:54 AM, you wrote:
> Hi again.
> To something different: I've read [1] that return type hints for functions > have been considered for PHP 6, possibly even planned. In [1], it says: "We > will add support for type-hinted return values."
> I've searched the archives, but haven't found much on this since about a > year ago. Does anyone have the latest on this? Is it planned, dropped, over > somebody's "smoking carcass", ;) or what?
> I've also tried the latest PHP 6 dev-version, a while ago, but it seems it's > not in there, yet, at least.
> If not dropped, have a syntax for this been agreed on?
> Regards,
> Terje
> [1] > http://www.php.net/~derick/meeting-notes.html#type-hinted-properties-and-return-values
Best regards, Marcus

Terje Slettebø

19 years ago
Hi Marcus. Thanks for replying. Yes, I understand that very well, having been involved in open source projects, myself, as well [1]. If I felt really strongly for this one, I could do it, myself. :) I was mostly just interested in knowing if this one was still a "go". In our systems, we've prepared for it, thus: function f(Something $value) /** @return SomethingElse */ { // ... } By the way, I appreciate all the work that you and the other developers are doing for PHP. Regards, Terje [1] I've been involved in Loki (http://sourceforge.net/projects/loki-lib), co-authoring the port of the library to Borland C++ (which was non-trivial, given that Loki uses cutting-edge C++), as well as having been project admin. Another project I'm involved in is the C++ "Concept Traits Library" (http://www.neoscientists.org/~tschwinger/boostdev/concept_traits/libs/conce pt_traits/doc/), which is a library to implement "concepts" (like Haskell's "type classes") in C++. Unfortunately, I haven't had a chance to do anything with either of these for a long time, due to work, so I full well understand that people may be busy with other things. :) ----- Original Message ----- From: "Marcus Boerger" <helly@php.net> To: "Terje Slettebø" <tslettebo@broadpark.no> Cc: <internals@lists.php.net> Sent: Tuesday, September 12, 2006 11:00 PM Subject: Re: [PHP-DEV] Return type hints
> Hello Terje, > > at some point i might find time to do something. I guess all others who > could do something in that area are occupied either by unicode or > namespaces. This means we still have this on the todo. We are only open > source and all do stuff in our free time.... > > best regards > marcus > > Tuesday, September 12, 2006, 11:40:54 AM, you wrote: > > > Hi again. > > > To something different: I've read [1] that return type hints for
functions
> > have been considered for PHP 6, possibly even planned. In [1], it says:
"We
> > will add support for type-hinted return values." > > > I've searched the archives, but haven't found much on this since about a > > year ago. Does anyone have the latest on this? Is it planned, dropped,
over
> > somebody's "smoking carcass", ;) or what? > > > I've also tried the latest PHP 6 dev-version, a while ago, but it seems
it's
> > not in there, yet, at least. > > > If not dropped, have a syntax for this been agreed on? > > > Regards, > > > Terje > > > [1] > >
http://www.php.net/~derick/meeting-notes.html#type-hinted-properties-and-return-values

Richard Quadling

19 years ago
On 12/09/06, Terje Slettebø <tslettebo@broadpark.no> wrote: > function f(Something $value) /** @return SomethingElse */ > { > // ... > } > One of the good things about PHP is the loose typing (1.00 == 1 == "1" sort of thing as I understand it). This has been useful. But one of the first things we are told about using PHP ITRW is to always validate user input and to make sure you only accept what you know to be valid data. More often than not, this ends up casting the data to a specific type (number of payments - int, date of birth - date, email address - string (or user type of email), delete - Boolean). You may even have functions which require/expect a parameter to be of a specific type. We can already use type hinting for arrays and classes for parameters. Type hinting could be extended to all types for user functions. Even the possibility of accepting multiple types for a single parameter could be used to support a mixed type. Recently we had a discussion about parameter overloading on methods. You can probably use __magic to produce the effect of parameter overloading. Whilst casting the return type is easy to do, having the return type as part of the function declaration would be very useful for auto-documentors. As for syntax, I would go with ... type function f(type $value) It would be useful to also have VOID as a return type, but that may be open for discussion. But mixed type returns (normal type -string/int/real/Boolean - for valid results AND Boolean False for failure) would need to be considered. -- ----- Richard Quadling Zend Certified Engineer : http://zend.com/zce.php?c=ZEND002498&amp;r=213474731 "Standing on the shoulders of some very clever giants!"

Terje Slettebø

19 years ago
>From: "Richard Quadling" <rquadling@googlemail.com>
> On 12/09/06, Terje Slettebø <tslettebo@broadpark.no> wrote: > > function f(Something $value) /** @return SomethingElse */ > > { > > // ... > > } > > One of the good things about PHP is the loose typing (1.00 == 1 == "1" > sort of thing as I understand it). This has been useful.
I'd say that's debatable. :) Yes, it can make it more convenient to handle data coming from outside the script (such as forms), but it can also hide bugs. While it can be argued that conversions between, say, arithmetic types (int and floats) may be useful, allowing conversion from something like NULL to empty string, integer 0, etc. (as PHP does) may be going a little over board, as an uninitialised variable (such as a member variable) may not be easily discovered. It's interesting to note that Java (a newer language than C++) actually has a stronger type system (at least in some respects) than C++: While C/C++ allows things like implicit conversion between int/float/pointer and bool (a legacy from C), Java does not, and if you think about it, it makes sense to disallow that, as boolean values are conceptually different from these.
> But one of the first things we are told about using PHP ITRW is to > always validate user input and to make sure you only accept what you > know to be valid data.
True, and at least with regard to function calls, with type hinting (as you mention below), that testing is done for you, so you don't have to, leading to less code and syntactic noise (and possibly better performance).
> We can already use type hinting for arrays and classes for parameters. > Type hinting could be extended to all types for user functions.
I asked about this about 1 1/2 year ago (as well as the possibility of function overloading - which _would_ be at least theoretically possible, now that we have type hints), on this list, but got a very negative response to that... So... I figured the PHP community wasn't ready for that, or didn't think it fit the language. I still think type hints for fundamental types could be a good idea, for catching errors early, such as passing NULL to a function expecting string (as long as it avoids the usual implicit conversion). Anyway, with Sara Golemon's operator overloading extension, it's possible to make your own Integer, Float, String, etc. types, and use them basically as built-in types, making it possible to use them for type hints.
> Even > the possibility of accepting multiple types for a single parameter > could be used to support a mixed type.
One way to do that could be to create a user-defined "variant" type (or "mixed" type, as you say), that may contain a specified number of types. Yes, I know that in PHP, basically all variables are "variants", but with a class, you may restrict it to just a few specific ones. Likewise, it's possible to create type-checked tuple types (a sequence of values, of specified types), and ditto arrays. As it's mentioned in the user-contributed notes on autoloading, you may even "abuse" the autoloader to implement "parametric types" (like templates in C++). For example, if you write: function f(Array_string $value) { } The autoloader may "synthesise" the "Array_string" type, from a generic typed array class, to produce a custom array type that enforces numerical indexes and string values (the above is really short for "Array_int_string", where "int" gives the key type, and "string" gives the value type). Again, this may be useful for expressing intentions in code, as well as runtime-enforced conditions.
> Recently we had a discussion about parameter overloading on methods. > You can probably use __magic to produce the effect of parameter > overloading.
I'm not sure what you mean by "parameter overloading". Do you mean function overloading? Yes, you can "simulate" that, using e.g. a dispatch based on func_get_args(), but it's rather inelegant, compared to real overloading. Also, it's impossible to overload existing functions in the standard library (if it was, you could provide your own count(), array_*-functions, etc. for user-defined array types.
> Whilst casting the return type is easy to do, having the return type > as part of the function declaration would be very useful for > auto-documentors.
Not only that, but in my opinion the more important thing that you may enforce a return type (forgetting to return a proper value from a function could be caught this way).
> As for syntax, I would go with ... > > type function f(type $value)
Yes, that's _one_ possibility. Let's see it in "all its glory" (i.e. with a lot of other qualifiers): public abstract SomeClass function f(SomeOther $value) Hm, maybe. Another alternative might be (closer to C/C++/Java syntax): <qualifiers> function <return type> <function name>(<parameters>) E.g.: public abstract function Someclass f(SomeOther $value)
> It would be useful to also have VOID as a return type, but that may be > open for discussion.
Yes, or perhaps more natural for PHP, "null".
> But mixed type returns (normal type -string/int/real/Boolean - for > valid results AND Boolean False for failure) would need to be > considered.
Perhaps something similar to current type hints could be used here, where you may allow the specified type _or_ null (if you default the argument). However, some kind of variant may be sufficient, here (i.e. no language support for mixed result needed), such as a type (class) like "Variant_SomeType_null", where you may check the resulting value (using implicit conversion to string via __toString()) if it's null (or false, or whatever). Regards, Terje

Richard Quadling

19 years ago
On 13/09/06, Terje Slettebø <tslettebo@broadpark.no> wrote: > >From: "Richard Quadling" <rquadling@googlemail.com> > > > On 12/09/06, Terje Slettebø <tslettebo@broadpark.no> wrote: > > > function f(Something $value) /** @return SomethingElse */ > > > { > > > // ... > > > } > > > > But one of the first things we are told about using PHP ITRW is to > > always validate user input and to make sure you only accept what you > > know to be valid data. > > True, and at least with regard to function calls, with type hinting (as you > mention below), that testing is done for you, so you don't have to, leading > to less code and syntactic noise (and possibly better performance). The issue then becomes what would happen to a value of the wrong type? You either have the option of using PHP's own internal casting mechanism, so f(int $i_int_expected) would internally cast the supplied parameter as an int or you have to produce a WARNING with a "parameter of the wrong type" message. But then what is passed to the function? This would have to be determined somehow. -- ----- Richard Quadling Zend Certified Engineer : http://zend.com/zce.php?c=ZEND002498&amp;r=213474731 "Standing on the shoulders of some very clever giants!"

Ron Korving

19 years ago
""Richard Quadling"" <rquadling@googlemail.com> schreef in bericht news:10845a340609130401q20127db0yf8e30f781622c63@mail.gmail.com...
> On 13/09/06, Terje Slettebø <tslettebo@broadpark.no> wrote:
..........
> The issue then becomes what would happen to a value of the wrong type? > > You either have the option of using PHP's own internal casting > mechanism, so f(int $i_int_expected) would internally cast the > supplied parameter as an int or you have to produce a WARNING with a > "parameter of the wrong type" message. But then what is passed to the > function? This would have to be determined somehow.
I think it would make sense to turn the value into NULL when the casting fails. And honestly, I would love this kind of type hinting. It has to be smart in the sense that if I say "double", and it's a string containing "0.123", it will either be casted to a double (which may be unfortunate, since floats and doubles are inaccurate), or simply let through as a string, because it follows double formatting (that being /-?[0-9]+(\.[0-9]+)?/). But this way type hinting for core types is only optional for people and it's not as strict as in the vast majority of other languages out there. This kind of smart type hinting would be simply perfect. Ron

Terje Slettebø

19 years ago
>From: "Richard Quadling" <rquadling@googlemail.com>
> On 13/09/06, Terje Slettebø <tslettebo@broadpark.no> wrote: > > >From: "Richard Quadling" <rquadling@googlemail.com> > > > > > On 12/09/06, Terje Slettebø <tslettebo@broadpark.no> wrote: > > > > function f(Something $value) /** @return SomethingElse */ > > > > { > > > > // ... > > > > } > > > > > > But one of the first things we are told about using PHP ITRW is to > > > always validate user input and to make sure you only accept what you > > > know to be valid data. > > > > True, and at least with regard to function calls, with type hinting (as
you
> > mention below), that testing is done for you, so you don't have to,
leading
> > to less code and syntactic noise (and possibly better performance). > > The issue then becomes what would happen to a value of the wrong type?
Getting a fatal error, like with today's parameter type hinting? As an aside: I find it a little ironic that something called "type _hint_" gives a _fatal_ error... (Not even a chance for the error handler to catch it...) It's as if it talks with two tongues: "Oh, yes, we are very liberal - we only _hint_ at what we accept. (Then, with much lower voice) However, we do stop with a fatal error, if you try something else..." "PHP: Desperately wants to be loosely typed, yet desperately wants to be strongly typed...? :)"
> You either have the option of using PHP's own internal casting > mechanism, so f(int $i_int_expected) would internally cast the > supplied parameter as an int or you have to produce a WARNING with a > "parameter of the wrong type" message. But then what is passed to the > function? This would have to be determined somehow.
I'm not sure what you talk about, here? We already _have_ type hints for arguments... Regards, Terje

Richard Lynch

19 years ago
On Wed, September 13, 2006 6:01 am, Richard Quadling wrote:
> The issue then becomes what would happen to a value of the wrong type? > > You either have the option of using PHP's own internal casting > mechanism, so f(int $i_int_expected) would internally cast the > supplied parameter as an int or you have to produce a WARNING with a > "parameter of the wrong type" message. But then what is passed to the > function? This would have to be determined somehow.
Could I just point out that MANY PHP functions do things like this: /* returns int for blah blah * returns false in case of error */ function foo($x){ if (world_has_ended()) return false; } So if you're going to insist on type hints, can we not at least make it sensible and have syntax like: int|bool function foo (){ } So foo() returns int or bool. Otherwise, you end up with (int) false strewn all through your code, and it looks all messy. There's a REASON why I'm writing PHP and not C, folks... :-)
-- Like Music? http://l-i-e.com/artists.htm

Brian Moon

19 years ago
Terje Slettebø wrote:
> I'd say that's debatable. :) Yes, it can make it more convenient to handle > data coming from outside the script (such as forms), but it can also hide > bugs. While it can be argued that conversions between, say, arithmetic types > (int and floats) may be useful, allowing conversion from something like NULL > to empty string, integer 0, etc. (as PHP does) may be going a little over > board, as an uninitialised variable (such as a member variable) may not be > easily discovered.
IMHO, that is covered by === and the NOTICE error level.
-- Brian Moon ------------- http://dealnews.com/ Its good to be cheap =)

Terje Slettebø

19 years ago
> Terje Slettebø wrote: > > I'd say that's debatable. :) Yes, it can make it more convenient to
handle
> > data coming from outside the script (such as forms), but it can also
hide
> > bugs. While it can be argued that conversions between, say, arithmetic
types
> > (int and floats) may be useful, allowing conversion from something like
NULL
> > to empty string, integer 0, etc. (as PHP does) may be going a little
over
> > board, as an uninitialised variable (such as a member variable) may not
be
> > easily discovered. > > IMHO, that is covered by === and the NOTICE error level.
Scenario: --- Start --- class Something { public function __construct() { // Oops, forgot to initialise $this->something... } public function f() { return $this->something; } private $something; } error_reporting(E_ALL); $something=new Something; echo $something->f()+10; // Prints "10". --- End --- This will run without any notices, warnings or errors. If we meant to initialise Something::something to a value, then there's no way to detect that in f() (other than manual type-checking), since we can't specify the type for Something::f()'s return type. Had we been able to specify e.g. "int" as the return type, the call to Something::f() would give us an error message, alerting us to the problem. As the program stands, it has a silent bug... How would you solve this with === or E_ALL? Regards, Terje

Brian Moon

19 years ago
> --- Start --- > > class Something > { > public function __construct() > { > // Oops, forgot to initialise $this->something... > } > > public function f() > { > return $this->something; > } > > private $something; > } > > > error_reporting(E_ALL); > > $something=new Something; > > echo $something->f()+10; // Prints "10".
If you can't trust the return values of your methods, I would use: $var = $something->f(); if($var!==NULL){ echo $var+10; // Prints "10". } However, its crap like this that reminds me why I don't use PHP OOP for all my code. I can find no non-OOP code that behaves this way. Even my favorite PHP trick, using settype() to initialize vars, does not set the var to NULL.
-- Brian Moon ------------- http://dealnews.com/ Its good to be cheap =)

Terje Slettebø

19 years ago
>From: "Brian Moon" <brianm@dealnews.com>
> > --- Start --- > > > > class Something > > { > > public function __construct() > > { > > // Oops, forgot to initialise $this->something... > > } > > > > public function f() > > { > > return $this->something; > > } > > > > private $something; > > } > > > > > > error_reporting(E_ALL); > > > > $something=new Something; > > > > echo $something->f()+10; // Prints "10". > > If you can't trust the return values of your methods, I would use: > > $var = $something->f(); > > if($var!==NULL){ > echo $var+10; // Prints "10". > }
Right... And you can always use return codes, instead of exceptions or trigger_error(). The problem is that there's nothing that _enforces_ this checking, and since it adds verbosity, it's typically not done. If you don't believe me have a look at some of all of the C code out there, which typically to a large degree don't check return values (and it shows... Programs segfaulting and the like, if something unexpected happens), as it makes the program convoluted and messy, and is easily forgotten. It's for reasons like this that exceptions (and possibly trigger_error()) were invented in the first place. It's similar with the example above: Type-checked return values means you don't have to write all these tedious manual checks, just to ensure program correctness (and had the return type hint been mandatory, there's no way you could forget it or not bother with it, either)..
> However, its crap like this that reminds me why I don't use PHP OOP for > all my code. I can find no non-OOP code that behaves this way.
The above was a contrived example, meant to illustrate the point. What's so bad about it? That it doesn't check the return value? Well... having to check the return value, to ensure things didn't go wrong is something I left a looong time ago, when I was programming C, before I started with C++ and Java, which gives better ways of handling this, and have only had to take it up again, in PHP.
> Even my > favorite PHP trick, using settype() to initialize vars, does not set the > var to NULL.
settype() is still a manual operation - there's no way to automatically guarantee initialisation. In a language like C++, the class members are default-initialised, unless you explicitly initialise them, so there's no way you can forget it or ignore it. The result: More robust programs. Regards, Terje

Brian Moon

19 years ago
Terje Slettebø wrote:
> The above was a contrived example, meant to illustrate the point. What's so > bad about it? That it doesn't check the return value?
I am not worried about the return value of the method. I am concerned that $this->something is unset yet does not throw a notice. This is only true for properties of objects. Any other variable in PHP does not behave this way. IMHO, PHP should either initialize that variable to a default type and value or throw a notice when you try and use it without setting its value.
-- Brian Moon ------------- http://dealnews.com/ Its good to be cheap =)

Richard Lynch

19 years ago
On Wed, September 13, 2006 4:57 am, Terje Slettebø wrote:
> I'd say that's debatable. :) Yes, it can make it more convenient to > handle > data coming from outside the script (such as forms), but it can also > hide > bugs. While it can be argued that conversions between, say, arithmetic > types > (int and floats) may be useful, allowing conversion from something > like NULL > to empty string, integer 0, etc. (as PHP does) may be going a little
Except that it's also very handy often-times.
> over > board, as an uninitialised variable (such as a member variable) may > not be > easily discovered.
You still haven't discovered E_NOTICE???... [much deleted] A year from now, are the purists going to be making missing type hints E_STRICT and E_DEPRECATED? :-) There's a point where I wonder why some people (not necessarily Terje) are using PHP at all. It's obvious they want an entirely different language... :-)
-- Like Music? http://l-i-e.com/artists.htm