Re: [PHP-DEV] [VOTE] declare(function_and_const_lookup='global')

2020-01-29 Thread tyson andre
> Agreed. I want to force explicit qualifications, and raise error on 
> unqualified names:
>
>  declare(strict_qualify=1);
>
> namespace foo;
>
> use function \{array_diff, var_dump};
> use const \bar\{a, b};
>
> $x = array_diff(a, b);
> if (count($x)) { // throw an \Error of some kind, as count is unqualified
> var_dump($x);
> }
>
> Pros... no bc break; short declare identifier with obvious values; code valid 
> even if declare is removed; no lookup performance penalty;
> easy to remember logic; forces enumeration of the "surface area" the code 
> wants to cover
> (which in turn helps developers think about how much work the code's doing); 
> has analogue in other similar languages (perl, python, node);
> makes explicit what functions are being used and where they originate; might 
> goad an implementation of wildcard use (`use function \{imap_*}`).

If this is allowing prefixing with backslashes, the "surface area" isn't 
guaranteed to be enumerated in one place.
Forbidding backslashes or namespace aliases for functions/constants would have 
other objections.

> I've not done the work to implement this, though I am happy to if there's 
> interest.
> But, it may not be feasible. I'd hope Tyson would kindly say "STFU not 
> possible"  if,
> from their recent experience, it couldn't be done. Apologies if earlier 
> thread discussion ruled this out categorically.
>
> But I like that it adds super-strictness for those who want that, while 
> keeping the super-flexibility of what we have now. That seems to be the way 
> we're going with this dual-world of loose- and strict-ness in PHP.

The issue would be that I'd expect it to be voted against for similar reasons 
to my RFC, but it's easy to implement.

`declare(function_and_const_lookup='global')` aimed to make something that was 
inconvenient to work with
with tooling more convenient in some ways with and without tooling.

Right now, it's already possible to fail your build if a file uses unqualified 
names, without code changes.
Tools like `phpcs` and `phan --plugin NotFullyQualifiedUsagePlugin` can be run 
in continuous integration or as a check on file save,
and have ways to detect the lack of explicit qualifications.
(If a project could set up `php --syntax-check` on all files, they could likely 
also set `phpcs` checks up).
Having a file `strict_qualify=1` throw/exit after a deployment or code release 
would be undesirable
(emitting a compiler warning when compiling would be safer, but make that 
setting a less useful guarantee of strictness)

It's possible to implement from a technical standpoint:
the lines that get changed are the same ones you can see in the PR for my RFC.
(If you mean throw at compile time, not at runtime)

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



Re: [PHP-DEV] How to debug a segmentation fault?

2020-01-29 Thread tyson andre
> Sorry, I didn't notice that https://bugs.php.net/bug.php?id=79194 was already 
> [solved and] closed with a similar answer.

In addition to phpspy, a tool I forgot to mention was Phan. 
(https://github.com/phan/phan)

`phan --redundant-condition-detection` will enable many of Phan's checks, 
including code that looks like a function or method calling itself 
unconditionally, or with the same args.
I got the idea for adding a check for PhanInfiniteRecursion (and 
PhanPossiblyInfiniteRecursionSameParams) after investigating a similar segfault 
over a year ago ago
(and considering most of those solutions),
to detect that type of bug before it ran.
https://github.com/phan/phan/blob/master/internal/Issue-Types-Caught-by-Phan.md#phaninfiniterecursion
 has an example of what it detects
--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP-DEV] How to debug a segmentation fault?

2020-01-29 Thread tyson andre
Sorry, I didn't notice that https://bugs.php.net/bug.php?id=79194 was already 
closed with a similar answer.
--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP-DEV] How to debug a segmentation fault?

2020-01-29 Thread tyson andre
>> I'm encountering a SIGSEGV in PHP-FPM on PHP 7.4.2 in a Symfony app. The
>> bug seems to happen during the rendering of a Twig template; this makes it
>> hard for me to pinpoint the code that triggers the segfault.
>
> I'm not sure if I could gather helpful enough info about the issue, but
> anyway I filed a bug here:
> https://bugs.php.net/bug.php?id=79194

>> gdb output for the segfault: (only showing the first 10 entries, it goes on 
>> and on for more than 2 entries—there may be many more, I gave up after 
>> that)

