# Scalar Type Hinting

- Thread: https://externals.io/message/58637
- Original archive: https://news-web.php.net/php.internals/58637
- Started by Raymond Irving on 2012-03-06T02:20:12+00:00
- Messages: 41
- Page 1 of 2: messages 1 to 25 (25 per page, add `?page=N` to the URL)
- Next page: https://externals.io/message/58637.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

---

## #58637 — Raymond Irving — 2012-03-06T02:20:12+00:00

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

Hello,

I came across some info on the web that states that scalar type hinting was
added to the PHP trunk but it did not make it's way into 5.4 because of
objections from the community. Will it ever make it's way into 5.5?

I know PHP is considered to be a weak typed language but it should also be
about freedom. Freedom for a PHP developer to choose to use scalar type
hinting whenever he/she sees the need.


Best regards,
__
Raymond

---

## #58638 — Kris Craig — 2012-03-06T02:55:30+00:00

URL: https://externals.io/message/58637#58638 · In reply to: #58637

Wow no offense, but your timing is terrible, Raymond!  We've been going
back and forth on this for the past couple weeks now, though the discussion
has quieted for the moment.

I would suggest you go through some of the recent posts on Internals.
Right now there basically is no solid consensus on this issue, though some
of us have been working to change that.  But as it stands now, I'm not
aware of any plans to introduce expanded typing of any kind in the
foreseeable future.  And even if we did, I highly doubt it would happen
before PHP 6.

--Kris




> Hello,
>
> I came across some info on the web that states that scalar type hinting was
> added to the PHP trunk but it did not make it's way into 5.4 because of
> objections from the community. Will it ever make it's way into 5.5?
>
> I know PHP is considered to be a weak typed language but it should also be
> about freedom. Freedom for a PHP developer to choose to use scalar type
> hinting whenever he/she sees the need.
>
>
> Best regards,
> __
> Raymond

---

## #58700 — Simon Schick — 2012-03-06T23:10:00+00:00

URL: https://externals.io/message/58637#58700 · In reply to: #58638

Hi,

It got quite around that because we have some RFCs to this where the
functionality seems to be defined as the people thought it should be.
Otherwise they can raise their hands and write a mail that they want to
update the RFC - but as there's no one doing that, I think we're quite
close to what we wanted.

Take a look at it and feel free to add your ideas in this thread.
https://wiki.php.net/rfc/parameter_type_casting_hints
https://wiki.php.net/rfc/object_cast_to_types

Bye
Simon

2012/3/6 Kris Craig <kris.craig@gmail.com>

> Wow no offense, but your timing is terrible, Raymond!  We've been going
> back and forth on this for the past couple weeks now, though the discussion
> has quieted for the moment.
>
> I would suggest you go through some of the recent posts on Internals.
> Right now there basically is no solid consensus on this issue, though some
> of us have been working to change that.  But as it stands now, I'm not
> aware of any plans to introduce expanded typing of any kind in the
> foreseeable future.  And even if we did, I highly doubt it would happen
> before PHP 6.
>
> --Kris
>
>
> 
>
> > […]
> was
> > […]
> be
> > […]

---

## #58704 — Anthony Ferrara — 2012-03-06T23:35:02+00:00

URL: https://externals.io/message/58637#58704 · In reply to: #58700

My concern is the total lack of talk on-list about it.  It's obviously
not perfect, but there has been little to no talk on-list about it.
That is an indication to me that it's not ready or that it won't get
in if put to a vote...

Thoughts?

Anthony

On Tue, Mar 6, 2012 at 6:10 PM, Simon Schick
<simonsimcity@googlemail.com> wrote:
> Hi,
>
> It got quite around that because we have some RFCs to this where the
> functionality seems to be defined as the people thought it should be.
> Otherwise they can raise their hands and write a mail that they want to
> update the RFC - but as there's no one doing that, I think we're quite
> close to what we wanted.
>
> Take a look at it and feel free to add your ideas in this thread.
> https://wiki.php.net/rfc/parameter_type_casting_hints
> https://wiki.php.net/rfc/object_cast_to_types
>
> Bye
> Simon
>
> 2012/3/6 Kris Craig <kris.craig@gmail.com>
>
> > […]

---

## #58705 — Kris Craig — 2012-03-06T23:45:23+00:00

URL: https://externals.io/message/58637#58705 · In reply to: #58704

Personally, speaking for myself at least, I've quieted on the subject
temporarily in favor of advocating some improvements to the RFC voting
process that will ultimately make it easier for us to work through these
type hinting questions.  I'll be resurrecting the discussion on this end
before too long.  =)

--Kris




> My concern is the total lack of talk on-list about it.  It's obviously
> not perfect, but there has been little to no talk on-list about it.
> That is an indication to me that it's not ready or that it won't get
> in if put to a vote...
>
> Thoughts?
>
> Anthony
>
> On Tue, Mar 6, 2012 at 6:10 PM, Simon Schick
> <simonsimcity@googlemail.com> wrote:
> > […]
> discussion
> > […]
> some
> > […]
> wrote:
> > […]
> hinting
> > […]
> of
> > […]
> also
> > […]
> type
> > […]

---

## #58706 — John Crenshaw — 2012-03-06T23:51:02+00:00

URL: https://externals.io/message/58637#58706 · In reply to: #58700

> Hi,
>
> It got quite around that because we have some RFCs to this where the functionality seems to be defined as the people thought it should be.
Otherwise they can raise their hands and write a mail that they want to update the RFC - but as there's no one doing that, I think we're quite close to what we wanted.
>
> Take a look at it and feel free to add your ideas in this thread.
> https://wiki.php.net/rfc/parameter_type_casting_hints
> https://wiki.php.net/rfc/object_cast_to_types
>
> Bye
> Simon

Sorry, I disagree. This is nowhere close IMO, and silence doesn't denote consent in this case. I actually basically stopped participating when it became apparent that people were determined to rush head first into creating a doomed RFC without any process to ensure that historical arguments were considered and addressed, with minimal attention to feedback, and with no concern for syntax (proposed syntax is as bad as the namespace syntax).

I'm in favor of addressing the type hinting issue, but I'm opposed to this RFC. It is crippled, confusing, and has a plethora of unaddressed issues. The object cast has similar problems, and although I recognize the value of this sort of functionality, the current proposal seems to mostly ignore a number of critical problems that were raised when it was discussed on the mailing list.

John Crenshaw
Priacta, Inc.

---

## #58707 — Anthony Ferrara — 2012-03-07T00:02:45+00:00

URL: https://externals.io/message/58637#58707 · In reply to: #58706

John,

> Sorry, I disagree. This is nowhere close IMO, and silence doesn't denote consent in this case. I actually basically stopped participating when it became apparent that people were determined to rush head first into creating a doomed RFC without any process to ensure that historical arguments were considered and addressed, with minimal attention to feedback, and with no concern for syntax (proposed syntax is as bad as the namespace syntax).

Well, my take on it was that thinking out-loud in a thread is not
going to get us anywhere with nothing to base the conversation on.  So
I picked an option and proposed it.  As now, we can base the
conversation around a real implementation.  Don't like the syntax?
Great!  Let's find a better solution.  But I felt that it was more
important to put a base for the conversation, rather than just letting
it wander aimlessly.

> I'm in favor of addressing the type hinting issue, but I'm opposed to this RFC. It is crippled, confusing, and has a plethora of unaddressed issues.

