Hướng dẫn php echo multiple lines

I am having a hard time where this code

is overlapping the column in a div. How can we multi line this?

asked Sep 9, 2016 at 13:00

10

You can wrap your string using wordwrap[] function like this:

wordwrap[$row['actualpost'], 10, '
'];

This function will wrap your long string into multiline.

Or

You can use this css for your div

word-wrap: break-word;

answered Sep 9, 2016 at 13:06

Neel IonNeel Ion

1,5471 gold badge11 silver badges14 bronze badges

12

try this it's work

answered Sep 9, 2016 at 13:07

4

In CSS :

.col-md-8
{
   width:100%;
   word-wrap: break-word;
}

answered Sep 9, 2016 at 13:32

1

Not the answer you're looking for? Browse other questions tagged php html or ask your own question.

How do you write PHP Arrow function with multiple line expressions?

JavaScript One Line Example:

const dob = [age] => 2021 - age;

PHP One Line Equivalent:

$dob = fn[$age] => 2021 - $age;

Javascript Multiple Line Example:

const dob = [age] => {
   if[!age] return null;
   const new_age = 2021 - age; 
   console.log["Your new age is " + new_age];

   return new_age;
}

WHAT IS PHP Equivalent for multiple line????

asked Jan 26, 2021 at 15:06

Emeka MbahEmeka Mbah

15.6k8 gold badges70 silver badges93 bronze badges

3

Arrow functions in PHP have the form fn [argument_list] => expr. You can only have a single expression in the body of the function.

You can write the expression over multiple lines without problem:

fn[$age] =>
      $age
    ? 2021 - $age
    : null

If you really need multiple expressions, then you can simply use anonymous function. The closures aren't automatic as they are with arrow functions, but if you don't need it, it gives exactly the same result.

$dob = function [$age] {
    if [!$age] { return null; }
    $new_age = 2021 - ^$age; 
    echo "Your new age is ". $new_age;

    return $new_age;
}

answered Jan 26, 2021 at 15:13

BlackholeBlackhole

19.5k7 gold badges67 silver badges67 bronze badges

4

The usage of multiple expressions is not allowed, according to the RFC. It covers the assignment of only a single expression. The extension is discussed further down in the RFC, but not implemented

answered Jan 26, 2021 at 15:13

Nico HaaseNico Haase

9,85735 gold badges37 silver badges60 bronze badges

Not the answer you're looking for? Browse other questions tagged php arrow-functions or ask your own question.

Hi Nuno,

A few days ago I opened a pull request that adds support for multi-line
arrow functions in PHP: //github.com/php/php-src/pull/6246.

Welcome to the list. Firstly, it's probably worth having a look in the
mailing list archives for prior discussions on this, as it was
definitely discussed during the earlier short closures RFCs [the
successful one that gave us fn[]=>expr, and a couple of earlier attempts
with different syntax and features].

Secondly, I'd like to point out that "short closures" actually have
three fundamental features:

  1. They have an implicit "return", making them ideal for single
    expressions rather than blocks of procedural code.
  2. They automatically capture all variables in scope, rather than having
    to import them with "use".
  3. They are shorter than normal closure declarations, both because of
    the above two features, and because "fn" is slightly shorter than
    "function".

I think it's worth making clear which of those three features we are
hoping to retain by combining arrow functions with blocks.

Feature 1 doesn't extend to code blocks in an obvious way. In some
languages, every statement is a valid expression, so you can place an
implicit "return" before the last statement of a block. In PHP, that's
not the case, so e.g. { $x = 'Hello World; echo $x; } cannot be
converted to { $x = 'Hello World; return echo $x; }. Alternatives
include converting to { $x = 'Hello World; echo $x; return null; } or
requiring all closure blocks to end with a valid expression.

Feature 2 is probably the one most people actually want extended, but in
my opinion is also the part most in need of justification, because it
changes the language quite fundamentally.

There are currently very few places in PHP where the scope of a variable
is not to the current function: properties of the current object must be
accessed via $this, and class properties via self:: or similar; globals
must be imported via a "global" statement, statics via a "static"
statement, and closed-over values via the "use" keyword. [The main
exception to this rule is the half-dozen built-in "superglobals"; I
think there are a few more obscure cases.]

In a single-expression closure, as currently allowed, there is limited
possibility for ambiguous scope. Extending this to function bodies of
any size leads to much more risk of complexity and confusion.

If you want to capture variables $a, $b, and $c, but have local
variables $x, $y, and $z, you would currently write this:

$f = function[] use [$a, $b, $c] {
    // $x, $y, $z must be local, because not imported
}

If we added an opt-in syntax for "capture everything", we might instead
write this:

$f = function[] use [*] {
     $x = $y = $z = null;
}

Without re-initialising all local variables, we would no longer be able
to know if they were actually local without looking at the surrounding
scope for a value that might be captured. I am unconvinced by this
trade-off of opt-out instead of opt-in.

One use case I've seen proposed is closures which capture a large number
of variables; I would be interested to see an example where this is the
case and is not a "code smell" in the same way as requiring a large
number of parameters.

In the above example I deliberately did not use the "fn[]=>" syntax,
because I believe this is really orthogonal to the other features - my
impression is that actual expression length [feature 3 above] is more of
a pleasant side-effect than a top priority for most people.

I would personally prefer the "fn[]=>" syntax to carry on meaning "this
is an expression elevated to function status", and have some other
syntax for a full closure that uses auto-capturing scope rules if that
feature is indeed needed.

Regards,

--
Rowan Tommins [né Collins]
[IMSoP]

1 year ago by Mike Schinkel — view source

unread

Hi Nuno,

A few days ago I opened a pull request that adds support for multi-line
arrow functions in PHP: //github.com/php/php-src/pull/6246.

Welcome to the list. Firstly, it's probably worth having a look in the mailing list archives for prior discussions on this, as it was definitely discussed during the earlier short closures RFCs [the successful one that gave us fn[]=>expr, and a couple of earlier attempts with different syntax and features].

Secondly, I'd like to point out that "short closures" actually have three fundamental features:

  1. They have an implicit "return", making them ideal for single expressions rather than blocks of procedural code.
  2. They automatically capture all variables in scope, rather than having to import them with "use".
  3. They are shorter than normal closure declarations, both because of the above two features, and because "fn" is slightly shorter than "function".

I think it's worth making clear which of those three features we are hoping to retain by combining arrow functions with blocks.

Feature 1 doesn't extend to code blocks in an obvious way. In some languages, every statement is a valid expression, so you can place an implicit "return" before the last statement of a block. In PHP, that's not the case, so e.g. { $x = 'Hello World; echo $x; } cannot be converted to { $x = 'Hello World; return echo $x; }. Alternatives include converting to { $x = 'Hello World; echo $x; return null; } or requiring all closure blocks to end with a valid expression.

Feature 2 is probably the one most people actually want extended, but in my opinion is also the part most in need of justification, because it changes the language quite fundamentally.

There are currently very few places in PHP where the scope of a variable is not to the current function: properties of the current object must be accessed via $this, and class properties via self:: or similar; globals must be imported via a "global" statement, statics via a "static" statement, and closed-over values via the "use" keyword. [The main exception to this rule is the half-dozen built-in "superglobals"; I think there are a few more obscure cases.]

In a single-expression closure, as currently allowed, there is limited possibility for ambiguous scope. Extending this to function bodies of any size leads to much more risk of complexity and confusion.

If you want to capture variables $a, $b, and $c, but have local variables $x, $y, and $z, you would currently write this:

$f = function[] use [$a, $b, $c] {
// $x, $y, $z must be local, because not imported
}

If we added an opt-in syntax for "capture everything", we might instead write this:

$f = function[] use [*] {
$x = $y = $z = null;
}

Without re-initialising all local variables, we would no longer be able to know if they were actually local without looking at the surrounding scope for a value that might be captured. I am unconvinced by this trade-off of opt-out instead of opt-in.

One use case I've seen proposed is closures which capture a large number of variables; I would be interested to see an example where this is the case and is not a "code smell" in the same way as requiring a large number of parameters.

In the above example I deliberately did not use the "fn[]=>" syntax, because I believe this is really orthogonal to the other features - my impression is that actual expression length [feature 3 above] is more of a pleasant side-effect than a top priority for most people.

I would personally prefer the "fn[]=>" syntax to carry on meaning "this is an expression elevated to function status", and have some other syntax for a full closure that uses auto-capturing scope rules if that feature is indeed needed.

Good analysis.

I agree #2 is the strongest motivator for some kind of improvement / change.

In at least one prior language I have used there was no distinction between local scope inside and outside of a closure, so when I first realized I had to use the "use" clause to make variable visible it was surprising to me.

In PHP I find this requirement rather annoying in the majority of cases. My functions and closures tend to be short and the number of local variables I use — both inside and outside the closure —tend to be small so I don't have a problem with confusing scope. Having to explicitly name the variables in a use statement feels like unfortunate overkill. But I do get your point.

OTOH, when inherited local variables are NOT modified within the closure, does that actually cause a problem? [honest question]

If not — and please check my logic — I would suggest PHP 8.1+ could allow closures to IMPLICITLY inherit local variables, but ONLY for variables that are READ, not for variables that are written.

Given this approach, variables would still need to be declared when variables need to be written, e.g. "use [ &$foo ]"

Although this relaxing of requirement to declare variables could theoretically break existing code, only code where variables are read inside closures before they are assigned with the same name as variables assigned outside the closure would "break", and those cases are flagged as a warning when error reporting is on.

For me, that would probably cover 90%+ of the use cases my the requirement to employ the "use" statement feels like overkill.

-Mike

1 year ago by Andreas Leathley — view source

unread

If we added an opt-in syntax for "capture everything", we might
instead write this:

$f = function[] use [*] {
     $x = $y = $z = null;
}

Without re-initialising all local variables, we would no longer be
able to know if they were actually local without looking at the
surrounding scope for a value that might be captured. I am unconvinced
by this trade-off of opt-out instead of opt-in.

One use case I've seen proposed is closures which capture a large
number of variables; I would be interested to see an example where
this is the case and is not a "code smell" in the same way as
requiring a large number of parameters.

Something like "use [*]" seems like a great enhancement to me. I often
use a wrapper function for SQL transactions, something like:

public function update[int $numberId, int $addressId, bool $isMainNumber
= false]: void
{
     $this->transaction->run[function [] use [$numberId, $addressId,
$isMainNumber]: void {
       // Do all SQL queries for the update
     }];
}

In these cases there is a lot of redundancy because of having to import
the variables, and if a variable is added, it has to be added in two
places in a slightly different way. The following would be much nicer:

public function update[int $numberId, int $addressId, bool $isMainNumber
= false]: void
{
     $this->transaction->run[function [] use [*]: void {
       // Do all SQL queries for the update
     }];
}

This would also increase code readability.

1 year ago by — view source

unread

Yes, "use [*]" is perfect!

With kind regards / Mit freundlichen Grüßen / S přátelským pozdravem,

Michael Voříšek

On 04.10.20 22:08, Rowan Tommins wrote:

If we added an opt-in syntax for "capture everything", we might
instead write this:

$f = function[] use [*] {
$x = $y = $z = null;
}

Without re-initialising all local variables, we would no longer be
able to know if they were actually local without looking at the
surrounding scope for a value that might be captured. I am unconvinced
by this trade-off of opt-out instead of opt-in.

One use case I've seen proposed is closures which capture a large
number of variables; I would be interested to see an example where
this is the case and is not a "code smell" in the same way as
requiring a large number of parameters.

Something like "use [*]" seems like a great enhancement to me. I often
use a wrapper function for SQL transactions, something like:

public function update[int $numberId, int $addressId, bool $isMainNumber
= false]: void
{
$this->transaction->run[function [] use [$numberId, $addressId,
$isMainNumber]: void {
// Do all SQL queries for the update
}];
}

In these cases there is a lot of redundancy because of having to import
the variables, and if a variable is added, it has to be added in two
places in a slightly different way. The following would be much nicer:

public function update[int $numberId, int $addressId, bool $isMainNumber
= false]: void
{
$this->transaction->run[function [] use [*]: void {
// Do all SQL queries for the update
}];
}

This would also increase code readability.

--

To unsubscribe, visit: //www.php.net/unsub.php

1 year ago by Lynn — view source

unread

On Mon, Oct 5, 2020 at 12:00 PM Michael Voříšek - ČVUT FEL <
> wrote:

Yes, "use [*]" is perfect!

With kind regards / Mit freundlichen Grüßen / S přátelským pozdravem,

Michael Voříšek

If we added an opt-in syntax for "capture everything", we might
instead write this:

$f = function[] use [*] {
$x = $y = $z = null;
}

Without re-initialising all local variables, we would no longer be
able to know if they were actually local without looking at the
surrounding scope for a value that might be captured. I am unconvinced
by this trade-off of opt-out instead of opt-in.

One use case I've seen proposed is closures which capture a large
number of variables; I would be interested to see an example where
this is the case and is not a "code smell" in the same way as
requiring a large number of parameters.

Something like "use [*]" seems like a great enhancement to me. I often
use a wrapper function for SQL transactions, something like:

public function update[int $numberId, int $addressId, bool $isMainNumber
= false]: void
{
$this->transaction->run[function [] use [$numberId, $addressId,
$isMainNumber]: void {
// Do all SQL queries for the update
}];
}

In these cases there is a lot of redundancy because of having to import
the variables, and if a variable is added, it has to be added in two
places in a slightly different way. The following would be much nicer:

public function update[int $numberId, int $addressId, bool $isMainNumber
= false]: void
{
$this->transaction->run[function [] use [*]: void {
// Do all SQL queries for the update
}];
}

This would also increase code readability.

--

To unsubscribe, visit: //www.php.net/unsub.php

How should php deal with the scenario where you want to use everything
and have one variable by reference?

function [] use [*, &$butNotThisOne] {};
1 year ago by Andreas Leathley — view source

unread

How should php deal with the scenario where you want to use everything
and have one variable by reference?

function [] use [*, &$butNotThisOne] {};

The easiest would be to only allow "use []" with no references or
additional syntax. "use []" would only copy all local variables into
the closure, no references. Personally I have never used references with
"use", I think it is much more niche compared to the regular copying,
and there is still the explicit [current] syntax to do references.

1 year ago by Markus Fischer — view source

unread

How should php deal with the scenario where you want to use everything
and have one variable by reference?

function [] use [*, &$butNotThisOne] {};

The easiest would be to only allow "use []" with no references or
additional syntax. "use []" would only copy all local variables into
the closure, no references. Personally I have never used references with
"use", I think it is much more niche compared to the regular copying,
and there is still the explicit [current] syntax to do references.

FTR, short arrow function implicitly only support "by value" bindings, I
just checked the docs.

I do use by ref with closures btw.

  • Markus
1 year ago by Sara Golemon — view source

unread

How should php deal with the scenario where you want to use everything
and have one variable by reference?

function [] use [*, &$butNotThisOne] {};

I would take a page out of C++'s book here. In C++ a closure is [some of
these bits can be omitted for brevity, but I'm not going to describe those
here as it's orthogonal to the topic]:

[capture, vars][type argName] -> returnType {
statements;
return retVal;
}

Looking specifically at the capture vars section [in the example we are
capturing two variables, one named 'capture', one named 'vars'], there are
wildcards available as well:

[=][bool bval] -> void {}

The equal sign [as above] captures all variables used in the closure by
value.
Similarly, the ampersand [&][int ival] -> void {} captures all variables
used by reference.

Exceptions can be added to that list just as you suggested, so:

[=,&foo][double dval] -> double { return foo + dval; }

Or

&,foo -> void { doSomething[foo]; }

I think we could apply the same in PHP terms:

function[float $dval] use [$, &$foo] { return $foo + $dval; };
function[] use [&$, $foo] { doSomething[$foo]; };

Plus or minor for parser convenience.

-Sara

1 year ago by Deleu — view source

unread

To me that seems like a great argument in favour of the proposal. If you'll
want all variables to be imported [which in this case makes completely
sense], then fn[] {} or fn[] => {} is much less verbose and inline with
the mentality to reach for short closures. We reach for short closures to
avoid use[] and convey that the outer process is intertwined with the
inner process. fn[] allows to strengthen the concept that there's no real
separation between running SQL stuff in a callable that wraps a database
transaction.

If we added an opt-in syntax for "capture everything", we might
instead write this:

$f = function[] use [*] {
$x = $y = $z = null;
}

Without re-initialising all local variables, we would no longer be
able to know if they were actually local without looking at the
surrounding scope for a value that might be captured. I am unconvinced
by this trade-off of opt-out instead of opt-in.

One use case I've seen proposed is closures which capture a large
number of variables; I would be interested to see an example where
this is the case and is not a "code smell" in the same way as
requiring a large number of parameters.

Something like "use [*]" seems like a great enhancement to me. I often
use a wrapper function for SQL transactions, something like:

public function update[int $numberId, int $addressId, bool $isMainNumber
= false]: void
{
     $this->transaction->run[function [] use [$numberId, $addressId,
$isMainNumber]: void {
       // Do all SQL queries for the update
     }];
}

In these cases there is a lot of redundancy because of having to import
the variables, and if a variable is added, it has to be added in two
places in a slightly different way. The following would be much nicer:

public function update[int $numberId, int $addressId, bool $isMainNumber
= false]: void
{
     $this->transaction->run[function [] use [*]: void {
       // Do all SQL queries for the update
     }];
}

This would also increase code readability.

--

To unsubscribe, visit: //www.php.net/unsub.php

--
Marco Aurélio Deleu

1 year ago by Andreas Leathley — view source

unread

To me that seems like a great argument in favour of the proposal. If you'll
want all variables to be imported [which in this case makes completely
sense], then fn[] {} or fn[] => {} is much less verbose and inline with
the mentality to reach for short closures. We reach for short closures to
avoid use[] and convey that the outer process is intertwined with the
inner process. fn[] allows to strengthen the concept that there's no real
separation between running SQL stuff in a callable that wraps a database
transaction.

Not necessarily: the arrow functions were specifically implemented for
very short anonymous functions with a return value. Making them more and
more like the existing "function" syntax would lead to having two
different ways of defining anonymous functions that mainly differentiate
themselves by including the parent scope by default or not.

I like the "function [] use [*]" suggestion because it is explicit and
opt-in. A shorter syntax like "fn [] {}" is less clear, and it could
lead to many people always using fn just because it is faster to write
[and less to think about], which then could lead to unintended side
effects because variables are being copied from the parent scope each
time. When you see a usage of "fn [] {}" while reading code you would
not know if the person used it because it was faster to write, or if the
parent scope variables are really needed.

1 year ago by Brent Roose — view source

unread

Hi internals

The reason multi-line short closures are so valued by userland devs is because they are shorter to write and prettier to read. While some of us might not agree on the definition of "prettier to read", it was one of the key arguments for adding short closures in the first place:

Anonymous functions in PHP can be quite verbose, even when they only perform a simple operation. Partly this is due to a large amount of syntactic boilerplate, and partly due to the need to manually import used variables. This makes code using simple closures hard to read and understand. This RFC proposes a more concise syntax for this pattern. [1]

We can have the discussion again on whether we like short closures or not, but it turned out most of internals and userland devs do — based on the vote count in the sigle line RFC and the reaction on Nuno's PR, as well as my experience from an OSS maintainer point of view.

Furthermore, the use[*] syntax misses the point of this proposal: it's not about being able to use all variables from the outer scope, it's about a clean syntax that's as short as possible — even when you personally disagree that it is. I've made the same argument before on this list: it's clear that the PHP community wants these changes: named arguments, property promotions, short closures, … these are all features that aren't necessary, still they are great features of a modern-day language.

I also want to quote from Larry Garfields book on thinking functionally in PHP [2], to demonstrate the signicant impact short closures already had today:

“Combined with PHP’s overall clunky syntax for doing functional-esque code, I generally didn’t go further than “pure functions are your friend,” either in my own code or what I explained to others.

That is, until PHP 7.4.

PHP 7.4’s introduction of short lambdas is, as we’ll see in this book, a game-changer. While it doesn’t make anything new possible, it makes a lot of things suddenly practical. That makes all the difference, so I decided it was time to buckle down and really dig into functional programming.”

Larry continues to write a whole book about functional programming in PHP, and short closures play a significant role.

So I hope to see more input on Nuno's PR from a techinical point of view: what's missing, what's needed to get this to the RFC phase, … and not only discussions about what syntax we like or not, or whether there are other ways to solve the same problem. Please provide Nuno with actionable feedback.

Kind regards
Brent

[1] //wiki.php.net/rfc/arrow_functions_v2 //wiki.php.net/rfc/arrow_functions_v2
[2] //leanpub.com/thinking-functionally-in-php //leanpub.com/thinking-functionally-in-php

To me that seems like a great argument in favour of the proposal. If you'll
want all variables to be imported [which in this case makes completely
sense], then fn[] {} or fn[] => {} is much less verbose and inline with
the mentality to reach for short closures. We reach for short closures to
avoid use[] and convey that the outer process is intertwined with the
inner process. fn[] allows to strengthen the concept that there's no real
separation between running SQL stuff in a callable that wraps a database
transaction.

Not necessarily: the arrow functions were specifically implemented for
very short anonymous functions with a return value. Making them more and
more like the existing "function" syntax would lead to having two
different ways of defining anonymous functions that mainly differentiate
themselves by including the parent scope by default or not.

I like the "function [] use [*]" suggestion because it is explicit and
opt-in. A shorter syntax like "fn [] {}" is less clear, and it could
lead to many people always using fn just because it is faster to write
[and less to think about], which then could lead to unintended side
effects because variables are being copied from the parent scope each
time. When you see a usage of "fn [] {}" while reading code you would
not know if the person used it because it was faster to write, or if the
parent scope variables are really needed.

--

To unsubscribe, visit: //www.php.net/unsub.php

1 year ago by G. P. B. — view source

unread

First, can you please bottom-post and not top-post.

Hi internals

The reason multi-line short closures are so valued by userland devs is
because they are shorter to write and prettier to read. While some of us
might not agree on the definition of "prettier to read", it was one of the
key arguments for adding short closures in the first place:

Anonymous functions in PHP can be quite verbose, even when they only
perform a simple operation. Partly this is due to a large amount of
syntactic boilerplate, and partly due to the need to manually import used
variables. This makes code using simple closures hard to read and
understand. This RFC proposes a more concise syntax for this pattern. [1]

We can have the discussion again on whether we like short closures or not,
but it turned out most of internals and userland devs do — based on the
vote count in the sigle line RFC and the reaction on Nuno's PR, as well as
my experience from an OSS maintainer point of view.

I didn't know we were meant to do code golfing with production code, might
have missed a memo somewhere.

Furthermore, the use[*] syntax misses the point of this proposal: it's
not about being able to use all variables from the outer scope,

If it's not about being able to use all variables [or even just one that is
irrelevant] from the outer scope, then what is the point?
Saving 6 characters by only writing fn[] {} instead of function {}?

it's about a clean syntax that's as short as possible — even when you
personally disagree that it is. I've made the same argument before on this
list: it's clear that the PHP community wants these changes:

Wanting something isn't an argument. Looking at what part of the community
wants, we should be using @ for attributes.

named arguments, property promotions, short closures, … these are all

features that aren't necessary, still they are great features of a
modern-day language.

Obviously nothing is necessary, we could write assembler style with only
goto statements.

I also want to quote from Larry Garfields book on thinking functionally in

PHP [2], to demonstrate the signicant impact short closures already had
today:

“Combined with PHP’s overall clunky syntax for doing functional-esque
code, I generally didn’t go further than “pure functions are your friend,”
either in my own code or what I explained to others.

That is, until PHP 7.4.

PHP 7.4’s introduction of short lambdas is, as we’ll see in this book, a
game-changer. While it doesn’t make anything new possible, it makes a lot
of things suddenly practical. That makes all the difference, so I decided
it was time to buckle down and really dig into functional programming.”

Larry continues to write a whole book about functional programming in PHP,
and short closures play a significant role.

Finally a resemblance of an actual argument.

So I hope to see more input on Nuno's PR from a techinical point of view:
what's missing, what's needed to get this to the RFC phase, … and not only
discussions about what syntax we like or not, or whether there are other
ways to solve the same problem. Please provide Nuno with actionable
feedback.

Kind regards
Brent

[1] //wiki.php.net/rfc/arrow_functions_v2 <
//wiki.php.net/rfc/arrow_functions_v2>;
[2] //leanpub.com/thinking-functionally-in-php <
//leanpub.com/thinking-functionally-in-php>;

Jokes aside, the actionable feedback is to argue why auto capture of the
outer scope should be added to the
language as "it is very not PHP" a direct quote from Rasmus from his talk
"25 years of PHP" [1] and from the
same section one of the reasons why people don't mind the current single
line expression form is because it
doesn't look like a new scope.
As Rowan said in his analysis changing this specific behaviour of scope
being able to "leak" into another one
needs a lot of justification, the current short closure syntax doesn't even
use braces {} which are the de facto
signal in PHP that you are entering in a new scope.

Going back to the use[*] syntax: the reason why people propose this
extension [which is not mutually exclusive
with adding support for fn {} without outer scope capture, albeit strange]
is that it is more in PHP traditional design
philosophy. You can argue against this syntax and in favour of Nuno's, but
again it is NOT missing the point.

Moreover, Larry has also made a PR which extends short closures [2] in a
way I personally find way more appealing.

Regards

George P. Banyard

[1] //youtu.be/Qa_xVjTiOUw?t=1895
[2] //github.com/php/php-src/pull/6221

1 year ago by G. P. B. — view source

unread

First, can you please bottom-post and not top-post.

Hi internals

The reason multi-line short closures are so valued by userland devs is
because they are shorter to write and prettier to read. While some of us
might not agree on the definition of "prettier to read", it was one of the
key arguments for adding short closures in the first place:

Anonymous functions in PHP can be quite verbose, even when they only
perform a simple operation. Partly this is due to a large amount of
syntactic boilerplate, and partly due to the need to manually import used
variables. This makes code using simple closures hard to read and
understand. This RFC proposes a more concise syntax for this pattern. [1]

We can have the discussion again on whether we like short closures or
not, but it turned out most of internals and userland devs do — based on
the vote count in the sigle line RFC and the reaction on Nuno's PR, as well
as my experience from an OSS maintainer point of view.

I didn't know we were meant to do code golfing with production code, might
have missed a memo somewhere.

Furthermore, the use[*] syntax misses the point of this proposal: it's
not about being able to use all variables from the outer scope,

If it's not about being able to use all variables [or even just one that
is irrelevant] from the outer scope, then what is the point?
Saving 6 characters by only writing fn[] {} instead of function {}?

it's about a clean syntax that's as short as possible — even when you
personally disagree that it is. I've made the same argument before on this
list: it's clear that the PHP community wants these changes:

Wanting something isn't an argument. Looking at what part of the community
wants, we should be using @ for attributes.

named arguments, property promotions, short closures, … these are all

features that aren't necessary, still they are great features of a
modern-day language.

Obviously nothing is necessary, we could write assembler style with only
goto statements.

I also want to quote from Larry Garfields book on thinking functionally in

PHP [2], to demonstrate the signicant impact short closures already had
today:

“Combined with PHP’s overall clunky syntax for doing functional-esque
code, I generally didn’t go further than “pure functions are your friend,”
either in my own code or what I explained to others.

That is, until PHP 7.4.

PHP 7.4’s introduction of short lambdas is, as we’ll see in this book,
a game-changer. While it doesn’t make anything new possible, it makes a lot
of things suddenly practical. That makes all the difference, so I decided
it was time to buckle down and really dig into functional programming.”

Larry continues to write a whole book about functional programming in
PHP, and short closures play a significant role.

Finally a resemblance of an actual argument.

So I hope to see more input on Nuno's PR from a techinical point of view:
what's missing, what's needed to get this to the RFC phase, … and not only
discussions about what syntax we like or not, or whether there are other
ways to solve the same problem. Please provide Nuno with actionable
feedback.

Kind regards
Brent

[1] //wiki.php.net/rfc/arrow_functions_v2 <
//wiki.php.net/rfc/arrow_functions_v2>;
[2] //leanpub.com/thinking-functionally-in-php <
//leanpub.com/thinking-functionally-in-php>;

Jokes aside, the actionable feedback is to argue why auto capture of the
outer scope should be added to the
language as "it is very not PHP" a direct quote from Rasmus from his talk
"25 years of PHP" [1] and from the
same section one of the reasons why people don't mind the current single
line expression form is because it
doesn't look like a new scope.
As Rowan said in his analysis changing this specific behaviour of scope
being able to "leak" into another one
needs a lot of justification, the current short closure syntax doesn't
even use braces {} which are the de facto
signal in PHP that you are entering in a new scope.

Going back to the use[*] syntax: the reason why people propose this
extension [which is not mutually exclusive
with adding support for fn {} without outer scope capture, albeit strange]
is that it is more in PHP traditional design
philosophy. You can argue against this syntax and in favour of Nuno's, but
again it is NOT missing the point.

Moreover, Larry has also made a PR which extends short closures [2] in a
way I personally find way more appealing.

Regards

George P. Banyard

[1] //youtu.be/Qa_xVjTiOUw?t=1895
[2] //github.com/php/php-src/pull/6221

Ressending to the list as I seem to have messed up my reply.

1 year ago by Rowan Tommins — view source

unread

Hi Brent,

We can have the discussion again on whether we like short closures or not, but it turned out most of internals_and_ userland devs do — based on the vote count in the sigle line RFC and the reaction on Nuno's PR, as well as my experience from an OSS maintainer point of view.

I don't know how much of the earlier discussion you saw at the time, or
have looked back at, but it's worth noting that the arrow functions RFC
which passed voting came after several long mailing list threads, and
several complete rewrites of the proposal, at least one of which went to
vote and was declined. The lack of multi-statement arrow functions
wasn't an accident, it was part of how consensus was achieved.

That doesn't mean we can't discuss multi-statement arrow functions now -
they were listed as "Future Scope", and we are now in that Future. :]
However, it does mean a new RFC doing so needs to set out its own
justification, not assume that everyone who voted Yes on the previous
RFC will vote Yes on this one as well.

Furthermore, the use[*] syntax misses the point of this proposal: it's not about being able to use all variables from the outer scope, it's about a clean syntax that's as short as possible

Rather than "missing the point", I think it's a case of different people
wanting different things from arrow functions. In one of the previous
discussions [1] I suggested three perspectives of what people wanted
them for:

[a] an improved syntax for declaring closures [in the way that [$foo,
$bar] is a shorter syntax for array[$foo, $bar]]
[b] improved semantics for declaring closures, where you don't have to
list the variables to be captured
[c] a new kind of closure designed for specific use cases, with its own
syntax and semantics

Those who wanted [c] are generally happy with what we have, with perhaps
an interest in making more statements available as expressions, such as
throw [2] and match [3].

Those who wanted [b] generally see the arrow syntax as a means to an
end, and are open to alternative syntaxes that achieve the relevant
semantics, such as use[*].

Those who wanted [a] may see things the other way around: the short
syntax is the goal, and auto-capture and implicit return are just the
ways to achieve that goal.

There's probably no way to please all three groups [and the various
combinations and nuances I've over-simplified], but it's useful to
acknowledge the existence of those who want some of what you want, but
don't agree on all of it.

I look forward to seeing the RFC if Nuno decides to proceed with it,
because I am much more interested in how it will affect users of PHP
than the technical details visible in the PR.

[1] //externals.io/message/98045#98209
[2] //wiki.php.net/rfc/throw_expression
[3] //wiki.php.net/rfc/match_expression_v2

Regards,

--
Rowan Tommins [né Collins]
[IMSoP]

Chủ Đề