Re: [PHP-DEV] Re: [VOTE] Userspace operator overloading

2020-03-25 Thread Jakob Givoni
On Wed, Mar 25, 2020 at 6:28 AM Christoph M. Becker  wrote:
>
> It seems to me that the RFC is not sufficiently specific enough
> regarding the concatenation of instances of classes which implement
> __toString().

Exactly what I was thinking too. Would be nice with some examples on this.

> So if we ever wanted to change the value of
> PHP_OPERAND_TYPES_NOT_SUPPORTED, we'd introduce a BC break.  Therefore
> the constant's value likely will never change, so using NULL directly to
> signal unsupported operand types would be fine, wouldn't it?

Agree on this too.

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP-DEV] Improving PHP's Object Egonomics: A broad analysis

2020-03-25 Thread Jakob Givoni
Hi Larry and Nicolas,

On Wed, Mar 25, 2020 at 9:24 AM Larry Garfield  wrote:

> > I'd like to propose something on the topic.
> > I'm adding object literals to the mix because that's another feature of the
> > language that we're missing a lot IMHO.
> > Actually, there is one existing syntax for objects: (object) [...]
>
> [...]
>
> 2) What's its order of execution with the constructor?  Vis, does the 
> constructor run after __create or before?  Does __construct get any 
> parameters passed to it?

That's the interesting question, though there's probably not any
sensible answer that works for all use cases. However, if this kind of
object casting (object literal notation) was limited to a certain
(extendable) internal class (SPL Struct?), we could have just a final
public function __construct(array $properties = []) that then
delegates the validation to an abstract __validation() method. Would
that at least be a useful alternative to constructor promotion?

> In that syntax, you have to remember which one comes first.  There's no 
> indication for the casual reader why
>
> public private $property;
>
> and
>
> private public $property;

I'm wondering - are there any use cases where you would have private
read and public write?

If not, maybe this issue can be simplified by adding (f.ex.)
"semiprivate" and "semiprotected" attribute keywords, the idea being
that they give readonly access to the anything else.

Though I think it would be great to have a nice, gracefully extensible
attribute syntax, maybe it's not necessary to fight over that for this
particular issue?

> Either way, what matters is who is in charge of dealing with the issues
> this might create. In both ways, what matters is that the original author
> won't be bothered for things that are not its responsibility. "I broke your
> app because you messed up with that private property on a class I
> authored?" no my problem. About final, I usually prefer using the "@final"
> annotation: it expressed exactly what I need to express as the author of
> the code: "if you extend, you're on your own - but I'm not dictating what
> you can/can't do either".
>
> I think this reasoning applies to my view on immutability :)

:-)
I can relate to that in general.
Though for immutability, I'm not so sure anymore...

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php



[PHP-DEV] RFC Raised for str_starts_with and str_ends_with

2020-03-25 Thread will

Hi,

Hope everyone is doing alright. I just raised a new RFC 
(https://wiki.php.net/rfc/add_str_starts_with_and_ends_with_functions , 
github patch: https://github.com/php/php-src/pull/5300) for adding 
str_starts_with and str_ends_with to PHP. I would like to open this RFC 
up to discussion.


I raised a similar RFC about 9 months ago 
(https://wiki.php.net/rfc/add_str_begin_and_end_functions) that was 
narrowly rejected. A major criticism of that RFC was the inclusion of 
case-insensitive versions of str_starts_with and str_ends_with. I have 
incorporated feedback from that experienced and narrowed the new RFC to 
only propose str_starts_with and str_ends_with.


Thanks,

Will

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP-DEV] Removing warning for failed include

2020-03-25 Thread Claude Pache



> Le 26 mars 2020 à 01:11, Levi Morrison via internals 
>  a écrit :
> 
> It's bothered me for quite some time that a failed include emits a
> warning. This is because it's by design that the author chose
> `include` and not `require`. It's _expected_ that it may fail and they
> are okay with that.
> 
> As an example, consider a classic autoloading case. It could be as
> simple and performant as:
> 
>$file = /* something derived from class name */;
>include $file;
> 
> But because of the warning, in practice authors tend to use
> `file_exists` + require instead:
> 
>$file = /* something derived from class name */;
>if (file_exists($file)) {
>require $file;
>}
> 
> Weird isn't it? Authors are using require instead of include for the
> case where failure is tolerated. This is a clear signal to me that
> include isn't doing its job. The warning gets in the way.
> 
> Any reasons we shouldn't just remove this warning for PHP 8?
> 

A quick look on the code base I’m taking care of, reveals that most `include` 
instructions expect that the file will be in fact included. If it isn’t, the 
error handler will be triggered and send me a bug report. (Yes I know, all 
those `include` could have been spelled `require`.)

On the other hand, in the occasional cases where I do want to include a file 
only if it exists, I wouldn’t lightheartedly remove the `file_exists()` check, 
because its presence makes the intent of the code clearer.

—Claude
--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP-DEV] Class cast

2020-03-25 Thread David Rodrigues
Hello!

> What's wrong with new Number(123)?

Actually it is a simplest case, where only a single information was
considered. But you can expand it to something more complex, where
currently you will need create a static method to copy the data, which is
not a normalized way like cast could do.

> Not sure why would you want to do this? What's the use case?

You could mix the previous answer when arguments to a method that expects a
Number, for instance: X::test((Number) $x).

Or you can increase the type of information when possible. For instance:

function requiresB(B $b);

But you have only A $a.

You can create:

function __cast($value) {
if ($value instanceof A) return B($value, 123, M_PI);
}

Then use:

requiresB((B) $a);



Atenciosamente,
David Rodrigues


Em qua., 25 de mar. de 2020 às 20:06, Stanislav Malyshev <
smalys...@gmail.com> escreveu:

> Hi!
>
> > 1. Converting from A to B:
> >
> > $a = 123;
> > $b = (Number) $a; // $b is now instanceof Number
> >
> > A instanceof Number will created based on $a value.
>
> What's wrong with new Number(123)?
>
> > 2. Reduce object type (I don't know the technical term):
> >
> > class A {}
> > class B extends A {}
> >
> > $b = new B;
> > $a = (A) $b;
> >
> > $a still is $b, but with "limited" access to A methods and properties.
>
> Not sure why would you want to do this? What's the use case?
> --
> Stas Malyshev
> smalys...@gmail.com
>


[PHP-DEV] Removing warning for failed include

2020-03-25 Thread Levi Morrison via internals
It's bothered me for quite some time that a failed include emits a
warning. This is because it's by design that the author chose
`include` and not `require`. It's _expected_ that it may fail and they
are okay with that.

As an example, consider a classic autoloading case. It could be as
simple and performant as:

$file = /* something derived from class name */;
include $file;

But because of the warning, in practice authors tend to use
`file_exists` + require instead:

$file = /* something derived from class name */;
if (file_exists($file)) {
require $file;
}

Weird isn't it? Authors are using require instead of include for the
case where failure is tolerated. This is a clear signal to me that
include isn't doing its job. The warning gets in the way.

Any reasons we shouldn't just remove this warning for PHP 8?

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP-DEV] Class cast