Then point out the issues.  Help improve it and make it something that
*should* go in the core.  That's why it's still in draft mode.  I
didn't propose it, or put it for discussion, I put it in draft for
that very reason.

As far as it being crippled, I'm not sure what you mean, just because
it's only doing casting?

As far as confusing, it is?  I thought this was actually one of the
more straight forward proposals, since it re-used so much from the
core (meaning that it doesn't add new behavior, it re-uses existing
behavior).

As far as having a plethora of unadressed issues, I'm absolutely sure
it does.  But I haven't seen a single one put out there so that it can
be fixed...

> The object cast has similar problems, and although I recognize the value of this sort of functionality, the current proposal seems to mostly ignore a number of critical problems that were raised when it was discussed on the mailing list.

Which were?  The critical problems that I saw on the list were mostly
related to the original proposal wrapping set() with __assign() (which
this proposal removed).  The only known issues that I know of that
remains is with the __toScalar() part (which in worst case can be
removed from the proposal).



These are RFCs.  I am (as their author) explicitly asking for your
comments and contribution.  They are not set in stone in the least...
In fact, the only way they would get to the point where I would
propose them is with enough input and overview that it was mature.
They are not mature now.

Can we make them mature?

Thanks,

Anthony

---

## #58711 — John Crenshaw — 2012-03-07T02:04:01+00:00

URL: https://externals.io/message/58637#58711 · In reply to: #58707

Disclaimer: The following is direct (maybe brutally so). I'm not trying to hurt any feeling or attack, but I'm not pulling punches either. I don't have the energy right now to polish this and make it all nice and gentle, so I'm sorry in advance. I hope you'll look past the directness and be able to get some useful feedback.

> John,
>
> > […]
>
> Well, my take on it was that thinking out-loud in a thread is not going to get us anywhere with nothing to base the conversation on.  So I picked an option and proposed it.  As now, we can base the conversation around a real implementation.  Don't like the syntax?
> Great!  Let's find a better solution.  But I felt that it was more important to put a base for the conversation, rather than just letting it wander aimlessly.
>

Yes, it was aimless discussion (though some would call it brainstorming). It was ready to move to the next level, which should have been gathering the constraints/requirements/problems into a coherent list to work from. What happened though was that this step was skipped entirely, so now there's been an attempt to write a preliminary spec without gathering the requirements first, which IMO is far worse than any amount of aimless discussion.

> > […]
>
> Then point out the issues.  Help improve it and make it something that
*should* go in the core.  That's why it's still in draft mode.  I didn't propose it, or put it for discussion, I put it in draft for that very reason.
>

A good number of issues with the current proposal were raised during the discussion on the mailing list. I don't feel like digging them all up right now, but off the top of my head I remember the following being raised and never saw any consensus for how to resolve them:
- inconsistent syntax (one syntax for scalars, a different one for classes)
- conflicting syntax (I.E. array vs. (array), RFC simply "allows" this, and ignores the confusion that this will create for users.)
- different from the syntax used in the docs
- lack of sufficient function to justify a core change
- chaos surrounding null (to accept and if so to cast or not? Creates a conflict between consistency and implications of the syntax)
- conflicts with references (RFC tries to address this by simply disallowing references, which IMO just ignores the need that would have caused this sort of code in the first place.)

There were others, but I'm not making an exhaustive list.

> As far as it being crippled, I'm not sure what you mean, just because it's only doing casting?
>

Yes, casting is barely better than doing nothing. If I want a dumb typecast I can do that already. What I can't do without massive boilerplate everywhere is an intelligent conversion that accepts safe conversions and gives a warning or error on unsafe conversions.

