Good evening,
I'm reviving my Void Return Type RFC, this time for PHP 7.1:
https://wiki.php.net/rfc/void_return_type
Please read it and tell me your thoughts!
Thanks.
P.S. As it so (fatefully?) happens, I originally introduced this on 14th
February, and it's now 14th October, so it's been exactly 8 months!
--
Andrea Faulds
http://ajf.me/
Hi!
I'm reviving my Void Return Type RFC, this time for PHP 7.1:
https://wiki.php.net/rfc/void_return_type
Please read it and tell me your thoughts!
I still see no point in this, as every PHP function actually returns
something (at least null). So this type would not actually be right and
would not reflect what actually is happening.
Moreover, I don't see any scenario where some code depends on a function
not returning something explicitly (i.e. does not use return value) but
function actually returns something explicitly and the calling code
breaks. This appears to be impossible, and thus there's no reason to
declare a function "void" except purely for documentation purposes.
Adding keywords to the language just to document this does not look to
me like a good idea.
--
Stas Malyshev
smalyshev@gmail.com
Hi Stas,
Stanislav Malyshev wrote:
I still see no point in this, as every PHP function actually returns
something (at least null). So this type would not actually be right and
would not reflect what actually is happening.
It wouldn't be incorrect. Not all languages with void
prevent a
function's use as an expression (or 'rvalue' in C parlance). In some, it
merely requires the function not to explicitly return a value.
And, heck, we use void in the PHP manual all the time.
Moreover, I don't see any scenario where some code depends on a function
not returning something explicitly (i.e. does not use return value) but
function actually returns something explicitly and the calling code
breaks. This appears to be impossible,
It most likely is, but it's not the only case that matters. What if you
mistakenly return a value in a function that's not supposed to? This
would catch you out.
and thus there's no reason to
declare a function "void" except purely for documentation purposes.
Adding keywords to the language just to document this does not look to
me like a good idea.
I feel that the basic facts about a function should be in the signature,
and shouldn't have to be hidden in a comment, if only because it's more
concicse and keeps information about parameters on the same line as the
parameters themselves. Unlike comments, type hints can't lie, because
they're actually enforced.
But, yes, it is mostly just useful for documentation. I can understand
your objection there.
Thanks.
Andrea Faulds
http://ajf.me/
Hi!
And, heck, we use void in the PHP manual all the time.
Yes, because PHP manual is the documentation :) Note that function
descriptions in the manual, while they are similar to PHP syntax, aren't
actually valid PHP, even after scalar typing introduction. Bizarrely
enough, they don't even match the return type syntax.
It most likely is, but it's not the only case that matters. What if you
mistakenly return a value in a function that's not supposed to? This
would catch you out.
Why would I care about such a mistake? Why would I care so much that I
would need a special language-level construct to catch it? How many such
mistakes happen and are they critical enough to have the engine
bothering with going after them? I think such mistakes are extremely
rare and insignificant.
I feel that the basic facts about a function should be in the signature,
and shouldn't have to be hidden in a comment, if only because it's more
I guess we disagree here, because I do not think comments are "hidden",
and I do not think signature of the function should be the comment. In
fact, in Java for example (which seems to be the model language for the
strict typing aficionados) it is long standing best practice to actually
verify the javadoc comments as part of the build and fail the build if
they are missing or wrong. I am not advocating for doing (or not doing
:) this in PHP, but I do say documentation is not "hidden" and strict
typing is not the same as documentation. Moreover, in this case strict
typing implies something that is outright false - the function that is
declared void does return a value, namely null. Even worse, if you do
try to return exactly the same value, the RFC requires failure in this
case, which makes zero sense as precisely the same thing happens in both
cases.
concicse and keeps information about parameters on the same line as the
parameters themselves. Unlike comments, type hints can't lie, because
they're actually enforced.
In fact, it is the opposite - as I said above, that particular type does
lie, and it has to, because what it tries to express actually does not
exist in PHP.
I might be reluctantly ok with tolerating purely documentation type, but
tolerating purely documentation type that is in fact untrue does not
look good to me.
Stas Malyshev
smalyshev@gmail.com
Hi!
I'm reviving my Void Return Type RFC, this time for PHP 7.1:
https://wiki.php.net/rfc/void_return_type
Please read it and tell me your thoughts!
I still see no point in this, as every PHP function actually returns
something (at least null). So this type would not actually be right and
would not reflect what actually is happening.
I agree that void
doesn't make sense given that we document that
return;
will return null1. If the union types RFC2 passes it
makes sense to allow Foo | null
which allows something of type Foo
or null
. To me it makes sense that if you then remove Foo
you are
left with null
, not void
. My personal recommendation because of
this would be to use null
for the return type and instead of void
.
Also, I do not think this feature is pointless. For instance, it has
value in interfaces. Declaring that a method does not return a value
means implementors cannot accidentally return something. This is
better than just documenting that it should not be done.
I agree that
void
doesn't make sense given that we document that
return;
will return null[1]. If the union types RFC[2] passes it
makes sense to allowFoo | null
which allows something of typeFoo
ornull
. To me it makes sense that if you then removeFoo
you are
left withnull
, notvoid
. My personal recommendation because of
this would be to usenull
for the return type and instead ofvoid
.Also, I do not think this feature is pointless. For instance, it has
value in interfaces. Declaring that a method does not return a value
means implementors cannot accidentally return something. This is
better than just documenting that it should not be done.
+1 these are my thoughts exactly. I would be for it if it was null, and
interfaces is exactly why I would be for it.
On Wed, Oct 14, 2015 at 4:00 PM, Stanislav Malyshev smalyshev@gmail.com
wrote:Hi!
I'm reviving my Void Return Type RFC, this time for PHP 7.1:
https://wiki.php.net/rfc/void_return_type
Please read it and tell me your thoughts!
I still see no point in this, as every PHP function actually returns
something (at least null). So this type would not actually be right and
would not reflect what actually is happening.I agree that
void
doesn't make sense given that we document that
return;
will return null1. If the union types RFC2 passes it
makes sense to allowFoo | null
which allows something of typeFoo
ornull
. To me it makes sense that if you then removeFoo
you are
left withnull
, notvoid
. My personal recommendation because of
this would be to usenull
for the return type and instead ofvoid
.
Isn't null supposed to mean the absense of a value and not take the place
of a value in PHP though? Didn't we just have a long conversation about
this in a thread about PHPSadness?
If I capture the result of a "void" method and check if my result variable
with isset(), I'll get false. This sounds like it's void of value to me.
Also, I do not think this feature is pointless. For instance, it has
value in interfaces. Declaring that a method does not return a value
means implementors cannot accidentally return something. This is
better than just documenting that it should not be done.
This is what I was thinking too, I'm not sure that there's much value
beyond that
Korvin Szanto wrote on 14/10/2015 23:55:
If I capture the result of a "void" method and check if my result variable
with isset(), I'll get false. This sounds like it's void of value to me.
But why "invent" (as far as PHP is concerned) this new keyword of "void"
to mean exactly the same thing "null" already means - absence of a
definite value?
Hi Rowan,
Rowan Collins wrote:
But why "invent" (as far as PHP is concerned) this new keyword of "void"
to mean exactly the same thing "null" already means - absence of a
definite value?
They don't mean exactly the same thing. null is a value to represent a
lack of a value. But there's also the concept of no value at all (a
missing variable, say). The closest we have to that in PHP already would
actually be unset
, but that's a strange choice given it's not what we
use in documentation (function prototypes, PHP manual, PHPDoc, etc. use
void
), and it's tainted by the bizarro (unset)
cast which casts to null.
Thanks.
--
Andrea Faulds
http://ajf.me/
Andrea Faulds wrote on 15/10/2015 16:32:
Hi Rowan,
Rowan Collins wrote:
But why "invent" (as far as PHP is concerned) this new keyword of "void"
to mean exactly the same thing "null" already means - absence of a
definite value?They don't mean exactly the same thing. null is a value to represent a
lack of a value. But there's also the concept of no value at all (a
missing variable, say). The closest we have to that in PHP already
would actually beunset
, but that's a strange choice given it's not
what we use in documentation (function prototypes, PHP manual, PHPDoc,
etc. usevoid
), and it's tainted by the bizarro(unset)
cast which
casts to null.
Oh, lord, not this discussion again! PHP has no concept of a variable
being in the "state" of unset; it has programmer hints to warn you if
you read before writing, and a couple of odd constructs which let you
access the current symbol table as a dictionary.
The manual has some weird wording in places which implies that a
variable takes on a type when first used, but in practice the rule is
much simpler: any variable which hasn't had a value assigned yet is
considered to have the value NULL, and normal cast rules apply from
there. The same is true of missing array keys, object properties,
unset() variables, unspecified return values, etc, etc, etc. They are
all NULL.
You could add a warning for "function foo() { return; } $a = foo();" to
match "$x = []; $a = $x['foo'];", but $a would still unambiguously
contain the value NULL
in both cases, and outside of some odd
applications like templating, it is values the program should be
concerned with, not the reason for those values.
Regards,
Rowan Collins
[IMSoP]
Korvin Szanto wrote on 14/10/2015 23:55:
If I capture the result of a "void" method and check if my result variable
with isset(), I'll get false. This sounds like it's void of value to me.But why "invent" (as far as PHP is concerned) this new keyword of "void" to
mean exactly the same thing "null" already means - absence of a definite
value?
It's already "invented" for PHP anyway:
http://docs.hhvm.com/manual/en/hack.annotations.examples.php - example
cheers,
Derick
Am 19.10.2015 um 11:46 schrieb Derick Rethans derick@php.net:
Korvin Szanto wrote on 14/10/2015 23:55:
If I capture the result of a "void" method and check if my result variable
with isset(), I'll get false. This sounds like it's void of value to me.But why "invent" (as far as PHP is concerned) this new keyword of "void" to
mean exactly the same thing "null" already means - absence of a definite
value?It's already "invented" for PHP anyway:
http://docs.hhvm.com/manual/en/hack.annotations.examples.php - example
cheers,
Derick
When something is "invented" in Hack, … How is that related to PHP?
Hack is a language where a major equal subset is same as in PHP, yes. But that's still not a reason to say it were "invented" for PHP.
Please do not use Hack as ultima ratio here, it just is one language like C, Java etc. which happens to have more in common with PHP than most. But it still is just one other language. It's not PHP.
Bob
Hi Levi,
Levi Morrison wrote:
Hi!
I'm reviving my Void Return Type RFC, this time for PHP 7.1:
https://wiki.php.net/rfc/void_return_type
Please read it and tell me your thoughts!
I still see no point in this, as every PHP function actually returns
something (at least null). So this type would not actually be right and
would not reflect what actually is happening.I agree that
void
doesn't make sense given that we document that
return;
will return null[1].
Both you and Stas have said this, but it's only true if we solely
consider C-like languages. Other languages do different things. In the
PHP manual, Hack, TypeScript, ActionScript, and most likely other
languages (these are just off the top of my head), void
functions do
still have an implicit result.
All of these languages would have had the choice to do what you're
suggesting and use null
, or its equivalent (undefined
for TypeScript
and ActionScript). They didn't. Why? If I had to guess, there's at least
three reasons. For one, void is the word languages usually use for this.
For another, void
and null
they mean different things. void
signifies a function isn't returning anything. null
signifies a
function that returns null, regardless of where that null came from.
function foo(): null { return some_probably_null_returning_function(); }
should surely be legal with a null
type hint, yet it's nonsensical
code. Finally, making a function truly "return nothing", i.e.
disallowing its use as an expression/rvalue, breaks some use cases, like
passing along the result of a callback.
PHP would neither be the first nor the last to be using void
in this way.
If the union types RFC[2] passes it
makes sense to allowFoo | null
which allows something of typeFoo
ornull
. To me it makes sense that if you then removeFoo
you are
left withnull
, notvoid
. My personal recommendation because of
this would be to usenull
for the return type and instead ofvoid
.
null
would be a weird type, because it doesn't make sense as a
parameter type, and as a return type, you don't really want to enforce
returning null, you want to enforce not returning at all (see the
example above). It feels like a poor man's substitute to me.
Thanks.
--
Andrea Faulds
http://ajf.me/
Both you and Stas have said this, but it's only true if we solely
consider C-like languages. Other languages do different things. In the
PHP manual, Hack, TypeScript, ActionScript, and most likely other
languages (these are just off the top of my head),void
functions do
still have an implicit result.All of these languages would have had the choice to do what you're
suggesting and usenull
, or its equivalent (undefined
for
TypeScript and ActionScript). They didn't. Why? If I had to guess,
there's at least three reasons. For one, void is the word languages
usually use for this. For another,void
andnull
they mean
different things.void
signifies a function isn't returning
anything.null
signifies a function that returns null, regardless
of where that null came from.function foo(): null { return some_probably_null_returning_function(); }
should surely be legal
with anull
type hint, yet it's nonsensical code. Finally, making a
function truly "return nothing", i.e. disallowing its use as an
expression/rvalue, breaks some use cases, like passing along the
result of a callback.PHP would neither be the first nor the last to be using
void
in this
way.If the union types RFC[2] passes it
makes sense to allowFoo | null
which allows something of typeFoo
ornull
. To me it makes sense that if you then removeFoo
you are
left withnull
, notvoid
. My personal recommendation because of
this would be to usenull
for the return type and instead ofvoid
.
null
would be a weird type, because it doesn't make sense as a
parameter type, and as a return type, you don't really want to enforce
returning null, you want to enforce not returning at all (see the
example above). It feels like a poor man's substitute to me.Thanks.
The tricky part here is that saying a function does not return is not
something PHP currently does:
No return implicitly returns NULL, which you can assign to a variable
if, for some strange reason, you were so inclined. So this would be
more than "just" a syntactic documentation feature.
Which I believe gives the following options:
- Change the language behavior such that
function foo() : void { ...}
$a = foo();
Is a syntax error (because there really was nothing returned to assign),
rather than resulting in $a having a value of NULL.
- Use null as a "type" (which I agree feels weird just saying it), such
that:
function foo() : null { ...}
$a = foo();
and
function foo() { ...}
$a = foo();
are identical. The former would impact the contents of the function
(eg, a non-empty return would be a parse error), but the external result
is the same ($a == NULL).
- Use the "void" keyword, but give it the same effect as option 2.
The RFC currently seems to propose option 3 (based on the "Use of void
functions in expressions" section). I don't have a strong feeling at
this point about which option I'd prefer.
--Larry Garfield
Hi Larry,
Larry Garfield wrote:
The tricky part here is that saying a function does not return is not
something PHP currently does:No return implicitly returns NULL, which you can assign to a variable
if, for some strange reason, you were so inclined. So this would be
more than "just" a syntactic documentation feature.
Which has been pointed out.
Which I believe gives the following options:
- Change the language behavior such that
function foo() : void { ...}
$a = foo();Is a syntax error (because there really was nothing returned to assign),
rather than resulting in $a having a value of NULL.
As the RFC notes, this breaks things, and is inconsistent with how PHP
already does things.
- Use null as a "type" (which I agree feels weird just saying it), such
that:function foo() : null { ...}
$a = foo();and
function foo() { ...}
$a = foo();are identical. The former would impact the contents of the function
(eg, a non-empty return would be a parse error), but the external result
is the same ($a == NULL).
This would be strange. The manual doesn't say null
, and I can't think
of any language which uses null
as the return type in this situation,
even when they have the same implicit-null-return behaviour that PHP has
(see the email you're replying to).
Also, wouldn't you expect this to behave like existing type hints, and
let you return a null value from any source? But that's not what you
would actually want, right?
Thanks.
--
Andrea Faulds
http://ajf.me/
Which I believe gives the following options:
- Change the language behavior such that
function foo() : void { ...}
$a = foo();Is a syntax error (because there really was nothing returned to assign),
rather than resulting in $a having a value of NULL.As the RFC notes, this breaks things, and is inconsistent with how PHP
already does things.
- Use null as a "type" (which I agree feels weird just saying it), such
that:function foo() : null { ...}
$a = foo();and
function foo() { ...}
$a = foo();are identical. The former would impact the contents of the function
(eg, a non-empty return would be a parse error), but the external result
is the same ($a == NULL).This would be strange. The manual doesn't say
null
, and I can't
think of any language which usesnull
as the return type in this
situation, even when they have the same implicit-null-return behaviour
that PHP has (see the email you're replying to).Also, wouldn't you expect this to behave like existing type hints, and
let you return a null value from any source? But that's not what you
would actually want, right?Thanks.
Well, that depends on the intent here. In practice, is the intent to
add a "no return at all" type of function (ie, $a = foo() is a syntax
error now where it was not before), or to make it explicit that the only
legal return is null (even if implicitly that means having a non-early
return statement is pointless)? Those are the two options. That may or
may not dictate the keyword that gets used.
It definitely sounds like you're favoring the second (as that's what the
RFC says). Which may or make not make "void" an odd keyword to choose
when what's actually happening is NULL
getting returned. Is NULL
a
void? (There's a deep philosophical question...)
As I said, I don't have a strong opinion on the subject yet. I'm just
trying to distil the discussion down to as small a question as possible. :-)
Cheers.
--Larry Garfield
Hi Larry,
Larry Garfield wrote:
This would be strange. The manual doesn't say
null
, and I can't
think of any language which usesnull
as the return type in this
situation, even when they have the same implicit-null-return behaviour
that PHP has (see the email you're replying to).Also, wouldn't you expect this to behave like existing type hints, and
let you return a null value from any source? But that's not what you
would actually want, right?Thanks.
Well, that depends on the intent here. In practice, is the intent to
add a "no return at all" type of function (ie, $a = foo() is a syntax
error now where it was not before), or to make it explicit that the only
legal return is null (even if implicitly that means having a non-early
return statement is pointless)? Those are the two options. That may or
may not dictate the keyword that gets used.
It would seem ideal to have "true" void functions which can't be used as
expressions, i.e. producing an error if you try to use them like in your
example. But they'd cause a backwards-compatibility headache, and I'm
not sure they're a good idea anyway. Every function call being an
expression is pretty handy. You can safely capture the return value of a
callback and pass it along, for instance.
In a sense, what this RFC offers might be called a compromise. It
enforces the rules of void
within the function, but at the end of the
day the caller still gets a null out of it since that's what PHP's
always done.
It definitely sounds like you're favoring the second (as that's what the
RFC says). Which may or make not make "void" an odd keyword to choose
when what's actually happening isNULL
getting returned. IsNULL
a
void? (There's a deep philosophical question...)
It's an interesting question. There's some precedent for using void
in
this way even though the functions aren't "truly" void. I mostly like
void
because it's the customary keyword to use, though. Everyone knows
what a 'void function' is.
As I said, I don't have a strong opinion on the subject yet. I'm just
trying to distil the discussion down to as small a question as possible.
:-)
I appreciate your efforts. I have a tendency to be a bit verbose in my
writing, so providing clarity is helpful. :)
Thanks.
Andrea Faulds
http://ajf.me/
In a sense, what this RFC offers might be called a compromise. It enforces
the rules ofvoid
within the function, but at the end of the day the
caller still gets a null out of it since that's what PHP's always done.
If this truly is the case, then all you get over hinting void as the return
type instead of null is a fatal error for return null; Sure you can argue
for capturing intent but realistically the difference in intent between
'returns no value' and 'does not return a value' is something for
philosophers to argue over not programmers. ;)
On 10/14/2015 06:00 PM, Andrea Faulds wrote: >> Both you and Stas have said this, but it's only true if we solely
consider C-like languages. Other languages do different things. In
the PHP manual, Hack, TypeScript, ActionScript, and most likely
other >> languages (these are just off the top of my head),void
functions >> do still have an implicit result. >> >> All of these
languages would have had the choice to do what you're >> suggesting and
usenull
, or its equivalent (undefined
for >> TypeScript and
ActionScript). They didn't. Why? If I had to guess, >> there's at least
three reasons. For one, void is the word languages >> usually use for
this. For another,void
andnull
they mean >> different things.
void
signifies a function isn't returning >> anything.null
signifies a function that returns null, regardless >> of where that
null came from.function foo(): null { return >> some_probably_null_returning_function(); }
should surely be legal >>
with anull
type hint, yet it's nonsensical code. Finally, making a >>
function truly "return nothing", i.e. disallowing its use as an >>
expression/rvalue, breaks some use cases, like passing along the >>
result of a callback. >> >> PHP would neither be the first nor the last
to be usingvoid
in >> this way. >> >>> If the union types RFC[2]
passes it >>> makes sense to allowFoo | null
which allows something
of typeFoo
>>> ornull
. To me it makes sense that if you then
removeFoo
you are >>> left withnull
, notvoid
. My personal
recommendation because of >>> this would be to usenull
for the return
type and instead ofvoid
. >> >>null
would be a weird type, because
it doesn't make sense as a >> parameter type, and as a return type, you
don't really want to >> enforce returning null, you want to enforce not
returning at all (see >> the example above). It feels like a poor man's
substitute to me. >> >> Thanks. > > The tricky part here is that saying
a function does not return is not > something PHP currently does: > >
https://3v4l.org/HtAuC > > No return implicitly returns NULL, which you
can assign to a variable > if, for some strange reason, you were so
inclined. So this would be > more than "just" a syntactic documentation
feature. > > Which I believe gives the following options: > > 1) Change
the language behavior such that > > function foo() : void { ...} > $a =
foo(); > > Is a syntax error (because there really was nothing returned
to > assign), rather than resulting in $a having a value of NULL. > > 2)
Use null as a "type" (which I agree feels weird just saying it), > such
that: > > function foo() : null { ...} > $a = foo(); > > and > >
function foo() { ...} > $a = foo(); > > are identical. The former would
impact the contents of the function > (eg, a non-empty return would be a
parse error), but the external > result is the same ($a == NULL). > > 3)
Use the "void" keyword, but give it the same effect as option 2. > > The
RFC currently seems to propose option 3 (based on the "Use of void >
functions in expressions" section). I don't have a strong feeling at >
this point about which option I'd prefer. >
Option 4)
// implicit return void
function foo () { return; }
// explicit return void
function foo () : void { return; };
// syntax error if returning something on explicit return void
function foo () : void { return null; };
// syntax error on using return value of explicit return void
function foo () : void { return; };
$bar = foo();
// return NULL
on implicit return void (this could also give a
warning/notice/deprecated error)
function foo () { return; };
$bar = foo(); // NULL
// mixing return void with any other return values could also result in
a warning/notice/deprecated error
function foo () { if ($bar) return; return $bar; };
--Larry Garfield >
I really like this as in my opinion if a function doesn't return
something it should be part of the function signature and it really
helps to avoid mistakes on writing code.
Marc
Good evening,
I'm reviving my Void Return Type RFC, this time for PHP 7.1:
https://wiki.php.net/rfc/void_return_type
Please read it and tell me your thoughts!
Thanks.
P.S. As it so (fatefully?) happens, I originally introduced this on 14th
February, and it's now 14th October, so it's been exactly 8 months!--
Andrea Faulds
http://ajf.me/--
Hi,
Semantically, I don't believe that there is sufficient difference between
"returns no value" and "returns a value which has been defined as having no
value" for us to care about it. The main difference you get between return
type of null and a return type of void seems to be some extra fatal errors,
for a developer there seems little value.
From a user confusion point of view; PHP currently considers return; and
return null; to be equivalent (in fact some code style checkers will
replace one with the other) If (and only if) a function has a return type
of void these two statements are no longer equivalent - one is a fatal
error one is not. For any other return type specification, return null; and
return; would behave the same. This in itself would be enough for me to be
against adding a return type of void.
(also could someone enable my wiki acc: carnage; sent an email ~a week ago
and haven't heard back yet :()
~C
Hey Chris,
Chris Riley wrote:
Semantically, I don't believe that there is sufficient difference between
"returns no value" and "returns a value which has been defined as having no
value" for us to care about it. The main difference you get between return
type of null and a return type of void seems to be some extra fatal errors,
for a developer there seems little value.From a user confusion point of view; PHP currently considers return; and
return null; to be equivalent (in fact some code style checkers will
replace one with the other) If (and only if) a function has a return type
of void these two statements are no longer equivalent - one is a fatal
error one is not. For any other return type specification, return null; and
return; would behave the same. This in itself would be enough for me to be
against adding a return type of void.
This is true, but void
isn't an ordinary return type. It exists to
ensure a function doesn't return anything, unlike other return types
which exist to ensure a function returns a specific thing.
return null;
is technically equivalent to return;
, but it's not
quite the same in intent, usually. We could special-case it and allow
it, but why? The return value isn't supposed to be used, why should we
allow you to specify it? A void function in PHP does technically produce
a result of null, but it might as well be false or -1 or whatever for
all we care. Also, if return null;
is to work, should return(null);
also work? How about return \null;
? return SOME_NULL_CONSTANT;
? It
seems silly to me since, again, the return value is insigificant.
Thanks.
Andrea Faulds
http://ajf.me/
Hey Chris,
Chris Riley wrote:
Semantically, I don't believe that there is sufficient difference between
"returns no value" and "returns a value which has been defined as having no
value" for us to care about it. The main difference you get between return
type of null and a return type of void seems to be some extra fatal errors,
for a developer there seems little value.From a user confusion point of view; PHP currently considers return; and
return null; to be equivalent (in fact some code style checkers will
replace one with the other) If (and only if) a function has a return type
of void these two statements are no longer equivalent - one is a fatal
error one is not. For any other return type specification, return null; and
return; would behave the same. This in itself would be enough for me to be
against adding a return type of void.
This is true, but void
isn't an ordinary return type. It exists to
ensure a function doesn't return anything, unlike other return types
which exist to ensure a function returns a specific thing.
return null;
is technically equivalent to return;
, but it's not
quite the same in intent, usually. We could special-case it and allow
it, but why? The return value isn't supposed to be used, why should we
allow you to specify it? A void function in PHP does technically produce
a result of null, but it might as well be false or -1 or whatever for
all we care. Also, if return null;
is to work, should return(null);
also work? How about return \null;
? return SOME_NULL_CONSTANT;
? It
seems silly to me since, again, the return value is insigificant.
Thanks.
Andrea Faulds
http://ajf.me/
Andrea Faulds wrote on 14/10/2015 22:52:
Good evening,
I'm reviving my Void Return Type RFC, this time for PHP 7.1:
https://wiki.php.net/rfc/void_return_type
Please read it and tell me your thoughts!
My feeling is that it is odd to have both of these be true at once:
- void functions can appear in expressions, where the return value is
interpreted as null - "return;" and "return null;" are no longer treated as equivalent
If the intent is to say "you can use this in an expression, but its
value will always be null so there's no point", then "return null;"
seems just as valid as "return;", and a typehint of "null" seems to make
more sense.
I take the point about making intent clear, but can't think of any other
interpretation of "this function always returns null" than "this
function has no meaningful result". In other words, I can't imagine
ever wanting to use "null" to mean something different from "void" in
this context.
I can see the point in denying the right to say "return
some_function_expected_to_return_null();" But in a sense this is no
different from declaring that a function returns int, and then writing
"return some_function_expected_to_return_int();"
If a void function can be used in an expression, it can be used in a
return expression, and if so, it feels natural for the type hint to
propagate:
function foo(): void { do_something(); }
function wrapped_foo(): void { do_something_else(); return foo(); }
// ERROR: can't specify return value in a void function
"return foo()" is not illegal because foo is declared void, but because
wrapped_foo is - even though the result is exactly as expected.
Regards,
Rowan Collins
[IMSoP]
Hi Rowan,
Rowan Collins wrote:
I can see the point in denying the right to say "return
some_function_expected_to_return_null();" But in a sense this is no
different from declaring that a function returns int, and then writing
"return some_function_expected_to_return_int();"If a void function can be used in an expression, it can be used in a
return expression, and if so, it feels natural for the type hint to
propagate:function foo(): void { do_something(); }
function wrapped_foo(): void { do_something_else(); return foo(); }
// ERROR: can't specify return value in a void function"return foo()" is not illegal because foo is declared void, but because
wrapped_foo is - even though the result is exactly as expected.
Hmm, this is an interesting case you've pointed out. Being able to do
return some_other_void_function();
is something I've desired in other
languages.
But what if that void function you're calling later adds a return value?
Now the calling function is returning a value other than null, violating
its type hint and producing a runtime error.
It's a shame there's no "tail call this other function and discard its
result" construct.
Thanks.
--
Andrea Faulds
http://ajf.me/
Andrea Faulds wrote on 15/10/2015 16:32:
Hmm, this is an interesting case you've pointed out. Being able to do
return some_other_void_function();
is something I've desired in
other languages.But what if that void function you're calling later adds a return
value? Now the calling function is returning a value other than null,
violating its type hint and producing a runtime error.
Well, fundamentally, this is true of anything short of full
type-checking. The type safety below is self-evident:
function foo(): int { return 42; }
function wrapped_foo(): int { return foo(); }
But foo() could later be changed to this:
function foo(): string { return 'The Answer'; }
The wrapped_foo() typehint is now broken. That's not really any
different from foo() starting off as void/returns-null and adding a
return value.
In both cases, a static analyser could detect the discrepancy, but the
Zend Engine will not, until the function is executed.
It's a shame there's no "tail call this other function and discard its
result" construct.
Yeah, I guess what you really want is for a void function to be able to
"goto foo();"
Regards,
Rowan Collins
[IMSoP]
I've been thinking about what PHP should do when accessing the return value
of a void
function, and so far, I think the consistent thing should be to
get NULL, while throwing an E_NOTICE.
$a = $b; //$b wasn't initiated.
This does the same thing. I tried accessing what was supposed to be
'nothing' ($b), and got NULL
with an E_NOTICE
being thrown.
function myFunc() : void { ... }
$a = myFunc();
I see no reason why this should silently assign NULL
to $a, specially with
"return null;" being explicitly forbidden.
My point is: we already use an implicit NULL
return on functions with
missing return values (or with "return ;"), but now we're explicitly
prohibiting even a NULL
return. The behaviour should be consistent (NULL
should be accessed, as for all undefined things), with an E_NOTICE.
function myFunc() { return ; }
$a = myFunc();
Should assign NULL
to $a and not throw an E_NOTICE
(this is the current
status), because a return type was not forbidden with the keyword 'void'.
2015-10-15 13:00 GMT-03:00 Rowan Collins rowan.collins@gmail.com:
Andrea Faulds wrote on 15/10/2015 16:32:
Hmm, this is an interesting case you've pointed out. Being able to do
return some_other_void_function();
is something I've desired in other
languages.But what if that void function you're calling later adds a return value?
Now the calling function is returning a value other than null, violating
its type hint and producing a runtime error.Well, fundamentally, this is true of anything short of full type-checking.
The type safety below is self-evident:function foo(): int { return 42; }
function wrapped_foo(): int { return foo(); }But foo() could later be changed to this:
function foo(): string { return 'The Answer'; }
The wrapped_foo() typehint is now broken. That's not really any different
from foo() starting off as void/returns-null and adding a return value.In both cases, a static analyser could detect the discrepancy, but the
Zend Engine will not, until the function is executed.It's a shame there's no "tail call this other function and discard its
result" construct.
Yeah, I guess what you really want is for a void function to be able to
"goto foo();"Regards,
Rowan Collins
[IMSoP]
Pedro Cordeiro wrote on 15/10/2015 17:14:
I've been thinking about what PHP should do when accessing the return
value of avoid
function, and so far, I think the consistent thing
should be to get NULL, while throwing an E_NOTICE.$a = $b; //$b wasn't initiated.
This does the same thing. I tried accessing what was supposed to be
'nothing' ($b), and gotNULL
with anE_NOTICE
being thrown.function myFunc() : void { ... }
$a = myFunc();I see no reason why this should silently assign
NULL
to $a,
specially with "return null;" being explicitly forbidden. ... The
behaviour should be consistent (NULL should be accessed, as for all
undefined things), with an E_NOTICE.
I don't know how easy this would be to implement, but I agree that this
would make the "void" keyword feel more meaningful.
Does the Engine have a way to know whether a return value is being used
or discarded for optimisation purposes? If so, could that logic be
hooked to provide the Notice?
Regards,
Rowan Collins
[IMSoP]
Hi Pedro,
Pedro Cordeiro wrote:
I've been thinking about what PHP should do when accessing the return value
of avoid
function, and so far, I think the consistent thing should be to
get NULL, while throwing an E_NOTICE.
We could do this, but I do wonder if it might cause a lot of E_NOTICEs
to pop up for existing code, assuming we applied this to built-in PHP
functions.
I'm not sure.
Thanks.
Andrea Faulds
http://ajf.me/
Andrea Faulds wrote on 15/10/2015 17:34:
Hi Pedro,
Pedro Cordeiro wrote:
I've been thinking about what PHP should do when accessing the return
value
of avoid
function, and so far, I think the consistent thing should
be to
get NULL, while throwing an E_NOTICE.We could do this, but I do wonder if it might cause a lot of E_NOTICEs
to pop up for existing code, assuming we applied this to built-in PHP
functions.I'm not sure.
The way Pedro described it, it wouldn't apply to any existing functions
because they wouldn't be declared void.
Obviously, type hints for internal functions are a bit weird anyway, but
there's no reason to assume that every function documented as void would
suddenly be annotated in the Engine as such and start returning notices.
Hi Rowan,
Rowan Collins wrote:
Andrea Faulds wrote on 15/10/2015 17:34:
Hi Pedro,
Pedro Cordeiro wrote:
I've been thinking about what PHP should do when accessing the return
value
of avoid
function, and so far, I think the consistent thing should
be to
get NULL, while throwing an E_NOTICE.We could do this, but I do wonder if it might cause a lot of E_NOTICEs
to pop up for existing code, assuming we applied this to built-in PHP
functions.I'm not sure.
The way Pedro described it, it wouldn't apply to any existing functions
because they wouldn't be declared void.Obviously, type hints for internal functions are a bit weird anyway, but
there's no reason to assume that every function documented as void would
suddenly be annotated in the Engine as such and start returning notices.
Why shouldn't it? For the scalar types, internal and userland functions
behave almost the same.
I'd like there the two to converge, not diverge.
--
Andrea Faulds
http://ajf.me/
Obviously, type hints for internal functions are a bit weird anyway,
but
there's no reason to assume that every function documented as void
would
suddenly be annotated in the Engine as such and start returning
notices.Why shouldn't it? For the scalar types, internal and userland functions behave almost the same.
Just for the same reason that an existing function that uses bare "return;" won't automatically be considered "void" - nobody has explicitly decided that that's the intent.
Sure, internal functions whose value shouldn't be used could be marked void, and those would start raising Notices if that was part of void's behaviour. But there would only be a blizzard of Notices if someone bulk updated every function in core which happens to return null, which doesn't seem like an automatic part of creating a void return behaviour. Especially if the whole point is that "void" signifies something more than "always returns null".
Since it's been mentioned a couple of times, I'd like to say that although the documentation is official, I think it should be considered descriptive not prescriptive - if it labels something as void, but the Engine doesn't consider it so, the manual would be wrong, not the Engine.
Regards,
Rowan Collins
[IMSoP]
On Thu, Oct 15, 2015 at 4:21 PM Rowan Collins rowan.collins@gmail.com
wrote:
Obviously, type hints for internal functions are a bit weird anyway,
but
there's no reason to assume that every function documented as void
would
suddenly be annotated in the Engine as such and start returning
notices.Why shouldn't it? For the scalar types, internal and userland functions
behave almost the same.Just for the same reason that an existing function that uses bare
"return;" won't automatically be considered "void" - nobody has explicitly
decided that that's the intent.Sure, internal functions whose value shouldn't be used could be marked
void, and those would start raising Notices if that was part of void's
behaviour. But there would only be a blizzard of Notices if someone bulk
updated every function in core which happens to return null, which doesn't
seem like an automatic part of creating a void return behaviour.
Especially if the whole point is that "void" signifies something more than
"always returns null".Since it's been mentioned a couple of times, I'd like to say that although
the documentation is official, I think it should be considered descriptive
not prescriptive - if it labels something as void, but the Engine doesn't
consider it so, the manual would be wrong, not the Engine.
Could we change the documentation for existing functions to return null,
and start using void properly moving forward?
Thanks,
Korvin
Hi Korvin,
Korvin Szanto wrote:
Could we change the documentation for existing functions to return null,
and start using void properly moving forward?
As I have stated several times now, we're not "misusing" void. PHP is
not the only language to use the word in this manner.
But why should we change the documentation anyway? We've used void for a
very long time, at least 17 years[0]. We don't just use it in the PHP
manual, it's also used in docblocks and the PHP source code's function
prototypes. It's the commonly-accepted, widely-used term. Until now this
was uncontroversial.
Why should we move heaven and earth when there's nothing wrong?
[0]
https://web.archive.org/web/19991002011107/http://php.net/manual/function.sort.php3
--
Andrea Faulds
http://ajf.me/
But why should we change the documentation anyway? We've used void for a
very long time, at least 17 years[0]. We don't just use it in the PHP
manual, it's also used in docblocks and the PHP source code's function
prototypes. It's the commonly-accepted, widely-used term. Until now this
was uncontroversial.
This are in my book is just the same as 'NULL'. Different styles of
working have different views on how things are interpreted. The function
sets for arrays as originally designed simply modified the target object
without returning any error code or similar value. The 'more modern' way
of doing this may be perhaps to 'return' the array? Or perhaps a count
of the number of elements moved - 0 indicates that nothing has changed.
I can see the reason you want the run time engine to flag an error if I
do $res = sort(xxx); but like many of the 'checks' that seem to be
bloating the run time code, I still see that as a function for a good
IDE rather than a run time error. void is just a documentational flag
that CURRENTLY there is nothing to return, but does not prevent a
modified version that may return a value at some point in the future.
What is 'controversial' is a change from the freedom of the user to
create code the way they want to work, which may wrap a void function in
a return check simply because at some point in the future they plan to
upgrade the simple off the shelf function call with something which
generates the return. I find enforced typing in the same bucket since
while some returns may clearly be 'integer' in other cases a later
development might use the fractional part for some other purpose. Others
seem to think that is bad practice? Having now two different styles of
working is something we simply now have to put up with, but loading the
bias even more in the direction of 'I think that you are wrong' needs to
have a very good case?
--
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
Rainbow Digital Media - http://rainbowdigitalmedia.co.uk
this would make the "void" keyword feel more meaningful.
I, too, had issues trying to understand what "void" was bringing to the
table. IMHO, it should warn people thinking some specific function/method
returns a value when it doesn't, not protect against some dev forgetting
the function he's writing should not return something.
IMHO, it's far more important to warn "Hey, this function returns NOTHING,
don't try to use its value because it doesn't exist!" then it is to warn
"Hey, this function can't return anything, stop trying to return things!".
Throwing an E_NOTICE
when accessing a void return value would make perfect
sense, as the compiler would strict check that the function author defined
a no-return and indeed returned nothing and would also warn whoever was
calling the function that it doesn't return anything.
We could do this, but I do wonder if it might cause a lot of E_NOTICEs to
pop up for existing code, assuming we applied this to built-in PHP
functions.
My proposal is to only throw an E_NOTICE
when accessing a return value from
a function that is explicitly marked with "void". A function with no return
("return ;") but with no ": void" on the signature would not necessarily
throw an E_NOTICE.
function myFunc() { return ; }
$a = myFunc(); //NULL should be assigned to $a silently, like it is today.
function myOtherFunc() : void { return ; }
$b = myOtherFunc(); //NULL should be assigned to $b, but an E_NOTICE
is
thrown.
2015-10-15 13:34 GMT-03:00 Andrea Faulds ajf@ajf.me:
Hi Pedro,
Pedro Cordeiro wrote:
I've been thinking about what PHP should do when accessing the return
value
of avoid
function, and so far, I think the consistent thing should be
to
get NULL, while throwing an E_NOTICE.We could do this, but I do wonder if it might cause a lot of E_NOTICEs to
pop up for existing code, assuming we applied this to built-in PHP
functions.I'm not sure.
Thanks.
Andrea Faulds
http://ajf.me/
Hi everyone,
Andrea Faulds wrote:
I'm reviving my Void Return Type RFC, this time for PHP 7.1:
https://wiki.php.net/rfc/void_return_type
Please read it and tell me your thoughts!
Since the void/null naming issue has been a frequently-asked question,
I've added a subsection to the RFC explaining why I chose this name. It
doesn't really say anything I haven't said already, it just summarises
it. In particular, it lists a bunch of languages using void
, some of
which do what PHP does.
The new section is here:
https://wiki.php.net/rfc/void_return_type#why_call_it_void_and_not_null
Thanks.
--
Andrea Faulds
http://ajf.me/
Hi Andrea
-----Ursprüngliche Nachricht-----
Von: Andrea Faulds [mailto:ajf@ajf.me]
Gesendet: Donnerstag, 15. Oktober 2015 23:04
An: internals@lists.php.net
Betreff: [PHP-DEV] Re: [RFC] Void Return Type (v0.2, reöpening)Hi everyone,
Andrea Faulds wrote:
I'm reviving my Void Return Type RFC, this time for PHP 7.1:
https://wiki.php.net/rfc/void_return_type
Please read it and tell me your thoughts!
Since the void/null naming issue has been a frequently-asked question, I've added a subsection to the RFC explaining
why I
chose this name. It doesn't really say anything I haven't said already, it just summarises it. In particular, it lists
a bunch of
languages usingvoid
, some of which do what PHP does.The new section is here:
https://wiki.php.net/rfc/void_return_type#why_call_it_void_and_not_nullThanks.
--
Andrea Faulds
http://ajf.me/--
You write in your RFC "others do allow void functions in expressions, just as PHP does, by making them implicitly return
some unit type."
You mentioned TypeScript -- unit type = null -- ActionScript -- unit type = undefined -- and Swift -- unit type = empty
tuple, ergo ().
TypeScript [1] allows to return null, ActionScript does not allow to return undefined, and Swift allows to return an
empty tuple explicitly [2].
I agree with others that is seems inconsistent to use the name void but allow to use void functions in expression
(return implicitly a unit type) and in the same time forbid to return the unit type explicitly in such functions.
IMO ActionScript should have allowed to return the unit type explicitly as well and so should PHP.
At first I did not like the idea of introducing void in PHP at all if it has not the same behaviour as in C -- meaning
it should be forbidden to use void functions in expressions -- but now I think it better suits PHP if void stands for
return nothing (hence null implicitly) or null explicitly. I think you should change your RFC to allow returning
explicitly null for two reasons:
- Implicit and explicit behaviour should be consistent. If a function returns null implicitly then it should be allowed
to return null explicitly. - Not everyone might be aware of the implicit behaviour and some code conventions might want to be explicit on this
part and dictate that one needs to express the behaviour in code.
To conclude, personally I want that the following are all equivalent:
function foo() : void {}
function foo() : void { return; }
function foo() : void { return null; }
To go a step further, I kind of like the idea that using the return value of a void function results (at least) in an
E_NOTICE. But maybe that is something for PHP 8.
Another random thought, why not treat void like Void [3] in Java where null is the only valid value of this type? Nah...
bad idea, would be too heavy to use an object everywhere and secondly it would force to write "return null;" all the
time, so forget about it.
[1] http://www.typescriptlang.org/Playground#src=function%20foo()%3Avoid%7Breturn%20null%3B%7D%0A
[2] http://swiftstub.com/114266460/?v=gm
[3] http://docs.oracle.com/javase/7/docs/api/java/lang/Void.html
Robert,
You write in your RFC "others do allow void functions in expressions, just as PHP does, by making them implicitly return
some unit type."
You mentioned TypeScript -- unit type = null -- ActionScript -- unit type = undefined -- and Swift -- unit type = empty
tuple, ergo ().
TypeScript [1] allows to return null, ActionScript does not allow to return undefined, and Swift allows to return an
empty tuple explicitly [2].I agree with others that is seems inconsistent to use the name void but allow to use void functions in expression
(return implicitly a unit type) and in the same time forbid to return the unit type explicitly in such functions.
IMO ActionScript should have allowed to return the unit type explicitly as well and so should PHP.
At first I did not like the idea of introducing void in PHP at all if it has not the same behaviour as in C -- meaning
it should be forbidden to use void functions in expressions -- but now I think it better suits PHP if void stands for
return nothing (hence null implicitly) or null explicitly. I think you should change your RFC to allow returning
explicitly null for two reasons:
- Implicit and explicit behaviour should be consistent. If a function returns null implicitly then it should be allowed
to return null explicitly.- Not everyone might be aware of the implicit behaviour and some code conventions might want to be explicit on this
part and dictate that one needs to express the behaviour in code.To conclude, personally I want that the following are all equivalent:
function foo() : void {}
function foo() : void { return; }
function foo() : void { return null; }To go a step further, I kind of like the idea that using the return value of a void function results (at least) in an
E_NOTICE. But maybe that is something for PHP 8.
I dislike this, because it punishes dynamic code (function composition).
For example:
$logUtility = partialLeft(function(string $a, string $b): void {
syslog(LOG_INFO, $a . ": " . $b);
});
$log = $log("Prefix");
$log("blah"); // writes "Prefix: blah" to the log
function partialLeft(callable $cb) {
return function($left) use ($cb) {
return function($right) use ($cb, $left) {
return $cb($left, $right);
};
};
}
Boom, notice.
Now, we could say that "that's the problem of the caller of
partialLeft", but the notice is raised inside of the closure inside of
partialLeft. Which would imply that it did something wrong. Something
that it couldn't possibly know about without booting a
reflectionfunction for it.
This would mean that generic higher order functions would need to be
duplicated, one for void functions and one for non-void functions. A
bit overkill...
That's just my $0.02
Anthony
Anthony,
-----Ursprüngliche Nachricht-----
Von: Anthony Ferrara [mailto:ircmaxell@gmail.com]
Gesendet: Freitag, 16. Oktober 2015 17:23
An: Robert Stoll
Cc: Andrea Faulds; internals@lists.php.net
Betreff: Re: [PHP-DEV] Re: [RFC] Void Return Type (v0.2, reöpening)Robert,
You write in your RFC "others do allow void functions in expressions,
just as PHP does, by making them implicitly return some unit type."
You mentioned TypeScript -- unit type = null -- ActionScript -- unit
type = undefined -- and Swift -- unit type = empty tuple, ergo ().
TypeScript [1] allows to return null, ActionScript does not allow to
return undefined, and Swift allows to return an empty tuple explicitly [2].I agree with others that is seems inconsistent to use the name void
but allow to use void functions in expression (return implicitly a unit type) and in the same time forbid to return the unit
type explicitly in such functions.
IMO ActionScript should have allowed to return the unit type explicitly as well and so should PHP.
At first I did not like the idea of introducing void in PHP at all if
it has not the same behaviour as in C -- meaning it should be
forbidden to use void functions in expressions -- but now I think it
better suits PHP if void stands for return nothing (hence null implicitly) or null explicitly. I think you should change your
RFC to allow returning explicitly null for two reasons:
- Implicit and explicit behaviour should be consistent. If a function
returns null implicitly then it should be allowed to return null explicitly.- Not everyone might be aware of the implicit behaviour and some code
conventions might want to be explicit on this part and dictate that one needs to express the behaviour in code.To conclude, personally I want that the following are all equivalent:
function foo() : void {}
function foo() : void { return; }
function foo() : void { return null; }To go a step further, I kind of like the idea that using the return
value of a void function results (at least) in an E_NOTICE. But maybe that is something for PHP 8.I dislike this, because it punishes dynamic code (function composition).
For example:
$logUtility = partialLeft(function(string $a, string $b): void {
syslog(LOG_INFO, $a . ": " . $b);
});$log = $log("Prefix");
$log("blah"); // writes "Prefix: blah" to the logfunction partialLeft(callable $cb) {
return function($left) use ($cb) {
return function($right) use ($cb, $left) {
return $cb($left, $right);
};
};
}Boom, notice.
Now, we could say that "that's the problem of the caller of partialLeft", but the notice is raised inside of the closure inside
of partialLeft. Which would imply that it did something wrong. Something that it couldn't possibly know about without
booting a reflectionfunction for it.This would mean that generic higher order functions would need to be duplicated, one for void functions and one for non-
void functions. A bit overkill...That's just my $0.02
Anthony
I agree only to a certain degree. If you had not used the type hint callable, then I could argue that the same applies for passing null to partialLeft.
Hence, the problem is rather that PHP does not yet support callable type hints with return type, something like callable:int, in which case it would be clear that the error was done by the caller.
Anthony,
-----Ursprüngliche Nachricht-----
Von: Anthony Ferrara [mailto:ircmaxell@gmail.com]
Gesendet: Freitag, 16. Oktober 2015 17:23
An: Robert Stoll
Cc: Andrea Faulds; internals@lists.php.net
Betreff: Re: [PHP-DEV] Re: [RFC] Void Return Type (v0.2, reöpening)Robert,
You write in your RFC "others do allow void functions in expressions,
just as PHP does, by making them implicitly return some unit type."
You mentioned TypeScript -- unit type = null -- ActionScript -- unit
type = undefined -- and Swift -- unit type = empty tuple, ergo ().
TypeScript [1] allows to return null, ActionScript does not allow to
return undefined, and Swift allows to return an empty tuple explicitly [2].I agree with others that is seems inconsistent to use the name void
but allow to use void functions in expression (return implicitly a unit type) and in the same time forbid to return the unit
type explicitly in such functions.
IMO ActionScript should have allowed to return the unit type explicitly as well and so should PHP.
At first I did not like the idea of introducing void in PHP at all if
it has not the same behaviour as in C -- meaning it should be
forbidden to use void functions in expressions -- but now I think it
better suits PHP if void stands for return nothing (hence null implicitly) or null explicitly. I think you should change your
RFC to allow returning explicitly null for two reasons:
- Implicit and explicit behaviour should be consistent. If a function
returns null implicitly then it should be allowed to return null explicitly.- Not everyone might be aware of the implicit behaviour and some code
conventions might want to be explicit on this part and dictate that one needs to express the behaviour in code.To conclude, personally I want that the following are all equivalent:
function foo() : void {}
function foo() : void { return; }
function foo() : void { return null; }To go a step further, I kind of like the idea that using the return
value of a void function results (at least) in an E_NOTICE. But maybe that is something for PHP 8.I dislike this, because it punishes dynamic code (function composition).
For example:
$logUtility = partialLeft(function(string $a, string $b): void {
syslog(LOG_INFO, $a . ": " . $b);
});$log = $log("Prefix");
$log("blah"); // writes "Prefix: blah" to the logfunction partialLeft(callable $cb) {
return function($left) use ($cb) {
return function($right) use ($cb, $left) {
return $cb($left, $right);
};
};
}Boom, notice.
Now, we could say that "that's the problem of the caller of partialLeft", but the notice is raised inside of the closure inside
of partialLeft. Which would imply that it did something wrong. Something that it couldn't possibly know about without
booting a reflectionfunction for it.This would mean that generic higher order functions would need to be duplicated, one for void functions and one for non-
void functions. A bit overkill...That's just my $0.02
Anthony
I agree only to a certain degree. If you had not used the type hint callable, then I could argue that the same applies for passing null to partialLeft.
Hence, the problem is rather that PHP does not yet support callable type hints with return type, something like callable:int, in which case it would be clear that the error was done by the caller.
While I may be in favor of typing callable signatures, I do want to
point out that the version that is typeless just works, and adding
types didn't work. To me this means the chosen type didn't accurately
portray the semantics. This is one reason I am in favor of null
instead of void
. Void does not accurately portray the semantics in
my opinion. If the return type was null instead of void there would be
no issue. Sure, the return value would be null, but partialLeft
doesn't care – it just passes whatever the result was.
You write in your RFC "others do allow void functions in expressions,
just as PHP does, by making them implicitly return some unit type."
You mentioned TypeScript -- unit type = null -- ActionScript -- unitTo conclude, personally I want that the following are all equivalent:
function foo() : void {}
function foo() : void { return; }
function foo() : void { return null; }To go a step further, I kind of like the idea that using the return
value of a void function results (at least) in an E_NOTICE. But maybe that is something for PHP 8.
I dislike this, because it punishes dynamic code (function composition).For example:
$logUtility = partialLeft(function(string $a, string $b): void {
syslog(LOG_INFO, $a . ": " . $b);
});$log = $log("Prefix");
$log("blah"); // writes "Prefix: blah" to the logfunction partialLeft(callable $cb) {
return function($left) use ($cb) {
return function($right) use ($cb, $left) {
return $cb($left, $right);
};
};
}Boom, notice.
Now, we could say that "that's the problem of the caller of partialLeft", but the notice is raised inside of the closure inside
of partialLeft. Which would imply that it did something wrong. Something that it couldn't possibly know about without
booting a reflectionfunction for it.This would mean that generic higher order functions would need to be duplicated, one for void functions and one for non-
void functions. A bit overkill...That's just my $0.02
Anthony
I agree only to a certain degree. If you had not used the type hint callable, then I could argue that the same applies for passing null to partialLeft.
Hence, the problem is rather that PHP does not yet support callable type hints with return type, something like callable:int, in which case it would be clear that the error was done by the caller.
That wouldn't help either, I think. Then you'd need a separate
partialLeft(callable:int $cb), partialLeft(callable:string $cb),
partialLeft(callable:float $cb), and partialLeft(callable:void $db). And
likely others. That seems exactly like what Anthony wants to avoid
(rightly).
Indirect calls to arbitrary functions does mean that they need to be
able to behave consistently when referred to abstractly. Vis, any
approach that involves:
function foo() : void {}
$a = foo();
triggering an error condition would make life drastically more difficult
for higher order function operations like partials or memoization. That
seems doubleplusungood.
One way around that would be to only trigger that behavior on a static
call, not a call to a variable function, but I have no idea if that's at
all feasible in the engine. I suspect it's more feasible than detecting
the function wrapping and only erroring at the top level caller, but now
I'm just talking out of my butt. :-)
That leaves "documentation of intent for the developer" (which is a
valid argument) and "slap someone's hand for returning non-null inside
the function itself" (which is valid, but leaves the question of whether
return null should error).
--Larry Garfield
Hi Larry,
-----Ursprüngliche Nachricht-----
Von: Larry Garfield [mailto:larry@garfieldtech.com]
Gesendet: Samstag, 24. Oktober 2015 00:36
An: internals@lists.php.net
Betreff: Re: AW: [PHP-DEV] Re: [RFC] Void Return Type (v0.2, reöpening)You write in your RFC "others do allow void functions in
expressions, just as PHP does, by making them implicitly return some unit type."
You mentioned TypeScript -- unit type = null -- ActionScript -- unitTo conclude, personally I want that the following are all equivalent:
function foo() : void {}
function foo() : void { return; }
function foo() : void { return null; }To go a step further, I kind of like the idea that using the return
value of a void function results (at least) in an E_NOTICE. But maybe that is something for PHP 8.
I dislike this, because it punishes dynamic code (function composition).For example:
$logUtility = partialLeft(function(string $a, string $b): void {
syslog(LOG_INFO, $a . ": " . $b); });$log = $log("Prefix");
$log("blah"); // writes "Prefix: blah" to the logfunction partialLeft(callable $cb) {
return function($left) use ($cb) {
return function($right) use ($cb, $left) {
return $cb($left, $right);
};
};
}Boom, notice.
Now, we could say that "that's the problem of the caller of
partialLeft", but the notice is raised inside of the closure inside
of partialLeft. Which would imply that it did something wrong. Something that it couldn't possibly know about without
booting a reflectionfunction for it.This would mean that generic higher order functions would need to be
duplicated, one for void functions and one for non- void functions. A bit overkill...That's just my $0.02
Anthony
I agree only to a certain degree. If you had not used the type hint callable, then I could argue that the same applies for
passing null to partialLeft.
Hence, the problem is rather that PHP does not yet support callable type hints with return type, something like
callable:int, in which case it would be clear that the error was done by the caller.That wouldn't help either, I think. Then you'd need a separate partialLeft(callable:int $cb), partialLeft(callable:string $cb),
partialLeft(callable:float $cb), and partialLeft(callable:void $db). And likely others. That seems exactly like what Anthony
wants to avoid (rightly).Indirect calls to arbitrary functions does mean that they need to be able to behave consistently when referred to
abstractly. Vis, any approach that involves:function foo() : void {}
$a = foo();triggering an error condition would make life drastically more difficult for higher order function operations like partials or
memoization. That seems doubleplusungood.One way around that would be to only trigger that behavior on a static call, not a call to a variable function, but I have no
idea if that's at all feasible in the engine. I suspect it's more feasible than detecting the function wrapping and only erroring
at the top level caller, but now I'm just talking out of my butt. :-)That leaves "documentation of intent for the developer" (which is a valid argument) and "slap someone's hand for
returning non-null inside the function itself" (which is valid, but leaves the question of whether return null should error).--Larry Garfield
--
Well, it really depends on the use case. I would probably not write such a generic partial function, especially not allowing functions which return a value and others which don't. I could imagine to use callable:mixed to allow values of arbitrary types to be returned. Yet, that would still not include a function which does not return a value. IMO we do not really proceed further with this RFC when discussing this special case - callable:int, callable:mixed etc is not supported by PHP now, so we should focus on the essential now.
IMO we should get an agreement what void means in PHP, I see the following options:
1 void is a type with a value set containing null (ergo corresponds to the set { null }) and hence it is perfectly fine to return null from a function with return type void (naming it void is controversial among the list -- others prefer null -- but that can be discussed further afterwards)
2 void is a type with an empty value set (a special value respectively) and hence one cannot return null from a function with return type void and
a) such a function returns null implicitly nonetheless
b) such a function returns a special value which triggers a fatal error when it is accessed
IMO 2a is inconsistent and I would only consider 1 or 2b
Hi Andrea,
I'm very much in favor of this RFC.
It's not just useful, I think void return declarations are needed in
order to establish sensible style rules for strict mode in real
projects. To be strict in our programming practices, the absence of a
return declaration signifies too many things in 7.0 -- it is excessively
overloaded.
I summarized the discussions with my colleagues here:
http://thefsb.tumblr.com/post/131487359475
Tom