2020-03-25 Thread Stanislav Malyshev
Hi!

> 1. Converting from A to B:
> 
> $a = 123;
> $b = (Number) $a; // $b is now instanceof Number
> 
> A instanceof Number will created based on $a value.

What's wrong with new Number(123)?

> 2. Reduce object type (I don't know the technical term):
> 
> class A {}
> class B extends A {}
> 
> $b = new B;
> $a = (A) $b;
> 
> $a still is $b, but with "limited" access to A methods and properties.

Not sure why would you want to do this? What's the use case?
-- 
Stas Malyshev
smalys...@gmail.com

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP-DEV] [RFC] [DISCUSSION] Type casting in array destructuring expressions

2020-03-25 Thread Levi Morrison via internals
To me, this is almost a good idea. However, I would want regular type
checking, not casts. Importantly, regular type checks would fit well
on allowing array destructuring directly in function signatures, which
would basically be a form of named parameters.

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP-DEV] Re: [RFC][DISCUSSION] throw expression

2020-03-25 Thread Andrea Faulds

Ilija Tovilo wrote:

Hi Andrea


but I am surprised you haven't mentioned the `and` and `or` operators


I did mention them in the RFC here:
https://wiki.php.net/rfc/throw_expression

If this RFC is accepted they will indeed be possible __

Regards



Oh, you are quite right! Sorry, I must not have read it too carefully :(

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP-DEV] [RFC][DISCUSSION] throw expression

2020-03-25 Thread Ilija Tovilo
Hi Andrea

> I would think we can just give `throw` an appropriate precedence so that 
> expressions like the above do what is desired

The example are taken from the RFC online. The following expression is already 
possible:

```php
throw $condition1 && $condition2 ? new Exception1() : new Exception2();
```

To make sure it keeps working the precedence needs to me very low. Thus the 
precedence might be slightly surprising which is why Dan suggests printing a 
warning.

Regards
 

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP-DEV] Re: [RFC][DISCUSSION] throw expression

2020-03-25 Thread Ilija Tovilo
Hi Andrea

> but I am surprised you haven't mentioned the `and` and `or` operators

I did mention them in the RFC here:
https://wiki.php.net/rfc/throw_expression

If this RFC is accepted they will indeed be possible __

Regards

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP-DEV] [RFC][DISCUSSION] throw expression

2020-03-25 Thread Andrea Faulds

Hi Dan,

Dan Ackroyd wrote:

Regarding the example:

$condition || throw new Exception('$condition must be truthy')
   && $condition2 || throw new Exception('$condition2 must be truthy');

The "Deprecate left-associative ternary operator"* RFC made it so that
parentheses are required when ternary operators are nested in
complicated statements.

Would a similar requirement for parentheses around complicated throw
expressions be a suitable solution to avoid people being surprised by
the behaviour?

cheers
Dan
Ack

* https://wiki.php.net/rfc/ternary_associativity



Is there a strong reason to require parentheses? I would think we can 
just give `throw` an appropriate precedence so that expressions like the 
above do what is desired — and then if you wanted to do something 
unusual, you would have to add parentheses anyway.


Regards,
Andrea

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php



[PHP-DEV] Re: [RFC][DISCUSSION] throw expression

2020-03-25 Thread Andrea Faulds

Hey Ilija,

Ilija Tovilo wrote:

Hi everybody! I hope you’re doing well.

  


Due to the modest feedback I’d like to move the throw expression RFC to “under 
discussion”.

https://wiki.php.net/rfc/throw_expression

  


In short, the RFC proposes to convert the throw statement into an expression to 
make it usable in arrow functions, the coalesce operator, as well as the 
ternary/elvis operator.


Thanks for this RFC, I have wanted this sometimes when writing PHP code. 
The ?? operator is one of those places, but I am surprised you haven't 
mentioned the `and` and `or` operators.


It is classic PHP style (probably borrowed from Perl?) to write e.g.:

$mysql = mysql_open(...) or die("Couldn't connect to MySQL");

Obviously not very modern with use of mysql_ ;)

But the `or` operator is still quite handy for this kind of trivial 
error handling, and it would be great to be able to write e.g.:


$fp = @fopen($filename, "r") or throw new Exception("Couldn't open 
file!");


Likewise for `and` (I think it is less common):

$somethingWentWrong and throw new Exception("Oh no!");

So I would be happy to see `throw` become an expression for these 
reasons, even if it is a bit conceptually weird given it never returns 
anything!


Thanks,
Andrea


--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP-DEV] [RFC] [DISCUSSION] Type casting in array destructuring expressions

2020-03-25 Thread Manuel Canga
Hi, Enno,



  En mié, 25 mar 2020 18:53:15 +0100 Enno Woortmann  
escribió 
 > Hi,
 > 
 > I've written the RFC and implemented a first patch concerning the idea
 > to allow type casting in array destructuring expressions.
 > 
 > 
 > The RFC is located at https://wiki.php.net/rfc/typecast_array_desctructuring
 > 
 > The patch can be found in MR 5296 located at
 > https://github.com/php/php-src/pull/5296
 > 
 > 
 > Thanks for further feedback!
 > 
 > Cheers, Enno
 > 

I like your RFC.  I hope it is approved.  However, I would change your 
examples. Because, this one:

["now" => (int) $now, "future" => (int) $future] = ["now" => "2020", "name" => 
"2021"];

You could do casting in this way:

["now" => $now, "future" => $future] = array_map('intval', ["now" => "2020", 
"name" => "2021"] );

If I were you I add examples with mixed types, like:

["address" => (string) $address, "floor" => (int) $floor] = ["address" => "My 
adress", "floor" => "3"];

I'm sorry my English

Regards
--
Manuel Canga

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP-DEV] [RFC] switch expression

2020-03-25 Thread Manuel Canga
Hi, internals,


  En mié, 25 mar 2020 17:21:29 +0100 Rowan Tommins 
 escribió 
 > On Wed, 25 Mar 2020 at 15:29, Ilija Tovilo  wrote:
 > 
 > > I don't think this would add any significant benefit over:
 > >
 > > ```php
 > > $x = true switch {
 > > $x  !== null && $x < 5 => ...
 > > }
 > > ```
 > >
 > 
 > 
 > The problem with that is that it requires a temporary variable to be
 > switched on. If I want to switch on, say, a method call, I can write this
 > for equality:
 > 
 > $result = $this->foo($bar) switch {
 > 1 => 'hello',
 > 2 => 'hi',
 > 3 => 'goodbye'
 > };

