# [RFC] Strict type hints (parameter and return value)

- Thread: https://externals.io/message/37068
- Original archive: https://news-web.php.net/php.internals/37068
- Started by Felipe Pena on 2008-04-17T14:42:46+00:00
- Messages: 54
- Page 1 of 3: messages 1 to 25 (25 per page, add `?page=N` to the URL)
- Next page: https://externals.io/message/37068.md?page=2
- 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

---

## #37068 — Felipe Pena — 2008-04-17T14:42:46+00:00

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

Hi.

Well, thinking better about the behavior of type hinting, i decided to
change the proposal for strict type. I.e. don't accept numeric string
as an intenger, etc.

If anyone wants use type hinting, i believe that it should be strict.
Otherwise, it makes more sense to not use it.

Examples, patches and tests: http://wiki.php.net/rfc/typehint


-- 
Regards,
Felipe Pena.

---

## #37071 — Paul Biggar — 2008-04-17T15:17:16+00:00

URL: https://externals.io/message/37068#37071 · In reply to: #37068

Hi Felipe,

Thanks for making the change. This is much more consistent. It remains
that there is no 'scalar' or 'numeric' hint. Are you planning on
including them?

I also wonder about allowing `NULL` for an 'array' type hint. Is this
acceptable? The patch seems to indicate it is. If so, why is this
allowed?


Thanks,
Paul


> Hi.
>
>  Well, thinking better about the behavior of type hinting, i decided to
>  change the proposal for strict type. I.e. don't accept numeric string
>  as an intenger, etc.
>
>  If anyone wants use type hinting, i believe that it should be strict.
>  Otherwise, it makes more sense to not use it.
>
>  Examples, patches and tests: http://wiki.php.net/rfc/typehint
>
>
>  --
>  Regards,
>  Felipe Pena.
>
>  --
>  
>  
>
>



-- 
Paul Biggar
paul.biggar@gmail.com

---

## #37072 — Felipe Pena — 2008-04-17T15:24:12+00:00

URL: https://externals.io/message/37068#37072 · In reply to: #37071

Em Qui, 2008-04-17 às 17:17 +0200, Paul Biggar escreveu:
> Hi Felipe,
> 
> Thanks for making the change. This is much more consistent. It remains
> that there is no 'scalar' or 'numeric' hint. Are you planning on
> including them?

No, i'm not planning to do that.

> 
> I also wonder about allowing `NULL` for an 'array' type hint. Is this
> acceptable? The patch seems to indicate it is. If so, why is this
> allowed?

I added yesterday an information about that in the doc:

"Functions are now able to force parameters to be objects (by specifying
the name of the class in the function prototype) or arrays (since PHP
5.1). However, if `NULL` is used as the default parameter value, it will
be allowed as an argument for any later call."

> 
> 
> Thanks,
> Paul
> 
> 
> > […]
> 
> 
> 
-- 
Regards,
Felipe Pena.

---

## #37073 — Paul Biggar — 2008-04-17T15:29:53+00:00

URL: https://externals.io/message/37068#37073 · In reply to: #37072

> > […]
>
>  No, i'm not planning to do that.

Ah, I should have been more specific. I meant to ask for those
changes. Can I ask why not?



> > […]
>
>  I added yesterday an information about that in the doc:
>
>  "Functions are now able to force parameters to be objects (by specifying
>  the name of the class in the function prototype) or arrays (since PHP
>  5.1). However, if `NULL` is used as the default parameter value, it will
>  be allowed as an argument for any later call."

That doesnt explain why its allowed. Can you elaborate?



Thanks,
Paul



> > […]
>  --
>  Regards,
>  Felipe Pena.
>
>



-- 
Paul Biggar
paul.biggar@gmail.com

---

## #37074 — Christian Schneider — 2008-04-17T15:41:39+00:00

URL: https://externals.io/message/37068#37074 · In reply to: #37068

