# [RFC] Enable strict_types checking for curl_setopt()

- Thread: https://externals.io/message/98843
- Original archive: https://news-web.php.net/php.internals/98843
- Started by Colin O'Dell on 2017-04-22T11:40:27+00:00
- Messages: 27
- Page 1 of 2: messages 1 to 25 (25 per page, add `?page=N` to the URL)
- Next page: https://externals.io/message/98843.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

---

## #98843 — Colin O'Dell — 2017-04-22T11:40:27+00:00

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

Hello internals,

I'd like to propose an enhancement to `curl_setopt()`
<http://php.net/manual/en/function.curl-setopt.php> which is used to
configure a given curl session.  The second argument of this function
defines which option to set and the third argument provides the
corresponding value to use.

Because each option expects the value to be a specific type, it makes sense
to enforce these types in strict type checking mode.  I'd therefore like to
propose that we introduce strict type enforcement inside `curl_setopt()` when
"declare(strict_types=1);" is being used.

The full details of the proposal, including the proposed patch, can be
found here: https://wiki.php.net/rfc/curl_setopt_strict_types

Huge thanks to Sara Golemon for the idea and creating the patch!

Cheers,

Colin O'Dell
colinodell@gmail.com

---

## #98848 — Sara Golemon — 2017-04-22T18:10:50+00:00

URL: https://externals.io/message/98843#98848 · In reply to: #98843

> I'd like to propose an enhancement to `curl_setopt()`
> <http://php.net/manual/en/function.curl-setopt.php> which is used to
> configure a given curl session.  The second argument of this function
> defines which option to set and the third argument provides the
> corresponding value to use.
>
> Because each option expects the value to be a specific type, it makes sense
> to enforce these types in strict type checking mode.  I'd therefore like to
> propose that we introduce strict type enforcement inside `curl_setopt()` when
> "declare(strict_types=1);" is being used.
>
> The full details of the proposal, including the proposed patch, can be
> found here: https://wiki.php.net/rfc/curl_setopt_strict_types
>
A note on the current state of the PR: Colin's RFC is based on the
first commit in that PR, but after more thought and some feedback from
NikiC, I piled a refactor on top of it which quite notably changes the
weak-mode handling.  See
https://github.com/php/php-src/pull/2495#issuecomment-296383366

So some decisions to make yet regarding precisely *how* we'd land the
final commit, but I hope we can all agree the intent stated in the RFC
is pretty sound: Improve type checking in `curl_setopt()` without
screwing over the majority of existing users.

-Sara

---

## #98863 — Stanislav Malyshev — 2017-04-24T20:20:10+00:00

URL: https://externals.io/message/98843#98863 · In reply to: #98843

Hi!

> Because each option expects the value to be a specific type, it makes sense
> to enforce these types in strict type checking mode.  I'd therefore like to
> propose that we introduce strict type enforcement inside `curl_setopt()` when
> "declare(strict_types=1);" is being used.

While it may make sense to check types per-option, that's not exactly
what scalar types are supposed to do - this is not argument typing, this
is internal function business logic, and I am not sure confusing the two
is really that good an idea.

-- 
Stas Malyshev
smalyshev@gmail.com

---

## #98864 — Fleshgrinder — 2017-04-24T20:24:19+00:00

URL: https://externals.io/message/98843#98864 · In reply to: #98863

> Hi!
> 
> > […]
> 
> While it may make sense to check types per-option, that's not exactly
> what scalar types are supposed to do - this is not argument typing, this
> is internal function business logic, and I am not sure confusing the two
> is really that good an idea.
> 

I completely agree with Stanislav at this point. `curl_setopt` can and
probably should validate the types of the various options, it may even
throw a `TypeError`, but it most certainly should not depend on the
`strict_types` declaration.

-- 
Richard "Fleshgrinder" Fussenegger

---

## #98865 — Sara Golemon — 2017-04-24T22:50:32+00:00