In this case, you can also do:

$result =  [
1 => 'hello',
2 => 'hi',
3 => 'goodbye'
 ][$this->foo($bar)];

With syntax very similar to proposed switch but this is using array.

Regards
 --
Manuel Canga

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php



[PHP-DEV] [RFC] [DISCUSSION] Type casting in array destructuring expressions

2020-03-25 Thread Enno Woortmann

Hi,

I've written the RFC and implemented a first patch concerning the idea
to allow type casting in array destructuring expressions.


The RFC is located at https://wiki.php.net/rfc/typecast_array_desctructuring

The patch can be found in MR 5296 located at
https://github.com/php/php-src/pull/5296


Thanks for further feedback!

Cheers, Enno

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP-DEV] Class cast

2020-03-25 Thread Benjamin Morel
>
> Currently PHP supports generic castings like (string), (int), ... maybe is
> time to allow class castings like (ToClass) $fromObject?


I've proposed something similar a year ago:
https://externals.io/message/105332

My intention wasn't to create an object from a scalar, nor was it to limit
to a class' methods & properties (hardly possible in PHP), but to ensure
that the value is an instance of the given class/interface, or throw an
exception.
My proposal wasn't so well received, though.

— Ben


Re: [PHP-DEV] [RFC] switch expression

2020-03-25 Thread Christoph M. Becker
On 25.03.2020 at 17:06, Dennis Birkholz wrote:
> Hello together,
>
> Am 25.03.20 um 16:46 schrieb Larry Garfield:
>> On Wed, Mar 25, 2020, at 10:29 AM, Ilija Tovilo wrote:
>>> Thanks for your feedback, Larry!
>>>
 One possible improvement to either version is allowing an expression on 
 the left side.  That is, rather than doing an equality match, do a boolean 
 match.
>>>
>>> This is how Rust does it:
>>>
>>> ```rust
>>> let x = match ... {
>>> Some(y) if y < 5 => ...
>>> }
>>> ```
>>>
>>> In other words, you can add an additional guard to each case that
>>> excepts any expression. We don't really benefit a lot from that since
>>> we don't have pattern matching. I don't think this would add any
>>> significant benefit over:
>>>
>>> ```php
>>> $x = true switch {
>>> $x  !== null && $x < 5 => ...
>>> }
>>> ```
>>
>> Good point, I'd forgotten about that potential trick.  So as long as an 
>> expression is allowed on the left, rather than just a literal, which is then 
>> == compared against the provided value, that should be "good enough" for 
>> most use cases.
>>
>> The implementation should include some tests to make sure that works 
>> properly, but I'm happy with the resulting syntax.
>>
>> So then the net result is:
>>
>> $var = switch($val) {
>>   case expr1 => expr2;
>> }
>>
>> Where $val gets compared against the result of each expr1, and if true then 
>> $var is set to expr2.
>
> on the first glance this all looks nice but you actually created
> something more like an if-expression that uses switch as a keyword
> because you stripped switch of some of its major features:
> - you compare the given value to possible cases -> you compare
> expressions to true
> - you can fall through to other cases without break
> - what about the default case?
>
> What about the following if-expression-syntax:
>
> $var = if ($x > 0) { return 1; }
>elseif ($x < 0) { return -1; }
>else { return 0; }
>
> Maybe this is more in line of what you want to do with your switch
> expression?

Or maybe even

  $var = $x > 0 ? 1
   :($x < 0 ? -1
   : 0);

Yes, the required parentheses are ugly, but in my opinion, this is still
better than a new if or switch(true) expression construct.

--
Christoph M. Becker

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php



[PHP-DEV] Class cast

2020-03-25 Thread David Rodrigues
Currently PHP supports generic castings like (string), (int), ... maybe is
time to allow class castings like (ToClass) $fromObject?

I think that it could be useful to converts to another kind of structure,
or even to reduce object type.

For instance:

---

1. Converting from A to B:

$a = 123;
$b = (Number) $a; // $b is now instanceof Number

A instanceof Number will created based on $a value.

---

2. Reduce object type (I don't know the technical term):

class A {}
class B extends A {}

$b = new B;
$a = (A) $b;

$a still is $b, but with "limited" access to A methods and properties.

---

To make possible custom some kind of castings, I suggests a new magic
method __cast($value).

class Number {
...
function __cast($value) {
if (is_int($value) || is_float($value)) return new static($value);
throw new TypeError();
}
}

Just to talk.


Atenciosamente,
David Rodrigues


Re: [PHP-DEV] [RFC] switch expression

2020-03-25 Thread Ilija Tovilo
Hi Rowan

> The problem with that is that it requires a temporary variable to be
> switched on. If I want to switch on, say, a method call, I can write this
> for equality:

I agree. The iffy part would be recognizing if the case expression should be 
equated to the switch input or evaluated on its own.
That is still something we could address in a later RFC for both the statement 
and expression.

Regards
 

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP-DEV] [RFC] switch expression

2020-03-25 Thread Ilija Tovilo
Hi Dennis

Thanks for your feedback!

> you can fall through to other cases without break

You could do the same using the || operator.

> what about the default case?

I haven't described the default case in my proposal but it is exactly what 
you'd expect it to be:

```php
$var = true switch {
$x > 0 => 1,
$x < 0 => -1,
default => 0,
};
```

> What about the following if-expression-syntax:

That would work (once again, Rust already does it) though not with the return 
keyword. We'd still need a block expression to pass the value from the block to 
the if expression. When I compare the two I definitely think the match 
expression is more readable.

Regards

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP-DEV] [RFC] switch expression

2020-03-25 Thread Rowan Tommins
On Wed, 25 Mar 2020 at 15:29, Ilija Tovilo  wrote:

> I don't think this would add any significant benefit over:
>
> ```php
> $x = true switch {
> $x  !== null && $x < 5 => ...
> }
> ```
>


The problem with that is that it requires a temporary variable to be
switched on. If I want to switch on, say, a method call, I can write this
for equality:

$result = $this->foo($bar) switch {
1 => 'hello',
2 => 'hi',
3 => 'goodbye'
};

For inequalities, the switch(true) version looks something like this (the
parentheses would probably be optional, but I'd personally use them for
readability):

$temp = $this->foo($bar);
$result = true switch {
($temp <= 1) => 'hello',
($temp == 2) => 'hi',
default => 'goodbye'
}

Using $$ to mean "value tested" would mean you could get rid of the temp
variable, and just write this:

