Re: [PHP-DEV] Cascade Operator (was Re: [PHP-DEV] Proposal for php7 class method return)
On Tue, Jul 12, 2016 at 6:36 PM, Rowan Collinswrote: > > Thinking about it, this becomes something more like a "with" keyword: > > with ( $counter ) { >count(); >count(); >count(); >count(); > } > > The semicolon suggests those lines are arbitrary statements, in which case it's ambiguous whether count() is a method or a normal function. And what if I want to call a function count() but $counter happens to have a count() method I didn't know about when writing the code? That's why I used a comma, to be clear the lines are *not* statements but rather only things that can go on the right of "->" (property access (assignment) or method call). The lines have their own definition, like the lines of an array literal do. I'm not sure if this is a good thing or not - with() statements exist in a > few languages, with varying degrees of acceptance. I don't remember seeing > one used as an expression like that before, though. > I'm only aware of the "with" statement in JavaScript, which is considered a real language wart because all it does is take an object and adds it to your scope chain, so that without knowing precisely what properties the object has, you can't predict what local variables are going to be masked and which ones aren't. There's a definite awkwardness of what to put on the left side of property > assignments too... > > with ( new Foo ) { var = 1 } > with ( new Foo ) { $var = 1 } > with ( new Foo ) { ->var = 1 } > > If the definition of the lines is "what can go right of ->" then it follows that the first line is correct, which also happens to be the most concise one :) . > > Overall, it's an interesting idea, but the details are fiddly, and the > gains marginal, IMO. > > I think the details are only fiddly if the lines can be arbitrary statements. > > Regards, > -- > Rowan Collins > [IMSoP] > > -- > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: http://www.php.net/unsub.php > >
Re: [PHP-DEV] Cascade Operator (was Re: [PHP-DEV] Proposal for php7 class method return)
> Thinking about it, this becomes something more like a "with" keyword I was starting to think along these lines. I do like the idea of being able to specify the context for a block - though, as you say, this feature raises issues, and in e.g. Javascript, these days, it is now strongly discouraged, and prevented in strict mode. I do think it would have some potentially pretty awesome uses though - for example, in templates, assuming this statement would have a non-block counterpart (like if and while have) you could "import" a class with HTML helper methods in this way: It also potentially lets you create highly convenient DSLs: with ($parser_helper) { $INT = seq(optional(char("-")), plus(digit())); } This would have potentially really good IDE support and offline inspections as well. I guess the biggest issue is what happens when you wrap multiple scopes? with ($a) { with ($b) { foo(); } } What happens in this case? I don't think there's any good answer to that question - if neither $b or $a implements foo(), the only thing the compiler could do, is dispatch $b->__call("foo", []) ... so you'd need some really complex logic and rules, and these constructs could have some pretty unpredictable performance implications as well. There's also the question of what happens in this case: with ($a) { bar(); } function bar() { with ($b) { fud(); } } Does it work in the local scope only, or would it be able to resolve as $a->fud() ? That's crazy, and it probably should work only in the lexical scope of the current function, but anyways - I think this feature raises a lot of ugly questions with no elegant answers... On Tue, Jul 12, 2016 at 10:36 AM, Rowan Collinswrote: > On 12/07/2016 00:14, Jesse Schalken wrote: >> >> If so, some consideration should be made as to which syntax is preferred >> to solve this problem generally for both setting properties and calling >> methods. >> >> I prefer the "obj { .. }" syntax because it mirrors object literals in >> JSON/JavaScript, object initializers in C# and C/C++ and Haskell record >> syntax, is particularly concise when nested to create large trees of >> objects, and avoids the noise of "->>" on each line. > > > All the examples you've given for that syntax are for initialisation, and > I'm not sure how readable it would be for the general "do several things in > a row" case: > > $counter { >count(), >count(), >count(), >count() > } > > Thinking about it, this becomes something more like a "with" keyword: > > with ( $counter ) { >count(); >count(); >count(); >count(); > } > > If with(){} could be used as an expression, you'd get something remarkably > close to your initialiser example: > > $this->setBlah( > with ( Blah::create(4) ) { > foo = $foo; > baz = with ( new Baz() ) { > markFixed(); > label = "Hello"; > }; > setBot(9); > } > ); > > I'm not sure if this is a good thing or not - with() statements exist in a > few languages, with varying degrees of acceptance. I don't remember seeing > one used as an expression like that before, though. > > There's a definite awkwardness of what to put on the left side of property > assignments too... > > with ( new Foo ) { var = 1 } > with ( new Foo ) { $var = 1 } > with ( new Foo ) { ->var = 1 } > > > Overall, it's an interesting idea, but the details are fiddly, and the gains > marginal, IMO. > > > Regards, > -- > Rowan Collins > [IMSoP] > > -- > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: http://www.php.net/unsub.php > -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] Cascade Operator (was Re: [PHP-DEV] Proposal for php7 class method return)
On 12/07/2016 14:54, Michael Morris wrote: Agreed, but what about static methods? Triple colon perhaps? A::setFoo(1) :::setBar(2) :::setBaz(3); This is a rather different feature, because you can't really express that as an expression returning something. What is $result set to if I run "$result = A:::setFoo(1)"? Or, equivalently, what is the value of the chain you've written? (Presumably, the "::" on the first line should be a ":::", otherwise I'm even less sure how to read it...) I think saying "if you want the cascade operator, you have to use an instance, not static methods" is reasonable enough. Especially with the perennial discussion about namespaced functions being better than classes with lots of static methods (if only we had function autoloading, etc, etc). Somebody quoted a concise explanation of the cascade operator earlier, which bears repeating, in PHP context: // Proposed $result = $foo->>bar(); // Valid in PHP 7 $result = ( function($subject){ $subject->bar(); return $subject; } )( $foo ); // Long-hand $foo->bar(); // discard return result $result = $foo; There's no magic needed to create longer chains, or combine this with other operators; it's not a transform done to the source code, just a normal expression. Regards, -- Rowan Collins [IMSoP] -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] Cascade Operator (was Re: [PHP-DEV] Proposal for php7 class method return)
IMO, static methods have very little need for this feature - you rarely need to make repeated series of static calls and static property assignments. Let's not complicate this. On Tue, Jul 12, 2016 at 3:54 PM, Michael Morriswrote: > On Mon, Jul 11, 2016 at 1:55 PM, Michał Brzuchalski < > michal.brzuchal...@gmail.com> wrote: > >> 11 lip 2016 18:31 "Rasmus Schultz" napisał(a): >> > >> > > what's the actual added value of this sort of operator? >> > >> > The only direct value to the language is brevity - mere convenience. >> > >> > But I think the biggest indirectly added value, is that this will >> > discourage people from the chainable methods anti-pattern - so this >> > has value to the community; those who write chainable methods can >> > stop, and those who want chainable methods can get a wider choice of >> > libraries that were previously too verbose in use for their taste. >> > >> > > For this sort of chaining I'd propose, in addition to the cascade >> operator, >> > > the chain operator. This would work like the cascade operator except >> that >> > > the return of the function is implicitly the first parameter of the >> next >> > > argument in the chain >> > >> > I don't like this idea, at all - I think we should aim for something >> > consistent with other languages. Per the Dart spec: >> > >> > > A cascaded method invocation expression of the form e..suffix is >> equivalent to the expression (t){t.suffix; return t;}(e). >> > >> > In other words, the expression always evaluates as the object, which >> > is fine for most cases, e.g. for everything you're doing with >> > chainable methods today - which can't actually return any values, >> > since they return $this. Note that something like PSR-7's HTTP >> > immutable models are actually factory methods, e.g. use-cases not >> > applicable to the cascade operator. >> > >> > The other marginal use case perhaps is cases where a builder of some >> > sort ends with a call to a factory method - this can be done without >> > adding a second operator, by using parens in a similar fashion to Dart >> > and others, e.g.: >> > >> > $object = ($builder >> > ->>setFoo(1) >> > ->>setBar(2) >> > ->>setBaz(3) >> > )->build(); >> > >> > Or obviously: >> > >> > $builder >> > ->>setFoo(1) >> > ->>setBar(2) >> > ->>setBaz(3); >> > >> > $object = $builder->build(); >> > >> > Regarding syntax - I feel the natural choice, e.g. similar to "." vs >> > "..", would be a longer arrow --> but that's ambiguous. (decrement >> > operator, greater than operator) >> > >> > The proposed |> operator looks horrible and is very awkward to type, >> > at least on both American and Danish keyboard - I use both. (it reads >> > like "or greater than" in my mind, so much so that glancing over >> > Sara's proposal earlier, I didn't even understand what it was.) >> > >> > Would something like ->> be ambiguous as well? That's fairly close too >> > - a double-headed arrow, not unlike the double dots of other >> > languages... >> > >> >> IMHO double-headed arrow looks pretty nice and whole idea is great. Very >> big +1 for this feature >> >> >> > Agreed, but what about static methods? Triple colon perhaps? > > A::setFoo(1) > :::setBar(2) > :::setBaz(3); > > And I do agree that the double period is cleaner, but the bus left the > station a very long time ago (PHP 3 at least) by making . the connotation > operator. Or at least I think so. If the parser could deal with it double > period would be best because it could apply to both contexts. > > $object->setFoo(1) > ..setBar(2) > ..setBaz(3); > > A_Class::setFoo(1) > ..setBar(2) > ..setBaz(3); > > But again, I don't know how feasible the above is since I know next to > nothing about internals. -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] Cascade Operator (was Re: [PHP-DEV] Proposal for php7 class method return)
On Mon, Jul 11, 2016 at 1:55 PM, Michał Brzuchalski < michal.brzuchal...@gmail.com> wrote: > 11 lip 2016 18:31 "Rasmus Schultz"napisał(a): > > > > > what's the actual added value of this sort of operator? > > > > The only direct value to the language is brevity - mere convenience. > > > > But I think the biggest indirectly added value, is that this will > > discourage people from the chainable methods anti-pattern - so this > > has value to the community; those who write chainable methods can > > stop, and those who want chainable methods can get a wider choice of > > libraries that were previously too verbose in use for their taste. > > > > > For this sort of chaining I'd propose, in addition to the cascade > operator, > > > the chain operator. This would work like the cascade operator except > that > > > the return of the function is implicitly the first parameter of the > next > > > argument in the chain > > > > I don't like this idea, at all - I think we should aim for something > > consistent with other languages. Per the Dart spec: > > > > > A cascaded method invocation expression of the form e..suffix is > equivalent to the expression (t){t.suffix; return t;}(e). > > > > In other words, the expression always evaluates as the object, which > > is fine for most cases, e.g. for everything you're doing with > > chainable methods today - which can't actually return any values, > > since they return $this. Note that something like PSR-7's HTTP > > immutable models are actually factory methods, e.g. use-cases not > > applicable to the cascade operator. > > > > The other marginal use case perhaps is cases where a builder of some > > sort ends with a call to a factory method - this can be done without > > adding a second operator, by using parens in a similar fashion to Dart > > and others, e.g.: > > > > $object = ($builder > > ->>setFoo(1) > > ->>setBar(2) > > ->>setBaz(3) > > )->build(); > > > > Or obviously: > > > > $builder > > ->>setFoo(1) > > ->>setBar(2) > > ->>setBaz(3); > > > > $object = $builder->build(); > > > > Regarding syntax - I feel the natural choice, e.g. similar to "." vs > > "..", would be a longer arrow --> but that's ambiguous. (decrement > > operator, greater than operator) > > > > The proposed |> operator looks horrible and is very awkward to type, > > at least on both American and Danish keyboard - I use both. (it reads > > like "or greater than" in my mind, so much so that glancing over > > Sara's proposal earlier, I didn't even understand what it was.) > > > > Would something like ->> be ambiguous as well? That's fairly close too > > - a double-headed arrow, not unlike the double dots of other > > languages... > > > > IMHO double-headed arrow looks pretty nice and whole idea is great. Very > big +1 for this feature > > > Agreed, but what about static methods? Triple colon perhaps? A::setFoo(1) :::setBar(2) :::setBaz(3); And I do agree that the double period is cleaner, but the bus left the station a very long time ago (PHP 3 at least) by making . the connotation operator. Or at least I think so. If the parser could deal with it double period would be best because it could apply to both contexts. $object->setFoo(1) ..setBar(2) ..setBaz(3); A_Class::setFoo(1) ..setBar(2) ..setBaz(3); But again, I don't know how feasible the above is since I know next to nothing about internals.
Re: [PHP-DEV] Cascade Operator (was Re: [PHP-DEV] Proposal for php7 class method return)
On 12/07/2016 00:14, Jesse Schalken wrote: If so, some consideration should be made as to which syntax is preferred to solve this problem generally for both setting properties and calling methods. I prefer the "obj { .. }" syntax because it mirrors object literals in JSON/JavaScript, object initializers in C# and C/C++ and Haskell record syntax, is particularly concise when nested to create large trees of objects, and avoids the noise of "->>" on each line. All the examples you've given for that syntax are for initialisation, and I'm not sure how readable it would be for the general "do several things in a row" case: $counter { count(), count(), count(), count() } Thinking about it, this becomes something more like a "with" keyword: with ( $counter ) { count(); count(); count(); count(); } If with(){} could be used as an expression, you'd get something remarkably close to your initialiser example: $this->setBlah( with ( Blah::create(4) ) { foo = $foo; baz = with ( new Baz() ) { markFixed(); label = "Hello"; }; setBot(9); } ); I'm not sure if this is a good thing or not - with() statements exist in a few languages, with varying degrees of acceptance. I don't remember seeing one used as an expression like that before, though. There's a definite awkwardness of what to put on the left side of property assignments too... with ( new Foo ) { var = 1 } with ( new Foo ) { $var = 1 } with ( new Foo ) { ->var = 1 } Overall, it's an interesting idea, but the details are fiddly, and the gains marginal, IMO. Regards, -- Rowan Collins [IMSoP] -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] Cascade Operator (was Re: [PHP-DEV] Proposal for php7 class method return)
On 07/11/2016 11:30 AM, Rasmus Schultz wrote: what's the actual added value of this sort of operator? The only direct value to the language is brevity - mere convenience. But I think the biggest indirectly added value, is that this will discourage people from the chainable methods anti-pattern - so this has value to the community; those who write chainable methods can stop, and those who want chainable methods can get a wider choice of libraries that were previously too verbose in use for their taste. As one of those proponents of chained methods / returning $this, I quite like this proposal. It neatly handles many (although not all) of the use cases for method chaining, specifically the most controversial ones, while not having any of the same potential issues. (Eg, when composing and delegating the method call to another object, you have to do some $this juggling.) It would not remove the need for all method chaining, but it would remove the need for the controversial ones that Rasmus is complaining about while letting people like me still write nicely compact and readable code. :-) (Modulo implementation details and debating the operator symbol for a few weeks, as per usual.) --Larry Garfield -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] Cascade Operator (was Re: [PHP-DEV] Proposal for php7 class method return)
2016-07-11 13:30 GMT-03:00 Rasmus Schultz: > Regarding syntax - I feel the natural choice, e.g. similar to "." vs > "..", would be a longer arrow --> but that's ambiguous. (decrement > operator, greater than operator) > Yes, it's ambiguous. It will also get confused for the (in)famous "goes to operator": http://stackoverflow.com/questions/1642028/what-is-the-name-of-the-operator
Re: [PHP-DEV] Cascade Operator (was Re: [PHP-DEV] Proposal for php7 class method return)
11 lip 2016 18:31 "Rasmus Schultz"napisał(a): > > > what's the actual added value of this sort of operator? > > The only direct value to the language is brevity - mere convenience. > > But I think the biggest indirectly added value, is that this will > discourage people from the chainable methods anti-pattern - so this > has value to the community; those who write chainable methods can > stop, and those who want chainable methods can get a wider choice of > libraries that were previously too verbose in use for their taste. > > > For this sort of chaining I'd propose, in addition to the cascade operator, > > the chain operator. This would work like the cascade operator except that > > the return of the function is implicitly the first parameter of the next > > argument in the chain > > I don't like this idea, at all - I think we should aim for something > consistent with other languages. Per the Dart spec: > > > A cascaded method invocation expression of the form e..suffix is equivalent to the expression (t){t.suffix; return t;}(e). > > In other words, the expression always evaluates as the object, which > is fine for most cases, e.g. for everything you're doing with > chainable methods today - which can't actually return any values, > since they return $this. Note that something like PSR-7's HTTP > immutable models are actually factory methods, e.g. use-cases not > applicable to the cascade operator. > > The other marginal use case perhaps is cases where a builder of some > sort ends with a call to a factory method - this can be done without > adding a second operator, by using parens in a similar fashion to Dart > and others, e.g.: > > $object = ($builder > ->>setFoo(1) > ->>setBar(2) > ->>setBaz(3) > )->build(); > > Or obviously: > > $builder > ->>setFoo(1) > ->>setBar(2) > ->>setBaz(3); > > $object = $builder->build(); > > Regarding syntax - I feel the natural choice, e.g. similar to "." vs > "..", would be a longer arrow --> but that's ambiguous. (decrement > operator, greater than operator) > > The proposed |> operator looks horrible and is very awkward to type, > at least on both American and Danish keyboard - I use both. (it reads > like "or greater than" in my mind, so much so that glancing over > Sara's proposal earlier, I didn't even understand what it was.) > > Would something like ->> be ambiguous as well? That's fairly close too > - a double-headed arrow, not unlike the double dots of other > languages... > IMHO double-headed arrow looks pretty nice and whole idea is great. Very big +1 for this feature > > On Mon, Jul 11, 2016 at 5:33 PM, Marco Pivetta wrote: > > Still interested: what's the actual added value of this sort of operator? > > > > Marco Pivetta > > > > http://twitter.com/Ocramius > > > > http://ocramius.github.com/ > > > > On 11 July 2016 at 17:28, Rowan Collins wrote: > > > >> On 11/07/2016 16:15, Michael Morris wrote: > >> > >>> But for that to currently work setSomething must return $this. A cascade > >>> operator would avoid this. What about => ? > >>> > >>> $a->setSomething('here')=>setSomethingElse('there'); > >>> > >> > >> This will be ambiguous with array syntax, e.g. > >> > >> $foo = [ $a->foo() => bar() ] > >> > >> could be a call to $a->foo() for the key and to bar() for the value, or > >> just a chain ending with the array value $a->bar(). > >> > >> Naming things is hard. Inventing operators is harder. ;) > >> > >> Also note that it's the *first* call that needs a special operator, in > >> order to discard the normal return and substitute the left-hand side, > >> otherwise mixed chains become ambiguous and probably horrible to implement > >> in the engine: > >> > >> $foo->bar()->baz()=>bob() // what is $this inside bob() ? > >> > >> > >> > >> For this sort of chaining I'd propose, in addition to the cascade operator, > >>> the chain operator. This would work like the cascade operator except that > >>> the return of the function is implicitly the first parameter of the next > >>> argument in the chain. Something like this? > >>> > >>> $a->add(1, 2):>subtract(3):>add(4); // return 4. > >>> > >> > >> This exact feature was proposed a couple of months ago by Sara Golemon. > >> See https://wiki.php.net/rfc/pipe-operator and the accompanying > >> discussion http://marc.info/?t=14619608891=4=2 > >> > >> As far as I know, it's not been formally withdrawn, so might be > >> resurrected in some for for 7.2. It might be interesting to see a cascade > >> operator at the same time, but some of the same concerns that came up in > >> that discussion will probably apply to any proposal. > >> > >> Regards, > >> -- > >> Rowan Collins > >> [IMSoP] > >> > >> -- > >> PHP Internals - PHP Runtime Development Mailing List > >> To unsubscribe, visit: http://www.php.net/unsub.php > >> > >> > > -- > PHP Internals - PHP Runtime Development Mailing List > To
Re: [PHP-DEV] Cascade Operator (was Re: [PHP-DEV] Proposal for php7 class method return)
> what's the actual added value of this sort of operator? The only direct value to the language is brevity - mere convenience. But I think the biggest indirectly added value, is that this will discourage people from the chainable methods anti-pattern - so this has value to the community; those who write chainable methods can stop, and those who want chainable methods can get a wider choice of libraries that were previously too verbose in use for their taste. > For this sort of chaining I'd propose, in addition to the cascade operator, > the chain operator. This would work like the cascade operator except that > the return of the function is implicitly the first parameter of the next > argument in the chain I don't like this idea, at all - I think we should aim for something consistent with other languages. Per the Dart spec: > A cascaded method invocation expression of the form e..suffix is equivalent > to the expression (t){t.suffix; return t;}(e). In other words, the expression always evaluates as the object, which is fine for most cases, e.g. for everything you're doing with chainable methods today - which can't actually return any values, since they return $this. Note that something like PSR-7's HTTP immutable models are actually factory methods, e.g. use-cases not applicable to the cascade operator. The other marginal use case perhaps is cases where a builder of some sort ends with a call to a factory method - this can be done without adding a second operator, by using parens in a similar fashion to Dart and others, e.g.: $object = ($builder ->>setFoo(1) ->>setBar(2) ->>setBaz(3) )->build(); Or obviously: $builder ->>setFoo(1) ->>setBar(2) ->>setBaz(3); $object = $builder->build(); Regarding syntax - I feel the natural choice, e.g. similar to "." vs "..", would be a longer arrow --> but that's ambiguous. (decrement operator, greater than operator) The proposed |> operator looks horrible and is very awkward to type, at least on both American and Danish keyboard - I use both. (it reads like "or greater than" in my mind, so much so that glancing over Sara's proposal earlier, I didn't even understand what it was.) Would something like ->> be ambiguous as well? That's fairly close too - a double-headed arrow, not unlike the double dots of other languages... On Mon, Jul 11, 2016 at 5:33 PM, Marco Pivettawrote: > Still interested: what's the actual added value of this sort of operator? > > Marco Pivetta > > http://twitter.com/Ocramius > > http://ocramius.github.com/ > > On 11 July 2016 at 17:28, Rowan Collins wrote: > >> On 11/07/2016 16:15, Michael Morris wrote: >> >>> But for that to currently work setSomething must return $this. A cascade >>> operator would avoid this. What about => ? >>> >>> $a->setSomething('here')=>setSomethingElse('there'); >>> >> >> This will be ambiguous with array syntax, e.g. >> >> $foo = [ $a->foo() => bar() ] >> >> could be a call to $a->foo() for the key and to bar() for the value, or >> just a chain ending with the array value $a->bar(). >> >> Naming things is hard. Inventing operators is harder. ;) >> >> Also note that it's the *first* call that needs a special operator, in >> order to discard the normal return and substitute the left-hand side, >> otherwise mixed chains become ambiguous and probably horrible to implement >> in the engine: >> >> $foo->bar()->baz()=>bob() // what is $this inside bob() ? >> >> >> >> For this sort of chaining I'd propose, in addition to the cascade operator, >>> the chain operator. This would work like the cascade operator except that >>> the return of the function is implicitly the first parameter of the next >>> argument in the chain. Something like this? >>> >>> $a->add(1, 2):>subtract(3):>add(4); // return 4. >>> >> >> This exact feature was proposed a couple of months ago by Sara Golemon. >> See https://wiki.php.net/rfc/pipe-operator and the accompanying >> discussion http://marc.info/?t=14619608891=4=2 >> >> As far as I know, it's not been formally withdrawn, so might be >> resurrected in some for for 7.2. It might be interesting to see a cascade >> operator at the same time, but some of the same concerns that came up in >> that discussion will probably apply to any proposal. >> >> Regards, >> -- >> Rowan Collins >> [IMSoP] >> >> -- >> PHP Internals - PHP Runtime Development Mailing List >> To unsubscribe, visit: http://www.php.net/unsub.php >> >> -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] Cascade Operator (was Re: [PHP-DEV] Proposal for php7 class method return)
On 11/07/2016 16:33, Marco Pivetta wrote: Still interested: what's the actual added value of this sort of operator? Arguably, the same value there is any syntax. You could say that the -> operator is just a more readable form of overloaded function calls: class Something { function bar(int $value); } $foo->bar(42); vs function bar(@overload Something $this, int $value); bar($foo, 42); And, indeed, that all operators are just a more readable form of function calls. Chaining syntax makes a certain style of programming easier. It doesn't allow you to do anything that you can't do without it, and the change is mostly cosmetic. Whether that's a good thing or bad thing depends whether you think that's a good style or not. A bit of a non-answer, perhaps, but the question is pretty woolly too. Regards, -- Rowan Collins [IMSoP] -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] Cascade Operator (was Re: [PHP-DEV] Proposal for php7 class method return)
Still interested: what's the actual added value of this sort of operator? Marco Pivetta http://twitter.com/Ocramius http://ocramius.github.com/ On 11 July 2016 at 17:28, Rowan Collinswrote: > On 11/07/2016 16:15, Michael Morris wrote: > >> But for that to currently work setSomething must return $this. A cascade >> operator would avoid this. What about => ? >> >> $a->setSomething('here')=>setSomethingElse('there'); >> > > This will be ambiguous with array syntax, e.g. > > $foo = [ $a->foo() => bar() ] > > could be a call to $a->foo() for the key and to bar() for the value, or > just a chain ending with the array value $a->bar(). > > Naming things is hard. Inventing operators is harder. ;) > > Also note that it's the *first* call that needs a special operator, in > order to discard the normal return and substitute the left-hand side, > otherwise mixed chains become ambiguous and probably horrible to implement > in the engine: > > $foo->bar()->baz()=>bob() // what is $this inside bob() ? > > > > For this sort of chaining I'd propose, in addition to the cascade operator, >> the chain operator. This would work like the cascade operator except that >> the return of the function is implicitly the first parameter of the next >> argument in the chain. Something like this? >> >> $a->add(1, 2):>subtract(3):>add(4); // return 4. >> > > This exact feature was proposed a couple of months ago by Sara Golemon. > See https://wiki.php.net/rfc/pipe-operator and the accompanying > discussion http://marc.info/?t=14619608891=4=2 > > As far as I know, it's not been formally withdrawn, so might be > resurrected in some for for 7.2. It might be interesting to see a cascade > operator at the same time, but some of the same concerns that came up in > that discussion will probably apply to any proposal. > > Regards, > -- > Rowan Collins > [IMSoP] > > -- > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: http://www.php.net/unsub.php > >
Re: [PHP-DEV] Cascade Operator (was Re: [PHP-DEV] Proposal for php7 class method return)
On 11/07/2016 16:15, Michael Morris wrote: But for that to currently work setSomething must return $this. A cascade operator would avoid this. What about => ? $a->setSomething('here')=>setSomethingElse('there'); This will be ambiguous with array syntax, e.g. $foo = [ $a->foo() => bar() ] could be a call to $a->foo() for the key and to bar() for the value, or just a chain ending with the array value $a->bar(). Naming things is hard. Inventing operators is harder. ;) Also note that it's the *first* call that needs a special operator, in order to discard the normal return and substitute the left-hand side, otherwise mixed chains become ambiguous and probably horrible to implement in the engine: $foo->bar()->baz()=>bob() // what is $this inside bob() ? For this sort of chaining I'd propose, in addition to the cascade operator, the chain operator. This would work like the cascade operator except that the return of the function is implicitly the first parameter of the next argument in the chain. Something like this? $a->add(1, 2):>subtract(3):>add(4); // return 4. This exact feature was proposed a couple of months ago by Sara Golemon. See https://wiki.php.net/rfc/pipe-operator and the accompanying discussion http://marc.info/?t=14619608891=4=2 As far as I know, it's not been formally withdrawn, so might be resurrected in some for for 7.2. It might be interesting to see a cascade operator at the same time, but some of the same concerns that came up in that discussion will probably apply to any proposal. Regards, -- Rowan Collins [IMSoP] -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
[PHP-DEV] Cascade Operator (was Re: [PHP-DEV] Proposal for php7 class method return)
On Sun, Jul 10, 2016 at 6:34 AM, Rasmus Schultzwrote: > > What you're really trying to accomplish is something like the ".." > operator found in some other languages - this is known as the "cascade > operator" in Dart, for example: > > > http://news.dartlang.org/2012/02/method-cascades-in-dart-posted-by-gilad.html > > There are several problems with method-chaining - the biggest problem, > as demonstrated by the cascade operator, is that this doesn't need to > be a problem you solve for every class; it can be done systemically > with a cascade operator, e.g. supported for every class, not just > those where you weave in this requirement. Also, method chaining is > inferior to a cascade operator, which would work not only for methods, > but for properties as well. More over, a cascade operator would work > for all existing libraries, whether the designer thought about > cascading use of various features or not. > > In short, this shouldn't and doesn't need to be a problem every > developer solves for each and every library - we can solve it for the > language instead. > > In other words, it seems you're trying to address a problem that > shouldn't exist in the first place, so that you can solve a recurring > problem you should not have to solve at all. > > I would be much more interested in seeing a proposal for a cascade > operator, which, in my opinion, addresses the real problem currently > driving developers to use method-chaining - I can only view that as an > unfortunate work-around. > > In my opinion, a cascade operator would move the language forward, > while the addition of a magical type-hint acting as sugar for "return > $this" merely solves a superficial problem - and propagates a bad > practice. > > This is a fascinating concept. There's a small gap to this implementation which I think can be improved on, but still fascinating. So we currently have -> for invocation of a method on an object. $a->setSomething('here')->setSomethingElse('there'); But for that to currently work setSomething must return $this. A cascade operator would avoid this. What about => ? $a->setSomething('here')=>setSomethingElse('there'); This alone is pretty cool, but what if you have a method that returns something you want to use as argument? The old prototype.js library. Consider the following class A { public function add( $a, $b) { return $a + b; } public function subtract( $a, $b) { return $a - $b; } } For this sort of chaining I'd propose, in addition to the cascade operator, the chain operator. This would work like the cascade operator except that the return of the function is implicitly the first parameter of the next argument in the chain. Something like this? $a->add(1, 2):>subtract(3):>add(4); // return 4. As can be seen above, I'm unsure of what the static method syntax should be.