URL: https://externals.io/message/98843#98865 · In reply to: #98864

> 
> > […]
>
> I completely agree with Stanislav at this point. `curl_setopt` can and
> probably should validate the types of the various options, it may even
> throw a `TypeError`, but it most certainly should not depend on the
> `strict_types` declaration.
>
I disagree. From the user's perspective it is argument typing.  The
internal implementation detail of that argument type being dependent
on another arg's value is just a detail.

-Sara

---

## #98866 — Stanislav Malyshev — 2017-04-24T23:09:26+00:00

URL: https://externals.io/message/98843#98866 · In reply to: #98865

Hi!

> I disagree. From the user's perspective it is argument typing.  The

Not really. Argument typing is when arguments have types. curl_setopt
arguments do not have known types, they have business logic inside that
says if argument X is equal to this, then argument Y must be of that
type. It's very different from what strict_types does.

> internal implementation detail of that argument type being dependent
> on another arg's value is just a detail.

It's not "just a detail", it's the whole point of it. The value argument
does not have a know type, it is typed only when you know the exact
value of another argument (and sometimes not even then - e.g.
 `CURLOPT_POSTFIELDS` accepts both strings and arrays). We don't have "type
that is defined by another type" in the type system, it's clearly
business logic. Which I have no problem with, but it shouldn't be part
of type system then.
-- 
Stas Malyshev
smalyshev@gmail.com

---

## #98867 — Sara Golemon — 2017-04-24T23:55:25+00:00

URL: https://externals.io/message/98843#98867 · In reply to: #98866

> it's clearly
> business logic. Which I have no problem with, but it shouldn't be part
> of type system then.
>
We're certainly arguing semantics at this point.  Let's agree that
type enforcement is a good thing (which you seemed to say in your
first response) and move on to how that's implemented.

Why shouldn't we allow the same call-time decision making around
strict/weak enforcement to apply to "business logic" type enforcement
as it does to argument types?  Surely consistency is a good thing as
well?

-Sara

---

## #98872 — michal.brzuchalski@gmail.com — 2017-04-25T04:00:23+00:00

URL: https://externals.io/message/98843#98872 · In reply to: #98867

25.04.2017 01:56 "Sara Golemon" <pollita@php.net> napisał(a):
>
> On Mon, Apr 24, 2017 at 4:09 PM, Stanislav Malyshev <smalyshev@gmail.com>
wrote:
> > […]
> We're certainly arguing semantics at this point.  Let's agree that
> type enforcement is a good thing (which you seemed to say in your
> first response) and move on to how that's implemented.

I agree with Stanislav. IMHO argument types are valueable when are
reflective by reflection and curl_setopt has no valuable info by reflection
and will never be. Curl implementation also uses resources cURL handle is
used. Maybe it's time to refactor and provide objects with option setters
with argument types?

>
> Why shouldn't we allow the same call-time decision making around
> strict/weak enforcement to apply to "business logic" type enforcement
> as it does to argument types?  Surely consistency is a good thing as
> well?
>
> -Sara

---

## #98877 — Sara Golemon — 2017-04-25T15:56:57+00:00

URL: https://externals.io/message/98843#98877 · In reply to: #98872

On Mon, Apr 24, 2017 at 9:00 PM, Michał Brzuchalski
<michal.brzuchalski@gmail.com> wrote:
> I agree with Stanislav. IMHO argument types are valueable when are
> reflective by reflection and curl_setopt has no valuable info by reflection
> and will never be. Curl implementation also uses resources cURL handle is
> used.
>
Literally zero internal functions have argument type reflection
(beyond class and array types).  `curl_setopt()` is not and would not be
any different in this regard.

https://3v4l.org/2BtPW

> Maybe it's time to refactor and provide objects with option setters
> with argument types?
>
I do agree there.  I've got a WiP "cURLi" extention in my homedir that
I've been poking at since ZendCon 2016.  I suppose if we don't put
type checking in `curl_setopt()` then that'll just push users who care
about type safety towards cURLi. :D