$result = $this->foo($bar) switch {
 ($$ <= 1) => 'hello',
 ($$ == 2) => 'hi',
 default => 'goodbye'
};

I've also previously thought about specifying an operator for switch
statements, which could be used with expressions as well, e.g.

$result = $this->foo($bar) switch <= {
 1 => 'hello',
 2 => 'hi',
 default => 'goodbye'
};

Again, though, this is something that could be added to switch statements
and expressions together, as a separate RFC.

Regards,
-- 
Rowan Tommins
[IMSoP]


Re: [PHP-DEV] Improving PHP's Object Egonomics: A broad analysis

2020-03-25 Thread Dennis Birkholz
Am 25.03.20 um 15:24 schrieb Larry Garfield:
> On Wed, Mar 25, 2020, at 5:57 AM, Nicolas Grekas wrote:
>> Máté suggested this syntax and it has my preference over the one you menton
>> Larry: doubling the visibility keyword could be enough to express
>> read+write access:
>>
>> public private $property; <= public read access, private write access
> 
> In that syntax, you have to remember which one comes first.  There's no 
> indication for the casual reader why 
> 
> public private $property;
> 
> and 
> 
> private public $property;
> 
> are different.  Plus, just looking at it, "wait, it's public and private?  
> WTF?  That doesn't even make sense."
> 
> It also doesn't extend gracefully to property accessors.  Whatever accessors 
> do, if they ever get resolved, would conflict with that, and thus we'd have 
> that many more weird combinations of property metadata that are incompatible.
> 
> The whole point of the syntax I proposed for asymmetric visibility is that 
> it's gracefully extensible, even if a little more verbose.  (If we can find a 
> syntax that is less verbose while still gracefully extensible, I am on board 
> with that.)

What about the following syntax:

class X {
public read private write $property;
}

That would play nicely with accessors:

class Y {
public read getProp private write setProp Type $property;

// or this way around to make it clear which is the setter
// and which is the property type
public getProp read private setProp write Type $property;

private function getProp() : ?Type {}
private function setProp (Type $newValue) {}
}

It seems to me this would allow a clear syntax where you can selectively
add accessor method for reading or writing or both, you can reuse
existing setting methods when refactoring.

Only the isset/unset accessors are missing. I am not sure if they are
necessary: isset could be equivalent to ($obj->getProp() !== null) and
unset to setting null, but I have not thought this through yet.

Greets
Dennis

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP-DEV] [RFC] switch expression

2020-03-25 Thread Dennis Birkholz
Hello together,

Am 25.03.20 um 16:46 schrieb Larry Garfield:
> On Wed, Mar 25, 2020, at 10:29 AM, Ilija Tovilo wrote:
>> Thanks for your feedback, Larry!
>>
>>> One possible improvement to either version is allowing an expression on the 
>>> left side.  That is, rather than doing an equality match, do a boolean 
>>> match.
>>
>> This is how Rust does it:
>>
>> ```rust
>> let x = match ... {
>> Some(y) if y < 5 => ...
>> }
>> ```
>>
>> In other words, you can add an additional guard to each case that 
>> excepts any expression. We don't really benefit a lot from that since 
>> we don't have pattern matching. I don't think this would add any 
>> significant benefit over:
>>
>> ```php
>> $x = true switch {
>> $x  !== null && $x < 5 => ...
>> }
>> ```
> 
> Good point, I'd forgotten about that potential trick.  So as long as an 
> expression is allowed on the left, rather than just a literal, which is then 
> == compared against the provided value, that should be "good enough" for most 
> use cases.
> 
> The implementation should include some tests to make sure that works 
> properly, but I'm happy with the resulting syntax.
> 
> So then the net result is:
> 
> $var = switch($val) {
>   case expr1 => expr2;
> }
> 
> Where $val gets compared against the result of each expr1, and if true then 
> $var is set to expr2.

on the first glance this all looks nice but you actually created
something more like an if-expression that uses switch as a keyword
because you stripped switch of some of its major features:
- you compare the given value to possible cases -> you compare
expressions to true
- you can fall through to other cases without break
- what about the default case?

What about the following if-expression-syntax:

$var = if ($x > 0) { return 1; }
   elseif ($x < 0) { return -1; }
   else { return 0; }

Maybe this is more in line of what you want to do with your switch
expression?

Greets
Dennis

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP-DEV] [RFC] switch expression

2020-03-25 Thread Larry Garfield
On Wed, Mar 25, 2020, at 10:29 AM, Ilija Tovilo wrote:
> Thanks for your feedback, Larry!
> 
> > One possible improvement to either version is allowing an expression on the 
> > left side.  That is, rather than doing an equality match, do a boolean 
> > match.
> 
> This is how Rust does it:
> 
> ```rust
> let x = match ... {
> Some(y) if y < 5 => ...
> }
> ```
> 
> In other words, you can add an additional guard to each case that 
> excepts any expression. We don't really benefit a lot from that since 
> we don't have pattern matching. I don't think this would add any 
> significant benefit over:
> 
> ```php
> $x = true switch {
> $x  !== null && $x < 5 => ...
> }
> ```

Good point, I'd forgotten about that potential trick.  So as long as an 
expression is allowed on the left, rather than just a literal, which is then == 
compared against the provided value, that should be "good enough" for most use 
cases.

The implementation should include some tests to make sure that works properly, 
but I'm happy with the resulting syntax.

So then the net result is:

$var = switch($val) {
  case expr1 => expr2;
}

Where $val gets compared against the result of each expr1, and if true then 
$var is set to expr2.

Endorse.

--Larry Garfield

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP-DEV] [RFC] switch expression

2020-03-25 Thread Ilija Tovilo
Thanks for your feedback, Larry!

> One possible improvement to either version is allowing an expression on the 
> left side.  That is, rather than doing an equality match, do a boolean match.

This is how Rust does it:

```rust
let x = match ... {
Some(y) if y < 5 => ...
}
```

In other words, you can add an additional guard to each case that excepts any 
expression. We don't really benefit a lot from that since we don't have pattern 
matching. I don't think this would add any significant benefit over:

```php
$x = true switch {
$x  !== null && $x < 5 => ...
}
```

Regards

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP-DEV] [RFC] switch expression

2020-03-25 Thread Larry Garfield
On Wed, Mar 25, 2020, at 9:27 AM, Ilija Tovilo wrote:
> Hi Michał
> 
>  
> 
> I’m sorry, unfortunately I missed your e-mail and RFC.
> 
> Let me know if you’re still working on it and I’ll back off of course.
> 
>  
> 
> Regards

I like the concept, and it looks like you're both on a similar track.  Give or 
take details, I would very much like to see something like it.