> #0  0x7f7ea5fdc6d1 in bf_zend_execute () from 
> /usr/lib64/php/modules/blackfire.so
> #1  0x560bec0b20c0 in ZEND_DO_FCALL_SPEC_RETVAL_USED_HANDLER () at 
> /usr/src/debug/php-7.4.2-1.fc31.remi.x86_64/Zend/zend_vm_execute.h:1714
> #2  execute_ex (ex=0x7f7e99d6b2c0) at 
> /usr/src/debug/php-7.4.2-1.fc31.remi.x86_64/Zend/zend_vm_execute.h:53821
> #3  0x7f7ea5fdc6f8 in bf_zend_execute () from 
> /usr/lib64/php/modules/blackfire.so
> #4  0x560bec0b20c0 in ZEND_DO_FCALL_SPEC_RETVAL_USED_HANDLER () at 
> /usr/src/debug/php-7.4.2-1.fc31.remi.x86_64/Zend/zend_vm_execute.h:1714
> #5  execute_ex (ex=0x7f7e99d6b2c0) at 
> /usr/src/debug/php-7.4.2-1.fc31.remi.x86_64/Zend/zend_vm_execute.h:53821

The symptoms sounds like you have a global function (each call handled in 
ZEND_DO_FCALL_SPEC_RETVAL_USED_HANDLER) that's recursively calling itself, 
infinitely. The stack trace doesn't say which.
When blackfire is used, it seems to use C's call stack, which leads to a stack 
overflow.
When blackfire is used, the C PHP engine manages a different stack and doesn't 
recurse, so it doesn't have a stack overflow, and the memory leak would be 
slower.

Infinite recursion leading to a segfault is **a known bug with no plans to be 
fixed that I know of,** which I've encountered many times.

You may also want to try running the same code with xdebug - Xdebug will 
throw/log an error if you recurse more than max_nesting_level(defaults to 100).
https://xdebug.org/docs/basic
That will give you the php function that calls itself.

If you can reproduce the issue consistently, you may also want to look into 
https://github.com/adsr/phpspy (It has a top-like mode:)
--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP-DEV] How to debug a segmentation fault?

2020-01-29 Thread Benjamin Morel
>
> I would add, since you're using PHP-FPM, that the pool configuration needs
> to have:
> process.dumpable = 1


Thank you! I could not generate a core dump before adding this
configuration option!
The generating a gdb backtrace
 page looks a big
outdated, it would be nice if someone could update it will all the helpful
info received in this thread.

I'm not sure if I could gather helpful enough info about the issue, but
anyway I filed a bug here:
https://bugs.php.net/bug.php?id=79194

Thank you,
Benjamin

On Wed, 29 Jan 2020 at 18:19, Bishop Bettini  wrote:

> On Tue, Jan 28, 2020 at 11:28 AM Benjamin Morel 
> wrote:
>
>> I'm encountering a SIGSEGV in PHP-FPM on PHP 7.4.2 in a Symfony app. The
>> bug seems to happen during the rendering of a Twig template; this makes it
>> hard for me to pinpoint the code that triggers the segfault.
>>
>> Could you please tell me what the procedure to collect information is, so
>> that I can file a useful bug report?
>>
>
> Great advice so far. I would add, since you're using PHP-FPM, that the
> pool configuration needs to have:
>
> process.dumpable = 1
>
> to get core dumps out of workers. Without this you might not get core
> dumps, even when you have other core dump settings configured (ulimit -c
> unlimited, chmod +r phpfpm, etc.).
>


Re: [PHP-DEV] [VOTE] declare(function_and_const_lookup='global')

2020-01-29 Thread Bishop Bettini
On Wed, Jan 29, 2020 at 3:12 PM Claude Pache  wrote:

>
>
> Le 29 janv. 2020 à 19:42, Bishop Bettini  a écrit :
>
> Cons... have to enumerate everything, potentially lots of work to do that
> to update old code to use; edge cases I'm not thinking about.
>
>
> Not only it is much work (although it could be partially automated), but
> it does not make much sense.
>
> I’ve taken a random file (~650 LoC) in the codebase I’m working on. With
> `declare(strict_qualify=1)`, I would have to add:
>
> use function
> array_filter
>   , array_flip
>   , array_key_exists
>   , array_keys
>   , array_push
>   , array_unshift
>   , compact
>   , ctype_digit
>   , idate
>   , in_array
>   , is_int
>   , is_string
>   , ksort
>   , ob_get_clean
>   , ob_start
>   , preg_match
>   , sprintf
>   , strlen
>   , strncmp
>   , substr_count
>   , trim
>   , usort;
>

A fair critique. Under the "goad use of wildcard import" pro, the quick way:
use \{*};

Any unqualified name is locked to the global namespace.

> I don’t see a clear advantage in declaring more than 20 global functions
> in each and every of the hundreds of files of the codebase—where it is
> evident that they are all global function (no, I don’t have a namespaced
> version of `is_int()`). Also, I think that there are better ways to
> discover if my colleague introduced surreptitiously a `system()` call in
> the codebase.
>