-Sara

---

## #98878 — Rowan Collins — 2017-04-25T16:37:41+00:00

URL: https://externals.io/message/98843#98878 · In reply to: #98877

> > […]
>I do agree there.  I've got a WiP "cURLi" extention in my homedir that
>I've been poking at since ZendCon 2016.  I suppose if we don't put
>type checking in `curl_setopt()` then that'll just push users who care
>about type safety towards cURLi. :D

Oh, lordy, yes please! The curl API is absolutely horrible, and just crying out for a more sane wrapper to be built into the language, rather than everyone writing their own messy classes.

Please can we also set some sane defaults (e.g. CURLOPT_RETURNTRANSFER) and a small amount of extra logic (e.g. capturing return headers) so that using it doesn't require a dozen lines of boilerplate to be useful?

Thanks,

-- 
Rowan Collins
[IMSoP]

---

## #98880 — Fleshgrinder — 2017-04-25T17:28:58+00:00

URL: https://externals.io/message/98843#98880 · In reply to: #98877

> On Mon, Apr 24, 2017 at 9:00 PM, Michał Brzuchalski
> <michal.brzuchalski@gmail.com> wrote:
> > […]
> Literally zero internal functions have argument type reflection
> (beyond class and array types).  `curl_setopt()` is not and would not be
> any different in this regard.
> 
> https://3v4l.org/2BtPW
> 
> > […]
> I do agree there.  I've got a WiP "cURLi" extention in my homedir that
> I've been poking at since ZendCon 2016.  I suppose if we don't put
> type checking in `curl_setopt()` then that'll just push users who care
> about type safety towards cURLi. :D
> 
> -Sara
> 

Way to go. This RFC is just wrong, and not _simply_ about semantics.

-- 
Richard "Fleshgrinder" Fussenegger

---

## #98881 — Andrea Faulds — 2017-04-25T22:51:03+00:00

URL: https://externals.io/message/98843#98881 · In reply to: #98872

Hi Michał,

Michał Brzuchalski wrote:
>IMHO argument types are valueable when are
> reflective by reflection and curl_setopt has no valuable info by reflection
> and will never be.

Neither do the vast majority of internal functions with parameter type 
checking.

-- 
Andrea Faulds
https://ajf.me/

---

## #98898 — Markus Fischer — 2017-04-28T14:34:46+00:00

URL: https://externals.io/message/98843#98898 · In reply to: #98843

Hi,


> Hello internals,
>
> I'd like to propose an enhancement to `curl_setopt()`
> <http://php.net/manual/en/function.curl-setopt.php> which is used to
> configure a given curl session.  The second argument of this function
> defines which option to set and the third argument provides the
> corresponding value to use.
>
> Because each option expects the value to be a specific type, it makes sense
> to enforce these types in strict type checking mode.  I'd therefore like to
> propose that we introduce strict type enforcement inside `curl_setopt()` when
> "declare(strict_types=1);" is being used.

I'm sorry to say but I think this /approach/ is a horrible idea :(

To me the intention of strict types is clearly on the functions publicly 
visible contract, i.e. it's reflectable parameters and not some business 
logic hidden inside a function.

regards,
- Markus

---

## #98899 — Sara Golemon — 2017-04-28T17:54:09+00:00

URL: https://externals.io/message/98843#98899 · In reply to: #98898

> To me the intention of strict types is clearly on the functions publicly
> visible contract, i.e. it's reflectable parameters and not some business
> logic hidden inside a function.
>
So you feel that declare(strict_types=1); should never apply to
internal functions?

-Sara

---

## #98900 — Rowan Collins — 2017-04-28T19:29:52+00:00

URL: https://externals.io/message/98843#98900 · In reply to: #98899