One possible improvement to either version is allowing an expression on the 
left side.  That is, rather than doing an equality match, do a boolean match.  
That would then allow:

$foo = switch($bar) {
  case $bar < 5 => $bar * 3;
  case $baz < 10 => $bar * 4;
  default => $bar * 5;
};

That would sidestep the need for pattern matching, as you can do anything an 
expression can do.  The obvious caveat of course is figuring out how to 
reference the variable being switched on, if it's not already a variable.  My 
first thought there is to borrow the $$ variable name from Sara's old function 
composition proposal, but there may be others.  There's likely other issues to 
discuss here but allowing expressions on the left would greatly improve the 
expressiveness of the construct.

I'd prefer to not allow multi-line statements on the right, ie, blocks.  That 
leads to too much potential for long and ugly code, which a construct like this 
should be avoiding.  Limiting it to a single expression keeps it compact; if 
you have more involved logic, then put it in a function and your expression is 
just... calling that function.  Problem solved.

Side note: I did a limited user-space implementation of the same concept a 
while back:

https://hive.blog/php/@crell/type-matching-in-php

But I'd definitely rather see it in the native syntax.

--Larry Garfield

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP-DEV] [RFC] switch expression

2020-03-25 Thread Ilija Tovilo
Hi Michał

 

I’m sorry, unfortunately I missed your e-mail and RFC.

Let me know if you’re still working on it and I’ll back off of course.

 

Regards

 



Re: [PHP-DEV] Improving PHP's Object Egonomics: A broad analysis

2020-03-25 Thread Larry Garfield
On Wed, Mar 25, 2020, at 5:57 AM, Nicolas Grekas wrote:
> > > https://hive.blog/php/@crell/improving-php-s-object-ergonomics

> > Named parameters are a pretty tough topic. I think one of the main points
> > of contention is that they make the parameters names part of the API
> > contract, and as such also subject to LSP. Your proposal offers two
> > possible ways to side-step this: First, by making named parameters opt-in
> > with a special syntax {}. Second, by limiting them to constructors. The
> > latter variant still exposes parameter names in the API, but at least does
> > not require their preservation across inheritance, as constructors are
> > excluded from LSP. I'm somewhat torn on this, because it makes named
> > parameters unusable with the very large body of existing methods, and
> > introduces an inconsistency in which methods can use named params and which
> > don't.
> >
> 
> I'd like to propose something on the topic.
> I'm adding object literals to the mix because that's another feature of the
> language that we're missing a lot IMHO.
> Actually, there is one existing syntax for objects: (object) [...]
> 
> My proposal is to allow any class in the casting operator: (Foo) [...]
> By default, all keys of the casted array would map to properties (with an
> error when no matching property exists in the current visibility scope). We
> would then allow for a new constructor method, either:
> public function __create(array $values)
> or:
> public static function __create(array $values): static
> 
> This method would take over the cast operator and decide how to construct
> an instance of such a class.
> 
> There is one drawback: accepted keys are not documented. Sure, property
> declarations can give a big hint.
> 
> But I think we can solve this issue later: it's not a blocker to still make
> things work nicely. Also, this issue already exists with all methods that
> accept an array of options - and we'll find a solution for those - either
> using docblocks (there are already ways to use them for that) or using
> attributes (would be the best of course, once we have them.)
> 
> Note that this __create() method looks a lot like __unserialize(): it's
> just called at a different place, but the implementations could be
> essentially the same.

Interesting.  If that allowed populating private properties than that would be 
more capable than either of the initializer proposals that have been put 
forward.

However, this alternate deserialization (as you note, it's basically 
__unserialize by another name) brings up other issues:

1) If it's a large number of properties, the __create method would still need 
to manually assign them to properties, just like constructors now.  It wouldn't 
benefit from constructor promotion.

2) What's its order of execution with the constructor?  Vis, does the 
constructor run after __create or before?  Does __construct get any parameters 
passed to it?  If it doesn't get called, that's yet another way to bypass the 
constructor and therefore bypass object validation.  ("Make invalid states 
unrepresentable".  If the properties don't logically make sense with each other 
that should be rejected as early as possible; syntactically if we can, via 
early validation if not.)

Named parameters have neither of those issues, as data still only comes in via 
the constructor so both promotion and validation work fine.

> Regarding the remainder, I think that all of readonly properties,
> > asymmetric visibility and property accessors have their place and value,
> > with some overlap between them. As you already mentioned, the previous
> > property accessors proposal also included asymettric visibility as a
> > special case, and that's how I would introduce it as well.
> >
> 
> Máté suggested this syntax and it has my preference over the one you menton
> Larry: doubling the visibility keyword could be enough to express
> read+write access:
> 
> public private $property; <= public read access, private write access

In that syntax, you have to remember which one comes first.  There's no 
indication for the casual reader why 

public private $property;

and 

private public $property;

are different.  Plus, just looking at it, "wait, it's public and private?  WTF? 
 That doesn't even make sense."

It also doesn't extend gracefully to property accessors.  Whatever accessors 
do, if they ever get resolved, would conflict with that, and thus we'd have 
that many more weird combinations of property metadata that are incompatible.

The whole point of the syntax I proposed for asymmetric visibility is that it's 
gracefully extensible, even if a little more verbose.  (If we can find a syntax 
that is less verbose while still gracefully extensible, I am on board with 
that.)

--Larry Garfield

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP-DEV] [RFC] switch expression

2020-03-25 Thread Michał Brzuchalski
Hi Ilija,

śr., 25 mar 2020 o 13:10 Ilija Tovilo  napisał(a):