Well, first, it's faster as Tyson described in the RFC: those are opcoded
and bypass the namespace lookup.

Second, and I find this the best reason, that enumeration tells me quite a
bit about what that code does. I don't need to see the code to know that
it's compute oriented, doesn't touch resources (eg files), and is doing
what PHP does best: string and array manipulation. It also shows me that
code's doing output buffer manipulation, which seems out of place and
suggests that should be refactored out.

IOW, it's a really nice abstract / summary of what the code's doing. And
that's some very good insight.


> Some time ago, I’ve tried the alternative approach in two files: adding a
> backslash before each and every global function (carefully avoiding
> non-functions such as `isset()`, `empty()` and `list()`). Well, it reminded
> me of the good old days when I used TeX intensively, but objectively, it
> didn’t make the code more clear or more secure (I’ve not tested its
> velocity, though).
>

I agree: qualifying the name at the usage site doesn't add much value, IMO.
It's frankly more noise than anything else.


Re: [PHP-DEV] [VOTE] declare(function_and_const_lookup='global')

2020-01-29 Thread Claude Pache


> Le 29 janv. 2020 à 19:42, Bishop Bettini  a écrit :
> 
> Cons... have to enumerate everything, potentially lots of work to do that
> to update old code to use; edge cases I'm not thinking about.


Not only it is much work (although it could be partially automated), but it 
does not make much sense.

I’ve taken a random file (~650 LoC) in the codebase I’m working on. With 
`declare(strict_qualify=1)`, I would have to add:

use function 
array_filter
  , array_flip
  , array_key_exists
  , array_keys
  , array_push
  , array_unshift
  , compact
  , ctype_digit
  , idate
  , in_array
  , is_int
  , is_string
  , ksort
  , ob_get_clean
  , ob_start
  , preg_match
  , sprintf
  , strlen
  , strncmp
  , substr_count
  , trim
  , usort;

I don’t see a clear advantage in declaring more than 20 global functions in 
each and every of the hundreds of files of the codebase—where it is evident 
that they are all global function (no, I don’t have a namespaced version of 
`is_int()`). Also, I think that there are better ways to discover if my 
colleague introduced surreptitiously a `system()` call in the codebase.

Some time ago, I’ve tried the alternative approach in two files: adding a 
backslash before each and every global function (carefully avoiding 
non-functions such as `isset()`, `empty()` and `list()`). Well, it reminded me 
of the good old days when I used TeX intensively, but objectively, it didn’t 
make the code more clear or more secure (I’ve not tested its velocity, though).

—Claude



Re: [PHP-DEV] [VOTE] declare(function_and_const_lookup='global')

2020-01-29 Thread Bishop Bettini
On Wed, Jan 29, 2020 at 5:56 AM Marco Pivetta  wrote:

> I voted "No" on this one, sorry.
>
> TL;DR: I'd rather have a mechanism to disable global function fallback, not
> something that makes un-imported symbols immediately global.
>
> The idea to disable PHP's implicit
> "fallback-to-something-that-may-or-may-not-exist" is great, and it could
> simplify some of the engine, as well as remove some caching mechanisms
> (lookup) in some contexts, but I'm pretty happy with disabling all global
> lookup functionality, rather than making them the default.
>
> I don't have a problem with `use function sprintf;` to import things from
> PHP, and actually use it to quickly grep whenever I do something extremely
> dangerous (like `use function umask;`).
> This gives me also a good overview of how much of the global symbols are
> still in my system, and to be replaced with something like
> `thecodingmachine/safe`.
>

Agreed. I want to force explicit qualifications, and raise error on
unqualified names:



Re: [PHP-DEV] How to debug a segmentation fault?

2020-01-29 Thread Bishop Bettini
On Tue, Jan 28, 2020 at 11:28 AM Benjamin Morel 
wrote:

> I'm encountering a SIGSEGV in PHP-FPM on PHP 7.4.2 in a Symfony app. The
> bug seems to happen during the rendering of a Twig template; this makes it
> hard for me to pinpoint the code that triggers the segfault.
>
> Could you please tell me what the procedure to collect information is, so
> that I can file a useful bug report?
>

Great advice so far. I would add, since you're using PHP-FPM, that the pool
configuration needs to have:

process.dumpable = 1

to get core dumps out of workers. Without this you might not get core
dumps, even when you have other core dump settings configured (ulimit -c
unlimited, chmod +r phpfpm, etc.).


Re: [PHP-DEV] Add viable long running execution model to php 8

