Hello Internals, Dmitry, Lukas, Johannes,
some time back (August 08) I complained about 'use' being at a weird
position and not at the same place as 'global' or 'static' where I
expected it. Back then Dmitry asked me to provide a patch to check out
the alternative. Now during the holidys I finally found some time to
change from:
$f = function() use ($x) {}
to:
$f = function() { use $x; }
Patch is attached.
Comments?
Best regards,
Marcus
Marcus Boerger schrieb:
$f = function() { use $x; }
+1 for consistency.
--
Sebastian Bergmann http://sebastian-bergmann.de/
GnuPG Key: 0xB85B5D69 / 27A7 2B14 09E4 98CD 6277 0E5B 6867 C514 B85B 5D69
On Sunday 04 January 2009 10:45:30 am Sebastian Bergmann wrote:
Marcus Boerger schrieb:
$f = function() { use $x; }
+1 for consistency.
+1 for consistency as well, which is why, as I recall, that syntax was
rejected.
$f = function() {
global $x; // By reference.
use $y; // By value or by reference?
}
If $y is by reference by default there was no obvious way to make it by value.
If by value, then it is inconsistent with the behavior of global, which is by
reference. It was determined that we definitely needed to be able to allow
both by value and by reference.
$f = function() use ($y, &$z) {
global $x; // By reference
}
$y is clearly by value, and $z clearly by reference, as that parallels the way
function parameters work right next to the lexical variables.
The way to increase consistency would be to allow the opposite:
$f = function($a, &$b) use ($y, &$z) global ($x, &$w) {
}
$x is pulled from global scope by value.
$w is pulled from global scope by reference.
$y is pulled from lexical scope by value.
$z is pulled from lexical scope by reference.
$a is pulled from calling scope by value.
$b is pulled from calling scope by reference.
Right now we have everything there except the global param list. I don't know
if we want to bother adding that in 5.3 at this point (as it would be a
syntax/feature change), but IMO that is the best way to improve consistency
while getting a little extra functionality (global by value) at the same time.
--
Larry Garfield
larry@garfieldtech.com
Hello Larry,
Sunday, January 4, 2009, 10:05:25 PM, you wrote:
On Sunday 04 January 2009 10:45:30 am Sebastian Bergmann wrote:
Marcus Boerger schrieb:
$f = function() { use $x; }
+1 for consistency.
+1 for consistency as well, which is why, as I recall, that syntax was
rejected.
$f = function() {
global $x; // By reference.
use $y; // By value or by reference?
}
If $y is by reference by default there was no obvious way to make it by value.
If by value, then it is inconsistent with the behavior of global, which is by
reference. It was determined that we definitely needed to be able to allow
both by value and by reference.
$f = function() use ($y, &$z) {
global $x; // By reference
}
$y is clearly by value, and $z clearly by reference, as that parallels the way
function parameters work right next to the lexical variables.
The way to increase consistency would be to allow the opposite:
And then what do we do with static? And besides how is:
...use (&$ref)
different from:
...use &$ref;
But maybe you want consistency by breaking nearly every PHP script ever
written? Or did I miss some Months and it is early April rather than early
January?
$f = function($a, &$b) use ($y, &$z) global ($x, &$w) {
}
$x is pulled from global scope by value.
$w is pulled from global scope by reference.
$y is pulled from lexical scope by value.
$z is pulled from lexical scope by reference.
$a is pulled from calling scope by value.
$b is pulled from calling scope by reference.
Right now we have everything there except the global param list. I don't know
if we want to bother adding that in 5.3 at this point (as it would be a
syntax/feature change), but IMO that is the best way to improve consistency
while getting a little extra functionality (global by value) at the same time.
--
Larry Garfield
larry@garfieldtech.com
Best regards,
Marcus
On Sunday 04 January 2009 8:17:27 pm Marcus Boerger wrote:
Hello Larry,
$f = function() use ($y, &$z) {
global $x; // By reference
}$y is clearly by value, and $z clearly by reference, as that parallels
the way function parameters work right next to the lexical variables.The way to increase consistency would be to allow the opposite:
And then what do we do with static? And besides how is:
...use (&$ref)
different from:
...use &$ref;
I don't recall if statics were discussed previously, but the concept of a by-
value static doesn't really make sense whereas it can for lexical or global
variables.
And the difference between use(&$var) and use &$var is that the latter looks
like it SHOULD behave like the existing global keyword does, but can't because
we need to support both by-value and by-reference. (Honestly I'm more likely
to use by-value myself, I think.) So you'd have "global $foo" which is by-ref
but "use $foo" which is by-value. That's not at all consistent or intuitive.
Putting it in the function signature means it behaves exactly like the rest of
the function signature with regards to by-value vs. by-reference behavior.
But maybe you want consistency by breaking nearly every PHP script ever
written? Or did I miss some Months and it is early April rather than early
January?
Neither. At no point did I suggest removing the existing global keyword or
altering its behavior. I simply said that if we're concerned about lexical
variables having one syntax and global variables a different syntax right now,
the solution is to allow global variables to use the same syntax as lexical
(in addition to the current mechanism) not to make lexical use the same syntax
as global (which is not flexible enough to handle the use cases lexical
variables need in a consistent fashion).
No, I didn't explicitly say to keep the existing syntax as well; I figured it
was implicit. If that didn't make it through, I apologize.
--
Larry Garfield
larry@garfieldtech.com
$f = function($a, &$b) use ($y, &$z) global ($x, &$w) {
It would still leave the "static" keyword as an outlier. It wouldn't
make sense to declare a static by-ref.
Another problem with this, is that "use" and "global" doesn't match
conceptually. To make sense, we would have to rename "use" to
something like "lexical" (I think we had that discussion a year ago).
With the current proposed syntax, that isn't as much of a problem,
because the syntactic placement of "use" helps you to understand its
meaning..
--
troels
Hi!
some time back (August 08) I complained about 'use' being at a weird
position and not at the same place as 'global' or 'static' where I
expected it. Back then Dmitry asked me to provide a patch to check out
the alternative. Now during the holidays I finally found some time to
change from:
$f = function() use ($x) {}
to:
$f = function() { use $x; }Patch is attached.
Comments?
I don't really see any "consistency" in it - this "use" syntax has
nothing to do with other "use" (namespace one) even if it looks almost
exactly like one in proposed patch. It also is subtly different from
global or static - different enough to make people think "ok, 'global'
is always by ref and 'use' looks like 'global' for consistency reasons -
does it mean it is consistently by-ref?" Not to mention questions like
"can I write 'use' in the middle of the code, since I can do it with
"consistent" constructs like 'static' or 'global'? What if I refer to
the variable before - will it be already bound?", etc. I think it would
not improve code readability and not really make it "consistent" anyway.
Stanislav Malyshev, Zend Software Architect
stas@zend.com http://www.zend.com/
(408)253-8829 MSN: stas@zend.com
Hello Stanislav,
Monday, January 5, 2009, 6:03:56 AM, you wrote:
Hi!
some time back (August 08) I complained about 'use' being at a weird
position and not at the same place as 'global' or 'static' where I
expected it. Back then Dmitry asked me to provide a patch to check out
the alternative. Now during the holidays I finally found some time to
change from:
$f = function() use ($x) {}
to:
$f = function() { use $x; }Patch is attached.
Comments?
I don't really see any "consistency" in it - this "use" syntax has
nothing to do with other "use" (namespace one) even if it looks almost
exactly like one in proposed patch. It also is subtly different from
global or static - different enough to make people think "ok, 'global'
is always by ref and 'use' looks like 'global' for consistency reasons -
does it mean it is consistently by-ref?" Not to mention questions like
"can I write 'use' in the middle of the code, since I can do it with
"consistent" constructs like 'static' or 'global'? What if I refer to
the variable before - will it be already bound?", etc. I think it would
not improve code readability and not really make it "consistent" anyway.
We have the same with global and static. Can you write them in the middle
of a funciton/method? So asking for what the consequence is, is irrelevant
unless you want to clean up that mess and correct the parser rules knowing
that it would break most PHP applications out there. Next, we chose 'use'
for the keyword, knowing that it was already used elsewhere, dciding that
it is the lesser evil opposed to creating yet another keyword with all
implications of that. So this part is irrelevant to my point as well.
What is left is moving something we decided upon so that it might look like
something that is similar already avoiding to create a pretty new syntax
that in my opinion is unnecessary different from anything we already have.
In fact 'use' means create a static variable from the surrounding context,
while 'static' means create a new static variable. Actually the executor
does not know the difference at all. Next 'global' means allow to use a
global variable.
So:
function () {
global $foo;
static $bar;
use $baz;
}
Is pretty clear to me, as all three statements have a defined keyword. And
I would really prefer if all I have to teach is the meaning of the keyword.
And not having to teach a completely new syntax:
function() use($baz) {
global $foo;
static $bar;
}
That simply contradicts the KISS approach because it requires one
additional level of understanding.
And to answer the other question. Obviously 'sttaic' and 'use' are executed
at compile time, so whereever you place them, they are executed before
anything else. Thus it doesn't matter where you place them.
So here consistency means placing a syntactical element at the same
syntactical location related syntactical elements are placed.
Best regards,
Marcus
Hi!
We have the same with global and static. Can you write them in the middle
of a funciton/method? So asking for what the consequence is, is irrelevant
Yes you can. Example:
<?php
$a = 1;
function foo()
{
$a = 2;
echo $a;
global $a;
echo $a;
}
foo();
that it would break most PHP applications out there. Next, we chose 'use'
for the keyword, knowing that it was already used elsewhere, dciding that
it is the lesser evil opposed to creating yet another keyword with all
implications of that. So this part is irrelevant to my point as well.
You are trying to make it greater evil that it would be otherwise, by
making syntax that does different things look exactly the same.
In fact 'use' means create a static variable from the surrounding context,
If you ignore the referencing semantics. Which you should not.
And to answer the other question. Obviously 'sttaic' and 'use' are executed
at compile time, so whereever you place them, they are executed before
Actually, static is a runtime construct - it generates FETCH_W opcode
and ASSIGN_REF opcode.
So here consistency means placing a syntactical element at the same
syntactical location related syntactical elements are placed.
The problem is that location is different (you can put static in the
middle of the code, and you can't put use there) and semantics is
different (static $a is by ref, use $a is not). Only thing similar is
that you work with variables in both cases. But if you compare to
function parameters, semantic is identical - it happens when entering a
function, it is specified at the start, it can be by-val or by ref. The
fact that inside engine it is implemented by reusing static's code is
not reason enough to expose the user to it.
Stanislav Malyshev, Zend Software Architect
stas@zend.com http://www.zend.com/
(408)253-8829 MSN: stas@zend.com
Personally I like the current syntax more and don't see any reason to
change it.
Thanks. Dmitry.
Marcus Boerger wrote:
Hello Internals, Dmitry, Lukas, Johannes,
some time back (August 08) I complained about 'use' being at a weird
position and not at the same place as 'global' or 'static' where I
expected it. Back then Dmitry asked me to provide a patch to check out
the alternative. Now during the holidys I finally found some time to
change from:
$f = function() use ($x) {}
to:
$f = function() { use $x; }Patch is attached.
Comments?
Best regards,
Marcus
I like how the current syntax forces you to define what your importing right
next to the function signature. It's easy to waste time debugging if your
assumptions about what's being imported into scope are wrong.
Erik Schulz - gradbot @ gmail, yahoo, aim
Software Engineer, Vulcan Inc.
Personally I like the current syntax more and don't see any reason to
change it.Thanks. Dmitry.
Marcus Boerger wrote:
Hello Internals, Dmitry, Lukas, Johannes,
some time back (August 08) I complained about 'use' being at a weird
position and not at the same place as 'global' or 'static' where I
expected it. Back then Dmitry asked me to provide a patch to check out
the alternative. Now during the holidys I finally found some time to
change from:
$f = function() use ($x) {}
to:
$f = function() { use $x; }Patch is attached.
Comments?
Best regards,
Marcus
Dmitry Stogov wrote:
Personally I like the current syntax more and don't see any reason to
change it.Thanks. Dmitry.
Marcus Boerger wrote:
Hello Internals, Dmitry, Lukas, Johannes,
some time back (August 08) I complained about 'use' being at a weird
position and not at the same place as 'global' or 'static' where I
expected it. Back then Dmitry asked me to provide a patch to check out
the alternative. Now during the holidys I finally found some time to
change from:
$f = function() use ($x) {}
to:
$f = function() { use $x; }Patch is attached.
Comments?
I think the current syntax may be clearer:
<?php
namespace blah;
include 'file/with/foo/namespace.php';
use foo/something;
$f = function() use ($x) {}
?>
<?php
namespace blah;
include 'file/with/foo/namespace.php';
use foo/something;
$f = function()
{
use $x;
}
?>
The second version requires a visual re-parsing, the first is clear at a
glance. In addition, if support for namespaced variables was ever
introduced, confusion would abound.
Thanks,
Greg
P.S. happy new year (I'm a bit slow)