Felipe Pena wrote:
> Well, thinking better about the behavior of type hinting, i decided to
> change the proposal for strict type. I.e. don't accept numeric string
> as an intenger, etc.

While it is now consistent with `is_int()` it means we end up with strict
but also stupid interfaces and hence lots of silly type conversions in
application code using such a function.
This is especially annoying as you normally have very few
implementations of a function but lots of code calling it.

You basically 'progressed' from
	function foo($x) { $x = (int)$x; ... }	# One place where type is
ensured or converted
	foo(42);
	foo(CONSTANT_42);
	foo($x);
	foo($db->x);
to
	function foo(int $x) { ... }
	foo(42);
	foo((int)CONSTANT_42);	# If you are not 100% about type
	foo((int)$x);		# If you are not 100% about type
	foo((int)$db->x);	# DBs normally return strings

- Chris

---

## #37075 — Chris Stockton — 2008-04-17T15:54:53+00:00

URL: https://externals.io/message/37068#37075 · In reply to: #37074

I like this patch, it adds a feature which a lot of companies and code base
would surely implement without breaking anything. The only thing I do not
like has already been mentioned, numeric and scalar are not included.

The one thing I don't dislike, but am unsure of the ease to understand by
users is the return type hinting syntax, using type casting. Maybe I am
wrong but do you think users might get confused by it since it already has
an existing purpose of transforming values to other types, maybe they will
think at glance it transforms the return type to something else? Of course
it would be fault of there own for not reading, but is it NATURAL to use the
existing type hints for it?

Why not:
function int foo($foo) { }

I understand the problem with adding the INT as a keyword, and how that
maybe:
function int int($foo) { }

is awkward, but would be rare and seems to be more correct. I know it would
be more difficult to implement the latter but it should not be impossible
should it?

Just throwing it out there, it is a nice patch and a nice feature for A LOT
of people even though it is not exactly the php way, but all things must
evolve.

-Chris

---

## #37077 — Sam Barrow — 2008-04-17T15:58:27+00:00

URL: https://externals.io/message/37068#37077 · In reply to: #37068

In this case, I'd suggest using my patch for parameter type hinting. It
utilizes the current type hinting system for minimal code changes,
whereas this is a whole new set of functionality. It also has scalar and
number types, and supports objects with __tostring methods.


> Hi.
> 
> Well, thinking better about the behavior of type hinting, i decided to
> change the proposal for strict type. I.e. don't accept numeric string
> as an intenger, etc.
> 
> If anyone wants use type hinting, i believe that it should be strict.
> Otherwise, it makes more sense to not use it.
> 
> Examples, patches and tests: http://wiki.php.net/rfc/typehint
> 
> 
> -- 
> Regards,
> Felipe Pena.

---

## #37076 — Pierre Joye — 2008-04-17T15:59:55+00:00

URL: https://externals.io/message/37068#37076 · In reply to: #37074

Hi Christian,

On Thu, Apr 17, 2008 at 5:41 PM, Christian Schneider
<cschneid@cschneid.com> wrote:
> Felipe Pena wrote:
> > […]
>
>  While it is now consistent with `is_int()` it means we end up with strict
>  but also stupid interfaces and hence lots of silly type conversions in
>  application code using such a function.

>  This is especially annoying as you normally have very few
>  implementations of a function but lots of code calling it.
>
>  You basically 'progressed' from
>         function foo($x) { $x = (int)$x; ... }  # One place where type is
>  ensured or converted
>         foo(42);
>         foo(CONSTANT_42);
>         foo($x);
>         foo($db->x);
>  to
>         function foo(int $x) { ... }
>         foo(42);
>         foo((int)CONSTANT_42);  # If you are not 100% about type
>         foo((int)$x);           # If you are not 100% about type
>         foo((int)$db->x);       # DBs normally return strings

You slowly understand the idea behind strict type hinting, you should
add these examples to the wiki ;-)