2020-01-29 Thread Peter Bowyer
On Tue, 28 Jan 2020 at 17:12, Rowan Tommins  wrote:

> I'd just like to point out that those two things are orthogonal: the fact
> that Swoole is distributed as an extension is not the reason it's
> incompatible with your existing code, and building a similar implementation
> into PHP under a different name wouldn't make the migration any easier.
>

You're absolutely right. The difference I'm thinking is that if there is
built-in support in the language, frameworks will embrace it. At the moment
I'd need to make my own fork to add compatibility with Swoole et al (or use
one of the experimental but unsupported forks out there), which isn't
attractive.

Peter


RE: [PHP-DEV] Operator overloading for userspace objects

2020-01-29 Thread jan.h.boehmer
> I would recommend not handling overloading of comparisons in the same 
> proposal. Comparison is more widely useful than other overloading and has a 
> more complex design space (especially when it comes to accommodating objects 
> that can only be compared for equality/inequality for example). Comparison 
> may also benefit more from having an interface than the other operators.

I understand your point. There was already an RFC with an similar idea 
(https://wiki.php.net/rfc/comparable). I think the idea of having an comparable 
interface could be really useful for things like sorting algorithms (so these 
could sort any comparable object). The case that structures must not define an 
order (but can have equality) is a good point, maybe this could be solved with 
two interfaces Comparable (which defines the spaceship operator) and another 
one like Matchable or Equalable (which only defines an is_equal function). I 
would not split the comparison operators any further (the RFC mentioned above 
even suggested to overload the not equal operator) or we end up with 
situations, where $a!=$b is not the same as !($a==$b), which would make the 
code using it very difficult to understand.

It is maybe reasonable to split operator and comparison overloading into 
different RFCs so they can be discussed separately. But if PHP decides to offer 
operation overloading it should also offer a possibility to compare custom 
objects, or the operation overloading looses some of its intended convenience 
(like the situation in PHP 7.0 where you could define scalar type hints, but 
could not allow passing null easily).

> Of course there are performance concerns here, and it could in some cases be 
> significantly more efficient to perform an in-place modification. It is 
> possible to allow that while still keeping the above semantics by only 
> allowing an in-place modification if $a has no over users (something that we 
> can check in the VM). But I don't think this should be part of an initial 
> proposal.

I agree. If there is real need for this case, it could be implemented later.

> Unfortunately, this implementation goes in the wrong direction: PHP already 
> has full internal support for operator overloading through the do_operation 
> object handler. Operator overloading should be exposed to userland through 
> that handler as well.

I have seen this mechanism too late, and I have to understand a bit more how it 
works exactly, but I agree that this internal operator overloading mechanism 
should be used. I think it should be the goal that internal and userspace 
classes should appear the same to the user in points of the operator 
overloading, so an user can just call for example parent::__add() if he is 
extending a PHP class (e.g. Carbon does that for the datetime class). I will 
try to build an implementation using the do_operation handler, when I have time.

> Thanks for working on this :) I think overloaded operators are a reasonable 
> addition to the language at this point. I think the main concern people tend 
> to have in this area is that operator overloading is going to be abused (see 
> for example << in C++). There are many very good use-cases for operator 
> overloading though (as mentioned, vector/matrix calculations, complex, 
> rationals, money, ...) Some of those are not common in PHP, but maybe the 
> lack of operator overloading is part of the problem there ;)

Ultimately we cannot really control how people will end up using the operation 
overloading, but in my opinion the benefits outweighs the drawbacks (also 
hopefully nobody would be insane enough to replace the print function with << 
;) ).
With FFI-bindings it would be possible to build cool math/calculation libraries 
(similar to numpy in python), that can be accessed easily via PHP and does big 
calculations in native speed. I don’t think PHP will become an scientific used 
language like python, but sometimes some higher math function in PHP could be 
helpful. Also at least the handling of money values is quite common in web 
applications.

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



Re: [PHP-DEV] Operator overloading for userspace objects

2020-01-29 Thread Olumide Samson
Would there be an RFC to push this feature(with the right handler, POC)
into PHP?

Or something would stop it from happening?



On Wed, 29 Jan 2020, 10:20 am Nikita Popov,  wrote:

