Hi!
I wrote a small patch that enables this kind of syntax in PHP:
foo()();
What it means is that if foo() returns callable value (which probably
should be function name or closure) then it would be called. Parameters
and more than two sets of () work too.
Of course, this is mostly useful for doing closures, and that was
primary drive for implementing it - to make working with closures and
especially function returning closures easier.
What does not work currently is $foo->bar()() - since it is surprisingly
hard to tell parser it's not {$foo->bar}()() - which of course is not
what I want to do.
The patch is here: http://random-bits-of.info/funcfunc.diff
What do you think? If somebody has better idea btw - maybe make
something like {foo()}() - and make that work for any expression inside
{} - that might work too. So, what do you think?
Stanislav Malyshev, Zend Software Architect
stas@zend.com http://www.zend.com/
(408)253-8829 MSN: stas@zend.com
I wrote a small patch that enables this kind of syntax in PHP:
foo()();
What it means is that if foo() returns callable value (which probably
should be function name or closure) then it would be called.
Parameters
and more than two sets of () work too.
Of course, this is mostly useful for doing closures, and that was
primary drive for implementing it - to make working with closures and
especially function returning closures easier.
What does not work currently is $foo->bar()() - since it is
surprisingly
hard to tell parser it's not {$foo->bar}()() - which of course is not
what I want to do.The patch is here: http://random-bits-of.info/funcfunc.diff
What do you think? If somebody has better idea btw - maybe make
something like {foo()}() - and make that work for any expression
inside
{} - that might work too. So, what do you think?
If I understand what this does...
I think it would be far easier to just keep using:
$foo_closure = foo();
$foo();
then to try to deal with foo()();
foo()(); just seems a bit too arcane to me...
--
Some people ask for gifts here.
I just want you to buy an Indie CD for yourself:
http://cdbaby.com/search/from/lynch
Hi!
I wrote a small patch that enables this kind of syntax in PHP:
foo()();
What it means is that if foo() returns callable value (which probably should be function name or closure) then it would be called. Parameters and more than two sets of () work too.
Of course, this is mostly useful for doing closures, and that was primary drive for implementing it - to make working with closures and especially function returning closures easier.
What does not work currently is $foo->bar()() - since it is surprisingly hard to tell parser it's not {$foo->bar}()() - which of course is not what I want to do.
I like it!
regarding $foo->bar()()…
is it possible to use precedence rules here? something like:
($foo->bar())();
What do you think? If somebody has better idea btw - maybe make something like {foo()}() - and make that work for any expression inside {} - that might work too. So, what do you think?
why curly braces?
Parentheses would feel more natural here.
Would be nice if something like this worked too:
(new Class())->method();
Would be nice if something like this worked too:
(new Class())->method();
I was just looking at some Java code and thinking, "man I wish PHP did this."
Would be nice if something like this worked too:
(new Class())->method();
I was just looking at some Java code and thinking, "man I wish PHP did this"
Funny, I was just thinking the opposite "man I wish PHP never allows
this" :)
Can of worms I say, can of worms..
--Jani
Funny, I was just thinking the opposite "man I wish PHP never allows
this" :)Can of worms I say, can of worms..
Exactly my thought.
Please, let's not open it.
--
Wbr,
Antony Dovgal
http://pinba.org - realtime statistics for PHP
On Tue, Jan 19, 2010 at 2:14 AM, Alexey Zakhlestin
indeyets@gmail.com wrote:Would be nice if something like this worked too:
  (new Class())->method();