> As far as confusing, it is?  I thought this was actually one of the more straight forward proposals, since it re-used so much from the core (meaning that it doesn't add new behavior, it re-uses existing behavior).
>

Yes, the syntax has some critical issues that create conflicting expectations. Look at the prior discussion. The current proposal doesn't really fix most of this.

> As far as having a plethora of unadressed issues, I'm absolutely sure it does.  But I haven't seen a single one put out there so that it can be fixed...
>

Again, look at the prior discussion of this syntax. Plenty of issues raised.

> > […]
>
> Which were?  The critical problems that I saw on the list were mostly related to the original proposal wrapping set() with __assign() (which this proposal removed).  The only known issues that I know of that remains is with the __toScalar() part (which in worst case can be removed from the proposal).
>

The biggest one that comes to mind is behavior with respect to operators. __toScalar() in your spec is an attempt to handle this, but IMO it really doesn't cut it. Off the top of my head problems with this solution include:
- This will lead to duplicated code
- Thinking about my own code, I have almost no idea how I would actually write a robust __toScalar() implementation. It's still going to be returning a string, or an integer. Very confusing.

>
>
> These are RFCs.  I am (as their author) explicitly asking for your comments and contribution.  They are not set in stone in the least...
> In fact, the only way they would get to the point where I would propose them is with enough input and overview that it was mature.
They are not mature now.
>
> Can we make them mature?
>
> Thanks,
>
> Anthony

Well, the big issue for me is that I think the type casting hints starts from a fundamentally bad foundation. The premise here is based on a syntax that is ugly and strange, and the syntax opens a bunch of new problems that I don't see a way to resolve. The reason for selecting this syntax was to avoid a BC break from reserving some new keywords. I don't really see this as a good trade.

As for the automatic casting functions, I like the concept, but some serious problems were raised in the discussions and many were never resolved very well. To some extent I'm not really seeing good solutions either. If I think of a solution I'll be sure to mention it, but right now this looks very much like a dead end to me.

John Crenshaw
Priacta, Inc.

---

## #58713 — Anthony Ferrara — 2012-03-07T03:28:37+00:00

URL: https://externals.io/message/58637#58713 · In reply to: #58711

John,


> Disclaimer: The following is direct (maybe brutally so). I'm not trying to hurt any feeling or attack, but I'm not pulling punches either. I don't have the energy right now to polish this and make it all nice and gentle, so I'm sorry in advance. I hope you'll look past the directness and be able to get some useful feedback.

Thank you for being candid.  I appreciate straight to the point
replies, as long as they are respectful (which yours was very much
so).  So thank you.  Now, to your points.

> Yes, it was aimless discussion (though some would call it brainstorming). It was ready to move to the next level, which should have been gathering the constraints/requirements/problems into a coherent list to work from. What happened though was that this step was skipped entirely, so now there's been an attempt to write a preliminary spec without gathering the requirements first, which IMO is far worse than any amount of aimless discussion.

With all honesty, I didn't see anything being gathered.  What I saw
was random ideas shot back and forth (with a good bunch ignored in all
the chatter).  There didn't really seem to be one or two clear
directions, but instead at least a dozen directions at the same time.
There was talk about implementing a "scalar" hint, about implementing
strict hints again, about implementing pseudo-casting hints that did
only simple checks, about hints that actually casted, about hints that
threw notices, about hints that threw warnings.

There didn't seem to be anything more than a bunch of people wanting
different things not even paying attention to the other conversation.
Could a spec have been developed from that?  Sure.  Would it have?
I'm not so sure.

So I picked a direction that seemed consistent with as much of it as
possible, and went with it.  I didn't ask anyone to stop other work,
or stop their discussion.  I just saw an opportunity to unify the
conversation around what seemed to be a commonality between the
comversation, and I took it.  If I stepped on anyone's toes, I'm
sorry...

> A good number of issues with the current proposal were raised during the discussion on the mailing list. I don't feel like digging them all up right now, but off the top of my head I remember the following being raised and never saw any consensus for how to resolve them:

I went over the replies to the initial POC thread that I posted
(http://marc.info/?t=133066037200001&r=1&w=2) and I'll rebut your
replies.

> - inconsistent syntax (one syntax for scalars, a different one for classes)

This is actually discussed in the RFC, as it is not inconsistent (it's
actually consistent with what the patch tries to achieve).  The syntax
for classes and normal arrays is a strict check, where if the match
fails an error is thrown.  This syntax attempts to distinguish between
that functionality by providing a different syntax altogether.  And
since it's casting the parameters, the syntax feels natural (for that
goal).

> - conflicting syntax (I.E. array vs. (array), RFC simply "allows" this, and ignores the confusion that this will create for users.)

Actually, it doesn't simply allow that.  It did it for a very specific
reason.  "array" is a strict check, and "(array)" is a casting check.
One will fatal if a non-array is passed, and the other will attempt to
convert the parameter to an array.  Very different functionality,
which are both internally consistent with the other syntax...

> - different from the syntax used in the docs

Actually, it's the exact same syntax used for casting in the docs.
It's different from class type hints, because it's intended to be so.
If you don't like it, that's fine.  But it's intentionally different.

> - lack of sufficient function to justify a core change

That's absolutely something to be considered.  However, I see erroring
on invalid casts as a bigger issue not the responsibility of a
**casting** hint patch.  So that's why I mention explicitly in the RFC
and my blog post that solving that problem should be another RFC
(culminating in a series of 3 RFCs that each work together very well
to fill the overall need).

> - chaos surrounding null (to accept and if so to cast or not? Creates a conflict between consistency and implications of the syntax)

That's absolutely a valid concern.  And that's what should be being
discussed, if people really feel that the current implementation is
wrong...

> - conflicts with references (RFC tries to address this by simply disallowing references, which IMO just ignores the need that would have caused this sort of code in the first place.)

Actually, it explicitly disallows references.  This was added because
it was explicitly requested on the list in many discussions (including
the initial one for the POC).  But if you can make a case on why to
implement it, and why it makes sense, then we can add it back.

> There were others, but I'm not making an exhaustive list.

Well, the ones that I saw were either rectified, requested (and
implemented) or (to me) showed a lack of understanding about the
rationale and decisions (which is valid, but shouldn't really bear
that much on the discussion, as I feel if you want to raise an issue,
you should at least have a cursory understanding of what you're
commenting about)...

> > […]
>
> Yes, casting is barely better than doing nothing. If I want a dumb typecast I can do that already. What I can't do without massive boilerplate everywhere is an intelligent conversion that accepts safe conversions and gives a warning or error on unsafe conversions.

Again, I personally see casting data-loss a bigger issue than just
parameter hinting, which should get its own RFC to clean up.  That's
why I didn't include it here.  On purpose...

> > […]
>
> Yes, the syntax has some critical issues that create conflicting expectations. Look at the prior discussion. The current proposal doesn't really fix most of this.

Conflicting expectations?  It looks like a cast to me, and that's what
it does.  I'm not sure where the conflicting expectation is.  I would
agree if it was foo(int $int) that did the casting.  That would be
conflicting.  But with the current syntax, I'm not sure I understand
your point...

> > […]
>
> Again, look at the prior discussion of this syntax. Plenty of issues raised.

Actually, I did.  And the only issue raised was by you here:
(http://marc.info/?l=php-internals&m=133066473032680&w=2).  And I
believe those issues were addressed in the RFC.  If you don't feel
that's adequate, that's fine, let's improve the RFC so that it does...

> The biggest one that comes to mind is behavior with respect to operators. __toScalar() in your spec is an attempt to handle this, but IMO it really doesn't cut it. Off the top of my head problems with this solution include:
> - This will lead to duplicated code

It will?  Yes, __toInt() and __toScalar() may have the same code in
it.  But that's always going to happen, unless you want to make "+" an
integer operation.  But you could just do __toScalar() { return (int)
$this; } to take care of that duplication.  The key is that it leaves
the determination of the type to return to the class, where it
belongs...

> - Thinking about my own code, I have almost no idea how I would actually write a robust __toScalar() implementation. It's still going to be returning a string, or an integer. Very confusing.

You probably won't implement it at all then.  I admit, the
__toScalar() method is the weak point of the RFC.  I personally want
the flexibility that it provides, but if people are strongly against
it, I think it can be removed without destroying the RFC's intent...

> Well, the big issue for me is that I think the type casting hints starts from a fundamentally bad foundation. The premise here is based on a syntax that is ugly and strange, and the syntax opens a bunch of new problems that I don't see a way to resolve. The reason for selecting this syntax was to avoid a BC break from reserving some new keywords. I don't really see this as a good trade.

To be perfectly clear, the reason for that syntax was **not** to avoid
a BC break.  It was to avoid a FC break.  I wanted a casting hint, and
I didn't want to restrict the possibility of adding strict hints
later.  And I wanted to clearly distinguish the current strict hints
(array + class) and the new casting hints.  To me, the most logical
way of doing that was to re-use the casting syntax.  Could we have
done foo(int? $foo) or foo(*int $foo) or foo(@int $foo) or whatever?
Sure.  But I'd argue that anything except foo(int $foo) would have
lead to FAR more confusion.

This way, it's re-using an existing syntax that **every** intermediate
developer is intimate with, and applying it to a case that's basically
functioning along the same lines...

> As for the automatic casting functions, I like the concept, but some serious problems were raised in the discussions and many were never resolved very well. To some extent I'm not really seeing good solutions either. If I think of a solution I'll be sure to mention it, but right now this looks very much like a dead end to me.

Actually, there weren't.  This is the thread you were referring to:
(http://marc.info/?t=133026833200004&r=1&w=2).  And re-reading it, the
problems that are raised are all centered around __assign() (and ever
so slightly the scalar casting now implemented as __toScalar()).  The
rest of it was barely discussed, and no real problems were raised.

I'm not saying this to say that there are no problems.  I'm saying
that, as far as I've seen, no significant (non-personal-preference)
issues have been raised about the topics both of these RFCs discuss
(with the possible exception of __toScalar(), to a far lesser extent).
 The topics that were objected two in those threads have been
rectified or eliminated altogether from these RFCs.

So, again, I ask.  Let's look at the actual issues, so we can make
these RFCs better (or show that they need to be thrown out).  I want
the best overall outcome, and if that means ditching my concepts
altogether, I have no problem with that.  I just don't want to see
them ditched because of invalid pre-conceived notions, or because of
miss-communication.

Thanks for the replies!

Anthony

---

## #58714 — Matthew Weier O'Phinney — 2012-03-07T04:18:43+00:00

URL: https://externals.io/message/58637#58714 · In reply to: #58704

> My concern is the total lack of talk on-list about it.  It's obviously
> not perfect, but there has been little to no talk on-list about it.
> That is an indication to me that it's not ready or that it won't get
> in if put to a vote...
>
> Thoughts?

I really like the proposal you set forth. I have zero clue what impact
it would have on performance, however, so I'm deferring that discussion
to those who do. 

As a user and framework developer, I'd love to see it in place -- 
casting support at the function/method parameter level would greatly 
simplify a lot of code I write.


> On Tue, Mar 6, 2012 at 6:10 PM, Simon Schick
><simonsimcity@googlemail.com> wrote:
> > […]


-- 
Matthew Weier O'Phinney
Project Lead            | matthew@zend.com
Zend Framework          | http://framework.zend.com/
PGP key: http://framework.zend.com/zf-matthew-pgp-key.asc

---

## #58719 — Stas Malyshev — 2012-03-07T07:31:07+00:00

URL: https://externals.io/message/58637#58719 · In reply to: #58714

Hi!

> > […]

Just took a look on it - the syntax proposed there is quite ugly and 
rather confusing, I really wouldn't like to have such syntax in PHP.
Also "(int) $foo = “1” will generate an E_COMPILE_ERROR" makes no sense 
to me.
Also, this line:
function test((int) $intParam, (string) $strParam = "foo", (array) 
$array) {}

is not proper PHP code - it contains optional parameter and then 
parameter with no default.

And can we please stop using word "hinting"?
We can call it type conversion, typecasting, type coercion, etc.
http://en.wikipedia.org/wiki/Type_conversion

But I don't see how there's any hinting involved.

-- 
Stanislav Malyshev, Software Architect
SugarCRM: http://www.sugarcrm.com/
(408)454-6900 ext. 227

---

## #58721 — Lester Caine — 2012-03-07T08:11:04+00:00

URL: https://externals.io/message/58637#58721 · In reply to: #58719

Stas Malyshev wrote:
> And can we please stop using word "hinting"?
> We can call it type conversion, typecasting, type coercion, etc.
> http://en.wikipedia.org/wiki/Type_conversion
>
> But I don't see how there's any hinting involved.

Is this were things have drifted from the original working base? I was under the 
impression that the idea was to give developers a nudge as to what type of 
parameter was required ( so documentation did the job for me ) rather than 
forcing a conversion when the wrong type was supplied?
Which particular problem is being worked on?

-- 
Lester Caine - G8HFL
-----------------------------
Contact - http://lsces.co.uk/wiki/?page=contact
L.S.Caine Electronic Services - http://lsces.co.uk
EnquirySolve - http://enquirysolve.com/
Model Engineers Digital Workshop - http://medw.co.uk//
Firebird - http://www.firebirdsql.org/index.php

---

## #58722 — Christian Kaps — 2012-03-07T08:22:21+00:00

URL: https://externals.io/message/58637#58722 · In reply to: #58719

Hi,

I'm with Stas here.

First let me say that I would like to see type hinting for scalars in 
PHP. As a userland developer it would help me to write clean and more 
robust code. But I think this proposal is only a workaround to get a 
round the main problem. It's a try to push similar functionality into 
PHP without breaking BC. I think it's the wrong way.

Anthony, You addressed one of the main issues in your last post.

> > […]

Why not try to change this first?

I know there are more issues to solve. But I think only solving issue 
piece by piece, regardless if BC breaks, brings a robust and clean 
implementation of this feature. Not immediately, maybe in the next major 
version.

Just my 2 cents.

Christian

Am 07.03.2012 08:31, schrieb Stas Malyshev:
> Hi!
>
> > […]
>
> Just took a look on it - the syntax proposed there is quite ugly and
> rather confusing, I really wouldn't like to have such syntax in PHP.
> Also "(int) $foo = “1” will generate an E_COMPILE_ERROR" makes no
> sense to me.
> Also, this line:
> function test((int) $intParam, (string) $strParam = "foo", (array) 
> $array) {}
>
> is not proper PHP code - it contains optional parameter and then
> parameter with no default.
>
> And can we please stop using word "hinting"?
> We can call it type conversion, typecasting, type coercion, etc.
> http://en.wikipedia.org/wiki/Type_conversion
>
> But I don't see how there's any hinting involved.
>
> --
> Stanislav Malyshev, Software Architect
> SugarCRM: http://www.sugarcrm.com/
> (408)454-6900 ext. 227

---

## #58739 — Anthony Ferrara — 2012-03-07T13:19:57+00:00

URL: https://externals.io/message/58637#58739 · In reply to: #58719

Stas,

Thanks for the comments!

inline.


> Hi!
>
> > […]
>
>
> Just took a look on it - the syntax proposed there is quite ugly and rather
> confusing, I really wouldn't like to have such syntax in PHP.

Ok, this is where I'm torn.  I have a few (read: about 4 or 5)
responses (mostly from people I respect quite a bit) that say it's
quite ugly and confusing.  I have had a lot more responses saying it's
simple, elegant and syntatically draws the difference between casting
and strict type checking.  I see your point, I really do.  It's not
the prettiest syntax out there.  But confusing?  I'm not so sure...  I
think you're too close to the problem to really understand it.  Or
perhaps I am...  I don't know.

But based on the conversations I've had with all sorts of devs about
this (some that I don't know personally, some that I do, some junior,
some senior), the vast majority of them got it without explanation.
The fact that cast syntax was re-used gave them enough of a hint as to
what it was doing that they guessed correctly.  Now, if you think it
should be doing something different, then definitely re-visit the
syntax.  But if it's going to be casting variables, the syntax does
make sense and carries an intrinsic value with it...

> Also "(int) $foo = “1” will generate an E_COMPILE_ERROR" makes no sense to
> me.

Actually, that makes perfect sense to me.  Think about it from the
reader perspective.  Sure, "(int) $foo = '1'" is pretty straight
forward, but what you you think if you saw:

foo ((string) $bar = 123);

Frankly, that would confuse the daylights out of me, and would force
me to stop and think about what would happen.  That's exactly what I
would like to avoid, the thinking step on reading it.  In fact, it
would make even less sense, since it would need to be cast, so the
following would return false:

function foo((string) $bar = 123) {
    return $bar === 123;
}
foo();

How much more confusing is that?  By restricting the default parameter
to be of the type being casted to, that sort of a problem wouldn't
happen and would be adverted by the compiler...

I think the difference is that I know that strings are not integers
and vise versa.  Even at the language level there are subtle
differences in behavior between the types, even if they store
equivalent values.

> Also, this line:
> function test((int) $intParam, (string) $strParam = "foo", (array) $array)
> {}
>
> is not proper PHP code - it contains optional parameter and then parameter
> with no default.

It is proper PHP code.  It parses just fine
(http://codepad.viper-7.com/rEHqZp).  Sure, it's not best practice
(and was an accident which has been fixed), but it's 100% valid and
proper PHP code and doesn't even raise `E_STRICT` errors...

> And can we please stop using word "hinting"?
> We can call it type conversion, typecasting, type coercion, etc.
> http://en.wikipedia.org/wiki/Type_conversion

Well, but I think that a distinction needs to be made about where it
is.  How about "Parameter Casting".  Better?

> But I don't see how there's any hinting involved.

The compiler (and any IDE) knows what the type of the variable will be
inside the function body.  How is that not hinting?

Anthony

---

## #58740 — Anthony Ferrara — 2012-03-07T13:23:36+00:00

URL: https://externals.io/message/58637#58740 · In reply to: #58722

Christian,

On Wed, Mar 7, 2012 at 3:22 AM, Christian Kaps
<christian.kaps@mohiva.com> wrote:
> Hi,
>
> I'm with Stas here.
>
> First let me say that I would like to see type hinting for scalars in PHP.
> As a userland developer it would help me to write clean and more robust
> code. But I think this proposal is only a workaround to get a round the main
> problem. It's a try to push similar functionality into PHP without breaking
> BC. I think it's the wrong way.

Again, the lack of a BC break is a side-effect of the main limiting
factor which was to allow for stricter checks in the future and keep
some semblance of a sensible syntax (having foo(int $foo) allow
foo("5") makes a lot less sense to me)...

> Anthony, You addressed one of the main issues in your last post.
>
>
> > […]
>
>
> Why not try to change this first?

The simple reason, is that I was under the impression that one or more
devs were writing that proposal.  I was going to let them. If they
have stopped, or want my help, or want me to do it, I'm all for
that...

Thanks,

Anthony

---

## #58743 — Arvids Godjuks — 2012-03-07T15:04:37+00:00

URL: https://externals.io/message/58637#58743 · In reply to: #58740

I, for one, decided not to participate in the discussions any more
because they always change to something different in a few hours of
discussion. I'm surprised how people tend to complicate the feature
into something weird and ugly. I now understand why core team just
ignores some discussions.

I don't like the function a( (int) $int) syntax and approach - it's
not type hinting, it's auto-converting arguments. And adding function
a( (array) $array) is just, well, pointless. Why? Because if you have
a conversion from scalar to array - you definitely have something
wrong in the code that needs fixing, not converting and continue to
run the code like it's OK. It should come like a barrier, not a
filter. And current array and object type hinting does just that. The
(object) is also pointless for type hinting. Why? Because you usually
expect not any damn object, but an object of certain type and it's
children. That works now just fine and errors the hell out if
something isn't right.

I realize that with scalars it's not that straight forward, but
complicating things by adding an auto-cast syntax and so on is just
ridiculous. Hints should stay, well, hints. The only problem we have
is complications of accepting numerical strings or numbers as strings.
And what to do with "null". Everything else is irrelevant.
function a(bool $bool) {}
a(10); // Kill your self against the wall - write a(true);
If you define bool - use the damn bool! It's not an "if" or "switch"
statement where auto-converting is usually used. It's a function call,
you should pass to it correct arguments. Type hinting is working only
for more internal API's - the data filtering and validating layer
using type hints will generate errors all over the place. We all know
how many security hole scanners out there that scan sites and pass all
kind of data to our scripts to break them and try exploiting that.

I consider interchangeable only three cases:
1. Numerical string.
2. Integers and floats as strings.
3. Integer and string  0 1 as bool.

Any other cases should error out.

Type hinting is not for using it all over the place - it should be
used in places it is really needed. And it should define the expected
type with some auto-converting limited special cases like I have
written above. That is really all it needs. No
super-duper-auto-converting type-hints, no variable type hinting and
other wild stuff I have seen during last 2-3 weeks.

Anything more complicated than that and count a -1 vote from me.

---

## #58744 — Alan Knowles — 2012-03-07T16:31:14+00:00

URL: https://externals.io/message/58637#58744 · In reply to: #58700

Comment in-line below...


> Hi,:
>
> It got quite around that because we have some RFCs to this where the
> functionality seems to be defined as the people thought it should be.
> Otherwise they can raise their hands and write a mail that they want to
> update the RFC - but as there's no one doing that, I think we're quite
> close to what we wanted.
>
> Take a look at it and feel free to add your ideas in this thread.
> https://wiki.php.net/rfc/parameter_type_casting_hints
> https://wiki.php.net/rfc/object_cast_to_types

Been watching this for a while, got slightly interested in the parameter 
casting thing, but then ran a little test
http://www.roojs.com/examples/types.php

Casting on PHP may help the code inside the function, but the result is 
some weird and wonderful magic for the calling code, not to mention that 
the docs for (int) casting say the behavior may change, don't expect it 
to work like that forever..

You could try some kind of stricter casting. Where odd conversions 
between array/object <-> bool/int/float/string do not work on parameter 
casting .. but then you end up with two types of casting ...

Anyway, will go back to lurking for a while..

Regards
Alan

>
> Bye
> Simon
>
> 2012/3/6 Kris Craig<kris.craig@gmail.com>
>
> > […]

---

## #58745 — Lazare Inepologlou — 2012-03-07T16:58:06+00:00

URL: https://externals.io/message/58637#58745 · In reply to: #58744

> You could try some kind of stricter casting. Where odd conversions
between array/object <-> bool/int/float/string do not work on parameter
casting .. but then you end up with two types of casting ...

I have used in depth the casting operators of C#, which are incredibly
flexible and powerful, and they are based on this exact idea. In C#, there
are two types of casting: implicit and explicit. The first is used for
trivial conversions and the later for the "odd" ones. It is possible to
classify PHP's casts into these two categories:

int to string: implicit
int to float:  implicit
int to object: explicit
int to array:  explicit
...

Once this classification is done, the code becomes much more sane. Examples:

function test_float( float test ) { ... }
test_float( 1.0 );  // ok
test_float( 1 );    // implicit int to float cast, ok

function test_array( array test ) { ... }
test_array( array() );  // ok
test_array( 1 );        // no implicit int to array cast, error!
test_array( (array)1 ); // explicit int to array cast, ok

I deliberately avoided using Anthony's cast-like syntax, because it does
not fit nicely here. Calling a function may cause an implicit cast, but it
will never do an explicit one.


Lazare INEPOLOGLOU
Ingénieur Logiciel


2012/3/7 Alan Knowles <alan@akbkhome.com>

> Comment in-line below...
>
> 
>
> > […]
>
> Been watching this for a while, got slightly interested in the parameter
> casting thing, but then ran a little test
> http://www.roojs.com/examples/types.php
>
> Casting on PHP may help the code inside the function, but the result is
> some weird and wonderful magic for the calling code, not to mention that
> the docs for (int) casting say the behavior may change, don't expect it to
> work like that forever..
>
> You could try some kind of stricter casting. Where odd conversions between
> array/object <-> bool/int/float/string do not work on parameter casting ..
> but then you end up with two types of casting ...
>
> Anyway, will go back to lurking for a while..
>
> Regards
> Alan
>
>
> > […]

---

## #58746 — Stas Malyshev — 2012-03-07T18:12:24+00:00

URL: https://externals.io/message/58637#58746 · In reply to: #58739

Hi!

> would make even less sense, since it would need to be cast, so the
> following would return false:
>
> function foo((string) $bar = 123) {
>      return $bar === 123;
> }
> foo();

You explicitly said "convert, then compare excluding conversion", what 
would you expect? That's like saying "why $a+1 is not equal to $a, it's 
almost the same?". No it's not - you just told PHP to modify it!

> How much more confusing is that?  By restricting the default parameter
> to be of the type being casted to, that sort of a problem wouldn't
> happen and would be adverted by the compiler...

I feel you're painting yourself into a corner here - inventing arbitrary 
restrictions and then inventing arbitrary problems to justify these 
restrictions. Why would your conversion convert, but not always convert? 
Why it would work with constants, but not in defaults?

> It is proper PHP code.  It parses just fine
> (http://codepad.viper-7.com/rEHqZp).  Sure, it's not best practice

The fact it parses doesn't mean it is proper code. The fact it's not 
errors out is actually a bug, as such function definition is broken. But 
let's not take the discussion too far out - just please do not promote 
such code in our RFCs.

> The compiler (and any IDE) knows what the type of the variable will be
> inside the function body.  How is that not hinting?

Hinting means something that is just for information and can be ignored 
it you don't need it. This is type coercion - you can not ignore it, it 
would change your variables. Calling it hinting implies it does not do 
anything, just informs IDE - that'd what PHPDoc does, but that's not 
what your proposed function does. Proper naming is important.
The compiler BTW doesn't know anything and has no way to know it and 
benefit from it in any way.
-- 
Stanislav Malyshev, Software Architect
SugarCRM: http://www.sugarcrm.com/
(408)454-6900 ext. 227

---

## #58757 — John Crenshaw — 2012-03-07T21:59:32+00:00

URL: https://externals.io/message/58637#58757 · In reply to: #58713

> From: Anthony Ferrara [mailto:ircmaxell@gmail.com] 
>
> John,
>
> 
> > […]
>
> I went over the replies to the initial POC thread that I posted
> (http://marc.info/?t=133066037200001&r=1&w=2) and I'll rebut your replies.
>

You've been spending a lot of time defending these proposals and trying to prove wrong feedback that raises concerns. This is preventing you from actually using the feedback to improve the proposals. You are losing out on perhaps the biggest advantage of the RFC process, which is that multiple minds can work together to hammer out an idea and make it really shine.

Most of your "rebuttals" focus entirely on whether the RFC contains sufficient information to make something technically work. That's not the point at all. I've read the RFC. I have no doubt that it "works", nor I think does anyone else. That's not the issue.

To quote a recent film: "Titan: Oh yeah? What's the difference? Megamind: PRESENTATION!". The code syntax is the UI that PHP presents to developers. Yes, this "works" (in the sense that it is possible to implement what the RFC describes), but there are serious usability and communication problems. Language is also one of the trickiest interfaces to work with because once you commit to something you are pretty much stuck with it forever (namespace separator). If every PHP developer is going to have to deal with this until the end of time it needs to be *awesome*.

> > […]
>
> This is actually discussed in the RFC, as it is not inconsistent (it's actually consistent with what the patch tries to achieve).  The syntax for classes and normal arrays is a strict check, where if the match fails an error is thrown.  This syntax attempts to distinguish between that functionality by providing a different syntax altogether.  And since it's casting the parameters, the syntax feels natural (for that goal).
>

You can mince words, but that doesn't change the problem. It is utterly inconsistent with the expectations in creates. You'll argue that it creates an expectation of a type cast, but you'd be wrong  in far too many cases. The syntax is similar enough to the syntax for parameter types in other languages that developers will think of it as basically the same thing. The syntax differs however from existing parameter type syntax.

The behavioral difference is also a problem, being too different from parameter typing to be useful (it doesn't actually vet the parameter), and yet close enough to validate the confusion (behaves too similarly to an implicit conversion). In the end you have a bizarre syntax that looks like one thing but is conceptually another, but with a subtle behavioral difference that is invisible except when it fails to fail.

> > […]
>
> Actually, it doesn't simply allow that.  It did it for a very specific reason.  "array" is a strict check, and "(array)" is a casting check.
> One will fatal if a non-array is passed, and the other will attempt to convert the parameter to an array.  Very different functionality, which are both internally consistent with the other syntax...
>

I know about the behavioral difference. I'm not talking about a technical conflict, I'm talking about a conflict in the mind of the developer. Given function(array $a, (array) $b){} the difference between $a and $b is a very advanced distinction and will be completely lost by the average developer.

The confusion is made worse by the fact that function(array $a) works, but function(int $a) doesn't, but function((int) $a) does. I know why, but the average developer just learning PHP for the first time won't get it at all.

> > […]
>
> Actually, it's the exact same syntax used for casting in the docs.
> It's different from class type hints, because it's intended to be so.
> If you don't like it, that's fine.  But it's intentionally different.
>

Sometimes I think you miss the point on purpose.

In the docs substr is defined as:
string substr ( string $string , int $start [, int $length ] )

If I wanted to write the same thing in my own code I would have to write:
function my_substr ( (string) $string , (int) $start , (int) $length )

One syntax for the docs, a different one in my code.

> > […]
>
> That's absolutely something to be considered.  However, I see erroring on invalid casts as a bigger issue not the responsibility of a
> **casting** hint patch.  So that's why I mention explicitly in the RFC and my blog post that solving that problem should be another RFC (culminating in a series of 3 RFCs that each work together very well to fill the overall need).
>

Well, if you argue that this proposal is actually a typecasting enhancement and not a parameter type enhancement, then yes, you'd be right. That's not how this is presented though, that's not where it is presented (Scalar Type Hinting discussion), that's not when it was presented, and that's not how it is getting perceived or measured.

As far as expanding type casting in this way, it doesn't make sense. There is no precedent, it looks and will get treated like parameter hinting (which you are saying it isn't), there is no additional functional value, and very little value of any sort beyond casts (just a tiny documentation boost and a savings in the number of characters in the few cases where a dumb type cast is good enough.)

> > […]
>
> That's absolutely a valid concern.  And that's what should be being discussed, if people really feel that the current implementation is wrong...
>
> > […]
>
> Actually, it explicitly disallows references.  This was added because it was explicitly requested on the list in many discussions (including the initial one for the POC).  But if you can make a case on why to implement it, and why it makes sense, then we can add it back.
>

Again, yes, I know that the RFC takes a position on this. My point is not that the RFC doesn't take a position, my point was that the position taken "ignores the need that would have caused this sort of code in the first place."

Reference parameters are basically return values. Just because a parameter will return a value doesn't mean that the type no longer matters. In fact, it means that the calling function should EXPECT the type to change, and EXPECT the value to be modified. One example that occurs to me off hand is preg_match, where the 3rd parameter is documented as an array reference. You can actually pass anything, but it's going to be an array when the function returns.

> > […]
>
> Well, the ones that I saw were either rectified, requested (and
> implemented) or (to me) showed a lack of understanding about the rationale and decisions (which is valid, but shouldn't really bear that much on the discussion, as I feel if you want to raise an issue, you should at least have a cursory understanding of what you're commenting about)...
>
> > […]
>
> Again, I personally see casting data-loss a bigger issue than just parameter hinting, which should get its own RFC to clean up.  That's why I didn't include it here.  On purpose...
>

You can't raise errors like this on lossy casts. Giving a warning if an implicit conversion loses data (123 + '456xyz', or substr('foo', 'bar')) makes sense, but if I explicitly write (int)'456xyz' or (int)23.7, I must not get a warning about data loss (otherwise it would be difficult/impossible to force a deliberately lossy conversion without warnings). Since we can't raise warnings on casts, you really won't be able to do it with casted parameters either (unless you're willing to accept a consistency break). These will be stuck in silence forever.

> > […]
>
> To be perfectly clear, the reason for that syntax was **not** to avoid a BC break.  It was to avoid a FC break.  I wanted a casting hint, and I didn't want to restrict the possibility of adding strict hints later.  And I wanted to clearly distinguish the current strict hints (array + class) and the new casting hints.  To me, the most logical way of doing that was to re-use the casting syntax.  Could we have done foo(int? $foo) or foo(*int $foo) or foo(@int $foo) or whatever?
>

Well, if that is the case, you did not succeed. The FC break you originally worked to avoid is something that can never happen anyway, and this does not avoid the most critical FC break.

First, "strict" types (in the sense of not allowing an integer to be passed to a string parameter) are never going to happen in PHP. Even C++ looks for an implicit conversion and uses that if available. PHP has well defined implicit conversions between scalars, and there is absolutely no chance that PHP is ever going to implement any form of typing that is more strict than typing in C++. A strict set of scalar types hint that don't juggle anything is just not in the cards.

Second, (bear with me) the form of typing that people seem to have settled on before this RFC was introduced is "the same typing as the core, but at the language level." To use a prior example, the core has:
string substr ( string $string , int $start ){...}

and the following behavior:
substr('foo', 'bar'); // `E_WARNING` 
substr(123, '1'); // '23'

I should be able to write an equivalent:

function my_substr ( string $string , int $start ){..}

and I should get matching behavior:
my_substr('foo', 'bar'); // `E_WARNING` 
my_substr(123, '1'); // '23'

Now here's the point, if somehow this proposal were accepted and incorporated into the language it would make it nearly impossible to later achieve the above. Having both would be confusing, because the behavioral difference is extremely narrow. Your syntax at that point really just silences lossy implicit conversions and would actually be more similar to what one might expect from:
function my_substr ( @string $string, @int $start ){..}

> Sure.  But I'd argue that anything except foo(int $foo) would have lead to FAR more confusion.
>

I don't think any other syntax is even an option. This syntax is used by existing type hints in PHP, and in the PHP documentation, and in basically all generated library documentation, and used for parameter types in every syntactically similar language.

> This way, it's re-using an existing syntax that **every** intermediate developer is intimate with, and applying it to a case that's basically functioning along the same lines...
>

And reusing that syntax leads this straight into the dead end indicated previously when talking about the FC objective.

John Crenshaw
Priacta, Inc.

---

## #58759 — Simon Schick — 2012-03-08T00:41:39+00:00

URL: https://externals.io/message/58637#58759 · In reply to: #58743

Hi Arvids,

I pretty much like this idea as it's more strict. Let me say something
to the questions you pointed out here.

2012/3/7 Arvids Godjuks <arvids.godjuks@gmail.com>:
> I realize that with scalars it's not that straight forward, but
> complicating things by adding an auto-cast syntax and so on is just
> ridiculous. Hints should stay, well, hints. The only problem we have
> is complications of accepting numerical strings or numbers as strings.
> And what to do with "null".

I'd like to handle it the same way as it's handled with the classes
right now. If null is not the default-value you'll get an error when
you pass null in there.
One thing I'd like opened here: If you define a default-value
different than null, should you be able to pass null as well and the
compiler will use the default-value?

> function a(bool $bool) {}
> a(10); // Kill your self against the wall - write a(true);
> If you define bool - use the damn bool!

I like that. What should we do if this appears? As it's now - just
throw an "Catchable fatal error" and let the script blow-up? I would
go this far.

>
> I consider interchangeable only three cases:
> 1. Numerical string.
> 2. Integers and floats as strings.
> 3. Integer and string  0 1 as bool.
>
> Any other cases should error out.

Until now I thought about the weak variable-types as a order ...
string, float, integer, Boolean.
All Boolean values are compatible be an integer (0 or 1) and all
integer are compatible to a float and so on. Do you think it's good to
have it this way? This would mean that you could also get a Boolean
true as string "1" ... I personally don't like that ... but I don't
know where to draw the strict-line.
Now think about that backwards. Can a "1" be passed as a parameter
that expects Boolean? If yes, I'd keep it consistent in both ways.

Bye
Simon

---

## #58760 — Anthony Ferrara — 2012-03-08T00:54:34+00:00

URL: https://externals.io/message/58637#58760 · In reply to: #58757

John,

Thanks a lot for the reply.  Comments inline:

> You've been spending a lot of time defending these proposals and trying to prove wrong feedback that raises concerns. This is preventing you from actually using the feedback to improve the proposals. You are losing out on perhaps the biggest advantage of the RFC process, which is that multiple minds can work together to hammer out an idea and make it really shine.

I only defended what I thought were misconceptions or miss-information
about them.  After all, the quickest way to a failure is assumption
(granted, this is ironic given the rest of this reply)...

> You can mince words, but that doesn't change the problem. It is utterly inconsistent with the expectations in creates. You'll argue that it creates an expectation of a type cast, but you'd be wrong  in far too many cases. The syntax is similar enough to the syntax for parameter types in other languages that developers will think of it as basically the same thing. The syntax differs however from existing parameter type syntax.

That was intentional.  That was the point I was trying to make...  But
let's keep going.

> The behavioral difference is also a problem, being too different from parameter typing to be useful (it doesn't actually vet the parameter), and yet close enough to validate the confusion (behaves too similarly to an implicit conversion). In the end you have a bizarre syntax that looks like one thing but is conceptually another, but with a subtle behavioral difference that is invisible except when it fails to fail.

Again, up to this point, this fits in with what was intended...

> I know about the behavioral difference. I'm not talking about a technical conflict, I'm talking about a conflict in the mind of the developer. Given function(array $a, (array) $b){} the difference between $a and $b is a very advanced distinction and will be completely lost by the average developer.

I actually think that it's not that advanced of a distinction, but
agree to disagree there.

> The confusion is made worse by the fact that function(array $a) works, but function(int $a) doesn't, but function((int) $a) does. I know why, but the average developer just learning PHP for the first time won't get it at all.

I won't argue that, but I would make the assertion that there are far
more dangerous things that PHP does that the average developer just
learning PHP won't get.  But again, let's go on...

> Sometimes I think you miss the point on purpose.
>
> In the docs substr is defined as:
> string substr ( string $string , int $start [, int $length ] )
>
> If I wanted to write the same thing in my own code I would have to write:
> function my_substr ( (string) $string , (int) $start , (int) $length )
>
> One syntax for the docs, a different one in my code.

Now, finally we get to a solid point.  I didn't make the connection to
the parameter hinting in the docs that you meant.  You said "syntax in
the docs", and I was thinking about the casting syntax, which is why I
asserted that both the syntax and the behavior are inline with the
docs.

We were both right, just talking about very different things.

Now, with that said, I completely see your point.

> Well, if you argue that this proposal is actually a typecasting enhancement and not a parameter type enhancement, then yes, you'd be right. That's not how this is presented though, that's not where it is presented (Scalar Type Hinting discussion), that's not when it was presented, and that's not how it is getting perceived or measured.

Well, I think that's part of the problem here.  People (including both
you and me) have so much vested in this discussion, that they are
reading things into the proposal that aren't there (both in a good
way, and a bad way).

> As far as expanding type casting in this way, it doesn't make sense. There is no precedent, it looks and will get treated like parameter hinting (which you are saying it isn't), there is no additional functional value, and very little value of any sort beyond casts (just a tiny documentation boost and a savings in the number of characters in the few cases where a dumb type cast is good enough.)

Well, I think there's a bit more to be gained on both the static
analysis front and the IDE integration front.  Additionally, defensive
coding now only needs to worry about 1 type, and it puts the onus to
ensure proper results on the caller (which is where I would argue it
belongs)...

> Again, yes, I know that the RFC takes a position on this. My point is not that the RFC doesn't take a position, my point was that the position taken "ignores the need that would have caused this sort of code in the first place."

It took a position, because there seemed to be a fair bit of concensus
on the list (in current and past dicussions) that this sort of thing
should explicitly disallow references.  I haven't seen much to the
opposite until:

> Reference parameters are basically return values. Just because a parameter will return a value doesn't mean that the type no longer matters. In fact, it means that the calling function should EXPECT the type to change, and EXPECT the value to be modified. One example that occurs to me off hand is preg_match, where the 3rd parameter is documented as an array reference. You can actually pass anything, but it's going to be an array when the function returns.

That's completely fair.  But I'd argue that it's also never going to
be consistent, since the cast only relies on the passing of the
variable, not the return:

function foo ((int) &$foo) {
    $foo = array();
}
$a = 1;
foo($a);

How the heck did $a become an array, when it was passed as an int?

> You can't raise errors like this on lossy casts. Giving a warning if an implicit conversion loses data (123 + '456xyz', or substr('foo', 'bar')) makes sense, but if I explicitly write (int)'456xyz' or (int)23.7, I must not get a warning about data loss (otherwise it would be difficult/impossible to force a deliberately lossy conversion without warnings). Since we can't raise warnings on casts, you really won't be able to do it with casted parameters either (unless you're willing to accept a consistency break). These will be stuck in silence forever.

Absolutely we can.  The key is not raising errors on all casts, but
distinguishing between explicit and implicit casts.  Explicit casts
always succeed (not sure if that's a good thing IMHO), and implicit
casts error.  I would consider passing a variable to a hinted
parameter would count as an implicit cast, since it's happening
**after** the call begins, which means it would issue an error...

> Well, if that is the case, you did not succeed. The FC break you originally worked to avoid is something that can never happen anyway, and this does not avoid the most critical FC break.

Well, then what's the point?

> First, "strict" types (in the sense of not allowing an integer to be passed to a string parameter) are never going to happen in PHP. Even C++ looks for an implicit conversion and uses that if available. PHP has well defined implicit conversions between scalars, and there is absolutely no chance that PHP is ever going to implement any form of typing that is more strict than typing in C++. A strict set of scalar types hint that don't juggle anything is just not in the cards.

To be clear, PHP does not have a well defined implicit conversion
between scalars.  It has at least 3 of them (actually more, but I'm
not going to count).  Doing $a + 1 causes one set of conversions.
Doing substr($a, 0) does another.  Doing echo $a does another (yes,
zend_parse_parameters and make_printable_zval have different (albiet
slightly) logic).

> Second, (bear with me) the form of typing that people seem to have settled on before this RFC was introduced is "the same typing as the core, but at the language level." To use a prior example, the core has:
> string substr ( string $string , int $start ){...}
>
> and the following behavior:
> substr('foo', 'bar'); // `E_WARNING` 
> substr(123, '1'); // '23'
>
> I should be able to write an equivalent:
>
> function my_substr ( string $string , int $start ){..}
>
> and I should get matching behavior:
> my_substr('foo', 'bar'); // `E_WARNING` 
> my_substr(123, '1'); // '23'
>
> Now here's the point, if somehow this proposal were accepted and incorporated into the language it would make it nearly impossible to later achieve the above. Having both would be confusing, because the behavioral difference is extremely narrow. Your syntax at that point really just silences lossy implicit conversions and would actually be more similar to what one might expect from:
> function my_substr ( @string $string, @int $start ){..}

Fair enough...

> > […]
>
> I don't think any other syntax is even an option. This syntax is used by existing type hints in PHP, and in the PHP documentation, and in basically all generated library documentation, and used for parameter types in every syntactically similar language.

Now we understand each other fully...

> And reusing that syntax leads this straight into the dead end indicated previously when talking about the FC objective.

Point taken.

I've withdrawn the parameter hinting RFC.



I truely thank you for helping me understand your concerns.  I only
wish they could have been shared more clearly at the POC phase so we
could have avoided this altogether...

Thanks,

Anthony

---

## #58761 — Simon Schick — 2012-03-08T00:54:42+00:00

URL: https://externals.io/message/58637#58761 · In reply to: #58759

Hi,

Just a small addition to what I wrote about handling null ...

function foo(array $d = array()) { var_dump($d); }
foo(null); // This fails with the message: Argument 1 passed to foo()
must be an array, null given

As this code fails I'd not expect to change this behavior for the weak-types.

function foo(int $d = 20) { var_dump($d); }
foo(null); // This should then also fail. Don't care about what's the
default-value.

Bye
Simon

2012/3/8 Simon Schick <simonsimcity@googlemail.com>:
> Hi Arvids,
>
> I pretty much like this idea as it's more strict. Let me say something
> to the questions you pointed out here.
>
> 2012/3/7 Arvids Godjuks <arvids.godjuks@gmail.com>:
> > […]
>
> I'd like to handle it the same way as it's handled with the classes
> right now. If null is not the default-value you'll get an error when
> you pass null in there.
> One thing I'd like opened here: If you define a default-value
> different than null, should you be able to pass null as well and the
> compiler will use the default-value?
>
> > […]
>
> I like that. What should we do if this appears? As it's now - just
> throw an "Catchable fatal error" and let the script blow-up? I would
> go this far.
>
> > […]
>
> Until now I thought about the weak variable-types as a order ...
> string, float, integer, Boolean.
> All Boolean values are compatible be an integer (0 or 1) and all
> integer are compatible to a float and so on. Do you think it's good to
> have it this way? This would mean that you could also get a Boolean
> true as string "1" ... I personally don't like that ... but I don't
> know where to draw the strict-line.
> Now think about that backwards. Can a "1" be passed as a parameter
> that expects Boolean? If yes, I'd keep it consistent in both ways.
>
> Bye
> Simon

---

## #58762 — John Crenshaw — 2012-03-08T01:14:02+00:00

URL: https://externals.io/message/58637#58762 · In reply to: #58760

> Now we understand each other fully...
> 
> Point taken.
> 
> I've withdrawn the parameter hinting RFC.
> 

Thanks...and aw crap. I hate feeling like I shut the door on something.

Let's make sure we can salvage as much as possible here:
1. The structure of the patch looked like it was reusable regardless of whether the final syntax used a typename of a cast, right? Let's not lose that.
2. Examining parameters from this perspective gave some good insight into the behavior of the system when implicitly converting inputs.

> I truely thank you for helping me understand your concerns.  I only wish they could have been shared more clearly at the POC phase so we could have avoided this altogether...
> 
> Thanks,
> 
> Anthony

I'm sorry for not raising the concerns well enough earlier.

John Crenshaw
Priacta, Inc.

---

## #58763 — Anthony Ferrara — 2012-03-08T01:20:40+00:00

URL: https://externals.io/message/58637#58763 · In reply to: #58762

John,

> Thanks...and aw crap. I hate feeling like I shut the door on something.

Not at all.  I don't feel bad about this in the least.  Yes, I would
have liked to have gotten it in, but I want a good solution before I
want mine.  So I'm absolutely willing to withdraw this RFC, as it does
have issues.

And it's not really shutting the door.  It's moving a roadblock over
so that another (hopefully better) proposal can take its place...

> Let's make sure we can salvage as much as possible here:
> 1. The structure of the patch looked like it was reusable regardless of whether the final syntax used a typename of a cast, right? Let's not lose that.

Yeah, there was some in there that I definitely learned from.
Including that the casting logic in the core is really in bad shape
(it's everywhere!).

> 2. Examining parameters from this perspective gave some good insight into the behavior of the system when implicitly converting inputs.

Oh, doing the RFC and the patch definitely had value.  It's not like
it's lost effort (and the reference is on the wiki still).  And I'm
glad I did a finalized patch, since it showed that some API change (on
C level) would be necessary (namely the argument parsing function, to
accept a double-pointer instead of a single one).

> I'm sorry for not raising the concerns well enough earlier.

You did.  We just didn't connect and understand each other (or I
didn't understand you) earlier.  But that's behind.  Let's move up and
on...

So, that leaves the question: where to go next...  (I have a somewhat
radical proposal that I'd like to make to list that's somewhat
releated, but I'm going to think it out first before posting)...


Thanks again,

Anthony

---

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