> On Wed, Jan 29, 2020 at 12:14 AM  wrote:
>
> > Hello everybody,
> >
> >
> >
> > the last days I have experimented a bit with operator overloading in
> > userspace classes (redefing the meaning of arithmetic operations like +,
> -,
> > *, etc. for your own classes).
> >
> > This could be useful for different libraries which implements custom
> > arithmetic objects (like money values, tensors, etc.) or things like
> > Symfony
> > string component (concatenate) operator, because it improves readability
> > much:
> >
> > $x * ($a + $b) instead of $x->multiply($a->add($b))
> >
> >
> >
> > 4 years ago, there was a RFC about this topic (
> > 
> > https://wiki.php.net/rfc/operator-overloading), which was discussed a
> bit
> > (
> >  https://externals.io/message/89967
> ),
> > but there was no real Outcome.
> >
> >
> >
> > I have tried to implement a proof of concept of the RFC, I encountered
> some
> > problems, when implementing the operator functions as (non-static) class
> > members and pass them only the “other” argument: What happens when we
> > encounter an expression like 2/$a and how can the class differ this from
> > $a/2. Also not every operation on every structure is e.g on commutative
> > (e.g. for matrices A*B =/= B*A). So I tried a C#-like approach, where the
> > operator implementations are static functions in the class, and both
> > arguments are passed. In my PHP implementation this would look something
> > like this:
> >
> >
> >
> > Class X {
> >
> > public static function __add($lhs, $rhs) {
> >
> > //...
> >
> >}
> >
> > }
> >
> >
> >
> > The class function can so decide what to do, based on both operands (so
> it
> > can decide if the developer wrote 2/$a or $a/2). Also that way an
> > implementor can not return $this by accident, which could lead to
> > unintended
> > side effect, if the result of the operation is somehow mutated.
> >
>
> Using static methods sounds reasonable to me.
>
> I have taken over the idea of defining a magic function for each operation
> > (like Python does), because I think that way it is the clearest way to
> see,
> > what operators a class implements (could be useful for static analysis).
> > The
> > downside to this approach is that this increases the number of magic
> > functions highly (my PoC-code defines 13 additional magic functions, and
> > the
> > unary operators are missing yet), so some people in the original
> discussion
> > suggest to define a single (magic) function, where the operator is
> passed,
> > and the user code decides, what to do. Advantageous is very extensible
> > (with
> > the right parser implementation, you could even define your own new
> > operators), with the cost that this method will become very complex for
> > data
> > structures which use multiple operators (large if-else or switch
> > constructions, which delegate the logic to the appropriate functions). An
> > other idea mentioned was to extract interfaces with common functionality
> > (like Arithmetically, Comparable, etc.) like done with the ArrayAccess or
> > Countable interfaces. The problem that I see here, is that this approach
> is
> > rather unflexible and it would be difficult to extract really universal
> > interfaces (e.g. vectors does not need a division (/) operation, but the
> > concatenation . could be really useful for implementing dot product).
> This
> > would lead to either that only parts of the interfaces are implemented
> (and
> > the other just throw exceptions) or that the interfaces contain only one
> or
> > two functions (so we would have many interfaces instead of magic
> functions
> > in the end).
> >
>
> Yes, i don't think it makes sense to group these operations in interfaces,
> the use-cases are just too diverse. It's possible to define one interface
> per operator (e.g. what Rust does), though I don't think this is going to
> be particularly useful in PHP. I would not want to see functions accepting
> int|float|(Add&Mul) show up, because someone is trying to be overly generic
> in their interfaces ;)
>
> As to whether it should be a single method or multiple, I would go for
> multiple methods, as that makes it more clear which operators are
> overloaded from an API perspective.
>
> On the topic which operators should be overloadable: My PoC-implementation
> > has magic functions for the arithmetic operators (+, -, *, /, %, **),
> > string
> > concatenation (.), and bit operations (>>, <<, &, |, ^). Comparison and
> > equality checks are implement using a common __compare() function, which
> > acts like an overload of the spaceship operator. Based if -1, 0 or +1 is
> > returned by the  comparison operators (<, >, <=, >=, ==) are evaluated. I
> > think this way w

Re: [PHP-DEV] How to debug a segmentation fault?

2020-01-29 Thread Nikita Popov
On Tue, Jan 28, 2020 at 5:29 PM Benjamin Morel 
wrote:

> Hi internals,
>
> I'm encountering a SIGSEGV in PHP-FPM on PHP 7.4.2 in a Symfony app. The
> bug seems to happen during the rendering of a Twig template; this makes it
> hard for me to pinpoint the code that triggers the segfault.
>
> Could you please tell me what the procedure to collect information is, so
> that I can file a useful bug report?
>

As the first step, I would always suggest to reproduce this issue with the
CLI binary (this includes the builtin server under -S localhost:8000 -t
public). That way you don't have to deal with multi-process FPM.

Once that is done, the easiest way to get some useful debugging information
is to run PHP under valgrind, this is done using "USE_ZEND_ALLOC=0 valgrind
php ...".

Nikita


Re: [PHP-DEV] [VOTE] declare(function_and_const_lookup='global')