More seriously, it should be about time to stop to argue about why you
consider it useless, not the PHP way, too many to write, usw...  But
to consider the proposal and the patch on their own and if the feature
will be added, is it the way we like to have it or how can it be
improved (keeping the goal in mind).

Whether PHP will have it or not is not yet decided, as far as I can
say. But I really like to have it (I don't feel like explaining again
why I like it is worth the bandwidth :)

Cheers,
-- 
Pierre
http://blog.thepimp.net | http://www.libgd.org

---

## #37078 — Sam Barrow — 2008-04-17T15:59:56+00:00

URL: https://externals.io/message/37068#37078 · In reply to: #37073

> 
> > […]
> 
> Ah, I should have been more specific. I meant to ask for those
> changes. Can I ask why not?

I think scalar is very important. For any function where you are
interacting with the database values or echoing output, scalar is very
useful.

> > […]
> 
> That doesnt explain why its allowed. Can you elaborate?
> 

The way i do it is to only allow null if null is the default. This way,
people cannot skip parameters using null unless specifically allowed to
in the function declaration.

> 
> Thanks,
> Paul
> 
> 
> 
> > […]
> 
> 
> 
> -- 
> Paul Biggar
> paul.biggar@gmail.com

---

## #37079 — Sam Barrow — 2008-04-17T16:01:36+00:00

URL: https://externals.io/message/37068#37079 · In reply to: #37075

> I like this patch, it adds a feature which a lot of companies and code base
> would surely implement without breaking anything. The only thing I do not
> like has already been mentioned, numeric and scalar are not included.
> 
> The one thing I don't dislike, but am unsure of the ease to understand by
> users is the return type hinting syntax, using type casting. Maybe I am
> wrong but do you think users might get confused by it since it already has
> an existing purpose of transforming values to other types, maybe they will
> think at glance it transforms the return type to something else? Of course
> it would be fault of there own for not reading, but is it NATURAL to use the
> existing type hints for it?
> 
> Why not:
> function int foo($foo) { }
> 
> I understand the problem with adding the INT as a keyword, and how that
> maybe:
> function int int($foo) { }

I like this alot better too, the only downside is compatibility
problems.

> is awkward, but would be rare and seems to be more correct. I know it would
> be more difficult to implement the latter but it should not be impossible
> should it?
> 
> Just throwing it out there, it is a nice patch and a nice feature for A LOT
> of people even though it is not exactly the php way, but all things must
> evolve.
> 
> -Chris

---

## #37080 — Chris Stockton — 2008-04-17T16:18:50+00:00

URL: https://externals.io/message/37068#37080 · In reply to: #37079

> I like this alot better too, the only downside is compatibility
> problems.


Can you explain, I understand; in partial the problem but I am curious what
can not be solved through added logic?

---

## #37081 — Sam Barrow — 2008-04-17T16:31:03+00:00

URL: https://externals.io/message/37068#37081 · In reply to: #37080

> 
> 
> > […]
> 
> 
> Can you explain, I understand; in partial the problem but I am curious what
> can not be solved through added logic?

function int() {
}

PHP won't know if this is a return type hint or function name. This
specific case might be solvable with added logic though, I really don't
know how to do it or how hard it would be; alot of this is done in the
parser which I am only slightly familiar with.

---

## #37082 — Stanislav Malyshev — 2008-04-17T16:33:22+00:00

URL: https://externals.io/message/37068#37082 · In reply to: #37068

Hi!

> If anyone wants use type hinting, i believe that it should be strict.
> Otherwise, it makes more sense to not use it.

Just for the record, I see absolutely no sense in strict type hints. 
While there might be some use cases when you want to save typing by 
having function convert the arguments instead of you doing it manually - 
there's absolutely no sense to check types strictly in PHP, especially 
taking into attention that no API ever worked that way, and that it 
would force users to surround each call to such function with checks for 
argument types, since PHP can not have static type control. Using such 
feature would be a nightmare.