>On Fri, Apr 28, 2017 at 9:34 AM, Markus Fischer <markus@fischer.name>
>wrote:
> > […]
>publicly
> > […]
>business
> > […]
>So you feel that declare(strict_types=1); should never apply to
>internal functions?

I don't see that assertion implied in any of the objections on this thread. The objection is that type checking currently only occurs at function boundaries: their signatures are matched against provided parameters, and their return declarations against returned values. The entire feature is equivalent to the compiler injecting either casts (weak mode) or assertions (strict mode) at the beginning and end of function definitions, *and nowhere else*.

This RFC introduces a check at a different point in the function: after the parameters have been examined, based not on the signature of the function, but an internal set of rules.

Notably, this is not a type of check that could be made in a userland function - or, rather, it would have to be made unconditionally, since the strict_types setting is explicitly invisible to the callee.

So, while I agree that checking the argument types for `curl_setopt()` is highly desirable, I am sympathetic to the argument that strict_types should not alter those checks.

That leaves us with either checking the types unconditionally (a significantly breaking change) or introducing a new, type-safe, API. That could mean a small but awkward set of type overloads (setBool, setInt, etc), or a large set of named setters (setReturnTransfer, setHeaders, etc) which could use normal parameter hinting to interact with strict_types.

As I mentioned, I think the entire PHP curl API is unnecessarily complicated to use, and the overloading of parameter types in curl_setopt actually contributes to this rather than simplifying anything.

Regards,

-- 
Rowan Collins
[IMSoP]

---

## #98901 — Sara Golemon — 2017-04-28T21:30:35+00:00

URL: https://externals.io/message/98843#98901 · In reply to: #98900

> 
> > […]
>
> I don't see that assertion implied in any of the objections on this thread.
>
It's implied by the statement of yours that I quoted. "To me the
intention of strict types is clearly on the functions publicly visible
contract, i.e. it's reflectable parameters and not some business logic
hidden inside a function."

Internal functions do not have reflectable type hints (apart from
array and object), ergo by your criteria you feel that strict types
does not apply.  Your words.

> The objection is that type checking currently only occurs at function boundaries:
> their signatures are matched against provided parameters, and their return
> declarations against returned values. The entire feature is equivalent to the
> compiler injecting either casts (weak mode) or assertions (strict mode) at the
> beginning and end of function definitions, *and nowhere else*.
>
But that isn't how strict type enforcement works in internal
functions.  I realize I'm being pedantic here, but since the objection
is on semantics grounds, I feel I must apply the same standards of
semantics to the counter argument.

The state of the PR at the moment is to apply function-entrance
criteria to arguments, the only thing which makes it (somewhat)
special is the degree of deferment from the C function entry till the
types are checked.  I say "somewhat", because it is not unique in this
regard, many internal functions apply varying signatures based on
initial argument and/or number of arguments.  See pg_*() functions for
my favorite example of this, though there are several examples in
standard as well.

> This RFC introduces a check at a different point in the function:
> after the parameters have been examined, based not on the
> signature of the function, but an internal set of rules.
>
Repeat; See above, this is not unique.

> Notably, this is not a type of check that could be made in a userland function -
> or, rather, it would have to be made unconditionally, since the strict_types setting
> is explicitly invisible to the callee.
>
Agreed, but userland and internal functions are not created equal and
this behavior is still not without precedent.

> So, while I agree that checking the argument types for `curl_setopt()` is highly desirable,
> I am sympathetic to the argument that strict_types should not alter those checks.
>
We disagree.

> That leaves us with either checking the types unconditionally (a significantly breaking change)
> or introducing a new, type-safe, API.
>
It also leaves us with the third option of what is presented by the
PR.  You do not have absolute veto.

> That could mean a small but awkward set of type overloads
> (setBool, setInt, etc), or a large set of named setters
> (setReturnTransfer, setHeaders, etc) which could use
> normal parameter hinting to interact with strict_types.
>
Eww. Eww. And eew.

I reject the idea of making a worse API for the sake of an artificial
purity standard which has long since been violated elsewhere.