2020-01-29 Thread Marco Pivetta
Hey Tyson,

I voted "No" on this one, sorry.

TL;DR: I'd rather have a mechanism to disable global function fallback, not
something that makes un-imported symbols immediately global.

The idea to disable PHP's implicit
"fallback-to-something-that-may-or-may-not-exist" is great, and it could
simplify some of the engine, as well as remove some caching mechanisms
(lookup) in some contexts, but I'm pretty happy with disabling all global
lookup functionality, rather than making them the default.

I don't have a problem with `use function sprintf;` to import things from
PHP, and actually use it to quickly grep whenever I do something extremely
dangerous (like `use function umask;`).
This gives me also a good overview of how much of the global symbols are
still in my system, and to be replaced with something like
`thecodingmachine/safe`.

I also deal with merge conflicts regularly: not a big issue either.

Greets,

Marco Pivetta

http://twitter.com/Ocramius

http://ocramius.github.com/


On Wed, Jan 29, 2020 at 3:22 AM tyson andre 
wrote:

> Hi internals,
>
> I've opened the vote on https://wiki.php.net/rfc/use_global_elements
> after weighing the pros and cons of discussed alternative approaches.
> Yesterday, I've finished the last set of updates I announced I would do
> based on RFC feedback.
>
> (that update was to require the statement 'use function ...'/'use const
> ...' before declaring that function/const
> outside the global namespace,
> if declare(function_and_const_lookup='global') is opted into)
>
> Voting closes on 2020-02-11.
>
> Thanks,
> - Tyson
> --
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: http://www.php.net/unsub.php
>
>


Re: [PHP-DEV] [VOTE] declare(function_and_const_lookup='global')

2020-01-29 Thread Claude Pache


> Le 29 janv. 2020 à 09:55, Bishop Bettini  a écrit :
> 
> Suppose I'm presented with this diff (and only this diff):
> 
> $a = array_diff($x, $y);
> + if (count($a)) die('Unexpected differences');
> 

Realistically, when I see that diff, I assume that those functions are the 
well-known global ones. The eventual presence 
`declare(function_and_const_lookup='global')` directive would make my 
assumption provable, which is an improvement. In the rare cases where that my 
assumption is false, an explicit `use function MyNs\{array_diff, count}` is 
welcome (and is already possible) in order to make my assumption refutable 
without needing to look for improbable redefinition of those functions in other 
files; such an explicit declaration would be mandatory in presence 
`declare(function_and_const_lookup='global')`, which is an improvement.

—Claude

[PHP-DEV] Re: [VOTE] declare(function_and_const_lookup='global')

2020-01-29 Thread Mark Randall

On Tue, Jan 28, 2020 at 8:22 PM tyson andre  wrote:

I've opened the vote on https://wiki.php.net/rfc/use_global_elements


I too would like to thank you for the effort put in, but I find myself 
in agreement with several of the other posters that I'm not sure this is 
the right way to go about it.


I'm not a fan of the disparity between classes and functions that this 
would introduce if used. Support for namespaced level functions is 
already quite poor (with lack of autoloading) and rather than try to 
gain a few bytes here and there, I think the better long-term option 
would be to simply remove support for them entirely in favour of static 
methods, and at that point the door is open to make functions and 
constants be global-only.


--
Mark Randall

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



Re: [PHP-DEV] [RFC] "use global functions/consts" statement

2020-01-29 Thread Rowan Tommins
On Wed, 29 Jan 2020 at 01:23, tyson andre  wrote:

> If a future language change changed the *default* resolution rules for
> functions or constants,
> I'd rather have future maintainers make the decision on whether to add a
> 'fallback' to make migration
> than on whether to remove the 'fallback' if it didn't make sense to
> support it.
>
> We have different values and expectations on what's likely to happen in
> the future of the language.
>



I think it's more that we have different understandings of what exists in
the language *right now*.

In my mind, strict_types has two modes, called 0 and 1; both have fully
documented behaviour, and changing either one of them would be a breaking
change. At the top of a file, I can specify which of those two modes I want
the code to run in. As a convenience, if I don't specify, the code will run
in mode 0 - but that doesn't have any implications for what mode 0 means.


Similarly, if this RFC is merged, we will have two algorithms for resolving
a function name in a namespace; let's call them mode A and mode B.

* Mode A is "namespace first, fallback to global". It was first defined in
PHP 5.3, and as far as I know hasn't changed since. We don't have to be
speculate on how that mode works, we've been writing code in that mode for
10+ years.
* Mode B is "global only", and is new in this RFC.