> Hi everybody!
>
>
>
> A few years ago I suggested adding a new `match` expression to the PHP
> language:
>
> https://externals.io/message/100487
>
>
>
> I arrogantly assumed someone will implement it for me which of course
> didn't happen. I'd finally like to get my own hands dirty. I have a very
> rough, incomplete prototype but I'd like to get your feedback before I
> continue working on the details.
>
>
>
> # Introduction
>
>
>
> This is what it looks like:
>
>
>
> ```php
>
> echo $i switch {
>
> 0 => "i equals 0",
>
> 1 => "i equals 1",
>
> 2 => "i equals 2",
>
> 3, 4 => "i equals 3 or 4",
>
> };
>
>
>
> // is roughly equivalent to
>
>
>
> switch ($i) {
>
> case 0:
>
> $tmp = "i equals 0";
>
> break;
>
> case 1:
>
> $tmp = "i equals 1";
>
> break;
>
> case 2:
>
> $tmp = "i equals 2";
>
> break;
>
> case 3:
>
> case 4:
>
> $tmp = "i equals 3 or 4";
>
> break;
>
> default:
>
> throw new InvalidArgumentException('Unhandled switch case');
>
> }
>
>
>
> echo $tmp;
>
> ```
>
>
>
> Some things to note:
>
>
>
> * Each case only accepts a single expression
>
> * The entire switch expression evaluates to the result of the executed case
>
> * There is no fallthrough, an implicit break is added after every case
>
> * Multiple case conditions are possible with comma separation
>
> * The default case throws a InvalidArgumentException by default
>
> * The switch keyword is used as an infix operator
>
>
>
> # Syntax
>
>
>
> Originally, I expected to reuse the current syntax and transform it into
> an expression.
>
>
>
> ```php
>
> $x = switch ($y) { ... };
>
> ```
>
>
>
> Turns out this is ambiguous.
>
>
>
> ```php
>
> switch ($y) { ... }
>
> [$a] = ...;
>
>
>
> // Could also be interpreted as
>
> switch ($y) { ... }[$a] = ...;
>
> ```
>
>
>
> I stole the new syntax from C# 8.0 which means at least some people will
> already be familiar with it:
>
>
> https://docs.microsoft.com/en-us/archive/msdn-magazine/2019/may/csharp-8-0-pattern-matching-in-csharp-8-0#the-evolution-of-pattern-matching-in-c-80
>
>
>
> # Type coercion
>
>
>
> One of the bigger weak points of the `switch` statement is the fact that
> it performs implicit type coercion.
>
>
>
> ```php
>
> switch ('foo') {
>
> case 0:
>
> echo "Oh no!\n";
>
> }
>
> ```
>
>
>
> While it's very tempting to fix this in the new `switch` expression it
> adds a confusing discrepancy between the `switch` statement and expression.
> I think it would be preferrable to keep the two the same and change the
> behavior of both in a new PHP edition (
> https://github.com/php/php-rfcs/pull/2).
>
>
>
> # Pattern matching
>
>
>
> I decided against pattern matching because PHP doesn't have algebraic data
> types and classes rarely have public properties. In my opinion the limited
> use cases don't justify the significant complexity added to the language.
> It would also, once again, add an unjustified discrepancy between the
> `switch` statement and expression. If at some point we do want to introduce
> pattern matching it might be better to introduce a different keyword (e.g.
> `match`) and make it work for both the statement and expression. In case
> you need to match a more complex expression the following still works fine:
>
>
>
> ```php
>
> echo true switch {
>
> is_int($x) => 'int',
>
> is_float($x) => 'float',
>
> is_string($x) => 'string',
>
> ...
>
> };
>
> ```
>
>
>
> # Blocks
>
>
>
> Sometimes it would be useful to split the expression into multiple
> statements to make it more readable. Unfortunately, in PHP there are no
> block expressions. Rust allows returning the last value by omitting the
> semicolon:
>
>
>
> ```php
>
> echo $x switch {
>
> 1 => {
>
> foo();
>
> bar();
>
> baz()
>
> },
>
> };
>
> ```
>
>
>
> This is indeed possible in PHP and could be implemented as part of the
> `switch` expression or as a general language feature. A nice side effect is
> that this could also be used in arrow functions:
>
>
>
> ```php
>
> $x = fn() => {
>
> foo();
>
> bar();
>
> baz()
>
> };
>
> ```
>
>
>
> This would, however, make it inconsistent with closures as they use the
> return keyword. Thus we would probably have to make sure arrow functions
> still work with return statement which would decrease the need for such a
> language construct. It is also very unlike anything else in PHP.
>
>
>
> # Poll
>
>
>
> This is a short overview of what I'll be working on in the coming weeks. I
> created a short poll for you guys to let me know if this idea is worth
> pursuing:
>
> https://forms.gle/stXMv72CAaDDxfwf8
>
>
>
> Stay safe!
>
>
That looks like what I've described a few months ago in
https://wiki.php.net/rfc/switch-expression-and-statement-improvement
If you dig into the mailing list you can even find almost ready to use

[PHP-DEV] [RFC] switch expression

2020-03-25 Thread Ilija Tovilo
Hi everybody!

 

A few years ago I suggested adding a new `match` expression to the PHP language:

https://externals.io/message/100487

 

I arrogantly assumed someone will implement it for me which of course didn't 
happen. I'd finally like to get my own hands dirty. I have a very rough, 
incomplete prototype but I'd like to get your feedback before I continue 
working on the details.

 

# Introduction

 

This is what it looks like:

 

```php

echo $i switch {

    0 => "i equals 0",

    1 => "i equals 1",

    2 => "i equals 2",

    3, 4 => "i equals 3 or 4",

};

 

// is roughly equivalent to

 

switch ($i) {

    case 0:

    $tmp = "i equals 0";

    break;

    case 1:

    $tmp = "i equals 1";

    break;

    case 2:

    $tmp = "i equals 2";

    break;

    case 3:

    case 4:

    $tmp = "i equals 3 or 4";

    break;

    default:

    throw new InvalidArgumentException('Unhandled switch case');

}

 

echo $tmp;

```

 

Some things to note:

 

* Each case only accepts a single expression

* The entire switch expression evaluates to the result of the executed case

* There is no fallthrough, an implicit break is added after every case

* Multiple case conditions are possible with comma separation

* The default case throws a InvalidArgumentException by default

* The switch keyword is used as an infix operator

 

# Syntax

 

Originally, I expected to reuse the current syntax and transform it into an 
expression.

 

```php

$x = switch ($y) { ... };

```

 

Turns out this is ambiguous.

 

```php

switch ($y) { ... }

[$a] = ...;

 

// Could also be interpreted as

switch ($y) { ... }[$a] = ...;

```

 

I stole the new syntax from C# 8.0 which means at least some people will 
already be familiar with it:

https://docs.microsoft.com/en-us/archive/msdn-magazine/2019/may/csharp-8-0-pattern-matching-in-csharp-8-0#the-evolution-of-pattern-matching-in-c-80

 

# Type coercion

 

One of the bigger weak points of the `switch` statement is the fact that it 
performs implicit type coercion.

 

```php

switch ('foo') {

    case 0:

    echo "Oh no!\n";

}

```

 

While it's very tempting to fix this in the new `switch` expression it adds a 
confusing discrepancy between the `switch` statement and expression. I think it 
would be preferrable to keep the two the same and change the behavior of both 
in a new PHP edition (https://github.com/php/php-rfcs/pull/2).

 

# Pattern matching

 

I decided against pattern matching because PHP doesn't have algebraic data 
types and classes rarely have public properties. In my opinion the limited use 
cases don't justify the significant complexity added to the language. It would 
also, once again, add an unjustified discrepancy between the `switch` statement 
and expression. If at some point we do want to introduce pattern matching it 
might be better to introduce a different keyword (e.g. `match`) and make it 
work for both the statement and expression. In case you need to match a more 
complex expression the following still works fine:

 

```php

echo true switch {

    is_int($x) => 'int',

    is_float($x) => 'float',

    is_string($x) => 'string',

    ...

};

```

 

# Blocks

 

Sometimes it would be useful to split the expression into multiple statements 
to make it more readable. Unfortunately, in PHP there are no block expressions. 
Rust allows returning the last value by omitting the semicolon:

 

```php

echo $x switch {

    1 => {

    foo();

    bar();

    baz()

    },

};

```

 

This is indeed possible in PHP and could be implemented as part of the `switch` 
expression or as a general language feature. A nice side effect is that this 
could also be used in arrow functions:

 

```php

$x = fn() => {

    foo();

    bar();

    baz()

};

```

 

This would, however, make it inconsistent with closures as they use the return 
keyword. Thus we would probably have to make sure arrow functions still work 
with return statement which would decrease the need for such a language 
construct. It is also very unlike anything else in PHP.

 

# Poll

 

This is a short overview of what I'll be working on in the coming weeks. I 
created a short poll for you guys to let me know if this idea is worth pursuing:

https://forms.gle/stXMv72CAaDDxfwf8

 

Stay safe!

 



Re: [PHP-DEV] [VOTE] Userspace operator overloading

2020-03-25 Thread Alexander Lisachenko
Hi, internals!

I want to mention, that all existing internal API of Zend could be
accessible via FFI as of PHP7.4. This gives opportunity to implement
userspace operator overloading as a simple PHP package.

I know, that FFI requires some polishing, but it could become a tool to
create interesting extensions via Z-Engine or similar libraries. Just for
example, I have a repository
https://github.com/lisachenko/native-types which provides an example of
userspace operator-overloading for matrices (see __doOperation method
implementation at
https://github.com/lisachenko/native-types/blob/master/src/Matrix.php#L232-L276
)

Please share you thoughts about this.

Best regards,
Alexander

пн, 23 мар. 2020 г. в 20:58, :

> Hi internals,
>
> I have opened voting on
> https://wiki.php.net/rfc/userspace_operator_overloading, which allows
> users
> to overload operators in their own classes.
>
> Voting closes on 2020-04-06.
>
> Regards,
> Jan Böhmer
>
> --
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: http://www.php.net/unsub.php
>
>


[PHP-DEV] Re: [VOTE] Userspace operator overloading

2020-03-25 Thread Christoph M. Becker
On 23.03.2020 at 18:58, jan.h.boeh...@gmx.de wrote:

> I have opened voting on
> https://wiki.php.net/rfc/userspace_operator_overloading, which allows users
> to overload operators in their own classes.

It seems to me that the RFC is not sufficiently specific enough
regarding the concatenation of instances of classes which implement
__toString().  The RFC itself doesn't mention that explicitly, and the
backward incompatible changes section states:

| As long as the user does not implement, the operator magic functions,
| operators on objects will behave in the previous way.

However, at least the current implementation raises two notices ("You
have to implement the __concat function") when concatenating Stringable
objects.

A minor issue: in my opinion, introducing
PHP_OPERAND_TYPES_NOT_SUPPORTED doesn't make sense.  The RFC says:

| Handlers can specify return typehints, but note that the return type
| has to be nullable (as PHP_OPERAND_TYPES_NOT_SUPPORTED has the value
| null).

So if we ever wanted to change the value of
PHP_OPERAND_TYPES_NOT_SUPPORTED, we'd introduce a BC break.  Therefore
the constant's value likely will never change, so using NULL directly to
signal unsupported operand types would be fine, wouldn't it?

--
Christoph M. Becker

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP-DEV] [VOTE] Userspace operator overloading

2020-03-25 Thread Nicolas Grekas
> 1. This is exposing functionality that already exists for internal classes
>

2. Because this just exposes existing functionality, the amount of
> technical complexity this introduces is very small
>


> 3. As mentioned, this functionality already exists internally and is used
> by GMP, where it works (imho) very well.
>

Thanks Nikita for the insights, that's really helpful.

I'd suggest removing the "PHP_OPERAND_TYPES_NOT_SUPPORTED" constant and
settle on null instead.
The reason is visible in the RFC: `public static function __mul($lhs, $rhs):
?Vector3` - nothing else than null can be returned here when looking at the
return type. Returning a const is just calling for "WTF" indirections IMHO.

I'm still voting yes, hoping for this const to be removed after if the RFC
passes, if it does :)

Nicolas


Re: [PHP-DEV] Improving PHP's Object Egonomics: A broad analysis

2020-03-25 Thread Nicolas Grekas
> > https://hive.blog/php/@crell/improving-php-s-object-ergonomics


Thanks Larry, that's a good way to move forward on these topics.

I generally like the ideal of combining property declaration and
> constructors. I've had this on my mind for a while already, and also
> received the same suggestion from a couple of other people (I think Nicolas
> was one of them?)


I confirm: that'd be super useful to clean the boilerplate.


> large enough that I will often go with a quick and simple ad-hoc array
> structure rather than declaring an explicit value object type.


Yes


> The main concern, as others have already mentioned, is that these inline
> declarations can end up being quite verbose, especially once attributes get
> involved.
>

I don't share this concern with attributes: they mix without any ambiguity,
which is what matters.
No syntax is perfect, ppl that prefer the current way will still be able to
use it.



> Named parameters are a pretty tough topic. I think one of the main points
> of contention is that they make the parameters names part of the API
> contract, and as such also subject to LSP. Your proposal offers two
> possible ways to side-step this: First, by making named parameters opt-in
> with a special syntax {}. Second, by limiting them to constructors. The
> latter variant still exposes parameter names in the API, but at least does
> not require their preservation across inheritance, as constructors are
> excluded from LSP. I'm somewhat torn on this, because it makes named
> parameters unusable with the very large body of existing methods, and
> introduces an inconsistency in which methods can use named params and which
> don't.
>

I'd like to propose something on the topic.
I'm adding object literals to the mix because that's another feature of the
language that we're missing a lot IMHO.
Actually, there is one existing syntax for objects: (object) [...]

My proposal is to allow any class in the casting operator: (Foo) [...]
By default, all keys of the casted array would map to properties (with an
error when no matching property exists in the current visibility scope). We
would then allow for a new constructor method, either:
public function __create(array $values)
or:
public static function __create(array $values): static

This method would take over the cast operator and decide how to construct
an instance of such a class.

There is one drawback: accepted keys are not documented. Sure, property
declarations can give a big hint.

But I think we can solve this issue later: it's not a blocker to still make
things work nicely. Also, this issue already exists with all methods that
accept an array of options - and we'll find a solution for those - either
using docblocks (there are already ways to use them for that) or using
attributes (would be the best of course, once we have them.)

Note that this __create() method looks a lot like __unserialize(): it's
just called at a different place, but the implementations could be
essentially the same.

Regarding the remainder, I think that all of readonly properties,
> asymmetric visibility and property accessors have their place and value,
> with some overlap between them. As you already mentioned, the previous
> property accessors proposal also included asymettric visibility as a
> special case, and that's how I would introduce it as well.
>

Máté suggested this syntax and it has my preference over the one you menton
Larry: doubling the visibility keyword could be enough to express
read+write access:

public private $property; <= public read access, private write access


However, I generally think that the main value really is the readonly
> properties as proposed in the recent RFC. Nowadays, a large fraction of the
> classes I use are immutable value objects, for which public readonly
> properties provide a much closer match to the semantics I want.
>
> I think that the problem with with-er methods is just that: It's a problem
> with with-er methods. It's what happens when you try to shove immutability
> into something that is not actually being used in an immutable manner.
> Don't pretend things are immutable when they aren't...
>

I think "withers" solve the problem of immutability in a very pragmatic and
convenient way.

Take e.g. "private": it can be bypassed using closure rebinding or
reflection, and this is really useful, e.g. to build "friendship" relations
between classes in the same package (like in C++).

On the other side, "final" is a real pain when needing to write
proxies/decorators. It just blocks extensibility for no technical reasons
really. Let me explain: If as a consumer, I DO want to extend a class,
nothing will prevent me to do so. There is always the last resort solution,
which is patching the too restrictive source class, either using a fork or
some code rewriting tool.

Either way, what matters is who is in charge of dealing with the issues
this might create. In both ways, what matters is that the original author

Re: [PHP-DEV] Re: [VOTE] Object-based token_get_all() alternative

2020-03-25 Thread Alexander Lisachenko
Hello, internals team!

I would like to propose to rename the PhpToken::getAll() method into the
PhpToken::tokenize(string $source) or PhpToken::lex(string $source) to use
a more meaningful verb word.

After renaming, it will sound more natural: $tokenStream =
PhpToken::tokenize($sourceCode)

Best regards,
Alexander


пн, 23 мар. 2020 г. в 19:04, Larry Garfield :

> On Mon, Mar 23, 2020, at 9:07 AM, Nikita Popov wrote:
> > On Fri, Mar 6, 2020 at 10:33 AM Nikita Popov 
> wrote:
> >
> > > Hi internals,
> > >
> > > I've opened voting on https://wiki.php.net/rfc/token_as_object, which
> > > adds a new object-based interface to the tokenizer. Voting closes on
> > > 2020-03-20.
> > >
> >
> > This RFC has been accepted unanimously, with 47 votes in favor.
> >
> > Based on the additional feedback in this thread, I'll also add a
> > __toString() method that returns the value of $token->text, unless anyone
> > has objects to that...
> >
> > Regards,
> > Nikita
>
> As long as __toString() is overridable in subclasses, that seems fine to
> me.
>
> --Larry Garfield
>
> --
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: http://www.php.net/unsub.php
>
>


Re: [PHP-DEV] [VOTE] Userspace operator overloading

2020-03-25 Thread Benjamin Eberlei
On Mon, Mar 23, 2020 at 6:58 PM  wrote:

> Hi internals,
>
> I have opened voting on
> https://wiki.php.net/rfc/userspace_operator_overloading, which allows
> users
> to overload operators in their own classes.
>
> Voting closes on 2020-04-06.
>
> Regards,
> Jan Böhmer
>

Thank you.

I voted yes on this for similar reasons than Nikita. I think it is
confusing to users why internal objects can overload these and userland
can't.

The simplicity of exposing this is another plus.

The potential for misuse is a non issue for me, because essentially this
applies to most features, especially with existing magic methods we have a
precedent that we can build upon instead of "repressing use".

>
> --
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: http://www.php.net/unsub.php
>
>


Re: [PHP-DEV] Improving PHP's Object Egonomics: A broad analysis

2020-03-25 Thread Peter Bowyer
>
> For details, see the full writeup:
>
> https://hive.blog/php/@crell/improving-php-s-object-ergonomics


An excellent writeup, thank you Larry.

Peter


Re: [PHP-DEV] [RFC] [DISCUSSION] Locale-independent float to string cast

2020-03-25 Thread Lynn
I'm very sorry, I pressed the reply instead of reply all button, I hope
this fixes it!

I agree that these cases can go horribly wrong. However, my reasoning is
> the following:
> - if a piece of code currently relies on locale-independence (e.g.
> automated data exports) then this
> change wouldn't cause any breakage since a workaround has already been in
> place there (e.g. the
> programmers use var_export() instead of casting)
> - if a piece of code relies on the locale-dependent string representation
> of floats then there will be
> a BC break, sure, however I believe that code isn't very sensitive to the
> change in the vast majority of the
> cases since that data is for presentation purposes only.
>

I know it's for presentation purpose only, sadly it's not used for just
presentation code. It's being consumed and parsed by automated imports that
expect a format different than `3.5`, because that's how it organically
evolved. Even when it was meant only for presentation, the consumer
expected the `3,5` format and will keep expecting this until we notify them
of a change (and then it will probably still take weeks before this is
fixed on their side). A lot of code that I've encountered is stuff like:
```
$csv .= $product->getPrice() . ';';

// older code I've seen come by
$product = get_product($$var5);
$csv .= $product['price'] . ';';
```
As much as I'd like to see this fixed and always give a `3.5`, sadly that's
not the case if you use a different locale. Going through thousands of
files to fix this, is not going to be an easy task, especially not as this
is often old enough to not be usable by static code analyzers.


> Or do you have other locale-dependent use-cases in mind? I am sure there
> are some but I think the number of the situations where the change is
> problematic is less than what it first seems.
>

No, this is the only issue I personally see with it. However, the impact
could be severe enough to not be able to upgrade to a new PHP version in
the foreseeable future, thus I would like to see an upgrade path, one that
tells you where it would've gone wrong, instead of turning the behavior on
or off. If I can gather the logs and thus find usages, I can pro-actively
start fixing where this would go wrong. I'll take a performance hit over a
breakage. Performance penalty would only have to apply if the locale is set
to something we know will change the outcome. Maybe it turns out this is a
small issue, maybe it's a big issue... I can't tell because it's either
upgrade & break, or upgrade & work in the proposed scenario. Some breakage
may take weeks to find out because scripts run periodically.

I fully understand that you don't see this as a big issue, and I really
wish I could say the same. I can't vote, so I can't change the outcome,
please consider my use-case when moving forward, thanks!

Regards,
Lynn