I was just looking at some Java code and thinking, "man I wish PHP did
this."
Whereas I look at that same code and think, "man I'm glad PHP doesn't
do that" :-)
Seriously, I don't like to have such complexity in the syntax.
KISS
--
Some people ask for gifts here.
I just want you to buy an Indie CD for yourself:
http://cdbaby.com/search/from/lynch
Alexey Zakhlestin wrote:
Would be nice if something like this worked too:
(new Class())->method();
If you really want to do this you can use a factory method:
Class::create()->method();
- Chris
Alexey Zakhlestin wrote:
Would be nice if something like this worked too:
(new Class())->method();If you really want to do this you can use a factory method:
Class::create()->method();
I know. That's what I do if I need it.
Or just create temporary variable
But, still, I want consistent syntax, which doesn't put limitations on me
this construct is an example of things, which many people take for granted and are shocked, when they discover, that they can't use it.
I saw a lot of questions on forums regarding it
Alexey Zakhlestin wrote:
Would be nice if something like this worked too:
(new Class())->method();If you really want to do this you can use a factory method:
Class::create()->method();I know. That's what I do if I need it.
Or just create temporary variableBut, still, I want consistent syntax, which doesn't put limitations on me
this construct is an example of things, which many people take for granted and are shocked, when they discover, that they can't use it.
I saw a lot of questions on forums regarding it
I am in favour of such things and get annoyed when it doesn't work.
I get annoyed because things like this don't work:
$a = '0123456789'[$i];
But I come from a C background and am a competent programmer.
I have seen the argument that things like this will confuse novice programmers,
maybe: but would they ever try to type something like that ?
--
Alain Williams
Linux/GNU Consultant - Mail systems, Web sites, Networking, Programmer, IT Lecturer.
+44 (0) 787 668 0256 http://www.phcomp.co.uk/
Parliament Hill Computers Ltd. Registration Information: http://www.phcomp.co.uk/contact.php
Past chairman of UKUUG: http://www.ukuug.org/
#include <std_disclaimer.h
I have seen the argument that things like this will confuse novice
programmers,
maybe: but would they ever try to type something like that ?
Yes, because they see the experts typing something like that.
What's more, they have to READ something typed like that.
If you think you get a lot of forum activity over why it doesn't work,
consider what you would see on the other side of that coin: All the
non-programmers coding in PHP who ask what it does.
--
Some people ask for gifts here.
I just want you to buy an Indie CD for yourself:
http://cdbaby.com/search/from/lynch
hi Stan,
Hi!
I wrote a small patch that enables this kind of syntax in PHP:
foo()();
What it means is that if foo() returns callable value (which probably should
be function name or closure) then it would be called. Parameters and more
than two sets of () work too.
Of course, this is mostly useful for doing closures, and that was primary
drive for implementing it - to make working with closures and especially
function returning closures easier.
What does not work currently is $foo->bar()() - since it is surprisingly
hard to tell parser it's not {$foo->bar}()() - which of course is not what I
want to do.The patch is here: http://random-bits-of.info/funcfunc.diff
What do you think? If somebody has better idea btw - maybe make something
like {foo()}() - and make that work for any expression inside {} - that
might work too. So, what do you think?
I'm not a fan of this kind of syntaxic sugars, especially for
procedural implementation only. What are the benefits?
Cheers,
Pierre
@pierrejoye | http://blog.thepimp.net | http://www.libgd.org
Hi!
I'm not a fan of this kind of syntaxic sugars, especially for
procedural implementation only. What are the benefits?
Some as all other syntax sugars - better-looking code.
Stanislav Malyshev, Zend Software Architect
stas@zend.com http://www.zend.com/
(408)253-8829 MSN: stas@zend.com
Hi!
I'm not a fan of this kind of syntaxic sugars, especially for
procedural implementation only. What are the benefits?Some as all other syntax sugars - better-looking code.
Ah ok, then let say -1 from here for the function()() thing, as I
don't see it as an improvement.
However I would really like the other things described in this thread
about methods.
Cheers,
Pierre
@pierrejoye | http://blog.thepimp.net | http://www.libgd.org
Hi!
I wrote a small patch that enables this kind of syntax in PHP:
foo()();
I'd rather see two other things that are missing, support for
dynamic object and array de-referencing like
(new class)->method() and get_array()["index"].
I honestly don't see func()()()() make anything better in the
world of a PHP programmer.
Regards,
Mike
Hi!
I wrote a small patch that enables this kind of syntax in PHP:
foo()();
I'd rather see two other things that are missing, support for
dynamic object and array de-referencing like
(new class)->method() and get_array()["index"].I honestly don't see func()()()() make anything better in the
world of a PHP programmer.
Exactly.
Cheers,
Pierre
@pierrejoye | http://blog.thepimp.net | http://www.libgd.org
2010/1/19 Pierre Joye pierre.php@gmail.com:
Hi!
I wrote a small patch that enables this kind of syntax in PHP:
foo()();
I'd rather see two other things that are missing, support for
dynamic object and array de-referencing like
(new class)->method() and get_array()["index"].I honestly don't see func()()()() make anything better in the
world of a PHP programmer.Exactly.
Cheers,
Pierre
Totally agree.
Hi,
Hi!
I wrote a small patch that enables this kind of syntax in PHP:
foo()();
I think that becomes hard to read quite easily.
I'd rather see two other things that are missing, support for
dynamic object and array de-referencing like
(new class)->method() and get_array()["index"].
For the latter - there's a patch by some user in the bug tracker, which
I can't find right now.
Having $foo[0]->bar(); and $foo()[0]; it might also make sense to allow
more of these, like the proposed foo()() but other than such consistency
I don't really like it ....
johannes
I'd rather see two other things that are missing, support for
dynamic object and array de-referencing like
(new class)->method() and get_array()["index"].I honestly don't see func()()()() make anything better in the
world of a PHP programmer.
The array de-referencing and dynamic objects are much more common use
cases in PHP than call de-referencing, has anyone even needed (or
wanted) to do a func()() before? I haven't.
That being said, it probably should work unless there's a good reason
not to allow it to work.
-Clint
Hi!
I'd rather see two other things that are missing, support for
dynamic object and array de-referencing like
(new class)->method() and get_array()["index"].
The second was next on my list, while the first seems to me kind of
exotic - why create object only to call one method and immediately drop
it? Why this method is not static then?
I honestly don't see func()()()() make anything better in the
world of a PHP programmer.
You probably don't use closures, right?
Stanislav Malyshev, Zend Software Architect
stas@zend.com http://www.zend.com/
(408)253-8829 MSN: stas@zend.com
The second was next on my list, while the first seems to me kind of exotic -
why create object only to call one method and immediately drop it? Why this
method is not static then?
Why would this imply "dropping" the object?
This:
$foo = (new bar())->someSetter();
Looks a lot better than this
$foo = new bar();
$foo->someSetter();
It's more obvious when you have to store your objects somewhere:
$foo->bar[$somevar] = (new bar())->someSetter();
Any object that returns $this a lot makes for a valid use case and
right now, we're forced to use a factory method hack, which doesn't
always work, especially in the cases where you have a dynamically
named class (and you can depend on inheritence to guarantee your
method, but not the existence of a static factory method).
What arguments are there against this? Why shouldn't it be allowed?
Eddie Drapkin wrote:
The second was next on my list, while the first seems to me kind of exotic -
why create object only to call one method and immediately drop it? Why this
method is not static then?Why would this imply "dropping" the object?
This:
$foo = (new bar())->someSetter();
Looks a lot better than this
$foo = new bar();
$foo->someSetter();
The second version is much clearer. You know exactly what $foo is. In
the shortened version you have no idea what $foo is without reading the
code for the someSetter() method. On first glance I would assume that
$foo would be the success/failure return of the setter and that the
object is dropped.
-Rasmus
Eddie Drapkin wrote:
The second was next on my list, while the first seems to me kind of exotic -
why create object only to call one method and immediately drop it? Why this
method is not static then?Why would this imply "dropping" the object?
This:
$foo = (new bar())->someSetter();
Looks a lot better than this
$foo = new bar();
$foo->someSetter();The second version is much clearer. You know exactly what $foo is. In
the shortened version you have no idea what $foo is without reading the
code for the someSetter() method. On first glance I would assume that
$foo would be the success/failure return of the setter and that the
object is dropped.-Rasmus
I don't think that's necessarily a fair statement to make. If you
were working within a set of guidelines, or even within just a style,
that "dictated" that setters return $this consistently across several
class (or even all of them), it wouldn't be any less clear than the
second. Assuming that you had no idea what the class did, or what
any of its methods returned, you could make the argument that the
former is less readable, but then again, if you're making wild guesses
at what methods return without reading code/documentation, you've got
bigger issues than the readability of a constructor + method call.
Even accepting the argument against readability, I don't think it's
strong enough to say that the feature is unacceptable. If used
properly, it can very well aid in the concision and readability of
code (especially if you're a fan of the "fluent" interface); I don't
agree with the thinking that presenting a case where a feature can be
used improperly is grounds for its dismissal. Were that the case,
nearly every feature in the language would be able to be dismissed,
no?
And to illustrate what I mean by fluent interface, there's a lot of
cases in code that I've written where I have something that looks
like:
Class::someFactory()->blah()->blah()->foo()->bar()->baz()->hello()->world();
//well, this is a little extreme
Which I think looks much better, and is more self documenting, as:
(new Class())->blah()->blah()->foo()->bar()->baz()->hello()->world();
Eddie Drapkin wrote:
Eddie Drapkin wrote:
The second was next on my list, while the first seems to me kind of exotic -
why create object only to call one method and immediately drop it? Why this
method is not static then?Why would this imply "dropping" the object?
This:
$foo = (new bar())->someSetter();
Looks a lot better than this
$foo = new bar();
$foo->someSetter();
The second version is much clearer. You know exactly what $foo is. In
the shortened version you have no idea what $foo is without reading the
code for the someSetter() method. On first glance I would assume that
$foo would be the success/failure return of the setter and that the
object is dropped.-Rasmus
I don't think that's necessarily a fair statement to make. If you
were working within a set of guidelines, or even within just a style,
that "dictated" that setters return $this consistently across several
class (or even all of them), it wouldn't be any less clear than the
second. Assuming that you had no idea what the class did, or what
any of its methods returned, you could make the argument that the
former is less readable, but then again, if you're making wild guesses
at what methods return without reading code/documentation, you've got
bigger issues than the readability of a constructor + method call.
Wild guesses? The point is that it doesn't matter what the setter
returns in the longer version because we know for a fact that the return
is dropped whereas it matters a lot in the shorter version and that is
where most people will guess wrong. And guess what, most people don't
read documentation. Trust me on this one.
-Rasmus
On Tue, Jan 19, 2010 at 11:05 AM, Stanislav Malyshev stas@zend.com
wrote:The second was next on my list, while the first seems to me kind of
exotic -
why create object only to call one method and immediately drop it?
Why this
method is not static then?Why would this imply "dropping" the object?
This:
$foo = (new bar())->someSetter();
Looks a lot better than this
$foo = new bar();
$foo->someSetter();
I would expect the first to put the result of someSetter() into $foo,
not the actual bar object...
For that, I'd expect to see:
($foo = new bar())->someSetter();
--
Some people ask for gifts here.
I just want you to buy an Indie CD for yourself:
http://cdbaby.com/search/from/lynch
Hi!
I'd rather see two other things that are missing, support for
dynamic object and array de-referencing like
(new class)->method() and get_array()["index"].The second was next on my list, while the first seems to me kind of
exotic - why create object only to call one method and immediately
drop
it? Why this method is not static then?I honestly don't see func()()()() make anything better in the
world of a PHP programmer.You probably don't use closures, right?
I use closures, though rarely.
When I use one, I consider it exotic/obtuse/unusual enough to require
self-documenting code, with a temp variable whose name include
'closure'.
I do not want something as tiny as () to be all I have to clue in the
new guy to a closure pattern/paradigm/algorithm.
Maybe if I was typing all closures all day in PHP I'd see more need
for it, but are you really doing this that often?
--
Some people ask for gifts here.
I just want you to buy an Indie CD for yourself:
http://cdbaby.com/search/from/lynch
Hi!
When I use one, I consider it exotic/obtuse/unusual enough to require
self-documenting code, with a temp variable whose name include
'closure'.
By "use" I meant not "use it so rarely that it's an exotic hack for me
that I have to explain what I did here", I mean "write code that relies
on this as routine language feature". Maybe I'm moving too fast though
and closure use is not that widespread in PHP, maybe it never will even.
Maybe if I was typing all closures all day in PHP I'd see more need
for it, but are you really doing this that often?
No, I don't do that often - but as soon as I started playing with it, I
felt the need for this syntax, that's why I did it. I think it's
usefulness depends a lot on how much you use them, so maybe I have to
wait and see if it will be mainstream enough.
Stanislav Malyshev, Zend Software Architect
stas@zend.com http://www.zend.com/
(408)253-8829 MSN: stas@zend.com
2010-01-19 17:05, Stanislav Malyshev skrev:
I honestly don't see func()()()() make anything better in the
world of a PHP programmer.You probably don't use closures, right?
Sorry for kidnapping a thread, bit it was this message that got me
thinking about raising the issue in earnest.
I'm also a little late to the party, replying to amonth old message,
since I do not have time to read this list as often as I'd like.
My question is not so much about implementation it is about language. I
have noticed quite a few times now that PHP developers use the word
"closure" when I would prefer "lambda".
In discussions about JavaScript (where I have spent most of my time the
last couple of years) the word "closure" is never used outside the
context of inherited scope, AFAIK.
A few examples:
<blockquote cite="http://www.javascriptkit.com/javatutors/closures.shtml"> Two one sentence summaries: * a closure is the local variables for a function - kept alive after the function has returned, or * a closure is a stack-frame which is not deallocated when the function returns. (as if a 'stack-frame' were malloc'ed instead of being on the stack!) <blockquote> <blockquote cite="http://www.webreference.com/programming/javascript/rg36/"> A closure takes place when a function creates an environment that binds local variables to it in such a way that they are kept alive after the function has returned. A closure is a special kind of object that combines two things: a function, and any local variables that were in-scope at the time that the closure was created. </blockquote>In my line of work I have read about 10 books on JavaScript the last
couple of years, including the works of all big names like D. Crockford,
John Resig, Nicholas Zakas, etc. They all describe closures in this fashion.
However, in the PHP manual as well as on this list, you seem to be
saying "closure" === "anonymous function" (which is what I'd rather see
called lambda).
This difference in the use of words is a bit confusing I would say. One
may also note that in JavaScript closures exists even with named
functions, i.e. it does not need to be anonymous.
Maybe this discussion belongs on the documentation list, but I wanted
the reach the core developers, since you are the guys (and gals) that
have produced the features and set the language.
If I am out of line, please let me know and I will take my questions
elsewhere.
Oh, yes, the question:
Wouldn't you agree that it is better for PHP to use the word closure as
it is being used in the JavaScript community?
--
Keryx Web (Lars Gunther)
http://keryx.se/
http://twitter.com/itpastorn/
http://itpastorn.blogspot.com/
Oh, yes, the question:
Wouldn't you agree that it is better for PHP to use the word closure as
it is being used in the JavaScript community?
There's a pretty big difference between how PHP implements closures and how
JavaScript implements them - in PHP, you have to explicitly request which
variables will be bound to the closure. Here's an example I've been using
on Freenode's ##PHP to demonstrate how a PHP closure might work.
$array = array(
array('foo' => 17, 'bar'=>'last'),
array('foo' => 1, 'bar'=>'first'),
array('foo' => 3, 'bar'=>'middle'),
);
function buildSorter($key) {
return function ($a, $b) use ($key) {
if ($a[$key] == $b[$key]) return 0; return ($a[$key] < $b[$key]) ? -1:1;
};
}
$sort = buildSorter('foo');
usort($array, $sort);
var_dump($array);
Not an example that's going to rock anyone's world, obviously, but I think
it's illustrative.
However, because of an implementation detail (all anonymous functions are
now implemented as instance of class 'Closure'), it might be hard to enforce a
strict use of the word 'closure' here - although, it is kind of interesting
to look at a var_dump()
of $sort:
object(Closure)#1 (2) {
["static"]=>
array(1) {
["key"]=>
string(3) "foo"
}
["parameter"]=>
array(2) {
["$a"]=>
string(10) "<required>"
["$b"]=>
string(10) "<required>"
}
}
Unfortunately, we're not allowed to query for that 'static' property
(Catchable fatal error: Closure object cannot have properties) and are
are explicitly discouraged from relying on this detail of implementation
("Anonymous functions are currently implemented using the Closure class.
This is an implementation detail and should not be relied upon.")
So to answer your question, for my money, since I can't currently tell the
difference in a programmatic way between an 'anonymous function' and a full
'closure', I don't find it that worrisome that the PHP world somewhat
conflates the two terms.
So to answer your question, for my money, since I can't currently tell the
difference in a programmatic way between an 'anonymous function' and a full
'closure', I don't find it that worrisome that the PHP world somewhat
conflates the two terms.
For me it's worrisome because future developers, that are just starting
programming with PHP, will need more time to understand that a
non-anonymous function, i.e. a function that has a name, may just as
well benefit of a closure concept (except in the PHP language (if I
don't count importing of global variables using the global statement)).
A closure is not a special kind of function, a closure is just a link
between a function (named or unnamed) and the environment it has been
defined in.
I totally agree with Keryx, we should use the correct names for these
concepts. If it was up to me, I'd name the internal class used to
represent lambdas Lambda.
--
Ionut G. Stan
I'm under construction | http://blog.igstan.ro/
2010-02-21 03:55, Joey Smith skrev:
There's a pretty big difference between how PHP implements closures and how
JavaScript implements them
I have seen that, but my question is about language, not implementation.
FWIW, taking my educator perspective, PHP's way of explicitly pointing
out what variables are part of the closure is very easy to explain.
The way you are using the word "closure" in your reply is consistent
with the way I'd like to see it used, though.
--
Keryx Web (Lars Gunther)
http://keryx.se/
http://twitter.com/itpastorn/
http://itpastorn.blogspot.com/
Hi!
My question is not so much about implementation it is about language. I
have noticed quite a few times now that PHP developers use the word
"closure" when I would prefer "lambda".
Everybody on the internet knows that Wikipedia is the ultimate source of
knowledge, and it says:
In computer science, a closure is a first-class function with free
variables that are bound in the lexical environment. Such a function is
said to be "closed over" its free variables.
I think this describes what PHP is doing.
However, in the PHP manual as well as on this list, you seem to be
saying "closure" === "anonymous function" (which is what I'd rather see
called lambda).
This is not entirely correct, you are right. There's a difference
between anonymous function and closure, though in practice in PHP
anonymous functions are closures (though some of them are rather trivial
ones with no variables to "close over") and that's now the only way to
do closure in PHP (i.e. you can't have non-anonymous closure function).
Stanislav Malyshev, Zend Software Architect
stas@zend.com http://www.zend.com/
(408)253-8829 MSN: stas@zend.com
This is not entirely correct, you are right. There's a difference
between anonymous function and closure, though in practice in PHP
anonymous functions are closures (though some of them are rather trivial
ones with no variables to "close over") and that's now the only way to
do closure in PHP (i.e. you can't have non-anonymous closure function).
Correct me if I'm wrong, but given the fact that PHP only* supports
functions defined in the global space**, with the additional ability to
import global variables using the global statement, wouldn't that make
named functions able to close-over global variables?
And, if the above is true, wouldn't it be consistent to support the use
statement on named functions, and then deprecate the global statement?
I remember one of the first implementation for closure, used a statement
similar to global for closing over variables (the lexical statement).
Thanks,
- I know it allows definition of function inside other functions, which
will ultimately end up in the global scope.
** namespaced functions don't make any difference, as variables aren't
namespaced.
--
Ionut G. Stan
I'm under construction | http://blog.igstan.ro/
** namespaced functions don't make any difference, as variables aren't
namespaced.
I never did understand why variables were not namespaced.
However, since 5.3 has been out for a while it might make things difficult to
make them - would break BC, unless the following was adopted -- something that
would really make me happy:
namespace foo;
var $bar; // Creates the variable $\foo\bar;
I still really want to have something like perl's ''use strict''. If 'var'
is used outside of a function then ''use strict'' becomes switched on, the
way to access a global variable would be to use the namespace \ - first
declare it:
var $\globalName;
Note that the 'global' keyword would still be used in functions:
function blob()
{
global $\globalName; // Import from $GLOBALS
global $bar; // Import from current namespace
}
The above might even be extended:
namespace foo;
public $bar; // Creates a variable $\foo\bar this is available to code outside the namespace
private $fred; // Creates $\foo\fred that cannot be accessed by code outside the namespace
Variables in a namespace would not appear in $GLOBALS.
--
Alain Williams
Linux/GNU Consultant - Mail systems, Web sites, Networking, Programmer, IT Lecturer.
+44 (0) 787 668 0256 http://www.phcomp.co.uk/
Parliament Hill Computers Ltd. Registration Information: http://www.phcomp.co.uk/contact.php
Past chairman of UKUUG: http://www.ukuug.org/
#include <std_disclaimer.h
Hi!
I never did understand why variables were not namespaced.
If you have so many global vars you need to namespace them, you should
not use global vars.
Stanislav Malyshev, Zend Software Architect
stas@zend.com http://www.zend.com/
(408)253-8829 MSN: stas@zend.com
maybe you want to pack your namespaced functions/classes with the
global variables used with them.
Tyrael
Hi!
I never did understand why variables were not namespaced.
If you have so many global vars you need to namespace them, you should not
use global vars.Stanislav Malyshev, Zend Software Architect
stas@zend.com http://www.zend.com/
(408)253-8829 MSN: stas@zend.com
maybe you want to pack your namespaced functions/classes with the
global variables used with them.
+1
Tyrael
--
Alain Williams
Linux/GNU Consultant - Mail systems, Web sites, Networking, Programmer, IT Lecturer.
+44 (0) 787 668 0256 http://www.phcomp.co.uk/
Parliament Hill Computers Ltd. Registration Information: http://www.phcomp.co.uk/contact.php
Past chairman of UKUUG: http://www.ukuug.org/
#include <std_disclaimer.h
Hi!
I never did understand why variables were not namespaced.
If you have so many global vars you need to namespace them, you should
not use global vars.
It is not a question of number -- you may have some module where the
functions need to share a couple of variables between themselves, eg a file handle.
If variables could be private to a namespace then you would be confident that
you would not get a variable name collision with some other, independently developed,
module.
Objects are not always the answer.
--
Alain Williams
Linux/GNU Consultant - Mail systems, Web sites, Networking, Programmer, IT Lecturer.
+44 (0) 787 668 0256 http://www.phcomp.co.uk/
Parliament Hill Computers Ltd. Registration Information: http://www.phcomp.co.uk/contact.php
Past chairman of UKUUG: http://www.ukuug.org/
#include <std_disclaimer.h
Hi!
I never did understand why variables were not namespaced.
If you have so many global vars you need to namespace them, you should
not use global vars.It is not a question of number -- you may have some module where the
functions need to share a couple of variables between themselves, eg a file handle.
If variables could be private to a namespace then you would be confident that
you would not get a variable name collision with some other, independently developed,
module.Objects are not always the answer.
in situation, which you described, objects are definitely the answer.
you have several functions, which share the same "state". that's very close to the definition of object.
Objects are not always the answer.
in situation, which you described, objects are definitely the answer.
you have several functions, which share the same "state". that's very close to the definition of object.
Maybe 'private static' -- ie shared between different objects.
It is not always appropriate, eg a generic logging function, called from all over
the place - it is not always convenient to pass a logging object around;
you just want to call the logging function.
OO is not always the answer.
--
Alain Williams
Linux/GNU Consultant - Mail systems, Web sites, Networking, Programmer, IT Lecturer.
+44 (0) 787 668 0256 http://www.phcomp.co.uk/
Parliament Hill Computers Ltd. Registration Information: http://www.phcomp.co.uk/contact.php
Past chairman of UKUUG: http://www.ukuug.org/
#include <std_disclaimer.h
Objects are not always the answer.
in situation, which you described, objects are definitely the answer.
you have several functions, which share the same "state". that's very close to the definition of object.Maybe 'private static' -- ie shared between different objects.
It is not always appropriate, eg a generic logging function, called from all over
the place - it is not always convenient to pass a logging object around;
you just want to call the logging function.
this one is solved by singleton ;)
gives real protection for "private" var as a bonus
Hi!
It is not a question of number -- you may have some module where the
functions need to share a couple of variables between themselves, eg a file handle.
Congratulations, you have just discovered why OO exists :)
Objects are not always the answer.
If you refuse to use language construct that fits your purpose and try
to reinvent it in a backwards way - it won't end up in anything useful.
Stanislav Malyshev, Zend Software Architect
stas@zend.com http://www.zend.com/
(408)253-8829 MSN: stas@zend.com
On Tuesday 23 February 2010 05:00:28 pm Ionut G. Stan wrote:
This is not entirely correct, you are right. There's a difference
between anonymous function and closure, though in practice in PHP
anonymous functions are closures (though some of them are rather trivial
ones with no variables to "close over") and that's now the only way to
do closure in PHP (i.e. you can't have non-anonymous closure function).Correct me if I'm wrong, but given the fact that PHP only* supports
functions defined in the global space**, with the additional ability to
import global variables using the global statement, wouldn't that make
named functions able to close-over global variables?And, if the above is true, wouldn't it be consistent to support the use
statement on named functions, and then deprecate the global statement?I remember one of the first implementation for closure, used a statement
similar to global for closing over variables (the lexical statement).
IMO, globals could and should use a similar syntax to lexical closures:
function foo($a, &$b) global ($c, &$d) {
// ...
}
That would allow a parallel syntax, and allow for both by-value and by-
reference globals, which currently we cannot do. And closures/lambdas
could/should support the same syntax for globals.
--Larry Garfield
Hi!
Correct me if I'm wrong, but given the fact that PHP only* supports
functions defined in the global space**, with the additional ability to
import global variables using the global statement, wouldn't that make
named functions able to close-over global variables?
It's different mechanism. Globals are just references to variables in
same global scope, they are not bound to any function, etc.
And, if the above is true, wouldn't it be consistent to support the use
statement on named functions, and then deprecate the global statement?
That's why I'm not a big fan of that "consistency" argument here on the
list - because it usually means "let's implement some feature because I
like it", but not more. Which is fine, but it has nothing to do with
consistency.
Particularly, scope capturing and all that has very little relation to
what globals do. Closures carry around "captured" variables. Regular
functions don't. Global scope exists independently of them.
The mechanism is similar (well, it's the same engine, how many there can
be? :) but they are not the same.
** namespaced functions don't make any difference, as variables aren't
namespaced.
I'm not sure what you mean here, as variables in PHP are scoped. Global
functions are not scoped, of course, but can be namespaced.
Stanislav Malyshev, Zend Software Architect
stas@zend.com http://www.zend.com/
(408)253-8829 MSN: stas@zend.com
Hi!
Correct me if I'm wrong, but given the fact that PHP only* supports
functions defined in the global space**, with the additional ability to
import global variables using the global statement, wouldn't that make
named functions able to close-over global variables?It's different mechanism. Globals are just references to variables in
same global scope, they are not bound to any function, etc.And, if the above is true, wouldn't it be consistent to support the use
statement on named functions, and then deprecate the global statement?That's why I'm not a big fan of that "consistency" argument here on the
list - because it usually means "let's implement some feature because I
like it", but not more. Which is fine, but it has nothing to do with
consistency.
Particularly, scope capturing and all that has very little relation to
what globals do. Closures carry around "captured" variables. Regular
functions don't. Global scope exists independently of them.
The mechanism is similar (well, it's the same engine, how many there can
be? :) but they are not the same.
What I was thinking when writing my previous email was this:
- Named functions using global variables (both can read and modify the
global variable):
$global_var = 'foo';
function named_1() {
global $global_var;
}
function named_2() {
global $global_var;
}
- Closures (both lambdas can read and modify the local var)
list($closure_1, $closure_2) = call_user_func(function () {
$local_var = 'foo';
return array(
function () use(& $local_var) {},
function () use(& $local_var) {},
);
});
As I see it right now, there's a duplication of concepts in there. The
only difference is that the first example uses the global scope, while
the second one uses the scope of an anonymous function.
But I admit this is just a nice-to-have thingy, not a necessity. Well,
for me at least. So I won't ask for it anymore :).
** namespaced functions don't make any difference, as variables aren't
namespaced.I'm not sure what you mean here, as variables in PHP are scoped. Global
functions are not scoped, of course, but can be namespaced.
I mean that variables declated outside of a namespaced function or class
are not namespaced.
namespace foo;
$this_is_a_global_var = 'foo';
function namespaced_function() {
global $this_is_a_globa_var;
}
--
Ionut G. Stan
I'm under construction | http://blog.igstan.ro/
Stanislav Malyshev wrote:
Hi!
My question is not so much about implementation it is about language. I
have noticed quite a few times now that PHP developers use the word
"closure" when I would prefer "lambda".Everybody on the internet knows that Wikipedia is the ultimate source
of knowledge, and it says:In computer science, a closure is a first-class function with free
variables that are bound in the lexical environment. Such a function
is said to be "closed over" its free variables.I think this describes what PHP is doing.
However, in the PHP manual as well as on this list, you seem to be
saying "closure" === "anonymous function" (which is what I'd rather see
called lambda).This is not entirely correct, you are right. There's a difference
between anonymous function and closure, though in practice in PHP
anonymous functions are closures (though some of them are rather
trivial ones with no variables to "close over") and that's now the
only way to do closure in PHP (i.e. you can't have non-anonymous
closure function).
I would rather say that PHP have both. Closure is just a subset of
lanbda. You say that a lambda is a closure whenever
the lambda capture variable from its outer scope.
You even have a special syntactic form to declare a lambda to be a
closure, the keyword "use".
-- Mathieu
Hello,
I wrote a small patch that enables this kind of syntax in PHP:
foo()();
...
I think language enhancements with no BC breaks that offer a wider
toolset to programmers is a good thing. I would also like to see the
other ideas in this thread implemented such as array access & object
creation.
The only thing I do not like about this is I do not beleive it fits
the PHP error model. Lets just say Bar::foo($arg) returns a function
callback or FALSE/NULL on a error condition. So you end up with a
function call to something that is not callable, the PHP way under
this case is to have a fatal error. I would rather not see more ways
to cause fatal errors in PHP (call to undefined method has gotten a
bit more popular since object chaining has risen in popularity as
well). Of course I know exceptions are likely out of the question for
these kinds of cases as well. These thoughts do not apply to array
access or object creation.
Regards,
-Chris
Hello,
I wrote a small patch that enables this kind of syntax in PHP:
foo()();
...I think language enhancements with no BC breaks that offer a wider
toolset to programmers is a good thing. I would also like to see the
other ideas in this thread implemented such as array access & object
creation.
enhancements in the sense that they enable things that were not possible before, sure. syntax sugar that hurts readability, not really.
if you are worried about key strokes switch to an IDE. if you are worried about performance use a byte code cache.
regards,
Lukas Kahwe Smith
mls@pooteeweet.org
Hello,
enhancements in the sense that they enable things that were not possible before, sure. syntax sugar that hurts readability, not really.
if you are worried about key strokes switch to an IDE. if you are worried about performance use a byte code cache.
I am not worried about key strokes or performance of my code, neither
were arguments I made. The points I am making is I believe array
access and object creation are fairly good utilities that would
naturally fit inside the language without looking like they do not
belong, I do not call those syntax sugar. The function calls I believe
could also be a utility that if not for PHP's error model could also
fit more naturally. Regardless of my belief on syntax highlighting I
think that the function patch could be useful and used responsibly by
the PHP user base and would be a good "enhancement", yes, I said
enhancement.
Syntax sugar already exists in PHP, and they call it syntax "sugar",
because it is sweet, not bitter, duh. :-)
Regards,
-Chris
Hi!
enhancements in the sense that they enable things that were not
possible before, sure. syntax sugar that hurts readability, not
really.
It starts to seem to me that the notion of readability is rather
different here than in the rest of the world. Lately, almost any syntax
sugar features - including ones present and popular in many other
languages - are consistently rejected because they "hurt readability".
I'm starting to feel there's a confusion (or erroneous identification)
between readability and verbosity - which is IMHO not good. We have
features like foo()->bar() that reduce verbosity and I think by now
everyone agrees they are a good idea. So I think it is worth to
reconsider the notion that reducing verbosity hurts readability.
Stanislav Malyshev, Zend Software Architect
stas@zend.com http://www.zend.com/
(408)253-8829 MSN: stas@zend.com
-----Original Message-----
From: Stanislav Malyshev [mailto:stas@zend.com]
Sent: 19 January 2010 00:28
To: 'PHP Internals'
Subject: [PHP-DEV] function call chainingHi!
I wrote a small patch that enables this kind of syntax in PHP:
foo()();
What it means is that if foo() returns callable value (which
probably should be function name or closure) then it would be
called. Parameters and more than two sets of () work too.
Of course, this is mostly useful for doing closures, and that
was primary drive for implementing it - to make working with
closures and especially function returning closures easier.
What does not work currently is $foo->bar()() - since it is
surprisingly hard to tell parser it's not {$foo->bar}()() -
which of course is not what I want to do.The patch is here: http://random-bits-of.info/funcfunc.diff
What do you think? If somebody has better idea btw - maybe
make something like {foo()}() - and make that work for any
expression inside {} - that might work too. So, what do you think?Stanislav Malyshev, Zend Software Architect
stas@zend.com http://www.zend.com/
(408)253-8829 MSN: stas@zend.com--
To
unsubscribe, visit: http://www.php.net/unsub.php
I've run into problems with
$foo1;
If the closure attempts to change the value of $foo[1] then PHP
complains.
So was forced to assign to a temporary variable before hand.
$f = $foo[1];
$f();
I guessing foo()() could also suffer from the problem?
Jared
Stanislav Malyshev wrote:
Hi!
I wrote a small patch that enables this kind of syntax in PHP:
foo()();
What it means is that if foo() returns callable value (which probably
should be function name or closure) then it would be called. Parameters
and more than two sets of () work too.
Of course, this is mostly useful for doing closures, and that was
primary drive for implementing it - to make working with closures and
especially function returning closures easier.
What does not work currently is $foo->bar()() - since it is surprisingly
hard to tell parser it's not {$foo->bar}()() - which of course is not
what I want to do.The patch is here: http://random-bits-of.info/funcfunc.diff
What do you think? If somebody has better idea btw - maybe make
something like {foo()}() - and make that work for any expression inside
{} - that might work too. So, what do you think?
I don't mind the foo()() syntax, especially now that we have closures.
But people are right, we have a longstanding feature request for
$foo()[0] as well, so if we start down this path of adding chaining, we
should do that one as well and see if any others make sense.
I do think the syntax is a bit ugly, but I also think it is clear what
it does and doesn't obscure/mislead the semantics of the call the way
the (new foo)->bar() suggestion does.
Not sure the {} expression syntax is needed. What sort of expressions
do you see being useful here that would need the braces? Stuff like
$a$idx works today without needing any extra syntax. Are you
thinking along the lines of:
{strtolower($a[$idx])}()
or something like that? That would make the "I hate linefeeds and
semi-colons" crowd happy, I guess.
-Rasmus
I don't mind the foo()() syntax, especially now that we have closures.
But people are right, we have a longstanding feature request for
$foo()[0] as well, so if we start down this path of adding chaining, we
should do that one as well and see if any others make sense.I do think the syntax is a bit ugly, but I also think it is clear what
it does and doesn't obscure/mislead the semantics of the call the way
the (new foo)->bar() suggestion does.
+1
regards,
Lukas Kahwe Smith
mls@pooteeweet.org
Hi!
I don't mind the foo()() syntax, especially now that we have closures.
But people are right, we have a longstanding feature request for
$foo()[0] as well, so if we start down this path of adding chaining, we
should do that one as well and see if any others make sense.
As I said, that was next on my TODO (which doesn't make a promise of
delivering it soon, that depends on so many external circumstances :)
Not sure the {} expression syntax is needed. What sort of expressions
do you see being useful here that would need the braces? Stuff like
$a$idx works today without needing any extra syntax. Are you
This is one of the reasons why I wanted to have ()() to work - you can
do $myMethods'foo' but as soon as you go from that to
getMyMethod('foo') you have to have temp vars. It's an ugly style.
thinking along the lines of:
{strtolower($a[$idx])}()
No, that is probably not very useful or nice. Only use I'd see as
interesting would be either distinguishing between $foo->method() and
($foo->propertyContainingClosure)() and alike.
or something like that? That would make the "I hate linefeeds and
semi-colons" crowd happy, I guess.
That's more about extra statements than about linefeeds and semicolons.
People like to speak in full expressive sentences, not. In chunks. Each
of which. Expresses only small. Part of. The whole meaning. Of the
sentence. You can feel the difference, right?
I, personally, felt the need to do ()() as soon as I started playing
with closures, since when you do that, you very soon having functions
returning closures, and that very soon leads to needing to call whatever
function fetching closure returned.
Of course, you can get too far with it, just as you can get too far with
run-on sentences. Just as in prose, one has to watch his style.
Stanislav Malyshev, Zend Software Architect
stas@zend.com http://www.zend.com/
(408)253-8829 MSN: stas@zend.com
Hi Stas:
People like to speak in full expressive sentences
Sure. But one needs to understand the language. Otherwise the reader
needs to go hunting around a dictionary (or in our case, the source code)
to figure out what the heck the person (code) is trying to say (do).
Chaining produces code that is not self-documenting.
--Dan
--
T H E A N A L Y S I S A N D S O L U T I O N S C O M P A N Y
data intensive web and database programming
http://www.AnalysisAndSolutions.com/
4015 7th Ave #4, Brooklyn NY 11232 v: 718-854-0335 f: 718-854-0409
Hi!
Sure. But one needs to understand the language. Otherwise the reader
needs to go hunting around a dictionary (or in our case, the source code)
to figure out what the heck the person (code) is trying to say (do).Chaining produces code that is not self-documenting.
If you don't understand the language, nothing is self-documenting. If
you have the basics, you'd be able to understand that if foo()+1 means
"take result of foo() and add one", then foo()() would be "take result
of foo() and call it as a function". Adding temp var would be just like
writing $number = foo(); $number_plus_one = $number+1; - excessive
verbosity with no added value. It's like writing comments in style of:
foo(); // call foo() - surely it's documented, but not useful in any way.
Stanislav Malyshev, Zend Software Architect
stas@zend.com http://www.zend.com/
(408)253-8829 MSN: stas@zend.com
Hi Stas:
If you don't understand the language, nothing is self-documenting.
Yes. For clarity, what I meant by the "knowing the language" reference,
I was imagining a PHP programmer trying to read/debug the code of a
pre-existing project for the first time. When the code does stuff like:
foo()()();
or
$eep->oop()->ork()->ah()->ah();
the newcomer will have to spend significant time rummaging around the
source code to figure out what classes are involved.
Thanks,
--Dan
--
T H E A N A L Y S I S A N D S O L U T I O N S C O M P A N Y
data intensive web and database programming
http://www.AnalysisAndSolutions.com/
4015 7th Ave #4, Brooklyn NY 11232 v: 718-854-0335 f: 718-854-0409
Hi!
$eep->oop()->ork()->ah()->ah();
the newcomer will have to spend significant time rummaging around the
source code to figure out what classes are involved.
As opposed to:
$oop = $eep->oop();
$ork = $oop->ork();
$ah = $ork->ah();
$ah2 = $ah->ah();
where it instantly becomes crystal clear! Come on, this argument of "I
could read any code without ever knowing anything about anything but you
feature broke it" is getting really stale. You couldn't, and the feature
changed nothing.
Stanislav Malyshev, Zend Software Architect
stas@zend.com http://www.zend.com/
(408)253-8829 MSN: stas@zend.com
Hi!
$eep->oop()->ork()->ah()->ah();
the newcomer will have to spend significant time rummaging around the
source code to figure out what classes are involved.As opposed to:
$oop = $eep->oop();
$ork = $oop->ork();
$ah = $ork->ah();
$ah2 = $ah->ah();where it instantly becomes crystal clear! Come on, this argument of "I
could read any code without ever knowing anything about anything but you
feature broke it" is getting really stale. You couldn't, and the feature
changed nothing.
+1
At least with $eep->oop()->ork()->ah()->ah() you don't have stray/unwanted
variables hanging round to confuse (or be misused) later.
--
Alain Williams
Linux/GNU Consultant - Mail systems, Web sites, Networking, Programmer, IT Lecturer.
+44 (0) 787 668 0256 http://www.phcomp.co.uk/
Parliament Hill Computers Ltd. Registration Information: http://www.phcomp.co.uk/contact.php
Past chairman of UKUUG: http://www.ukuug.org/
#include <std_disclaimer.h
$eep->oop()->ork()->ah()->ah();
the newcomer will have to spend significant time rummaging around the
source code to figure out what classes are involved.
As opposed to:
$oop = $eep->oop();
$ork = $oop->ork();
$ah = $ork->ah();
$ah2 = $ah->ah();where it instantly becomes crystal clear! Come on, this argument of "I
could read any code without ever knowing anything about anything but you
feature broke it" is getting really stale. You couldn't, and the feature
changed nothing.
+1At least with $eep->oop()->ork()->ah()->ah() you don't have stray/unwanted
variables hanging round to confuse (or be misused) later.
+1
It also supports the "allocation is not initialization" (or anti-RAII) pattern found in languages like Objective-C:
Objective-C:
String *s = [[String alloc] initWithFormat:@"I'm a little teapot, %@ and %@", @"short", @"stout"];
PHP:
$s = (new String)->sprintf("I'm a little teapot, %s and %s", "short", "stout");
(Obviously a very, very contrived example, meant only to illustrate the pattern.)
-- Gwynne
Instead of adding yet-another feature, how about fixing the bugs in the
existing ones first? f.e. there is open bug related to closures, fixing
that might be good idea before adding yet another way to abuse them:
And in total there are 33 scripting engine (including class/Object
releated stuff) bugs open in the db of which most are even verified.
Yes, it's fun to add new stuff, forget the old crap?
--Jani
Religious programming is the problem.
$eep->oop()->ork()->ah()->ah();
the newcomer will have to spend significant time rummaging around the
source code to figure out what classes are involved.
As opposed to:
$oop = $eep->oop();
$ork = $oop->ork();
$ah = $ork->ah();
$ah2 = $ah->ah();
No amount of syntax change will alter the "true believer", it just
creates new religions. New rituals, new syntax, new languages.
To that end, I suggest a "trinity" operator, three colons in a row...
ObjectIDont'Understand::methodIhaven'tread:::DoWhatIWant.
When it fails, the failing will be on the part of the invocator,
because the trinity is not bound by logic. Any bugs would question the
faith, which is infallible, by definition.
Backing up, maybe it's a bad idea to argue about compilers.... with
people who haven't written them.
Hi Stas:
$oop = $eep->oop();
$ork = $oop->ork();
$ah = $ork->ah();
$ah2 = $ah->ah();where it instantly becomes crystal clear!
:) Yep, that's lousy code.
Variables should be named for the classes they represent.
$eep = new eep;
$eep->oop();
$decorator = $eep->ork();
$decorator->ah();
$decorator->ah();
// Output, of course, is "I love you".
// What do you mean you've never seen The Jetsons?!
Now it's clear that oop() is a method of eep while ork returns a
decorator object that contains the ah() method. No guess work involved.
If everything is chained, it's a pain to figure out such basic workings.
I'll leave it at this.
Thanks,
--Dan
--
T H E A N A L Y S I S A N D S O L U T I O N S C O M P A N Y
data intensive web and database programming
http://www.AnalysisAndSolutions.com/
4015 7th Ave #4, Brooklyn NY 11232 v: 718-854-0335 f: 718-854-0409
If everything is chained, it's a pain to figure out such basic workings.
Hi,
I still find it hard to understand why some should artificially claim basic
constructs supported by other languages for years are somehow more complex
than PHP's existing semantics.
Supporting dereferencing in all situations where it produces unambigous
results is necessary to improve consistency of the language, so we stop
seeing people surprised why something works in one context, but not another.
Working around PHP's limitation with redundant factory methods and temp vars
do not help code readability.
They are just arbitrarily imposed because of an irrational fear that
suddenly everyone will be jumping on the new feature for his entire
codebase. Even most poor coders are smarter than this.
Regards,
Stan Vassilev
Op 1/19/10 1:27 AM, Stanislav Malyshev schreef:
Hi!
I wrote a small patch that enables this kind of syntax in PHP:
foo()();
What it means is that if foo() returns callable value (which probably
should be function name or closure) then it would be called. Parameters
and more than two sets of () work too.
Of course, this is mostly useful for doing closures, and that was
primary drive for implementing it - to make working with closures and
especially function returning closures easier.
What does not work currently is $foo->bar()() - since it is surprisingly
hard to tell parser it's not {$foo->bar}()() - which of course is not
what I want to do.The patch is here: http://random-bits-of.info/funcfunc.diff
What do you think? If somebody has better idea btw - maybe make
something like {foo()}() - and make that work for any expression inside
{} - that might work too. So, what do you think?
cool as ice! :-)
I do worry how many painful edge cases this throw up and
additionally how many beginner coders with a bit of JS experience would continuely
complain/moan/question why PHP didn't work they [think] JS works, for instance the
classic JS closure-type tricks, e.g.:
doIt = function(a, b) { return function() { return b(a);} }
func = (function() { var bar = ''; return function(foo) { doIt(foo, bar)(); } })();
document.write(func(function(a) { return a + '-fooey'; }));
it's quite obvious how easy it is to make javascript code very difficult to follow,
personally I love it, but using it sensibly requires alot of care and attention,
it's worth considering whether giving PHPer another very powerful gun is wise
choice ... especially given how often they/we/(me!) put holes in feet.
I can imagine you'd be opening yourself up for sleepless night and lots of
unwarranted abuse for having offered a new bit of greatness.
given that Closures are still in their relative infancy (mostly in the context of
production use) and the fact that this is liable to still of itself be in flux,
and additionally the mountain of work/details (AFAIKT) required for PHP6, that, maybe,
such functionality should be put on the backburner for now. at some stage all the new stuff
(most notably Closures) will stabalize to such a degree that it would become more
manageable to introduce such a thing.
just my 2 cents.