In the same way I can specify the strict_types mode, I want to be able to
specify at the top of a file whether it should run in mode A or mode B. If
I don't specify, it makes sense to assume mode A, but that's just a
convenience; it could theoretically give an error telling me to confirm
which mode I want.

Of course things might change in future:

* Someone might add mode C, in which case I can select that for files where
I want to use it.
* The default mode might change from A to C. All my existing code is
written to use mode A, so I want to make sure it continues to run in mode A
until I've updated it.
* We might deprecate and remove mode A, in which case I'll get log messages
for the files where I've specified mode A, telling me to change my code to
run in mode B or C.

In all of those scenarios, it's an advantage to be able to declare mode A.
In none of those scenarios do I get any advantage by specifying "use
default mode".




> > Can you provide an example of when you'd want to use 'default' instead of
> > specifying the mode you've written the file to run in?
>
> The use cases are similar to the reasons why I'd want to use
> strict_types=0.
> strict_types=0 is rare in practice.
>
> 1. Explicitly writing in code that you have chosen on a setting for the
> file
>and decided not to use 'global'.
> 2. Overriding the namespace default if
> https://wiki.php.net/rfc/namespace_scoped_declares
>gets accepted.
>



The reason I asked for specific examples is because every single scenario
I've thought of so far, whether it's future changes to the language or
namespace-scoped declares, would work better with an explicit mode setting,
not a 'default' option.

For instance, over-riding the namespace default sounds like a plausible use
for 'default', but in practice, you wouldn't care which mode was the
default for PHP; you would know that this particular file will only run
correctly in mode A. So you would specify mode A at the top of the file,
not 'default'.

I have genuinely tried to come up with a situation where 'default' would be
useful, and I have failed.



Regards,
-- 
Rowan Tommins
[IMSoP]


Re: [PHP-DEV] [VOTE] declare(function_and_const_lookup='global')

2020-01-29 Thread Lynn
On Wed, Jan 29, 2020 at 9:55 AM Bishop Bettini  wrote:

> Notwithstanding the excellent work done in the PR, I lean toward a No vote.
>
> Suppose I'm presented with this diff (and only this diff):
>
> $a = array_diff($x, $y);
> + if (count($a)) die('Unexpected differences');
>
> Where does count come from? I can't tell from this diff. It could be local
> to this namespace, or it could be global. In the current implementation, I
> have to scroll to the top of the file, check for what namespace I am in,
> and what use are made. In the proposed implementation, I have also to check
> the top of the file, but now its for
> "declare(function_and_cost_lookup='global')" and the presence (or not) of
> "use function count".
>
> It's not clear to me this is an improvement over status quo.
>
> [...]
>
> What do you think?
>

Hi,

I think that when we're at a point where developers start using existing
core function names for custom functions and they start 'overriding'
things, you already have this problem, regardless of this RFC. You already
have to check whether or not the function was defined via a `use` statement
on top. I don't think your example of the diff would have a difference
between `use` and `declare` when it comes to reviewing.

I would advice developers to avoid using core function names in namespaces
for custom functions, as doing this would open up a whole different can of
worms when it comes to developer experience.

Regards,
Lynn


Re: [PHP-DEV] Operator overloading for userspace objects

2020-01-29 Thread Nikita Popov
On Wed, Jan 29, 2020 at 12:14 AM  wrote:

> Hello everybody,
>
>
>
> the last days I have experimented a bit with operator overloading in
> userspace classes (redefing the meaning of arithmetic operations like +, -,
> *, etc. for your own classes).
>
> This could be useful for different libraries which implements custom
> arithmetic objects (like money values, tensors, etc.) or things like
> Symfony
> string component (concatenate) operator, because it improves readability
> much:
>
> $x * ($a + $b) instead of $x->multiply($a->add($b))
>
>
>
> 4 years ago, there was a RFC about this topic (
> 
> https://wiki.php.net/rfc/operator-overloading), which was discussed a bit
> (
>  https://externals.io/message/89967),
> but there was no real Outcome.
>
>
>
> I have tried to implement a proof of concept of the RFC, I encountered some
> problems, when implementing the operator functions as (non-static) class
> members and pass them only the “other” argument: What happens when we
> encounter an expression like 2/$a and how can the class differ this from
> $a/2. Also not every operation on every structure is e.g on commutative
> (e.g. for matrices A*B =/= B*A). So I tried a C#-like approach, where the
> operator implementations are static functions in the class, and both
> arguments are passed. In my PHP implementation this would look something
> like this:
>
>
>
> Class X {
>
> public static function __add($lhs, $rhs) {
>
> //...
>
>}
>
> }
>
>
>
> The class function can so decide what to do, based on both operands (so it
> can decide if the developer wrote 2/$a or $a/2). Also that way an
> implementor can not return $this by accident, which could lead to
> unintended
> side effect, if the result of the operation is somehow mutated.
>

Using static methods sounds reasonable to me.

I have taken over the idea of defining a magic function for each operation
> (like Python does), because I think that way it is the clearest way to see,
> what operators a class implements (could be useful for static analysis).
> The
> downside to this approach is that this increases the number of magic
> functions highly (my PoC-code defines 13 additional magic functions, and
> the
> unary operators are missing yet), so some people in the original discussion
> suggest to define a single (magic) function, where the operator is passed,
> and the user code decides, what to do. Advantageous is very extensible
> (with
> the right parser implementation, you could even define your own new
> operators), with the cost that this method will become very complex for
> data
> structures which use multiple operators (large if-else or switch
> constructions, which delegate the logic to the appropriate functions). An
> other idea mentioned was to extract interfaces with common functionality
> (like Arithmetically, Comparable, etc.) like done with the ArrayAccess or
> Countable interfaces. The problem that I see here, is that this approach is
> rather unflexible and it would be difficult to extract really universal
> interfaces (e.g. vectors does not need a division (/) operation, but the
> concatenation . could be really useful for implementing dot product). This
> would lead to either that only parts of the interfaces are implemented (and
> the other just throw exceptions) or that the interfaces contain only one or
> two functions (so we would have many interfaces instead of magic functions
> in the end).
>

Yes, i don't think it makes sense to group these operations in interfaces,
the use-cases are just too diverse. It's possible to define one interface
per operator (e.g. what Rust does), though I don't think this is going to
be particularly useful in PHP. I would not want to see functions accepting
int|float|(Add&Mul) show up, because someone is trying to be overly generic
in their interfaces ;)

As to whether it should be a single method or multiple, I would go for
multiple methods, as that makes it more clear which operators are
overloaded from an API perspective.

On the topic which operators should be overloadable: My PoC-implementation
> has magic functions for the arithmetic operators (+, -, *, /, %, **),
> string
> concatenation (.), and bit operations (>>, <<, &, |, ^). Comparison and
> equality checks are implement using a common __compare() function, which
> acts like an overload of the spaceship operator. Based if -1, 0 or +1 is
> returned by the  comparison operators (<, >, <=, >=, ==) are evaluated. I
> think this way we can enforce, that the assumed standard logic (e.g
> !($a<$b)=($a>=$b) and ($a<$b)=($b>$a)) of comparison is implemented. Also I
> don’t think this would restrict real world applications much (if you have
> an
> example, where a separate definition of < and >= could be useful, please
> comment it).
>

I would recommend not handling overloading of comparisons in the same
proposal. Comparison is more widely useful than

Re: [PHP-DEV] [VOTE] declare(function_and_const_lookup='global')

2020-01-29 Thread Bishop Bettini
On Tue, Jan 28, 2020 at 9:22 PM tyson andre 
wrote:

>
> I've opened the vote on https://wiki.php.net/rfc/use_global_elements
> after weighing the pros and cons of discussed alternative approaches.
> Yesterday, I've finished the last set of updates I announced I would do
> based on RFC feedback.
>
> (that update was to require the statement 'use function ...'/'use const
> ...' before declaring that function/const
> outside the global namespace,
> if declare(function_and_const_lookup='global') is opted into)
>
> Voting closes on 2020-02-11.
>

Notwithstanding the excellent work done in the PR, I lean toward a No vote.

Suppose I'm presented with this diff (and only this diff):

$a = array_diff($x, $y);
+ if (count($a)) die('Unexpected differences');

Where does count come from? I can't tell from this diff. It could be local
to this namespace, or it could be global. In the current implementation, I
have to scroll to the top of the file, check for what namespace I am in,
and what use are made. In the proposed implementation, I have also to check
the top of the file, but now its for
"declare(function_and_cost_lookup='global')" and the presence (or not) of
"use function count".

It's not clear to me this is an improvement over status quo.

Indeed, I worry that implementing the proposal may increase overall
cognitive burden for PHP developers.  Today, any developer can look at any
file or snippet in any code base, anywhere in the world, and know that
using an unqualified name follows a single, language-defined algorithm.
Were this proposal accepted, developers no longer have that guarantee. The
code might be using the original algorithm, or it might be using the new
algorithm. The only way to know is to check for and remember the state
based on the presence of -- and value of -- this new declaration.

Resolving ambiguities has a compute cost and a cognitive cost. While the
proposal improves the compute cost, I'm not sure the same can be said of
the cognitive cost. So I am leaning toward a No vote.

What do you think?