-- 
Stanislav Malyshev, Zend Software Architect
stas@zend.com   http://www.zend.com/
(408)253-8829   MSN: stas@zend.com

---

## #37083 — Chris Stockton — 2008-04-17T16:50:48+00:00

URL: https://externals.io/message/37068#37083 · In reply to: #37082

> Just for the record, I see absolutely no sense in strict type hints. While
> there might be some use cases when you want to save typing by having
> function convert the arguments instead of you doing it manually - there's
> absolutely no sense to check types strictly in PHP, especially taking into
> attention that no API ever worked that way, and that it would force users to
> surround each call to such function with checks for argument types, since
> PHP can not have static type control. Using such feature would be a
> nightmare.


You have a good point, but I think it might have slightly more benefit then
we may think. Less code bloat for the checks many of us already enforce is
one.

Doing some greps in the Zend Framework is a good example.

grep -riE -A2
"is_(binary|bool|double|float|int|long|null|numeric|object|real|resource|scalar|string|unicode)"
*

I get tons of parameter checks which throw exceptions, so users already have
to check there code prior to sending it up the chain. And by "Check" a good
framework, like Zend, will do the boundary checking for you, so as long as
it is the right type you are ok.

So:
function foo($var) { if(!is_int($var)) { throw new exception('not int'); }}

Turns to:
function foo(int $bar) { }

which is called like this in both cases, maybe with a try catch etc etc:
foo((int) $baz['bar']);

-Chris

---

## #37084 — Stanislav Malyshev — 2008-04-17T16:57:12+00:00

URL: https://externals.io/message/37068#37084 · In reply to: #37083

Hi!

> So:
> function foo($var) { if(!is_int($var)) { throw new exception('not int'); }}

What's the use of such code? If $var is '1' and not 1, what's the use of 
throwing an exception and having to handle it later (basically by 
failing the task, since you don't know how to do foo() now) - instead of 
just doing with that 1 what was intended for? There's no any difference 
between 1 and '1' that can be important to anybody. Only difference is 
the way it is represented in underlying bits in zvals, about which 
nobody should ever care. That's like making function that would accept 
only arguments that has 3'rd bit of pointer set to 1 and 5th bit set to 
0, and reject all others. No sane application should ever behave this 
way. Writing such function is just plain wrong, it replaces the 
substance of programming with nitpicking over the details that are not 
important. Whole phenomenon of dynamic languages has grown on the 
principle of liberating people from caring for bits and concentrate on 
substance, and now you try to drag the bits back in.

> which is called like this in both cases, maybe with a try catch etc etc:
> foo((int) $baz['bar']);

So every time you call foo you need try/catch? And that's supposed to be 
_good_?
-- 
Stanislav Malyshev, Zend Software Architect
stas@zend.com   http://www.zend.com/
(408)253-8829   MSN: stas@zend.com

---

## #37088 — Chris Stockton — 2008-04-17T17:06:17+00:00

URL: https://externals.io/message/37068#37088 · In reply to: #37084

> What's the use of such code? If $var is '1' and not 1, what's the use of
> throwing an exception and having to handle it later (basically by failing
> the task, since you don't know how to do foo() now) - instead of just doing
> with that 1 what was intended for? There's no any difference between 1 and
> '1' that can be important to anybody. Only difference is the way it is
> represented in underlying bits in zvals, about which nobody should ever
> care. That's like making function that would accept only arguments that has
> 3'rd bit of pointer set to 1 and 5th bit set to 0, and reject all others. No
> sane application should ever behave this way. Writing such function is just
> plain wrong, it replaces the substance of programming with nitpicking over
> the details that are not important. Whole phenomenon of dynamic languages
> has grown on the principle of liberating people from caring for bits and
> concentrate on substance, and now you try to drag the bits back in.
> So every time you call foo you need try/catch? And that's supposed to be
> _good_?


Somebody missed the point...

Seeing how you work for zend I thought maybe you have used the zend
framework = ) Sorry in my example I used "int" instead of "numeric", but my
point is the same, grep in zend framework for is_bool.

It does what you are complaining about:

From: Zend_Pdf_Element_Numeric
    public function __construct($val)
    {
        if ( !is_numeric($val) ) {
            throw new Zend_Pdf_Exception('Argument must be numeric');
        }

        $this->value   = $val;
    }

That could be...
    public function __construct(numeric $val)
    {
        $this->value   = $val;
    }

So, let's re-visit my point of "less code bloat"....

---

## #37091 — Sam Barrow — 2008-04-17T17:11:48+00:00

URL: https://externals.io/message/37068#37091 · In reply to: #37088

> 
> 
> > […]
> 
> 
> Somebody missed the point...
> 
> Seeing how you work for zend I thought maybe you have used the zend
> framework = ) Sorry in my example I used "int" instead of "numeric", but my
> point is the same, grep in zend framework for is_bool.
> 
> It does what you are complaining about:
> 
> From: Zend_Pdf_Element_Numeric
>     public function __construct($val)
>     {
>         if ( !is_numeric($val) ) {
>             throw new Zend_Pdf_Exception('Argument must be numeric');
>         }
> 
>         $this->value   = $val;
>     }
> 
> That could be...
>     public function __construct(numeric $val)
>     {
>         $this->value   = $val;
>     }
> 
> So, let's re-visit my point of "less code bloat"....