> As I mentioned, I think the entire PHP curl API is unnecessarily complicated
> to use, and the overloading of parameter types in curl_setopt actually
> contributes to this rather than simplifying anything.
>
I agree that the overloading of the `curl_setopt()` function is the
cause of a problem.  I just disagree that allowing opt-in validation
of those types fails to solve it.

-Sara

---

## #98903 — Rowan Collins — 2017-04-28T23:05:34+00:00

URL: https://externals.io/message/98843#98903 · In reply to: #98901

>On Fri, Apr 28, 2017 at 2:29 PM, Rowan Collins
><rowan.collins@gmail.com> wrote:
> > […]
>thread.
> > […]
>It's implied by the statement of yours that I quoted. "To me the
>intention of strict types is clearly on the functions publicly visible
>contract, i.e. it's reflectable parameters and not some business logic
>hidden inside a function."
>
>Internal functions do not have reflectable type hints (apart from
>array and object), ergo by your criteria you feel that strict types
>does not apply.  Your words.

Just to clarify, I jumped into the thread to put my explanation of what I think people were objecting to. It is not my words you are quoting there, they don't speak for me, and I don't speak for them. My apologies for the confusion.

Personally, I don't think the literal fact of reflection not being available is all that relevant either way. It's certainly not the objection I was raising.


> > […]
>boundaries:

>  I say "somewhat", because it is not unique in this
>regard, many internal functions apply varying signatures based on
>initial argument and/or number of arguments.  See pg_*() functions for
>my favorite example of this, though there are several examples in
>standard as well.

Then I stand corrected. I was unaware that there were already internal functions which performed checking that couldn't be done the same way in userland; specifically, that checked more than basic signatures, but only under strict_types mode. Nor did I spot those examples in this thread, so it's possible that other people are also unaware of that precedent. But again, to be clear, it may just be me.


> > […]
>is highly desirable,
> > […]
>those checks.
> > […]
>We disagree.

Fair enough.


> > […]
>significantly breaking change)
> > […]
>It also leaves us with the third option of what is presented by the
>PR.  You do not have absolute veto.

I never claimed to have any sort of veto, I don't even have formal voting rights, I just have an opinion. What I meant was "it leaves two options which I would back right now, based on the reservations I just explained". Other people can back whatever options they like, including the fourth option of "no change", or ideas neither us have thought of.


> > […]
>Eww. Eww. And eew.
>
>I reject the idea of making a worse API for the sake of an artificial
>purity standard which has long since been violated elsewhere.

Personally, I think if we were designing from scratch, having a setHeaders method which took an array (and an associative one at that) would seem a better API than a weird polymorphic function with a manual page a mile long.

Regards,

-- 
Rowan Collins
[IMSoP]

---

## #98904 — Sara Golemon — 2017-04-28T23:30:06+00:00

URL: https://externals.io/message/98843#98904 · In reply to: #98903

> > […]
>
> Personally, I think if we were designing from scratch, having a
> setHeaders method which took an array (and an associative
> one at that) would seem a better API than a weird polymorphic
> function with a manual page a mile long.
>
We can agree on this, and others in this thread have said as much as
well.  I've also mentioned that I've been poking at a new curl binding
since last November.  Funnily enough, it's a mix of a
monolithic/polymorphic setOpt() method and where appropriate,
setSomeSpecificThing() methods.

When I get it to a stable point I'll toss it on github.

-Sara

---

## #98905 — Rowan Collins — 2017-04-29T15:01:50+00:00

URL: https://externals.io/message/98843#98905 · In reply to: #98904

>On Fri, Apr 28, 2017 at 6:05 PM, Rowan Collins
><rowan.collins@gmail.com> wrote:
> > […]
>We can agree on this, and others in this thread have said as much as
>well.  I've also mentioned that I've been poking at a new curl binding
>since last November.  Funnily enough, it's a mix of a
>monolithic/polymorphic setOpt() method and where appropriate,
>setSomeSpecificThing() methods.

