# Return type hints

- Thread: https://externals.io/message/25630
- Original archive: https://news-web.php.net/php.internals/25630
- Started by tslettebo@broadpark.no on 2006-09-12T09:40:54+00:00
- Messages: 20
- Reply by email to internals@lists.php.net
- More for agents: search with https://externals.io/search.md?q={query} · JSON API at https://externals.io/api · documentation at https://externals.io/llms.txt

---

## #25630 — tslettebo@broadpark.no — 2006-09-12T09:40:54+00:00

URL: https://externals.io/message/25630#25630

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

---

## #25639 — Marcus Boerger — 2006-09-12T21:00:42+00:00

URL: https://externals.io/message/25630#25639 · In reply to: #25630

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

---

## #25651 — Richard Quadling — 2006-09-13T07:53:29+00:00

URL: https://externals.io/message/25630#25651

> 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!"

---

## #25655 — tslettebo@broadpark.no — 2006-09-13T09:57:08+00:00

URL: https://externals.io/message/25630#25655 · In reply to: #25651

>From: "Richard Quadling" <rquadling@googlemail.com>

> 
> > […]
>
> 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

---

## #25656 — Richard Quadling — 2006-09-13T11:01:44+00:00

URL: https://externals.io/message/25630#25656 · In reply to: #25655

> > […]
>
> > […]
>
> 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!"

---

## #25662 — Brian Moon — 2006-09-13T14:50:39+00:00

URL: https://externals.io/message/25630#25662 · In reply to: #25655

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 =)

---

## #25672 — tslettebo@broadpark.no — 2006-09-13T19:00:12+00:00

URL: https://externals.io/message/25630#25672 · In reply to: #25656

>From: "Richard Quadling" <rquadling@googlemail.com>

> 
> > […]
you
> > […]
leading
> > […]
>
> 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

---

## #25673 — tslettebo@broadpark.no — 2006-09-13T19:11:55+00:00

URL: https://externals.io/message/25630#25673 · In reply to: #25662

> Terje Slettebø wrote:
> > […]
handle
> > […]
hide
> > […]
types
> > […]
 `NULL` 
> > […]
over
> > […]
be
> > […]
>
> 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

---

## #25675 — Brian Moon — 2006-09-13T21:47:45+00:00

URL: https://externals.io/message/25630#25675 · In reply to: #25673

> --- 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 =)

---

## #25678 — tslettebo@broadpark.no — 2006-09-14T05:54:34+00:00

URL: https://externals.io/message/25630#25678 · In reply to: #25675

>From: "Brian Moon" <brianm@dealnews.com>

> > […]
>
> 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

---

## #25683 — Brian Moon — 2006-09-14T14:43:09+00:00

URL: https://externals.io/message/25630#25683 · In reply to: #25678

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 =)

---

## #25692 — tslettebo@broadpark.no — 2006-09-14T17:45:31+00:00

URL: https://externals.io/message/25630#25692 · In reply to: #25683

> Terje Slettebø wrote:
> > […]
so
> > […]
>
> 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.

I completely agree. :) _Then_ I understood you; I thought you meant my
example(code) was "crap"... :)

Another weird thing of PHP's implementation of OO is that propagation of
constructor calls to the base class is not ensured, something I can't for
the life of me understand why, but that deserves its own thread...

Regards,

Terje

---

## #25711 — tslettebo@broadpark.no — 2006-09-14T19:47:20+00:00

URL: https://externals.io/message/25630#25711

(This went to me privately, but in order for this to benefit the discussion,
I reply to the list, as well. Besides, there's now another thread for this,
too)

Hi Richard.

> When would the constructor be called automatically? I've used Delphi
> and you use the inherit verb (or inherited - long time ago - can't
> remember exactly). In PHP parent::__construct (though I think
> parent::__METHOD__ would be cleaner as this removes ambiguity on the
> actual name for all inherited methods).

Well, let's look at C++, which I'm most familiar with. Here's an example:

class Base
{
  protected:
    Base(int a) { ... }
};

class Derived : public Base
{
   public:
    Derived() : Base(123) // Base class constructor called here
    {
      ...
    }
}

In C++, the order of construction goes from the top base class to the most
derived class (although using virtual inheritance complicates that a
little), and destruction happens in the reverse order. One important point
is that the all the base class constructors (if any) are called before the
derived class's constructor body (i.e. what's between "{" and "}") is
entered. This way, you may rely on properly constructed base classes, as
well as initialised member variables, in the constructor. The "Derived() :
Base(123)" syntax is, as may be familiar, an "initialiser list", and may be
used to initialise both any base classes, as well as member variables.