Actually, is_numeric checks for strings that contain numeric values,
it's not the same as is_bool, is_int, is_float, etc, which check the
variable's type.

Your point is very valid for is_int and similar functions, just not
 `is_numeric()`. I just did a grep on zend framework for is_int and there
were tons of results.

---

## #37094 — Chris Stockton — 2008-04-17T17:23:44+00:00

URL: https://externals.io/message/37068#37094 · In reply to: #37091

> Actually, is_numeric checks for strings that contain numeric values,
> it's not the same as is_bool, is_int, is_float, etc, which check the
> variable's type.

Hence my second example = )


> Your point is very valid for is_int and similar functions, just not
> `is_numeric()`. I just did a grep on zend framework for is_int and there
> were tons of results.
>
I think it is valid for anything, numeric type hinting is very appropriate
in php.

---

## #37095 — Sam Barrow — 2008-04-17T17:23:46+00:00

URL: https://externals.io/message/37068#37095 · In reply to: #37094

> On Thu, Apr 17, 2008 at 10:11 AM, Sam Barrow <sam@sambarrow.com>
> wrote:
>         Actually, is_numeric checks for strings that contain numeric
>         values,
>         it's not the same as is_bool, is_int, is_float, etc, which
>         check the
>         variable's type.
> Hence my second example = )
> 
>  
>         Your point is very valid for is_int and similar functions,
>         just not
>         `is_numeric()`. I just did a grep on zend framework for is_int
>         and there
>         were tons of results.
> I think it is valid for anything, numeric type hinting is very
> appropriate in php.

Numeric type hinting is valid, all I'm saying is that PHP's is_numeric
function doesn't perform a strict type check like is_int or is_bool. I
agree with you I just think you misunderstood the purpose of the
is_numeric function.

---

## #37096 — Felipe Pena — 2008-04-17T17:27:23+00:00

URL: https://externals.io/message/37068#37096 · In reply to: #37081

Em Qui, 2008-04-17 às 12:31 -0400, Sam Barrow escreveu:
> 
> > […]
> 
> function int() {
> }
> 
> PHP won't know if this is a return type hint or function name. This
> specific case might be solvable with added logic though, I really don't
> know how to do it or how hard it would be; alot of this is done in the
> parser which I am only slightly familiar with.
> 