That mix sounds very reasonable. Does it still make you go "eww" to suggest that those settings that don't deserve their own method, and take a boolean argument rather than a string or int, could have a different method, such as setFlag? Because that's really all I was suggesting: a more visible distinction that said "this method always takes a boolean", rather than "this method must be given a boolean if given this, that, or the other".


Meanwhile, I'll repeat that if there really is precedent for functions validating their arguments based on both strict_types mode and the value of some other parameter, then my concern (mostly) evaporates, and I suspect others' might also. I just checked through the thread and RFC, and can't see these examples being named, so I would very much appreciate a specific example.

Perhaps the precedents seem obvious to you, and that's why this whole conversation is frustrating you? It definitely feels like there is some miscommunication, because you seem surprised that people have any concerns at all.

Regards,
-- 
Rowan Collins
[IMSoP]

---

## #98906 — Sara Golemon — 2017-04-29T15:53:43+00:00

URL: https://externals.io/message/98843#98906 · In reply to: #98905

> That mix sounds very reasonable. Does it still make you go "eww" to suggest
> that those settings that don't deserve their own method, and take a boolean
> argument rather than a string or int, could have a different method, such as
> setFlag? Because that's really all I was suggesting: a more visible
> distinction that said "this method always takes a boolean", rather than
> "this method must be given a boolean if given this, that, or the other".
>
It certainly seems unnecessary.  setBool(), setInt(), setOffset(),
setString(), versus setOption() is imposing a design detail on the
consumer that shouldn't be relevant to them.  In fact, in weak mode,
it becomes especially irrelevant to know the difference between an int
and a bool setting.  Specifying type in the method name is essentially
imposing a cognitive form of strict mode on those who don't want it.

> Meanwhile, I'll repeat that if there really is precedent for functions
> validating their arguments based on both strict_types mode and the value of
> some other parameter, then my concern (mostly) evaporates, and I suspect
> others' might also. I just checked through the thread and RFC, and can't see
> these examples being named, so I would very much appreciate a specific
> example.
>
Not on *both* strict mode and the value of another parameter, there's
very little application of strict mode throughout the codebase because
strict mode is new.  What there are precedents of, and what I was
responding to in your earlier email, was the idea that an arguments
type can vary based on the type and/or number of other arguments.
This precedent exists in the pg_*() methods as I already pointed you
at, and a quick grep shows `stream_context_set_option()`, and a
particularly fascinating "signature" in intlcal_set().

> Perhaps the precedents seem obvious to you, and that's why this whole
> conversation is frustrating you? It definitely feels like there is some
> miscommunication, because you seem surprised that people have any concerns
> at all.
>
I'm not surprised that there are concerns, I'm just shocked that the
concerns are so poorly founded.  Arguments I've heard so far fall into
two categories.

1. If the parameter isn't reflectable, then it shouldn't be subject to
enforcement.
This argument holds no water because internal functions can only
reflect array or object type hints, yet we enforce other types
routinely.

2. Type enforcement should not depend on the declare(strict_types=1); directive.
This argument is ridiculous on the face of it, since that's precisely
what that declare() directive was designed for.  The fact that the
type being enforced is dependent on another arg's value is an
irrelevant implementation detail.  Think about the user's experience
here.  Bob wants to call curl_setopt($ch, CURLOPT_RETURNTRANSFER,
$value);   Bob expects $value to be validated and used as a boolean.
If Bob has strict_types set, he expects an exception if $value isn't a
bool, if it's not set, he expects the value to be quietly converted
(if possible within type affinity).

-Sara

---

## #98907 — Fleshgrinder — 2017-04-29T16:11:14+00:00

URL: https://externals.io/message/98843#98907 · In reply to: #98906