With reference to another thread about uninitialised member variables: In
C++, unless these are initialised using the initialiser list, they will be
default-constructed, so they are also in a well-defined state, on entry to
the constructor body. The same goes for any base classes.

Now, what to do in PHP? As PHP is defined, the best might simply be to give
an error/warning/notice, if a base class hasn't been initialised (i.e. had
its constructor called) when the derived class constructor finishes. As PHP
doesn't have concepts like initialiser lists, or default-construction of
base classes and member variables (unless these are explicitly constructed
in these lists), it may not be much point in trying to do it that way in
PHP.

Regards,

Terje

> 
> > […]
What's
> > […]
not
> > […]
a
> > […]
without
> > […]
for
> > […]

---

## #25712 — Marcus Boerger — 2006-09-14T20:33:53+00:00

URL: https://externals.io/message/25630#25712 · In reply to: #25711

Hello Terje,

Thursday, September 14, 2006, 9:47:20 PM, you wrote:

> (This went to me privately, but in order for this to benefit the discussion,
> I reply to the list, as well. Besides, there's now another thread for this,
> too)

> Hi Richard.

> > […]

> Well, let's look at C++, which I'm most familiar with.

PHP is not C++ and speaking of constructors and destrcutors PHP goes morethe
Delphi way. We do not claim to follow any other language precisely, PHP is
it's own language with its own feature set.

It seems to me that you are using the wrong language. I guess you should
have a look at Phyton.

best regards
marcus

---

## #25715 — tslettebo@broadpark.no — 2006-09-15T06:33:05+00:00

URL: https://externals.io/message/25630#25715 · In reply to: #25712

> > […]
>
> > […]
>
> PHP is not C++

Ah, I was kind of waiting for that one... :) Yet, that says absolutely
nothing about why PHP works the way it does.

> and speaking of constructors and destrcutors PHP goes morethe Delphi way.

If constructors/destructors are not "the PHP way", then why even have them?

> We do not claim to follow any other language precisely, PHP is
> it's own language with its own feature set.

Naturally, but is it unreasonable to think that there's a reason for the way
things work in PHP...? And to ask _why_ PHP doesn't let you ensure that a
class has its constructor/destructor called? Why implement
constructors/destructors in such a way that they may - or may not - be
called? "Do you feel lucky?"

Regards,

Terje

---

## #25716 — tslettebo@broadpark.no — 2006-09-15T06:48:01+00:00

URL: https://externals.io/message/25630#25716 · In reply to: #25712

>From: "Marcus Boerger" <helly@php.net>

> PHP is not C++ and speaking of constructors and destrcutors PHP goes
morethe
> Delphi way.

I'd also like to know _why_ constructors/destructors are less fit for PHP,
than these other languages? How can you be sure that objects of a class are
properly initialised, and that they clean up after themselves? (Yes, I know
the runtime cleans up after them, at script termination, if want to be
sloppy, but that still doesn't cover the constructor case)

---

## #25717 — Marian Kostadinov — 2006-09-15T08:00:21+00:00

URL: https://externals.io/message/25630#25717 · In reply to: #25716

Well, PHP is a loosely typed language. You have much more freedom when you
write a code. Constructors are not an exception. It is very convinient that
you may not call the parent constructor and many people do it, believe me!
And also the flag for the internal classes that has been discussed is maybe
enough for PHP.

2006/9/15, Terje Slettebø <tslettebo@broadpark.no>:
>
> > […]
>
> > […]
> morethe
> > […]
>
> I'd also like to know _why_ constructors/destructors are less fit for PHP,
> than these other languages? How can you be sure that objects of a class
> are
> properly initialised, and that they clean up after themselves? (Yes, I
> know
> the runtime cleans up after them, at script termination, if want to be
> sloppy, but that still doesn't cover the constructor case)

---

## #25721 — Robert Deaton — 2006-09-15T13:30:02+00:00

URL: https://externals.io/message/25630#25721 · In reply to: #25716

> > […]
>
> > […]
> morethe
> > […]
>
> I'd also like to know _why_ constructors/destructors are less fit for PHP,
> than these other languages?

Nobody said that. Marcus said PHP takes a more Delphi-like approach
rather than a C++-like approach. PHP following some other language
rather than your language of choice doesn't mean that its designed
wrong.

-- 
--Robert Deaton

---

## #25871 — Richard Lynch — 2006-09-28T19:50:56+00:00

URL: https://externals.io/message/25630#25871 · In reply to: #25655

> 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

---

## #25872 — Richard Lynch — 2006-09-28T19:54:02+00:00

URL: https://externals.io/message/25630#25872 · In reply to: #25656

> 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
