Evening internals,
With this message I'd like to go to vote
with the Callable prototypes RFC targeted at 7.1:
https://wiki.php.net/rfc/callable-types
We've renamed it (previously was "Callable types") as RFC names often
dictate how users will call the feature and I want it to be more
accurate/descriptive.
Also the reflection part was added although I'm short on time currently,
so implementation for that will be ready later. (speaking of
implementation,
it also currently doesn't use cache_slots - also something I'll add when
I have a little bit of time)
Evening internals,
With this message I'd like to go to vote
with the Callable prototypes RFC targeted at 7.1:
https://wiki.php.net/rfc/callable-typesWe've renamed it (previously was "Callable types") as RFC names often
dictate how users will call the feature and I want it to be more
accurate/descriptive.Also the reflection part was added although I'm short on time currently,
so implementation for that will be ready later. (speaking of implementation,
it also currently doesn't use cache_slots - also something I'll add when
I have a little bit of time)--
A quick question before I vote: do callable prototypes allow for
default parameters in the signature? There are examples for having a
function passed that has a default parameters but I am not seeing it
anywhere in the callable prototype definition so I thought I'd ask.
Evening internals,
With this message I'd like to go to vote
with the Callable prototypes RFC targeted at 7.1:
https://wiki.php.net/rfc/callable-typesWe've renamed it (previously was "Callable types") as RFC names often
dictate how users will call the feature and I want it to be more
accurate/descriptive.Also the reflection part was added although I'm short on time currently,
so implementation for that will be ready later. (speaking of implementation,
it also currently doesn't use cache_slots - also something I'll add when
I have a little bit of time)--
A quick question before I vote: do callable prototypes allow for
default parameters in the signature? There are examples for having a
function passed that has a default parameters but I am not seeing it
anywhere in the callable prototype definition so I thought I'd ask.
Hey Levi,
Although it could be done as a later RFC, my stance on it is that default values don't belong to the prototype of the function.
Why I think that callable typehint doesn't need default values for params is: you either need this parameter to exist and even if there are cases where you'd like to pass some kind of 'default' value implicitly, you as a caller shouldn't impose on the callee responsibility to have this same value in his definition and instead just pass your argument explicitly... or if you don't need this parameter (as in you don't plan to pass anything explicitly) then you should just ask for a function without this parameter as there is clearly no need for it at all.
Moreover I would argue interfaces have it wrong here too: the fact that default values are part of an interface yet their invariance is not enforced, yields an interesting sort of possible LSP violation. F.e. if we have an interface Logger (a completely unreal example but it shows what can go wrong) with function 'log($message, $level = LOG_DEBUG);' and a funny implementation that decided to change default value of $level to LOG_ALERT, then all callers of Logger#log who relied on the fact that level if not specified, will be LOG_DEBUG, who also happen to get the funny implementation of Logger will produce unneeded noise in the logs with their alert level messages which were intended to be debug messages :(
Evening internals,
With this message I'd like to go to vote
with the Callable prototypes RFC targeted at 7.1:
https://wiki.php.net/rfc/callable-typesWe've renamed it (previously was "Callable types") as RFC names often
dictate how users will call the feature and I want it to be more
accurate/descriptive.Also the reflection part was added although I'm short on time currently,
so implementation for that will be ready later. (speaking of implementation,
it also currently doesn't use cache_slots - also something I'll add when
I have a little bit of time)--
A quick question before I vote: do callable prototypes allow for
default parameters in the signature? There are examples for having a
function passed that has a default parameters but I am not seeing it
anywhere in the callable prototype definition so I thought I'd ask.Hey Levi,
Although it could be done as a later RFC, my stance on it is that default values don't belong to the prototype of the function.
Why I think that callable typehint doesn't need default values for params is: you either need this parameter to exist and even if there are cases where you'd like to pass some kind of 'default' value implicitly, you as a caller shouldn't impose on the callee responsibility to have this same value in his definition and instead just pass your argument explicitly... or if you don't need this parameter (as in you don't plan to pass anything explicitly) then you should just ask for a function without this parameter as there is clearly no need for it at all.
Moreover I would argue interfaces have it wrong here too: the fact that default values are part of an interface yet their invariance is not enforced, yields an interesting sort of possible LSP violation. F.e. if we have an interface Logger (a completely unreal example but it shows what can go wrong) with function 'log($message, $level = LOG_DEBUG);' and a funny implementation that decided to change default value of $level to LOG_ALERT, then all callers of Logger#log who relied on the fact that level if not specified, will be LOG_DEBUG, who also happen to get the funny implementation of Logger will produce unneeded noise in the logs with their alert level messages which were intended to be debug messages :(
Please document this restriction in the RFC. I guess I'm the only one
who expected it to be there since it didn't come up before, but it
just seems missing. You don't need to take it out of voting for this
clarification, imo.
On Mon, May 23, 2016 at 1:19 PM, Nikita Nefedov inefedor@gmail.com
wrote:A quick question before I vote: do callable prototypes allow for
default parameters in the signature? There are examples for having a
function passed that has a default parameters but I am not seeing it
anywhere in the callable prototype definition so I thought I'd ask.Hey Levi,
Although it could be done as a later RFC, my stance on it is that
default values don't belong to the prototype of the function.Why I think that callable typehint doesn't need default values for
params is: you either need this parameter to exist and even if there
are cases where you'd like to pass some kind of 'default' value
implicitly, you as a caller shouldn't impose on the callee
responsibility to have this same value in his definition and instead
just pass your argument explicitly... or if you don't need this
parameter (as in you don't plan to pass anything explicitly) then you
should just ask for a function without this parameter as there is
clearly no need for it at all.Moreover I would argue interfaces have it wrong here too: the fact that
default values are part of an interface yet their invariance is not
enforced, yields an interesting sort of possible LSP violation. F.e. if
we have an interface Logger (a completely unreal example but it shows
what can go wrong) with function 'log($message, $level = LOG_DEBUG);'
and a funny implementation that decided to change default value of
$level to LOG_ALERT, then all callers of Logger#log who relied on the
fact that level if not specified, will be LOG_DEBUG, who also happen to
get the funny implementation of Logger will produce unneeded noise in
the logs with their alert level messages which were intended to be
debug messages :(Please document this restriction in the RFC. I guess I'm the only one
who expected it to be there since it didn't come up before, but it
just seems missing. You don't need to take it out of voting for this
clarification, imo.
Morning,
sure thing, added it in the RFC
Hey,
I have a question regarding strict/weak types.
Currently, you cannot pass a callable function(string $foo) {} to a signature requiring (callable(int)), if I understood the code correctly.
But weak types actually should allow that as it's totally fine to pass an integer to a string in weak mode.
Is there any particular reason to this seemingly arbitrary restriction?
Bob
Am 23.05.2016 um 16:27 schrieb Nikita Nefedov inefedor@gmail.com:
Evening internals,
With this message I'd like to go to vote
with the Callable prototypes RFC targeted at 7.1:
https://wiki.php.net/rfc/callable-typesWe've renamed it (previously was "Callable types") as RFC names often
dictate how users will call the feature and I want it to be more
accurate/descriptive.Also the reflection part was added although I'm short on time currently,
so implementation for that will be ready later. (speaking of implementation,
it also currently doesn't use cache_slots - also something I'll add when
I have a little bit of time)
Hi Bob,
When you pass an int
to a string
type parameter in weak mode
it's being coerced to the needed type (not just directly passed).
This is quite complex, because you'd need to copy zend_function
and all its members (without changing the original zend_function).
I would love to support it but all in all it comes down to
implementation here for me, so I'd rather do it in a separate
RFC.
If you meant accepting function(string $foo){}
as an argument
of callable(int)
parameter without coercing then this would
be impossible due the fact that this all is context-dependent.
Which means that the function which got function(string $foo){}
in place of callable(int)
could itself be strict-mode
and when it would call this function it would raise a TypeError.
On Mon, 23 May 2016 20:05:50 +0300, Bob Weinand bobwei9@hotmail.com
wrote:
Hey,
I have a question regarding strict/weak types.
Currently, you cannot pass a callable function(string $foo) {} to a
signature requiring (callable(int)), if I understood the code correctly.But weak types actually should allow that as it's totally fine to pass
an integer to a string in weak mode.Is there any particular reason to this seemingly arbitrary restriction?
Bob
Am 23.05.2016 um 16:27 schrieb Nikita Nefedov inefedor@gmail.com:
Evening internals,
With this message I'd like to go to vote
with the Callable prototypes RFC targeted at 7.1:
https://wiki.php.net/rfc/callable-typesWe've renamed it (previously was "Callable types") as RFC names often
dictate how users will call the feature and I want it to be more
accurate/descriptive.Also the reflection part was added although I'm short on time currently,
so implementation for that will be ready later. (speaking of
implementation,
it also currently doesn't use cache_slots - also something I'll add when
I have a little bit of time)
Hello Nikita,
When you pass an
int
to astring
type parameter in weak mode
it's being coerced to the needed type (not just directly passed).This is quite complex, because you'd need to copy zend_function
and all its members (without changing the original zend_function).I would love to support it but all in all it comes down to
implementation here for me, so I'd rather do it in a separate
RFC.
I like the RFC, however I do not like this behavior.
This would behave differently then how current weak/strict mode works.
I was never a fan of the weak mode to begin with, but now introducing
something which deals in the area of argument passing and not behaving
to what a 2/3 majority agreed is IMHO a no-go. The current RFC does not
even mention that.
Maybe it's not feasible anyway, but in any case I'm missing
input/discussion in this area.
- Markus
On Mon, 23 May 2016 22:59:10 +0300, Markus Fischer markus@fischer.name
wrote:
Hello Nikita,
When you pass an
int
to astring
type parameter in weak mode
it's being coerced to the needed type (not just directly passed).This is quite complex, because you'd need to copy zend_function
and all its members (without changing the original zend_function).I would love to support it but all in all it comes down to
implementation here for me, so I'd rather do it in a separate
RFC.I like the RFC, however I do not like this behavior.
This would behave differently then how current weak/strict mode works.I was never a fan of the weak mode to begin with, but now introducing
something which deals in the area of argument passing and not behaving
to what a 2/3 majority agreed is IMHO a no-go. The current RFC does not
even mention that.Maybe it's not feasible anyway, but in any case I'm missing
input/discussion in this area.
- Markus
Morning Markus,
Well, those strict/weak modes were initially invented for basic types,
not for composite types so I'd question if their support is needed at
all...
For example regardlessly of what mode your file in, if you implement
an interface with function foo(int $b)
you'd always have to implement
it with int
, and not float
.
Hi Nikita,
With this message I'd like to go to vote
with the Callable prototypes RFC targeted at 7.1:
https://wiki.php.net/rfc/callable-types
To explain my vote - I think we definitely need to be able to specify
the signatures of callables in PHP, and I would very probably support
either a 'typedef' RFC, or an expansion of current functional type
(i.e. invokables) to be easier to use with functions, but I just
couldn't possibly vote for an RFC that means people would sometimes
write code similar to this:
function foo(int $a, int $b,
callable(callable(callable(callable(int, int):int $zebranky, int):int
$pik, int):int $fot, int):int $zot): int {
return $zot($a, $b);
}
to use the feature of the RFC.
I realise that is an extreme case, but I think that splitting where a
type is defined (with a name) and the place where it is used to be
separate places, is one of the things that the design of PHP got
right. It makes it easier to read code, even if it makes the language
feel less 'powerful' than other languages.
cheers
Dan
On Tue, 24 May 2016 02:24:12 +0300, Dan Ackroyd danack@basereality.com
wrote:
Hi Nikita,
With this message I'd like to go to vote
with the Callable prototypes RFC targeted at 7.1:
https://wiki.php.net/rfc/callable-typesTo explain my vote - I think we definitely need to be able to specify
the signatures of callables in PHP, and I would very probably support
either a 'typedef' RFC, or an expansion of current functional type
(i.e. invokables) to be easier to use with functions, but I just
couldn't possibly vote for an RFC that means people would sometimes
write code similar to this:function foo(int $a, int $b,
callable(callable(callable(callable(int, int):int $zebranky, int):int
$pik, int):int $fot, int):int $zot): int {
return $zot($a, $b);
}to use the feature of the RFC.
I realise that is an extreme case, but I think that splitting where a
type is defined (with a name) and the place where it is used to be
separate places, is one of the things that the design of PHP got
right. It makes it easier to read code, even if it makes the language
feel less 'powerful' than other languages.cheers
Dan
Morning Dan,
I think we definitely would need type aliases. But I also hoped for
union types to get in, so that after these two we could have another RFC
that would do typedefs for callables and for unions.
Doing typedefs for callables only seems too narrow. People would
probably vote 'no' for that RFC because apart from creating new syntax for
callables it would also create a flavour of typedef that works in limited
scope only. And that seems completely fair, typedef is another feature.
And even with typedefs I see no reason not to support inline callable
prots.
Do you remember 'Arbitrary expressions' RFC? I look at it just like at
expressions, and I think there's a need for any possible type to be
expressed directly in a parameter typehint. Making code more readable
would be a responsibility of a user who would decide whether he needs
to use function signatures or not.
Regarding Joe's functional interfaces, I wish they were passing vote.
They can be a nice addition (and a pretty simple one) to the language.
I also think they are not related to this RFC, as their usage is completely
different... What I am aiming at with this (and possibly next) RFC is
to make function composition work better and functional interfaces don't
touch this subject at all. The fact that function needs to opt-in and
the fact that the signature of a function needs to be completely
same as in interface (so no variance) makes it useless in cases
where callable prototypes should be used instead.
I realise that is an extreme case, but I think that splitting where a
type is defined (with a name) and the place where it is used to be
separate places
I think so too but "callable(int): int" is not defining a type, it is
using it. On the other hand "callable" here is a type constructor.
If we would have generics of some form this would be similar to:
"Function<int, int>" where you don't define a type but you create it
passing "int, int" arguments to a type constructor (or a template,
or a generic class) which results in a type in the end. When you
get parametrized types there's a natural need for parameterizing
them in place...
Evening internals,
The vote for Callable prototypes has been declined with 18 votes in favor
and 19 against adding the feature.
Thanks everyone for participating, we will work on problems raised in the
discussion and see if it meets people's expectations in 7.2