> Not on *both* strict mode and the value of another parameter, there's
> very little application of strict mode throughout the codebase because
> strict mode is new.  What there are precedents of, and what I was
> responding to in your earlier email, was the idea that an arguments
> type can vary based on the type and/or number of other arguments.
> This precedent exists in the pg_*() methods as I already pointed you
> at, and a quick grep shows `stream_context_set_option()`, and a
> particularly fascinating "signature" in intlcal_set().
> 

There is nothing wrong about having business rules inside that check
types based on another argument. The problem we are pointing out is
about those business rules making use strict types.


> I'm not surprised that there are concerns, I'm just shocked that the
> concerns are so poorly founded.  Arguments I've heard so far fall into
> two categories.
> 
> 1. If the parameter isn't reflectable, then it shouldn't be subject to
> enforcement.
> This argument holds no water because internal functions can only
> reflect array or object type hints, yet we enforce other types
> routinely.
> 
> 2. Type enforcement should not depend on the declare(strict_types=1); directive.
> This argument is ridiculous on the face of it, since that's precisely
> what that declare() directive was designed for.  The fact that the
> type being enforced is dependent on another arg's value is an
> irrelevant implementation detail.  Think about the user's experience
> here.  Bob wants to call curl_setopt($ch, CURLOPT_RETURNTRANSFER,
> $value);   Bob expects $value to be validated and used as a boolean.
> If Bob has strict_types set, he expects an exception if $value isn't a
> bool, if it's not set, he expects the value to be quietly converted
> (if possible within type affinity).
> 
> -Sara
> 

Let me be Bob, and my assumption would be completely different. I expect
that internals behave the same as userland implementations. I know that
this is not the case in every circumstance, but those where this
assumption does not hold true are meant to cover very special edge
cases, like GMP. I consider many others as being ugly hacks.

I expect strict types to affect the arguments I pass to a routine, not
more, not less. The fact that internals are not reflective is sad, we
most probably should do something about that. Regardless, this
expectation and/or assumption holds true.

In other words, I consult the docs and if the signature states an
expected type for a parameter of a routine, I expect strict types to
validate that for me, not more, not less. The docs of `curl_setopt`
states `mixed` for `$value` and that is what I expect.

https://php.net/curl-setopt

This does not mean that it is not allowed to throw an exception if the
value is of another type, but it must not use strict types to determine
its mode. Simply because I cannot do the same in userland.

-- 
Richard "Fleshgrinder" Fussenegger

---

## #98908 — Sara Golemon — 2017-04-29T16:25:45+00:00

URL: https://externals.io/message/98843#98908 · In reply to: #98907

> Let me be Bob, and my assumption would be completely different. I expect
> that internals behave the same as userland implementations. I know that
> this is not the case in every circumstance, but those where this
> assumption does not hold true are meant to cover very special edge
> cases, like GMP. I consider many others as being ugly hacks.
>
Your example of GMP can't be simply dismissed as "a special edge
case", it's precisely true that internals does not always follow the
same rules as userspace and often it breaks those rules for very good
reason.

> I expect strict types to affect the arguments I pass to a routine, not
> more, not less.
>
Agreed.  And that's what this proposal suggests.  If I took at your
word here, I would expect you to support this RFC.

> In other words, I consult the docs and if the signature states an
> expected type for a parameter of a routine, I expect strict types to
> validate that for me, not more, not less. The docs of `curl_setopt`
> states `mixed` for `$value` and that is what I expect.
>
> https://php.net/curl-setopt
>
Again, you're weakening your own position.  The PHP manual page for
 `curl_setopt()` GOES ON to state the per-option types which should be
passed for $value.  I expect strict types to validate that for me, not
more, not less.  The fact that you fail to read past the first line of
the manual page doesn't invalidate the function's *total* signature.

> This does not mean that it is not allowed to throw an exception if the
> value is of another type, but it must not use strict types to determine
> its mode. Simply because I cannot do the same in userland.
>
Again, false.  The fact* that something can not be done in userland
does not preclude doing it in internals.  You mentioned one such case
at the start of your reply and there are plenty others.