I'm not a bison expert, but i don't know how make the parser accepts
'function type name()', actually i get two Shift/reduce and two
Reduce/reduce conflicts because the `T_STRING` as a possible type name. 
... Maybe it is an known issue.

-- 
Regards,
Felipe Pena.

---

## #37098 — Derick Rethans — 2008-04-17T17:35:00+00:00

URL: https://externals.io/message/37068#37098 · In reply to: #37072

> Em Qui, 2008-04-17 às 17:17 +0200, Paul Biggar escreveu:
> > […]
> 
> No, i'm not planning to do that.

I don't think scalar is very useful, but I do think there is a case for 
numeric.

regards,
Derick

-- 
Derick Rethans
http://derickrethans.nl | http://ezcomponents.org | http://xdebug.org

---

## #37100 — Brian Moon — 2008-04-17T17:48:52+00:00

URL: https://externals.io/message/37068#37100 · In reply to: #37098

Derick Rethans wrote:
> I don't think scalar is very useful, but I do think there is a case for 
> numeric.

I don't think string is useful.  I would use scalar instead.  I only 
need to know that the variable is not an array or object.  I can echo, 
concatenate, etc. any scalar as if it was a string.

-- 

Brian Moon
Senior Developer/Engineer
------------------------------
When you care enough to spend the very least.
http://dealnews.com/

---

## #37101 — Brian Moon — 2008-04-17T17:52:32+00:00

URL: https://externals.io/message/37068#37101 · In reply to: #37095

> I just did a grep on zend framework for is_int
> and there were tons of results.

No offense to Zend, I love thos guys, but I don't think using Zend 
Framework as the gold standard for how people want to code in PHP is the 
right thing to do.

-- 

Brian Moon
Senior Developer/Engineer
------------------------------
When you care enough to spend the very least.
http://dealnews.com/

---

## #37103 — Stanislav Malyshev — 2008-04-17T17:59:21+00:00

URL: https://externals.io/message/37068#37103 · In reply to: #37088

Hi!

> Seeing how you work for zend I thought maybe you have used the zend 
> framework = ) Sorry in my example I used "int" instead of "numeric", but 
> my point is the same, grep in zend framework for is_bool.

It might come as a surprise to you, but I did not write whole Zend 
Framework personally :) Moreover, as even more surprise I did not even 
inspect personally each line of code. As a final shock, I am not 
convinced functions in PHP should throw exceptions when parameters don't 
match - and even if they do, first they should attempt to make sense of 
parameters (which makes string hints like "integer" and "string" make no 
sense - you can convert a lot of things to int or string). Even if they 
can't, it's much better to be handled on user code level with error 
message that makes sense and way that makes sense for application - but 
I could kind of live with the scenario where these hints would work as 
internal function types work now. However, that's not what is proposed - 
what is proposed is that if you've got int typehint, '1' would be 
rejected. Having such restriction makes no sense and goes contrary to 
what PHP and dynamic languages in general are.
-- 
Stanislav Malyshev, Zend Software Architect
stas@zend.com   http://www.zend.com/
(408)253-8829   MSN: stas@zend.com

---

## #37104 — Paul Biggar — 2008-04-17T18:07:25+00:00

URL: https://externals.io/message/37068#37104 · In reply to: #37103

Hi Stanislav,




> As a final shock, I am not convinced
> functions in PHP should throw exceptions when parameters don't match - and
> even if they do, first they should attempt to make sense of parameters
> (which makes string hints like "integer" and "string" make no sense - you
> can convert a lot of things to int or string).

This is of course why I suggested that the best approach would be
automatically convert them, rather than reject a type which can be
coerced appropriately. I would settle for the current proposal, but if
you're going to make the language weakly-typed, which it is, it is
more appropriate to keep this in line with the rest of the language.


Paul


-- 
Paul Biggar
paul.biggar@gmail.com

---

Next page: https://externals.io/message/37068.md?page=2