-Sara

* Pedantically: This is not even true.  Using backtraces and some
simple hacks, it's quite possible to determine the caller's
strict_types setting from userspace.  But that's going off on a
tangent...

---

## #98909 — Christoph M. Becker — 2017-04-29T17:17:06+00:00

URL: https://externals.io/message/98843#98909 · In reply to: #98907

> The fact that internals are not reflective is sad, we
> most probably should do something about that.
As of PHP 7.0.0 there is ZEND_ARG_TYPE_INFO[1] which is not yet used,
though, presumably due to BC concerns.

[1]
<https://php-lxr.adamharvey.name/source/xref/PHP-7.0/Zend/zend_API.h#107>

-- 
Christoph M. Becker

---

## #98910 — Fleshgrinder — 2017-04-29T17:43:00+00:00

URL: https://externals.io/message/98843#98910 · In reply to: #98908

> Your example of GMP can't be simply dismissed as "a special edge
> case", it's precisely true that internals does not always follow the
> same rules as userspace and often it breaks those rules for very good
> reason.
> 

I only said that I do not consider GMP being a dirty hack. I still think
that it is very wrong that we cannot achieve the same in userland.
Operator overloading is something I would love to see.


> Again, you're weakening your own position.  The PHP manual page for
> `curl_setopt()` GOES ON to state the per-option types which should be
> passed for $value.  I expect strict types to validate that for me, not
> more, not less.  The fact that you fail to read past the first line of
> the manual page doesn't invalidate the function's *total* signature.
> 

No, this is about the logic inside the function and not it's signature.
Part of the signature is everything before the opening brace. Of course
there are still some short-comings here which I hope will be resolved in
the future, e.g. union types, exceptions, generics; for those we are
required to rely on documentation, for now.

I for one am totally in favor of having dedicated methods for all
options on an option class. It makes it straight forward to discover the
possibilities that are available. The implementation is also simple with
the aid of macros. Doing that would mean that the types of the arguments
are part of the signature. Heck, the array arguments could be variadic
and thus type safe.


> Again, false.  The fact* that something can not be done in userland
> does not preclude doing it in internals.  You mentioned one such case
> at the start of your reply and there are plenty others.
> 

Of course we can do it, the question is, if we should do it. It makes
the language unpredictable at times, and that is a bad thing.


> * Pedantically: This is not even true.  Using backtraces and some
> simple hacks, it's quite possible to determine the caller's
> strict_types setting from userspace.  But that's going off on a
> tangent...
> 

More dirty hacks?

I understand that we disagree, but do not try to tell me how I think
about how things should work. Your assumptions/expectations about these
things are built around the idea that strict types is a flag that
changes PHP's behavior. My idea of strict types is built around the idea
that it makes PHP behave they way other sane type safe languages work
(the word sane limits the amount of languages to compare to, Java is
definitely not part of that because of null references, but Kotlin,
Ceylon, Rust, would definitely be candidates).

-- 
Richard "Fleshgrinder" Fussenegger

---

## #98911 — Rowan Collins — 2017-04-29T19:46:34+00:00

URL: https://externals.io/message/98843#98911 · In reply to: #98908

>Your example of GMP can't be simply dismissed as "a special edge
>case", it's precisely true that internals does not always follow the
>same rules as userspace and often it breaks those rules for very good
>reason.

I think the adage applies here that you should first acknowledge rules before you break them. GMP *is* a special case; it is one of very few instances, if not the only instance, of overloading arithmetic operators, and IIRC that was the subject of a whole RFC. It was agreed that the use case justifies the special behaviour.

In this case, we should acknowledge that userland cannot (delta dirty backtrace hack) change behaviour based on strict types inside the body of the function, and in most cases neither sold internal functions. We can then decide if this use case merits breaking that rule or not.

Regards,

-- 
Rowan Collins
[IMSoP]

---

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