Re: [PHP-DEV] Bringing Peace to the Galaxy

2019-08-30 Thread Andreas Hennings
On Fri, 30 Aug 2019 at 19:38, Chase Peeler  wrote:
> On Fri, Aug 30, 2019 at 12:39 PM Andreas Hennings 
> wrote:
> > The only way to make this possible is to either deny all progress, or
> > to make a distinction on file level (or "package level", whatever that
> > means).
> > So, opt-in BC breaks.
> >
> That's not true at all. There are a ton of things that have been discussed
> that will progress the language and don't require any sort of BC break.
> Union types is one example. Support for Enums is another.
>
> Even if a BC break is required, it's not automatically a bad thing. Whether
> we are looking at plugging up a big security hole, getting rid of/modifying
> a rarely used feature, adding support for something that it's currently
> impossible to do, or just doing something that adds tremendous value to the
> language. In all of those cases the impact of the BC break should be
> weighed against the benefits.

The problem and trade-offs I am describing are already impacting me today.
I am working on a Drupal 7 site with lots of legacy code, and I am
developing Drupal 7 contrib modules that I want to be available to a
large audience.

In one of these modules I initially used the ?? null coalesce operator.
Then I had to replace all of the instances of ?? with the more verbose
old-school code, to make it compatible with older PHP, because there
are still enough Drupal 7 installations out there which have not
upgraded to PHP 7 yet.
I also had issues with old 3rd party libraries, which stood in the way
of PHP version upgrade.

In a world with "editions" per file or per package, such projects
could more easily use the newest PHP version, while the old libraries
would continue working.

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



Re: [PHP-DEV] Bringing Peace to the Galaxy

2019-08-30 Thread Andreas Hennings
I would very much like to see "editions" or "generations".

> I do plan to create an RFC on this topic.

I am looking forward to this Proposal from Nikita.

So, at the risk of repeating some ideas that Nikita already mentioned
elsewhere, I am sharing my own thoughts..


## Motivation

In this mailing list, it often comes across as if BC support vs
"modernizing" the language is a matter of personal preference.
The reality is: After a given time, a complex PHP project (whether it
be a website or something else) will be a collection of old and new,
custom and 3rd party code.

The same applies to framework ecosystems, or the entire ecosystem of
3rd party libraries (in composer/packagist and elsewhere).

As a (website) project developer:
- I want to use the newest tricks of the language, and have the
strictest warnings possible, in new custom code.
- I want to pick from a wide variety of (old and new) 3rd party libraries.
- I don't want to be forced to update or replace legacy 3rd party
libraries, that might have been added before I even joined the
project, and I have no idea what they do.
- I don't want to be forced to fix old legacy custom code, of which I
don't know what it does. Or rather, I want to choose when to do this
based on the project life cycle.
- After phases of active development, I want to be able to put the
site in a mode where it "just works", until the client wants a major
revamp.
- I want the project to run on different local and server
environments, possibly sharing the space with other projects.

As a library/packge developer:
- I want to use the newest tricks of the language, and have the
strictest warnings possible, in new code.
- I want my library to be compatible with a wide audience with
different PHP versions. Existing projects should have the option to
include my library without throwing away or revamping all their old
stuff.
- If developing within a framework ecosystem (e.g. Drupal), I want my
library to be compatible with other packages in the same ecosystem,
and the PHP version(s) most commonly used within that ecosystem.
- After a phase of active development on (a major version of) the
package, I want the package (or that major version) to turn into a
low-maintenance mode, and focus either on the new major version, or on
other things in life. People should be able to use the aging package
without major disruption.

As a PHP language designer (which I cannot claim to be, but doing it anyway):
- I want modern PHP to be a "competitive" language.
- At the same time I want PHP to maintain the reputation of being a
stable and reliable platform for existing projects.
- I want a continuous, incremental evolution of the language, with one
change at a time, to allow for sufficient discussion and not lose the
community.
- I want to allow for future changes which I cannot even dream of today.

So I constantly want to "have my cake and eat it, too".
Not based on personal preference, but on real-world requirements.


## Proposal / Idea

The only way to make this possible is to either deny all progress, or
to make a distinction on file level (or "package level", whatever that
means).
So, opt-in BC breaks.

To me the "file level" seems most realistic.
If someone can make a convincing point of what "package level" would
mean technically, why not.
I just think that "package" is not a clearly defined term, and often
all you have is a file (e.g. with symlink, or when downloading a file
from some place).
And sometimes you might want different versions / generations in the
same package.

This would mean:
- A PHP file can specifiy the "generation" or "edition" or simply the
version of PHP that it claims to be compatible with. One (perhaps
silly) idea would be to have an alternative open tag like " wrote:
>
> On Thu, Aug 8, 2019 at 11:02 PM Nikita Popov  wrote:
>
> > On Thu, Aug 8, 2019 at 10:17 PM Zeev Suraski  wrote:
> >
> >> [... and not in the Sith Lord kind of way.]
> >>
> >> Looking at some of the recent (& not so recent) discussions on internals@
> >> ,
> >> some of the recent proposals, as well as some of the statements made
> >> regarding the future direction of the language - makes it fairly clear
> >> that
> >> we have a growing sense of polarization.
> >>
> >> As Peter put it yesterday (I may be paraphrasing a bit) - some folks just
> >> want to clear some legacy stuff.  I think that in practice it goes well
> >> beyond that - many on internals@ see parts of PHP as in bad need of
> >> repair
> >> (scoop: I agree with some of that), while other capabilities, that exist
> >> in
> >> other competing languages - are - in their opinion - sorely missing.
> >>
> >> At the other end of the spectrum, we have folks who think that we should
> >> retain the strong bias for downwards compatibility we always had, that PHP
> >> isn't in dire need of an overhauling repair and that as far as features go
> >> - less is more - and we don't have to race to replicate features from
> >> other
> >> languages - 

Re: [PHP-DEV] RFC: var_export - short syntax for array

2019-08-21 Thread Andreas Hennings
Avoiding disruption is indeed a concern.
As an example, Drupal 7 features module uses a custom variation of
var_export() to write configuration to code, which is then typically
tracked in git.

I am not sure if changing the native var_export() would have an impact
here, and anyway the module can be updated if necessary, to guarantee
stability of the output.

What I would ask is to limit the frequency of change in this function, or
make it opt-in.

There are other issues with the format besides just the long array syntax.
E.g. opening bracket on same line? Indentation?
https://3v4l.org/MFLgd

Ideally all of this would be "normalized" in one go, based on popular
convention (psr-whichever), or it should be opt-in.

Alternatively there could be a new function or class, leaving var_export()
alone.

Влад Макин  schrieb am Mi., 21. Aug. 2019, 08:55:

> Thanks for the feedback!  I will back with improved version of RFC.
>
> вт, 20 авг. 2019 г., 23:01 Sara Golemon :
>
> > On Tue, Aug 20, 2019 at 1:05 PM Влад Макин  wrote:
> >
> >> I would like to propose a little change in var_export function behavior.
> >> For today, this function returns string representation of array in old
> >> style with “array” keyword:
> >>
> >> var_export([]); // array()
> >>
> >> I think it would be better if the function returned array representation
> >> in
> >> modern square brackets syntax:
> >>
> >> var_export([]); // []
> >>
> >> I do like the idea of doing this, and would even be generally okay with
> > just making always work that way since the introduction of square bracket
> > syntax is really *quite* old.
> >
> > The only people I could see being bothered by the change in output would
> > be automated code-generation suddenly seeing a (potentially quite
> massive)
> > diff as the bracket style changes.  As an example,
> > https://github.com/php/web-php/blob/master/include/releases.inc is a 10k
> > line var_export() generated list.  I'm actually /not/ bothered by the
> idea
> > of having a big point-in-time flip of that structure, though I'd want to
> > make sure all RMs switch versions at the same time, otherwise it could
> get
> > noisy.
> >
> > Perhaps an option to quell any dissent might be to add a third param
> > $options to allow controlling this behavior.
> >
> > function var_export(mixed $data, bool $return = false, int $options = 0):
> > string {}
> >
> > And you could either pass EXPORT_SHORT_ARRAY or EXPORT_LONG_ARRAY or
> > whatever you want to call the constants depending on which behavior you'd
> > make default (and honestly, I think we'd make the existing format
> default).
> >
> > -Sara
> >
>


Re: [PHP-DEV] [VOTE] Strict operators directive

2019-07-09 Thread Andreas Heigl


Am 09.07.19 um 12:06 schrieb Christian Schneider:
> Am 09.07.2019 um 11:30 schrieb Marco Pivetta :
>> I wasn't sure about the full implications of this, but after some thought,
>> the worst that can happen is excessive strictness, requiring to drop a
>> single declaration on top of a file 
> 
> When you drop the declaration on top of the file the semantics of your 
> operators suddenly change, e.g.
>   "42" < "7"
> changes from true to false and you get subtle bugs.
> 
> And if you try to read other people's code (or even try to copy/paste it) 
> then make sure you keep in mind which mode they are programming in.

But that's the same for `declare(strict_types=1);`

Cheers

Andreas
-- 
  ,,,
 (o o)
+-----ooO-(_)-Ooo-+
| Andreas Heigl   |
| mailto:andr...@heigl.org  N 50°22'59.5" E 08°23'58" |
| http://andreas.heigl.org   http://hei.gl/wiFKy7 |
+-+
| http://hei.gl/root-ca   |
+-+



signature.asc
Description: OpenPGP digital signature


Re: [PHP-DEV] Re: Checkout phpdoc

2019-06-25 Thread Andreas Heigl
Am 25. Juni 2019 23:41:42 MESZ schrieb Benjamin Morel 
:
>By the way, is there any work in progress to migrate the PHP manual to
>Git?
>The docs <https://www.php.net/git.php>only say:
>
>The PHP manual is still currently hosted on SVN, although it will be
>> migrated to Git in the future.
>
>
>I'd love to be able to fix things in the PHP manual with a simple PR;
>the
>current process has always repelled me.
>
>Ben
>
>On Tue, 25 Jun 2019 at 11:10, Sascha Schumann <
>sascha.schum...@myrasecurity.com> wrote:
>
>> I have disabled SNI for the upstreams on svn2.php.net.
>>
>> If the problem persists, please provide a way to reproduce the issue.
>>
>> Thanks
>> Sascha

There is a small team of people currently working on moving the docs to git.

Due to the tight integration of SVN into the workflow it's not as easy as we 
all thought to do the actual move.

For more infos feel free to head over to https://github.com/phpdoctest/meta

Cheers

Andreas

-- 
  ,,,
         (o o)
+-ooO-(_)-Ooo-+
| Andreas Heigl   |
| mailto:andr...@heigl.org  N 50°22'59.5" E 08°23'58" |
| https://andreas.heigl.org https://bit.ly/wiFKy7 |
+-+

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



Re: [PHP-DEV] The real world ...

2019-06-13 Thread Andreas Heigl


Am 13.06.19 um 15:30 schrieb Sjon Hortensius:
> FWIW - hiding database passwords (when using PDO) would be possible when
> https://github.com/php/php-src/pull/2684 gets included

I was more thinking of a more general approach as PDO is not the only
place where passwords are transfered. So having a generic Password-VO
that could be used like a password-string for BC but would not show up
in stack-traces - or at least not the cleartext-password - might improve
the security aspect regardless of where the password will be used. Yes,
at one point the cleartext-password needs to be handed over to the VO
and before that it will appear in stack-traces.


I did a userland-implementation but it still requires to hand over the
cleartext-password to relevant functions in PHP and there the stacktrace
can again leak the password. So having such a functionality in the core
would improve things.

Cheers

Andreas
> 
> Cheers,
> Sjon
> 
> On Thu, Jun 13, 2019 at 9:56 AM Andreas Heigl  wrote:
> 
>> Hey All
>>
>> Am 13.06.19 um 09:41 schrieb Nikita Popov:
>>> On Thu, Jun 13, 2019 at 9:35 AM Lester Caine  wrote:
>>>
>>>> Seen in the wild ... company name sanitised
>>>>
>>>> Warning: mysqli::mysqli(): (HY000/2002): No such file or directory in
>>>> /home/888/public_html/system/library/db/mysqli.php on line 7
>>>>
>>>> Fatal error: Uncaught exception 'Exception' with message 'Error: >>> />Error No: ' in /home/888/public_html/system/library/db/mysqli.php:10
>>>> Stack trace: #0
>>>> /home/888/public_html/system/nitro/core/nitro_db.php(29):
>>>> DB\MySQLi->__construct('localhost', '888_4y65f5...',
>>>> 'J?vJr+j5iCju-bo...', '888_4y65f5...', '3306') #1
>>>> /home/888/public_html/system/nitro/core/nitro_db.php(13):
>>>> NitroDb->__construct('mysqli', 'localhost', '888_4y65f5...',
>>>> 'J?vJr+j5iCju-bo...', '888_4y65f5...', '3306') #2
>>>>
>> /home/888/public_html/system/storage/modification/system/library/db.php(11):
>>>>
>>>> NitroDb::getInstanceWithParams('mysqli', 'localhost', '888_4y65f5...',
>>>> 'J?vJr+j5iCju-bo...', '888_4y65f5...', '3306') #3
>>>> /home/888/public_html/system/framework.php(36):
>>>> DB->__construct('mysqli', 'localhost', '888_4y65f5...',
>>>> 'J?vJr+j5iCju-bo...', '888_4y65f5...', '3306') #4
>>>> /home/888/public_html/vqmod/vqcache/vq2-system_startup.php(124):
>>>> require_once('/home/888 in
>>>> /home/888/public_html/system/library/db/mysqli.php on line 10
>>>> 你的代码出错了:
>>>>
>>>> I presume something has been updated that they have not been aware of
>>>> since it's library file that triggered the warning ... but it's not the
>>>> first time in recent years I've seen this sort of information on
>>>> commercial sites and while my own clients just get white screens, those
>>>> are created by the likes of Wordpress when 'automatic updates' happen.
>>>>
>>>> Many years ago the response was "well don't update", but 'current
>>>> practice' takes that out of OUR hands! So isn't it time that the
>>>> triggering exceptions like this did produce a more user secure response
>>>> to protect against leaks like this and provide a better alternative than
>>>> a white screen?
>>>>
>>>> In the case of this live site, I actually placed an order as it was only
>>>> some links that triggered the fault, which may explain why they were not
>>>> even aware there was a problem :( From the 'development' side, NitroDb->
>>>> should obviously be handling the problem anyway.
>>>>
>>>
>>> display_errors=Off in production.
>>>
>>
>> While that makes absolute sense perhaps thinking whether there is a way
>> to mark password-parameters in core-functions and hide them in
>> Stack-traces might improve security as that would also hide
>> user-provided credentials in log-files.
>> That would not target userland methods/functions. Though having a
>> Core-Value-object for credentials might even allow *that*
>>
>> Just my 0.02 €
>>
>> Cheers
>>
>> Andreas
>> --
>>   ,,,
>>  (o o)
>> +-----ooO-(_)-Ooo-+
>> | Andreas Heigl   |
>> | mailto:andr...@heigl.org  N 50°22'59.5&qu

Re: [PHP-DEV] The real world ...

2019-06-13 Thread Andreas Heigl
Hey Lester, hey All

Am 13.06.19 um 10:36 schrieb Lester Caine:
> On 13/06/2019 08:55, Andreas Heigl wrote:
>>> display_errors=Off in production.
> 
> Which give a white screen ... fine for security but useless for people
> using the site!
> 
>> While that makes absolute sense perhaps thinking whether there is a way
>> to mark password-parameters in core-functions and hide them in
>> Stack-traces might improve security as that would also hide
>> user-provided credentials in log-files.
>> That would not target userland methods/functions. Though having a
>> Core-Value-object for credentials might even allow*that*
> 
> Sanitising things would be a nice to have especially where log files are
> on 'cloud' storage, but the ability to give an end user some indication
> that there is a problem WHILE display_errors=Off would be helpful? I
> know the white screen problem has been discussed many time over the
> years ...
> 
> Personally I STILL use display_errors=on and just make sure that
> sensitive information is not displayed in the stack. Most of the time it
> IS just the warnings one gets and clients can report them and see they
> are cleared ... so some sort of middle ground between off and on would
> be helpful?

If you're so keen on providing the user something to see without having
to use display_errors=on: Have you had a look at
https://php.net/register_shutdown_function ?

You can always use that to figure out whether there was a fatal error
and then display something nice to the user.

No leaked stacktrace, no leaked credentials, user is informed, everyone
is happy :-)

Cheers

Andreas
-- 
  ,,,
     (o o)
+-ooO-(_)-Ooo-+
| Andreas Heigl   |
| mailto:andr...@heigl.org  N 50°22'59.5" E 08°23'58" |
| http://andreas.heigl.org   http://hei.gl/wiFKy7 |
+-+
| http://hei.gl/root-ca   |
+-+



signature.asc
Description: OpenPGP digital signature


Re: [PHP-DEV] The real world ...

2019-06-13 Thread Andreas Heigl
Hey All

Am 13.06.19 um 09:41 schrieb Nikita Popov:
> On Thu, Jun 13, 2019 at 9:35 AM Lester Caine  wrote:
> 
>> Seen in the wild ... company name sanitised
>>
>> Warning: mysqli::mysqli(): (HY000/2002): No such file or directory in
>> /home/888/public_html/system/library/db/mysqli.php on line 7
>>
>> Fatal error: Uncaught exception 'Exception' with message 'Error: > />Error No: ' in /home/888/public_html/system/library/db/mysqli.php:10
>> Stack trace: #0
>> /home/888/public_html/system/nitro/core/nitro_db.php(29):
>> DB\MySQLi->__construct('localhost', '888_4y65f5...',
>> 'J?vJr+j5iCju-bo...', '888_4y65f5...', '3306') #1
>> /home/888/public_html/system/nitro/core/nitro_db.php(13):
>> NitroDb->__construct('mysqli', 'localhost', '888_4y65f5...',
>> 'J?vJr+j5iCju-bo...', '888_4y65f5...', '3306') #2
>> /home/888/public_html/system/storage/modification/system/library/db.php(11):
>>
>> NitroDb::getInstanceWithParams('mysqli', 'localhost', '888_4y65f5...',
>> 'J?vJr+j5iCju-bo...', '888_4y65f5...', '3306') #3
>> /home/888/public_html/system/framework.php(36):
>> DB->__construct('mysqli', 'localhost', '888_4y65f5...',
>> 'J?vJr+j5iCju-bo...', '888_4y65f5...', '3306') #4
>> /home/888/public_html/vqmod/vqcache/vq2-system_startup.php(124):
>> require_once('/home/888 in
>> /home/888/public_html/system/library/db/mysqli.php on line 10
>> 你的代码出错了:
>>
>> I presume something has been updated that they have not been aware of
>> since it's library file that triggered the warning ... but it's not the
>> first time in recent years I've seen this sort of information on
>> commercial sites and while my own clients just get white screens, those
>> are created by the likes of Wordpress when 'automatic updates' happen.
>>
>> Many years ago the response was "well don't update", but 'current
>> practice' takes that out of OUR hands! So isn't it time that the
>> triggering exceptions like this did produce a more user secure response
>> to protect against leaks like this and provide a better alternative than
>> a white screen?
>>
>> In the case of this live site, I actually placed an order as it was only
>> some links that triggered the fault, which may explain why they were not
>> even aware there was a problem :( From the 'development' side, NitroDb->
>> should obviously be handling the problem anyway.
>>
> 
> display_errors=Off in production.
> 

While that makes absolute sense perhaps thinking whether there is a way
to mark password-parameters in core-functions and hide them in
Stack-traces might improve security as that would also hide
user-provided credentials in log-files.
That would not target userland methods/functions. Though having a
Core-Value-object for credentials might even allow *that*

Just my 0.02 €

Cheers

Andreas
-- 
  ,,,
 (o o)
+-ooO-(_)-Ooo-+
| Andreas Heigl   |
| mailto:andr...@heigl.org  N 50°22'59.5" E 08°23'58" |
| http://andreas.heigl.org   http://hei.gl/wiFKy7 |
+-+
| http://hei.gl/root-ca   |
+-+



signature.asc
Description: OpenPGP digital signature


Re: [PHP-DEV] Wiki display problem

2019-06-03 Thread Andreas Heigl
Am 03.06.19 um 17:07 schrieb Sascha Schumann:
> As there are other protocols beside http/https running on news.php.net 
> (NNTP), we unfortunately cannot switch the whole subdomain to the cdn.

How would you like to switch to the CDN? By DNS? Or we need to create a
separate DNS-Entry for NNTP (nntp.php.net). I'd need to check how much
reconfiguration that'd mean though... And that might mean that others
will need to change their endpoints from news.php.net to nntp.php.net.
IIRC externals.io f.e. uses NNTP to retrieve the messages

Cheers

Andreas

-- 
  ,,,
 (o o)
+-ooO-(_)-Ooo-+
| Andreas Heigl   |
| mailto:andr...@heigl.org  N 50°22'59.5" E 08°23'58" |
| http://andreas.heigl.org   http://hei.gl/wiFKy7 |
+-+
| http://hei.gl/root-ca   |
+-+



signature.asc
Description: OpenPGP digital signature


Re: [PHP-DEV] Wiki display problem

2019-06-03 Thread Andreas Heigl
Looks like the stylesheets are loaded from shared.php.net which still
seems to be on an old certificate. Therefore the styles are not loaded

Who can have a look into that?

Cheers

Andreas

Am 03.06.19 um 12:52 schrieb Joe Watkins:
> I think this may be related to the ssl issues from earlier today, may have
> been overlooked ?
> 
> Cheers
> Joe
> 

-- 
  ,,,
 (o o)
+-----ooO-(_)-Ooo-+
| Andreas Heigl   |
| mailto:andr...@heigl.org  N 50°22'59.5" E 08°23'58" |
| http://andreas.heigl.org   http://hei.gl/wiFKy7 |
+-+
| http://hei.gl/root-ca   |
+-+



signature.asc
Description: OpenPGP digital signature


Re: [PHP-DEV] Re: [RFC] Allow throwing exceptions from __toString()

2019-05-13 Thread Andreas Heigl
Hey Nikita, hey all

Am 13.05.19 um 16:05 schrieb Nikita Popov:
> On Tue, Apr 30, 2019 at 3:32 PM Nikita Popov  wrote:
> 
>> Hi internals,
>>
>> I've already brought up this topic on list a couple of weeks ago... I've
>> now updated the implementation based on feedback at the time, and turned
>> this into a proper RFC:
>>
>> https://wiki.php.net/rfc/tostring_exceptions
>>
>> Regards,
>> Nikita
>>
> 
> If there's no more comments here, I'd like to start voting on this RFC
> tomorrow.

As the change is technically a BC-break (as you state in the RFC) I
wondered why the target is PHP7.4 and not 8.

So far I didn't find a discussion on that but I might not have dug deep
enough. So if this has already been discussed then I'd really appreciate
a hint to the discussion.

Thanks

Andreas
-- 
  ,,,
 (o o)
+-ooO-(_)-Ooo-+
| Andreas Heigl   |
| mailto:andr...@heigl.org  N 50°22'59.5" E 08°23'58" |
| http://andreas.heigl.org   http://hei.gl/wiFKy7 |
+-+
| http://hei.gl/root-ca   |
+-+



signature.asc
Description: OpenPGP digital signature


Re: [PHP-DEV] RFC Process: more productive conversations

2019-03-25 Thread Andreas Heigl



> Am 25.03.2019 um 15:39 schrieb Peter Bowyer :
> 
>> On Mon, 25 Mar 2019 at 14:02, Dan Ackroyd  wrote:
>> 
>> I don't believe forcing people to explain their votes actually does that.
>> 
>> It does something quite similar, of forcing people to try to
>> articulate how the RFC needs to change for them to change their vote
>> from a no to a yes. At least that is how I have perceived the
>> intentions of people who have asked for 'no' voters to explain their
>> vote.
>> 
> 
> It also ties in with the view previously expressed that we should restrict
> voting rights because (my paraphrase) "too many people can vote for
> something they don't understand and won't have to maintain".
> 
> Asking people to say why they voted the way they did helps explore this:
> can people give a cogent reason for their vote?

Shall we then also expect people that vote "yes" to explain why they voted for 
the feature? To see whether they understood what they where voting on?

Then we should couple the vote to a comment in the wikinpage and without a 
comment there's no way to vote. 

That way all the information would be readily available in the RFC and no one 
would need to add comments after an RFC was voted upon. Because IMO that 
information as well as the process that lead to acceptance of the RFC are also 
important to afterwards make clear why that feature was implememted the way it 
was. So all RFCs and also all voters would be treated the same.

Just my 0.02€

Cheers

Andreas 


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



Re: [PHP-DEV] Old style constructors in PHP-8

2019-01-30 Thread Andreas Heigl


Am Mittwoch, den 30.01.2019, 09:30 -0600 schrieb Larry Garfield:
> On Wednesday, January 30, 2019 5:41:45 AM CST Nikita Popov wrote:
> > On Wed, Jan 30, 2019 at 12:11 PM Dmitry Stogov 
> > wrote:
> > > Hi,
> > > 
> > > 
> > > I've just noticed that Wordpress-4.1 on PHP master started
> > > silently
> > > produce different output.
> > > 
> > > The problem that PHP master started to ignore old-style
> > > constructors.
> > > 
> > > They were deprecated in PHP-7 and PHP produced the following
> > > warning
> > > 
> > > 
> > > Deprecated: Methods with the same name as their class will not be
> > > constructors in a future version of PHP; ... has a deprecated
> > > constructor
> > > 
> > > 
> > > PHP master doesn't produce any warnings and just constructs a
> > > class
> > > without constructor.
> > > 
> > > This silent behavior change may become a problem for porting
> > > legacy code
> > > to PHP-8,
> > > 
> > > May be, it makes sense to emit fatal error in case of old-style
> > > constructor.
> > > 
> > > 
> > > Thanks. Dmitry.
> > 
> > First of all, it is probably important to note that the RFC for
> > this (
> > https://wiki.php.net/rfc/remove_php4_constructors) explicitly
> > specifies
> > that in PHP 8 methods with the same name as the class are
> > interpreted as
> > ordinary methods and no warning or error is thrown. I've CC'd Levi
> > and
> > Andrea, who authored this RFC.
> > 
> > I think as an end goal, what the RFC specifies is preferable for a
> > number
> > of reasons:
> > 
> >  * You should be able to call your methods whatever you like. PHP
> > only
> > reserves the __ prefix for itself.
> >  * The behavior is consistent with classes inside namespaces, where
> > methods
> > with the same name as the class are treated as normal methods for a
> > long
> > time already.
> >  * The fact that a method has the same name as the class may be
> > completely
> > incidental if it comes from a trait (see
> > https://bugs.php.net/bug.php?id=77470). The trait does not control
> > in which
> > classes it may be used and which names those classes may have.
> 
> Every Drupal 7 or 8 site includes classes that have a method name the
> same as 
> the class name, on the assumption that it's safe to do for a normal
> method in 
> current PHP versions.  Making that suddenly a Fatal would be, er,
> bad. :-)
> 
> As others have noted, this is easily solved with static analysis
> tools.  
> There's been discussion of WP moving to a PHP 7-based version of PHP
> sometime 
> this year (no promises, but that's the scuttlebutt), which would let
> them 
> convert to __construct() universally and safely well before PHP 8
> becomes an 
> issue.

AFAIK WP requires PHP5 already as the minimum PHP-Version. And AFAIK
__construct worked with that as well. So there should be no need to
wait for PHP7 readiness in WordPress to tackle this issue. 

Replacing the function-name-as-class-name constructors with __construct
should be possible without a BC-break already. Even with PHP 5.0 as a
min-requirement.

Or am I missing something?

Cheers

Andreas
  ,,,
  
   (o o)
+
-ooO-(_)-Ooo-+
| Andreas
Heigl   |
| mailto:
andr...@heigl.org  N 50°22'59.5" E 08°23'58" |
| 
http://andreas.heigl.org   http://hei.gl/wiFKy7 |
+-
+
| 
http://hei.gl/root-ca   |
+-
+


signature.asc
Description: This is a digitally signed message part


Re: [PHP-DEV] bugs.php.net usability, migration to a different tool

2018-08-08 Thread Andreas Heigl
Hey Zach

> Am 08.08.2018 um 17:59 schrieb Hoffman, Zachary Robert :
> 
>> On Wed, 2018-08-08 at 16:14 +0200, Johannes Schlüter wrote:
>> On Di, 2018-08-07 at 15:10 -0500, Sara Golemon wrote:
>> On Tue, Aug 7, 2018 at 1:17 PM, Tymoteusz Motylewski
>>  wrote:
>> 
>> - the UI is terrible (not useful, confusing, misleading)
>> 
>> UI is harsh and a bit 90s in styling, but I have a hard time agreeing
>> with the rest of that statement.  What is confusing to you?
>> 
>> My biggest issue with the UI is the selection of category when
>> reporting/editing bugs. That lst is hge. Other than that I'm happy
>> it's no JavaScript overloaded thing, but simply works.
>> (room for improvement exits)
> 
> While we are talking about the "package affected" dropdown, one
> accessibility issue is that the package names are indented by category,
> which makes it impossible to autocomplete a package name using your
> keyboard.
> 
> The correct way to do this is to surround each category in an
>  tag, which distinguishes category names from package names.
> 
> --
> Zach Hoffman

Feel free to open a PR against https://github.com/php/web-bugs 

Thanks for helping out!

Cheers

Andreas

Re: [PHP-DEV] Re: [PATCH] Make var_export() output "(object)array(..." instead of"stdClass::__set_state(..." for stdClass

2018-07-07 Thread Andreas Hennings
I do not disagree, just want to make an observation.

If multiple properties or array keys reference the same instance of
\stdClass, there will be multiple instances with identical values after a
round-trip with var_export() + eval().
This is not necessarily a problem, just something to be aware of.

On Wed, 4 Jul 2018 at 22:33, Christoph M. Becker  wrote:

> On 14.03.2017 at 19:57, Andrea Faulds wrote:
>
> > Since stdClass has no __set_state method, var_export() produces unusable
> > output if given an object of that class. I wrote a patch that would make
> > var_export() produce a cast to object instead, which could be evaluated
> > to get back a stdClass:
> >
> > https://github.com/php/php-src/pull/2420
> >
> > Any thoughts/comments?
> >
> > If you're wondering about whether a __set_state method should be added
> > to stdClass, I posted some thoughts in the pull request discussion
> already.
>
> FTR: If nobody objects, I'll merge this PR into master on 2018-07-12, so
> that it goes into PHP 7.3.
>
> See .
>
> --
> Christoph M. Becker
>
> --
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: http://www.php.net/unsub.php
>
>


Re: [PHP-DEV] [PATCH] new function for real local date

2018-03-13 Thread Andreas Heigl
Hey Ruud.


Am 13.03.18 um 20:18 schrieb ruud.bak...@caiway.nl:
> As there is no function for getting a real local date for day names and month 
> names, I wrote a function for that. Maybe an option for a new PHP version?
> 
>  
> function localdate(string $format, int $timestamp, string $locale) {
> 
> $oldlocale = setlocale(LC_TIME, 0);
> setlocale(LC_TIME, $locale);
> 
> $date = '';
> for ($i = 0; $i < strlen($format); $i++) {
> 
> $char = substr($format, $i, 1);
> switch ($char) {
> case 'D':
> $date .= strftime('%a', $timestamp);
> break;
> case 'l':
> $date .= strftime('%A', $timestamp);
> break;
> case 'M':
> $date .= strftime('%b', $timestamp);
> break;
> case 'F':
> $date .= strftime('%B', $timestamp);
> break;
> default:
> $date .= date($char, $timestamp);
> break;
> }
> }
> 
> setlocale(LC_TIME, $oldlocale);
> 
> return $date;
> }

May I ask what you actually mean by "real local date for day names and
month names"?

Or is this something like this:



Cheers

Andreas

-- 
  ,,,
     (o o)
+-ooO-(_)-Ooo-+
| Andreas Heigl   |
| mailto:andr...@heigl.org  N 50°22'59.5" E 08°23'58" |
| http://andreas.heigl.org   http://hei.gl/wiFKy7 |
+-+
| http://hei.gl/root-ca   |
+-+


0x5BFCE472.asc
Description: application/pgp-keys


signature.asc
Description: OpenPGP digital signature


Re: [PHP-DEV] Traits with interfaces

2018-03-01 Thread Andreas Hennings
> don't use traits

Yes, in general, yes.
Composition is great, and I use it most of the time.
I still do have some cases where I think that base classes (with
private properties) are justified, and then some cases where either
traits or multiple inheritance would be justified.
We could agree to set this debate aside, and focus on the original
proposal, assuming it is for those people who have a good reason to
use traits.
But I have a feeling that this part of the discussion ("traits are
bad") isn't over. I will get back to it further below.


> due to the previous point, inheriting a type from a trait becomes a dangerous 
> BC boundary, easily broken by consumers of the trait when consumers alias or 
> when the trait implementor adds a new interface implementation

Yes.
On the other hand, many traits out there really try to comply with an
existing interface, and are meant as a replacement for additional base
classes.
The renaming is technically possible, but how often does it occur in reality?

So what about this modified proposal:
- A trait can "promise" to comply with an interface. We could use the
"implements" keyword for this, but maybe we should rather use
something else.
- Using the trait in a class does NOT automatically add that interface
to the class.

I personally don't have a strong desire for this functionality. But at
least this would circumvent the problems you pointed out.


In my personal experience, in all the cases where I did use traits, I
would have rather used multiple inheritance.
Or let's say: In many cases where I did use traits, or base classes, I
did later find a better solution with composition.

A good base class, for me, has
- private properties
- abstract protected methods
- possibly final public methods

In which cases would I use (single) base classes instead of composition?
- If composition would require awkward one-off interfaces.
- If the to-be-implemented methods have parameter constraints that
cannot be expressed in the signature.

E.g. a base class could implement a public method, do some sanity
checks and preparation on the parameters, then call the abstract
protected method with the processed parameters.

In which cases would I use multiple base classes instead of
composition or single base classes?
- If I want to provide an object with a rich verbose interface to a
consumer, possibly extending multiple smaller interfaces.
(- If I am implementing someone else's interface, which happens to
have more methods than I want to fit in one class.)

Base classes allow to implement partial functionality in isolated
(encapsulated) pockets of an object.
Often each of these pockets is nothing more than a decorator of the
partial interface, and the actual functionality happens in the
injected object.
I would prefer to implement those decorator pockets separately and
then extend them one by one. But this is not possible, because we
don't have multiple inheritance in PHP.

Traits are quite useless for this purpose. They encapsulate nothing.
Therefore I don't like them.

Sometimes if I started with the assumption that I want to provide a
rich one-object interface at least in some places in the architecture,
I later regret it, and split it up again.
But I do think that some cases are justified.






On 1 March 2018 at 01:34, Marco Pivetta  wrote:
> This cannot work for a number of reasons:
>
>  - a trait is not a type, and does not practically exist at runtime
>  - trait defined API can be imported with changed/aliased names, breaking
> therefore the contact defined in the interface
>  - due to the previous point, inheriting a type from a trait becomes a
> dangerous BC boundary, easily broken by consumers of the trait when
> consumers alias or when the trait implementor adds a new interface
> implementation
>
> My general suggestions:
>  - don't use traits
>  - don't use traits
>  - also, don't use traits
>  - remember to not use traits
>  - traits: don't
>  - things you shouldn't use on Betelgeuse and other systems: traits
>
> Besides jokes, inheriting signatures together with implementations
> (inheritance, abstract types) is less and less endorsed in the PHP
> ecosystem, as it just increases coupling by a huge lot. At least from my
> own experience, things are finally moving towards more composition over
> inheritance.
>
> On 28 Feb 2018 21:58, "David Rodrigues"  wrote:
>
>> Why traits doesn't supports interfaces (via implements) like classes does?
>>
>> It could be useful when trait implements part of abstract functions from
>> interface, then the class that uses this traits should implements the
>> another part.
>>
>> It could turn it possible (pseudo-code):
>>
>> interface VisibilityControlContract
>> - public function isVisible(): bool;
>>
>> trait VisibilityControlTrait implements VisibilityControlContract
>> - public function isVisible(): bool { ... }
>>
>> class UserModel (not need implements VisibilityControlContract directly)

Re: [PHP-DEV][RFC][DISCUSSION] Immutability

2018-02-26 Thread Andreas Hennings
Hello,
my thoughts.
For me personally the proposed feature would not be very useful.
i like immutable objects. But for me the pattern of choice is private
properties + constructor + optional "wither" methods.

The "wither" methods create a clone of the object, then set a property
value on the clone, then return the clone.
This would already not work if the property is marked as immutable
with the proposed feature.

Also static method constructors that write directly on the object
would not work, because technically they are not part of the
constructor.

For private properties the proposed feature would add little benefit.
Any private property can be made practically immutable by writing the
class accordingly: Not having setters, etc.

Where this feature would become useful is if someone prefers public
properties over getter methods.
But again, this would prevent any unconventional constructor, like
withers or static factories.

I think a better and more useful feature would be read-public, write-private.
Maybe like this? https://wiki.php.net/rfc/readonly_properties
(For some reason I cannot open the RFC wiki pages. Maybe they are down?)

This would achieve the same goal: Making a property practically immutable.
But it would still allow unconventional constructors.
It would be the implementor's job to decide which method should be
allowed to modify a property, and which shouldn't.



On 26 February 2018 at 13:52, Silvio Marijić  wrote:
> Currently the build is failing in some parts of the codebase that are
> obviously affected in some way.
> I ran valgrind for couple of failing tests and I got numerous reports about
> memory leaks and conditional jumps over uninitialized values.
> Not sure what is the reason for that, I had merge conflict with upstream
> master couple days ago, might be a reason.
>
> I would appreciate if anyone could give me hand on this ?
>
> On Feb 26, 2018 1:48 PM, "Silvio Marijić"  wrote:
>
>> Currently the build is failing in some parts of the codebase that are
>> obviously affected in some way.
>> I ran valgrind for couple of failing tests and I got numerous reports
>> about memory leaks and conditional jumps over uninitialized values.
>> Not sure what is the reason for that, I had merge conflict with upstream
>> master couple days ago, might be a reason.
>>
>> I would appreciate if anyone could give me hand on this ?
>>
>> On Feb 26, 2018 1:44 PM, marijic.sil...@gmail.com wrote:
>>
>> Yes, I've also took that into consideration when choosing keyword.
>>
>> On Feb 26, 2018 11:35 AM, "Crocodile"  wrote:
>>
>> Is "value" or "immutable" going to become a new reserved word? Ain't we
>> going to have some BC breaks because of that? If so, then "value" is going
>> to bring more BC breaks then "immutable".
>>
>> On Sun, Feb 25, 2018 at 8:02 PM Paul Jones  wrote:
>>
>>>
>>>
>>> > On Feb 25, 2018, at 12:59, Silvio Marijić 
>>> wrote:
>>> >
>>> > Here is link to tweet https://twitter.com/SilvioMari
>>> jic/status/965564630071300096
>>>
>>> After having read that, I think "immutable" is still perfectly reasonable.
>>>
>>>
>>> --
>>> Paul M. Jones
>>> pmjo...@pmjones.io
>>> http://paul-m-jones.com
>>>
>>> Modernizing Legacy Applications in PHP
>>> https://leanpub.com/mlaphp
>>>
>>> Solving the N+1 Problem in PHP
>>> https://leanpub.com/sn1php
>>>
>>>
>>>
>>>
>>> --
>>> PHP Internals - PHP Runtime Development Mailing List
>>> To unsubscribe, visit: http://www.php.net/unsub.php
>>>
>>> --
>> Best regards,
>> Victor Bolshov
>>
>>
>>
>>

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



Re: [PHP-DEV] var_export() array format

2018-02-17 Thread Andreas Hennings
On 18 February 2018 at 02:04, David Rodrigues  wrote:
> I just think that is not responsability of PHP to care about output format
> at core level (although we have the json pretty output support...).

Why not?
E.g. JSON_PRETTY_PRINT is something I use a lot, often in situations
where I don't or cannot use a 3rd party package.
E.g.
- if I abuse 3v4l.org as a php console
- in a one-off single-file cli script
- in a debugging session, or any temporary code.
- if my involvement with the project is not deep enough to justify
adding a dependency

>
> Maybe you can found some solution with packages.

See the last section of my initial message:
>>
>> Why not a userland implementation?
>> E.g. https://packagist.org/packages/riimu/kit-phpencoder
>>
>> var_export() is often used in experimental code or when just playing
>> around, situations where developers usually prefer to avoid adding a
>> 3rd party dependency.
>> Also there is no way to add a 3rd party dependency on e.g. 3v4l.org.
>> And a custom one-off implementation is not what developers should
>> spend their time on (although I did it a few times already).

If we already have a native function that generates PHP code, then we
should expect it to produce usable output..

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



[PHP-DEV] var_export() array format

2018-02-17 Thread Andreas Hennings
I sometimes use var_export() to export a structured array and then
copy+paste it into my code.
And sometimes I use it as part of an automatic code generator.

Unfortunately, the output is usually not in the format that I want, or
that is common for most projects / code styles.

- Indentation is 2 spaces instead of 4, as in most projects.
- It uses traditional "array()" format, instead of "[]".
- It puts a space after "array", so "array (" instead of "array(".
- It puts "array (" on a new line after "=>", instead of "'key' =>
array(" on one line.
- Empty arrays occupy two lines instead of one, so "array (\n)"
instead of "array ()".

E.g. https://3v4l.org/nl4uJ

The IDE can fix some of these problems with a single operation. Others
require cumbersome manual treatment.
E.g. my IDE (PhpStorm) cannot automatically remove the line break
between "=>" and "array (".

Code generators can be designed to fix all of the problems, but imo
they should not have to deal with this stuff.

--

## Proposed change

I really think the default behavior of var_export() must remain
unchanged for BC.
Re-running the same script in different PHP versions should produce
the same output each time.

What we can do is add a third parameter with flags.
Then we can introduce named flag combinations for known code styles.

Flag constants could be
- VAR_EXPORT_INDENT_TAB
- VAR_EXPORT_INDENT_2
- VAR_EXPORT_INDENT_3
- VAR_EXPORT_INDENT_4
- VAR_EXPORT_ARRAY_SHORT_SYNTAX for "[]" instead of "array (..)".
- VAR_EXPORT_ARRAY_NO_INITIAL_BREAK for " => array (" instead of "
=>\n  array(".
- VAR_EXPORT_ARRAY_NO_INITIAL_SPACE for "array(" instead of "array (".
- VAR_EXPORT_ARRAY_ONELINE_IF_EMPTY

>From other discussions:
- VAR_EXPORT_STDCLASS_AS_CAST for "(object)array (.." instead of
"stdClass::__set_state(array(..))".
- VAR_EXPORT_FQCN for "\stdClass" and "\Acme\Animal" instead of
"stdClass" and "Acme\Animal".

The naming is open for debate, of course.

I prefixed all array-related constants with *_ARRAY_* so that they
group up more nicely.

I considered for a moment to prefix the constants with "PHP_" or
something else instead of "VAR_EXPORT_", so they could be used
elsewhere in the future.

--

For a short time I considered to mix all this into the second
parameter which currently only accepts boolean.
Once you use any non-zero flags, it would always return.
For my taste, the print-by-default is a bad idea anyway.

But I now think a third parameter would be more transparent and clean.

The indentation could be solved with a 4th parameter instead of
*_INDENT_* constants.
See https://externals.io/message/51345#51351

Another alternative would be to introduce yet another function which
always returns, has a more useful default format, and where the second
parameter accepts flags like mentioned above.
But somehow it feels wrong to me to introduce such a new function
which mostly does the same as an already existing one.
But most of them are quite specific to var_export(), and would not
make sense elsewhere.

--

Why not a userland implementation?
E.g. https://packagist.org/packages/riimu/kit-phpencoder

var_export() is often used in experimental code or when just playing
around, situations where developers usually prefer to avoid adding a
3rd party dependency.
Also there is no way to add a 3rd party dependency on e.g. 3v4l.org.
And a custom one-off implementation is not what developers should
spend their time on (although I did it a few times already).

-

-- Andreas

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



Re: [PHP-DEV] [RFC][DISCUSSION] Strong Typing Syntax

2018-01-25 Thread Andreas Hennings
I will not

On 22 January 2018 at 22:11, Stanislav Malyshev  wrote:
> Hi!
>
>> I want to see strict typing as an option, not a requirement.
>
> You seem to be under impression that this somehow makes things easier.
> It does not. To explain: let's say you design a strictly typed language,
> like Java. The compiler knows which variable is of which type at every
> point, and if it's not clear for some reason, it errors out. You can
> build a compiler on top of those assumptions.
> Now let's say you design a loosely typed language, like Javascript. The
> compiler knows variables have no types, only values have it, and builds
> on top of that (as in, it doesn't need to implement type tracking for
> variables).
> Now, you come in and say - let's make the compiler have *both*
> assumptions - that sometimes it's strict and sometimes it's not.
> Sometimes you need to track variable types and sometimes you don't.
> Sometimes you have type information and can rely on it, and sometimes
> you don't and have to type-juggle.
> Do you really think this just made things *easier*? To implement both
> Java and Javascript inside the same compiler, with radically different
> types of assumption? If you have desire to answer "yes", then a) please
> believe me it is not true b) please try to implement a couple of
> compilers and see how easy it is.

I do not doubt that it would be a lot of work, possibly so much that
it becomes unrealistic.

There are languages which have a number of strict types and then a
"variant" type.
https://en.wikipedia.org/wiki/Variant_type
https://msdn.microsoft.com/en-us/vba/language-reference-vba/articles/variant-data-type

In PHP, to allow a mix of strict statically typed variables and
dynamically typed variables, we could adopt such a model, where all
dynamically typed variables would have the type "variant".

The strict types would become the basic model, and the variant type
would be a special case within that model.

This does not make this any easier to implement, but it seems more
promising than seeing this as two parallel systems which have to be
maintained separately.


>
> Having two options is not even twice as harder as having one. It's much
> more. So "optional" part adds all work that needs to be done to support
> strict typing in PHP, and on top of that, you also have to add work that
> needs to be done to support cases where half of the code is typed and
> the other half is not. And this is not only code writing work - this is
> conceptual design work, testing work, documenting work, etc.
>
> Without even going to the merits of the proposal itself, it certainly
> looks to me like you are seriously underestimating what we're talking
> about, complexity-wise. I am not saying it's not possible at all - a lot
> of things are possible. It's just "it's merely an option" is exactly the
> wrong position to take.
>
>> Create a symbol table that holds the strict variables and the types they
>> are locked into.  The strict keyword pushes them onto that table, the var
>> keyword pulls them off. When an operation that cares about type occurs
>> check that table - if the var appears there than authenticate it.
>
> And now every function and code piece that works with symbol tables
> needs to be modified to account for the fact that there are two of them.
> Every lookup is now two lookups, and no idea how $$var would even work
> at all.
>
> --
> Stas Malyshev
> smalys...@gmail.com
>
> --
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: http://www.php.net/unsub.php
>

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



Re: [PHP-DEV] null coalesce addition assignment operator ??+=

2018-01-20 Thread Andreas Hennings
On 20 January 2018 at 12:02, Midori Koçak  wrote:
> What is going on here? I think I missed the original post.

https://externals.io/message/101620

Here you can find all messages.

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



Re: [PHP-DEV] null coalesce addition assignment operator ??+=

2018-01-19 Thread Andreas Hennings
As mentioned earlier:
In hack (hhvm), operators like +=, *= etc do allow the left side to be
undefined.
(However, ++ and -- do not allow the left side to be undefined.)

I wonder if this is intended, or by accident.

On 20 January 2018 at 06:47, Andreas Hennings <andr...@dqxtech.net> wrote:
> On 20 January 2018 at 04:29, Aidan Woods <aidantwo...@gmail.com> wrote:
>> On 20 January 2018 at 01:25, Andreas Hennings <andr...@dqxtech.net> wrote:
>>>
>>> On 19 January 2018 at 16:12, Sara Golemon <poll...@php.net> wrote:
>>> > On Thu, Jan 18, 2018 at 7:13 PM, Christoph M. Becker <cmbecke...@gmx.de>
>>> > wrote:
>>> >> On 18.01.2018 at 23:58, Stanislav Malyshev wrote:
>>> >>
>>> >>>> I propose even more such operators:
>>> >>>> null coalesce addition assignment ??+= (for strings and numbers)
>>> >>>> null coalesce subtraction assignment ??-=
>>> >>>> null coalesce increment ??++
>>> >>>> null coalesce decrement ??--
>>> >>>> null coalesce multiplication assingment ??*=
>>> >>>
>>> >>> I think this is taking it too far. If you want language like that, you
>>> >>> always have APL :)
>>> >>
>>> >> Why do we discuss extensions to an operator which has still (after
>>> >> nearly two years) not be implemented due to implementation
>>> >> difficulties?
>>> >>
>>> > Am I the only one who looked at the original post and assumed he was
>>> > taking the piss?
>>> > Similar to the jokes about spaceship assignment <=>= and
>>> > equality/identicality assignment === (not to be confused with
>>> > identical non-assign, which is ===) and .
>>>
>>> I can definitely say it was not a joke.
>>> I can see myself and others use the ??+= and also ??++, and would have
>>> used them in the past, if they had been available.
>>> The others, I don't care as much.
>>>
>>> For me, a good enough conclusion of this conversation would be one of:
>>> A: Yeah seems useful, but let's wait (or work) until ??= is
>>> implemented and released, and observe how it is being used.
>>> B: No one will ever use it, and it would hurt the language.
>>>
>>
>> Going by the example, would this operator's behaviour be a little confusing?
>>
>> As I understand it the (maybe) upcoming `??=` operator will assign in the
>> case that the lhs is *not defined*.
>> But for `??+=` incrementing appears to be desired when the lhs *is defined*,
>> (with assignment to the operator related identity element in the case that
>> the lhs is undefined).
>>
>> While the use-case seems to add value in the scenario, I think it is
>> possibly
>> inconsistent with the way `??=` works?
>
> I think it depends how you see it.
>
> // shortcut
> return $x ??= 5;
> return $y ??+= 5;
>
> // spelled out, looks inconsistent
> return isset($x) ? $x : ($x = 5);
> return isset($y) ? ($y += 5) : ($y = 5);
>
> // spelled out, looks a bit more consistent (despite being broken)
> return (isset($x) ? $x : ($x = 5));
> return (isset($y) ? $y : ($y = 0)) += 5;  // invalid code, because
> ternary is not a valid lhs.
>
> The line is invalid, but shows the mental model or the excuse that
> allows us to claim this is consistent.
>
> But yeah, I can see how someone would expect a different behavior:
>
> return isset($x) ? $x : ($x = 5);
> return isset($y) ? $y : ($y += 5);
>
> This would not make sense or be useful because:
> For $y === NULL, this would evaluate as
> return $y = NULL + 5:
>
> Still, your argument raises a valid concern that the operator might be
> misunderstood.
>
>
>
> If we get ??=, I previously thought we could use it like this, to
> replicate ??+=:
>
> return ($y ??= 0) += 5;
>
> Unfortunately, I think we can expect that ??= won't be a valid lhs,
> because neither is *= or += etc.
> E.g. this is invalid:
> ($y *= 3) += 1;
> https://3v4l.org/oKIkl
>
>
>>
>> Furthermore, I think you can generalise this in user-land and end up with a
>> better result.
>
> comments below.
>
>>
>> When dealing with structured data (i.e. when you expect strings mapping to
>> ints in your example) you may consider writing a simple class for making
>> such type guarantees. Something simple like https://3v4l.org/5Sh04 would
>> produce the desired result, and let you obtain the result in one line at
>> point
>> of use.

Re: [PHP-DEV] null coalesce addition assignment operator ??+=

2018-01-19 Thread Andreas Hennings
On 20 January 2018 at 04:29, Aidan Woods <aidantwo...@gmail.com> wrote:
> On 20 January 2018 at 01:25, Andreas Hennings <andr...@dqxtech.net> wrote:
>>
>> On 19 January 2018 at 16:12, Sara Golemon <poll...@php.net> wrote:
>> > On Thu, Jan 18, 2018 at 7:13 PM, Christoph M. Becker <cmbecke...@gmx.de>
>> > wrote:
>> >> On 18.01.2018 at 23:58, Stanislav Malyshev wrote:
>> >>
>> >>>> I propose even more such operators:
>> >>>> null coalesce addition assignment ??+= (for strings and numbers)
>> >>>> null coalesce subtraction assignment ??-=
>> >>>> null coalesce increment ??++
>> >>>> null coalesce decrement ??--
>> >>>> null coalesce multiplication assingment ??*=
>> >>>
>> >>> I think this is taking it too far. If you want language like that, you
>> >>> always have APL :)
>> >>
>> >> Why do we discuss extensions to an operator which has still (after
>> >> nearly two years) not be implemented due to implementation
>> >> difficulties?
>> >>
>> > Am I the only one who looked at the original post and assumed he was
>> > taking the piss?
>> > Similar to the jokes about spaceship assignment <=>= and
>> > equality/identicality assignment === (not to be confused with
>> > identical non-assign, which is ===) and .
>>
>> I can definitely say it was not a joke.
>> I can see myself and others use the ??+= and also ??++, and would have
>> used them in the past, if they had been available.
>> The others, I don't care as much.
>>
>> For me, a good enough conclusion of this conversation would be one of:
>> A: Yeah seems useful, but let's wait (or work) until ??= is
>> implemented and released, and observe how it is being used.
>> B: No one will ever use it, and it would hurt the language.
>>
>
> Going by the example, would this operator's behaviour be a little confusing?
>
> As I understand it the (maybe) upcoming `??=` operator will assign in the
> case that the lhs is *not defined*.
> But for `??+=` incrementing appears to be desired when the lhs *is defined*,
> (with assignment to the operator related identity element in the case that
> the lhs is undefined).
>
> While the use-case seems to add value in the scenario, I think it is
> possibly
> inconsistent with the way `??=` works?

I think it depends how you see it.

// shortcut
return $x ??= 5;
return $y ??+= 5;

// spelled out, looks inconsistent
return isset($x) ? $x : ($x = 5);
return isset($y) ? ($y += 5) : ($y = 5);

// spelled out, looks a bit more consistent (despite being broken)
return (isset($x) ? $x : ($x = 5));
return (isset($y) ? $y : ($y = 0)) += 5;  // invalid code, because
ternary is not a valid lhs.

The line is invalid, but shows the mental model or the excuse that
allows us to claim this is consistent.

But yeah, I can see how someone would expect a different behavior:

return isset($x) ? $x : ($x = 5);
return isset($y) ? $y : ($y += 5);

This would not make sense or be useful because:
For $y === NULL, this would evaluate as
return $y = NULL + 5:

Still, your argument raises a valid concern that the operator might be
misunderstood.



If we get ??=, I previously thought we could use it like this, to
replicate ??+=:

return ($y ??= 0) += 5;

Unfortunately, I think we can expect that ??= won't be a valid lhs,
because neither is *= or += etc.
E.g. this is invalid:
($y *= 3) += 1;
https://3v4l.org/oKIkl


>
> Furthermore, I think you can generalise this in user-land and end up with a
> better result.

comments below.

>
> When dealing with structured data (i.e. when you expect strings mapping to
> ints in your example) you may consider writing a simple class for making
> such type guarantees. Something simple like https://3v4l.org/5Sh04 would
> produce the desired result, and let you obtain the result in one line at
> point
> of use.
>
> Nothing ties you into using a class for the storage though, you could
> simplify
> even further and just create some abstract class representing an "array
> toolbox"
> for these kind of operations, e.g. https://3v4l.org/ZJcom
> So that the array initialisation, foreach loop, and operator are replaced
> with a
> single line again at point of use (after defining the arraytools class
> once).
>
> If you wanted it to work more generally, you could use a reference to delay
> lookup, and keep your current code structure https://3v4l.org/TJYhq

I was never a big friend of those array functions with callback
arguments, which force me to remember a signature.
I find a simple foreach() to be more readable. I

Re: [PHP-DEV] null coalesce addition assignment operator ??+=

2018-01-19 Thread Andreas Hennings
On 19 January 2018 at 16:12, Sara Golemon  wrote:
> On Thu, Jan 18, 2018 at 7:13 PM, Christoph M. Becker  
> wrote:
>> On 18.01.2018 at 23:58, Stanislav Malyshev wrote:
>>
 I propose even more such operators:
 null coalesce addition assignment ??+= (for strings and numbers)
 null coalesce subtraction assignment ??-=
 null coalesce increment ??++
 null coalesce decrement ??--
 null coalesce multiplication assingment ??*=
>>>
>>> I think this is taking it too far. If you want language like that, you
>>> always have APL :)
>>
>> Why do we discuss extensions to an operator which has still (after
>> nearly two years) not be implemented due to implementation difficulties?
>>
> Am I the only one who looked at the original post and assumed he was
> taking the piss?
> Similar to the jokes about spaceship assignment <=>= and
> equality/identicality assignment === (not to be confused with
> identical non-assign, which is ===) and .

I can definitely say it was not a joke.
I can see myself and others use the ??+= and also ??++, and would have
used them in the past, if they had been available.
The others, I don't care as much.

For me, a good enough conclusion of this conversation would be one of:
A: Yeah seems useful, but let's wait (or work) until ??= is
implemented and released, and observe how it is being used.
B: No one will ever use it, and it would hurt the language.

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



[PHP-DEV] Re: null coalesce addition assignment operator ??+=

2018-01-18 Thread Andreas Hennings
Some background / personal experience
(cross-posting with Stanislav, but I am sending it anyway)

I regularly see code with arrays in loops, where the ??+= or ??++
would be nice to have.
I do not remember seeing use cases for *=.
In all the cases I remember, the left side was an array offset, not a
plain variable.

I think the spec has to be for plain variables first, even if the main
use case is arrays.
I only added the ??*=, ??-=, ??++, ??-- for completeness, but I can
live without.


On 18 January 2018 at 23:58, Stanislav Malyshev <smalys...@gmail.com> wrote:
> I think this is taking it too far. If you want language like that, you
> always have APL :)

It looks a bit cluttery (one character too many for an operator?), but
I think it is useful and intuitive.
If you understand ??, ??= and +=, you also understand ??+=.
But let's see what others say.


On 18 January 2018 at 23:52, Andreas Hennings <andr...@dqxtech.net> wrote:
> The "Null Coalescing Assignment Operator" (or null coalesce assignment
> operator) was proposed and accepted in
> https://wiki.php.net/rfc/null_coalesce_equal_operator
>
> I propose even more such operators:
> null coalesce addition assignment ??+= (for strings and numbers)
> null coalesce subtraction assignment ??-=
> null coalesce increment ??++
> null coalesce decrement ??--
> null coalesce multiplication assingment ??*=
>
>
> ## Details
>
> Each block contains 3 equivalent statements.
>
> $x ??+= 5;  // proposed new syntax
> ($x ??= 0) += 5;  // syntax with null coalesce assignment operator
> $x = ($x ?? 0) + 5;  // syntax with simple null coalesce operator
>
> $x ??+= 'suffix';  // proposed new syntax
> ($x ??= '') += 'suffix';  // syntax with null coalesce assignment operator
> $x = ($x ?? '') + 'suffix';  // syntax with simple null coalesce operator
>
> $x ??++;  // proposed new syntax
> ($x ??= 0)++;
> $x = ($x ?? 0) + 1;
>
> $x ??*= 2;  // proposed new syntax
> ($x ??= 1) *= 2;
> $x = ($x ?? 1) * 2;
>
> Note that in each case PHP needs to determine the "neutral element" of
> the operation.
> For string concat this is the empty string. For number addition this
> is 0. For number multiplication it is 1.
>
>
> ## Example:
>
> For me, the most common use case would be something like this:
>
> $fruitpacks = [
>   ['apples', 3],
>   ['pears', 1],
>   ['apples', 6],
>   ['grapes', 22],
> ];
>
> $totals_by_name = [];
> foreach ($fruitpacks as [$name, $amount]) {
>   $totals_by_name[$name] ??+= $amount;  // proposed new syntax
> }
>
> $totals_by_name_expected = [
>   'apples' => 9,
>   'pears' => 1,
>   'grapes' => 22,
> ];
>
> assert($totals_by_name === $totals_by_name_expected);
>
>
> ## Notes
>
> In PHP, the "+=" operator already behaves almost like "??+=", but adds
> a "Notice: Undefined offset" or "Notice: Undefined variable", if the
> left side is not defined yet.
> hhvm apparently does not produce this notice.
> https://3v4l.org/l0l0K

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



[PHP-DEV] null coalesce addition assignment operator ??+=

2018-01-18 Thread Andreas Hennings
The "Null Coalescing Assignment Operator" (or null coalesce assignment
operator) was proposed and accepted in
https://wiki.php.net/rfc/null_coalesce_equal_operator

I propose even more such operators:
null coalesce addition assignment ??+= (for strings and numbers)
null coalesce subtraction assignment ??-=
null coalesce increment ??++
null coalesce decrement ??--
null coalesce multiplication assingment ??*=


## Details

Each block contains 3 equivalent statements.

$x ??+= 5;  // proposed new syntax
($x ??= 0) += 5;  // syntax with null coalesce assignment operator
$x = ($x ?? 0) + 5;  // syntax with simple null coalesce operator

$x ??+= 'suffix';  // proposed new syntax
($x ??= '') += 'suffix';  // syntax with null coalesce assignment operator
$x = ($x ?? '') + 'suffix';  // syntax with simple null coalesce operator

$x ??++;  // proposed new syntax
($x ??= 0)++;
$x = ($x ?? 0) + 1;

$x ??*= 2;  // proposed new syntax
($x ??= 1) *= 2;
$x = ($x ?? 1) * 2;

Note that in each case PHP needs to determine the "neutral element" of
the operation.
For string concat this is the empty string. For number addition this
is 0. For number multiplication it is 1.


## Example:

For me, the most common use case would be something like this:

$fruitpacks = [
  ['apples', 3],
  ['pears', 1],
  ['apples', 6],
  ['grapes', 22],
];

$totals_by_name = [];
foreach ($fruitpacks as [$name, $amount]) {
  $totals_by_name[$name] ??+= $amount;  // proposed new syntax
}

$totals_by_name_expected = [
  'apples' => 9,
  'pears' => 1,
  'grapes' => 22,
];

assert($totals_by_name === $totals_by_name_expected);


## Notes

In PHP, the "+=" operator already behaves almost like "??+=", but adds
a "Notice: Undefined offset" or "Notice: Undefined variable", if the
left side is not defined yet.
hhvm apparently does not produce this notice.
https://3v4l.org/l0l0K

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



Re: [PHP-DEV] [RFC][DISCUSSION] Strong Typing Syntax

2018-01-10 Thread Andreas Hennings
Whether we work with runtime type checks or compile-time static analysis:
The user-facing language design questions would still be the same, right?
E.g. we would still have to distinguish type-locked parameter values
vs dynamically typed parameter values.

On 10 January 2018 at 20:23, Andreas Hennings <andr...@dqxtech.net> wrote:
> On 10 January 2018 at 19:59, Rasmus Lerdorf <ras...@lerdorf.com> wrote:
>>
>> Now if the RFC was a plan for baking a compile-time static analysis engine
>> into PHP itself, that would be interesting. But that is a *massive* project.
>
> Even with my limited understanding of the engine, I can imagine this
> to be a lot of work.
> But it sounds much better to me than adding more expensive runtime type 
> checks.
> I think it would be worth exploring as a long-term direction.

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



Re: [PHP-DEV] [RFC][DISCUSSION] Strong Typing Syntax

2018-01-10 Thread Andreas Hennings
On 10 January 2018 at 19:59, Rasmus Lerdorf  wrote:
>
> Now if the RFC was a plan for baking a compile-time static analysis engine
> into PHP itself, that would be interesting. But that is a *massive* project.

Even with my limited understanding of the engine, I can imagine this
to be a lot of work.
But it sounds much better to me than adding more expensive runtime type checks.
I think it would be worth exploring as a long-term direction.

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



Re: [PHP-DEV] [RFC][DISCUSSION] Strong Typing Syntax

2018-01-05 Thread Andreas Hennings
On 5 January 2018 at 11:35, Dan Ackroyd  wrote:
> On 5 January 2018 at 02:01, Michael Morris  wrote:
>>
>> what if the underlying zval wasn’t a zval but a separate
>> class specific to the data type but implementing the same interface as
>> zval?
>
> I believe the only sensible answer to that is 'mu', as that question
> is based on misunderstanding.
>
> The internals of the PHP engine is C, and zvals are structs not
> classes, and so there is no interface. In userland classes are also
> zvals.  
> http://www.phpinternalsbook.com/php7/internal_types/zvals/basic_structure.html


I think a good beginners intro is this,
http://php.net/manual/de/internals2.variables.intro.php

Yes, these things are structs, and there are no interfaces.

It would be possible, in theory, to create a different struct for
type-locked variables, where the type is not stored with each
instance, but in the opcode.
Or perhaps separate structs per type.

This would obviously be a huge amount of work, and a radical change to
the language, so I do not imagine this going to happen any time soon.
Every place in code that currently deals with the _zval_struct would
then have to consider all other structs.
The opcode could then be optimized for such type-locked variables, and
this would reduce cost in memory and performance.

The next best thing would be to keep the existing _zval_struct also
for type-locked variables, and still try to optimize the opcode as if
the type is known at compile time.
Still a lot of work, I imagine, because it still affects every place
where we deal with a variable.

The third option is to keep the implementation as if all types are
dynamic, and only add some type checks here and there, which can be
globally enabled or disabled.
This is what other gradually typed languages do, as pointed out by
Rowan Collins,

> The biggest issue with any proposal, though, is going to be performance. I 
> don't think this is an incidental detail to be dealt with later, it is a 
> fundamental issue with the way type hints in PHP have evolved. PHP is 
> extremely unusual, if not unique, in exclusively enforcing type constraints 
> at runtime. Other languages with "gradual typing" such as Python, Hack, and 
> Dart, use the annotations only in separate static analysers and/or when a 
> runtime debug flag is set (similar to enabling assertions).


>
> Also, I think people who try to guess at how to make changes to the
> engine, are doing a small disservice to people who have already tried
> to implement this.

This is a dilemma.
I think there are some people with valuable opinions on language
design, which did not find the time yet to study the engine
implementation.
So, either we risk occasional ignorant ideas, or we will miss some
valuable contributions.

I personally want to eventually study the engine in more detail, but I
don't think I need to completely self-censor myself until then.
Instead, I have to make a judgement call each time if my limited
understanding is sufficient to allow a meaningful contribution to the
discussion.

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



Re: [PHP-DEV] [RFC][DISCUSSION] Strong Typing Syntax

2018-01-04 Thread Andreas Hennings
On 3 January 2018 at 21:26, Rowan Collins <rowan.coll...@gmail.com> wrote:
> Hi Michael,
>
> On 02/01/2018 10:35, Michael Morris wrote:
>>
>> I would like to propose a clean way to add some strong typing to PHP in a
>> manner that is almost fully backward compatible (there is a behavior
>> change
>> with PHP 7 type declarations). As I don't have access to the add RFC's to
>> the wiki I'll place this here.
>
>
> Thanks for putting this together. Perhaps unlike Andreas, I think it is good
> to look at typing changes as a unified framework, rather than considering
> "typed properties", "typed variables", etc, as separate concerns. If we
> don't, there is a real risk we'll end up making decisions now that hobble us
> for future changes, or over-complicating things in one area because we're
> not yet ready to make changes in another.

I think the best strategy is to develop a greater vision of where we
want to go, and then identify manageably small steps that move us in
this direction, and that do not create conflicts in the future. This
means we are both right.

I still think the following are good "small steps":
- typed properties with type lock
- typed local variables with type lock
- discussion whether and when parameters should be type-locked in the
function body.

Of course there should be consistency between those steps.

You are right, we also need to consider when these types should be
validated, and/or how the variables would be implemented.
Perhaps we could actually create a system where type-locked variables
use less memory, because they no longer need to store the type of the
variable?
E.g. a type-locked integer would only use the 64 bit or whichever size
we currently use to store the actual number.


> The biggest issue with any proposal, though, is going to be performance. I 
> don't think this is an incidental detail to be dealt with later, it is a 
> fundamental issue with the way type hints in PHP have evolved. PHP is 
> extremely unusual, if not unique, in exclusively enforcing type constraints 
> at runtime. Other languages with "gradual typing" such as Python, Hack, and 
> Dart, use the annotations only in separate static analysers and/or when a 
> runtime debug flag is set (similar to enabling assertions).

A system where all variables are type-locked could in fact be faster
than a system with dynamically typed variables.
Depends on the implementation, of course. I imagine it would be a lot
of work to get there.

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



Re: [PHP-DEV] [RFC][DISCUSSION] Strong Typing Syntax

2018-01-03 Thread Andreas Hennings
Another idea I have when reading this proposal is "implicit" typing
based on the initialization.

E.g.

$x = 5;
$x = 'hello';  // -> Error: $x was initialized as integer, and cannot
hold a string.

or

$x = $a + $b;
$x = 'hello';  // -> Error: $x was initialized as number (int|float),
and cannot hold a string.

To me this is only acceptable if the implicit type can be determined
at compile time.
So:

if ($weather_is_nice) {
  $x = 5;
}
else {
  $x = 'hello';  // -> Error: $x would be initialized as int
elsewhere, so cannot be initialized as string.
}


This change would be controversial and leave a lot of questions.
It would be a BC break, unless we introduce yet another declare()
setting, e.g. declare(implicit_types=1).

It could be tricky for global variables, or in combination with
include/require, where the variable can be seen from outside a
function body, and outside the range of the declare() statement.

I only mention it here because it relates to the proposal. I do not
have a strong opinion on it atm.


On 3 January 2018 at 18:10, Andreas Hennings <andr...@dqxtech.net> wrote:
> This proposal contains some interesting ideas, which I see as separate:
> 1. A syntax to declare the type of local variables.
> 2. A syntax to declare the type of object properties.
> 3. Preventing local variables, object properties and parameters to
> change their type after initialization/declaration.
>
> For me the point 3 is the most interesting one.
> I think the other points are already discussed elsewhere in some way,
> although they are clearly related to 3.
>
> Point 3 would be a BC break, if we would introduce it for parameters.
> Current behavior: https://3v4l.org/bjaLQ
>
> Local variables and object properties currently cannot be types, so
> point 3 would not be a BC break for them, if we introduce it together
> with 1 and 2.
> But then we would have an inconsistency between parameters and local
> vars / object properties.
>
> What we could do to avoid BC break is to introduce
> declare(fixed_parameter_types=1) in addition to
> declare(strict_types=1).
> For local variables and object properties, the type would always be fixed.
> But for parameters, it would only be fixed if the
> declare(fixed_parameter_types=1) is active.
>
> Maybe to make it less verbose, we could say declare(strict_types=2),
> which would mean the combination of both those things?
> Or some other type of shortcut.
> I think we will have to think about shortcuts like this if we
> introduce more "modes" in the future.
>
>
>> Currently the var keyword is used to formally declare a variable.
>
> Are you talking about local variables?
> In which PHP version? https://3v4l.org/o0PFg
>
> Afaik, currently var is only used for class/object properties from the
> time when people did not declare the visibility as
> public/protected/private.
>
>
>> If the type is omitted, scalar is assumed.  If Fleshgrinder's scalar RFC is
>> accepted then it would make sense to allow programmers to explicitly
>> declare the variable as a scalar, but in any event when the type is omitted
>> scalar must be assumed for backwards compatibility.
>
> If no type is specified, then "mixed" should be assumed, not "scalar".
> Assuming "scalar" would be a BC break, and it would be confusing.
>
>
> On 3 January 2018 at 10:03, Michael Morris <tendo...@gmail.com> wrote:
>> On Wed, Jan 3, 2018 at 3:50 AM, Niklas Keller <m...@kelunik.com> wrote:
>>
>>> Hey Michael,
>>>
>>> I don't think the BC break is acceptable. You argue that scalar type
>>> declarations are relatively new, but in fact they're already years old now.
>>> They're used in most PHP 7+ packages. Even if changing types might be
>>> discouraged, it still happens a lot.
>>>
>>
>> Hmm.  Well, that aspect of this can be dropped. What about the rest of it?

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



Re: [PHP-DEV] [RFC][DISCUSSION] Strong Typing Syntax

2018-01-03 Thread Andreas Hennings
This proposal contains some interesting ideas, which I see as separate:
1. A syntax to declare the type of local variables.
2. A syntax to declare the type of object properties.
3. Preventing local variables, object properties and parameters to
change their type after initialization/declaration.

For me the point 3 is the most interesting one.
I think the other points are already discussed elsewhere in some way,
although they are clearly related to 3.

Point 3 would be a BC break, if we would introduce it for parameters.
Current behavior: https://3v4l.org/bjaLQ

Local variables and object properties currently cannot be types, so
point 3 would not be a BC break for them, if we introduce it together
with 1 and 2.
But then we would have an inconsistency between parameters and local
vars / object properties.

What we could do to avoid BC break is to introduce
declare(fixed_parameter_types=1) in addition to
declare(strict_types=1).
For local variables and object properties, the type would always be fixed.
But for parameters, it would only be fixed if the
declare(fixed_parameter_types=1) is active.

Maybe to make it less verbose, we could say declare(strict_types=2),
which would mean the combination of both those things?
Or some other type of shortcut.
I think we will have to think about shortcuts like this if we
introduce more "modes" in the future.


> Currently the var keyword is used to formally declare a variable.

Are you talking about local variables?
In which PHP version? https://3v4l.org/o0PFg

Afaik, currently var is only used for class/object properties from the
time when people did not declare the visibility as
public/protected/private.


> If the type is omitted, scalar is assumed.  If Fleshgrinder's scalar RFC is
> accepted then it would make sense to allow programmers to explicitly
> declare the variable as a scalar, but in any event when the type is omitted
> scalar must be assumed for backwards compatibility.

If no type is specified, then "mixed" should be assumed, not "scalar".
Assuming "scalar" would be a BC break, and it would be confusing.


On 3 January 2018 at 10:03, Michael Morris  wrote:
> On Wed, Jan 3, 2018 at 3:50 AM, Niklas Keller  wrote:
>
>> Hey Michael,
>>
>> I don't think the BC break is acceptable. You argue that scalar type
>> declarations are relatively new, but in fact they're already years old now.
>> They're used in most PHP 7+ packages. Even if changing types might be
>> discouraged, it still happens a lot.
>>
>
> Hmm.  Well, that aspect of this can be dropped. What about the rest of it?

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



Re: [PHP-DEV] Mailing list moderation

2018-01-03 Thread Andreas Heigl
Am 03.01.18 um 10:55 schrieb Sanford Whiteman:
> Tony, you have a point in the sense that a proposed Code of Conduct --
> which would have been binding on posts to lists @php.net -- provoked a
> fiery   debate  (to  put  it  mildly)  and  was  eventually  withdrawn
> (http://news.php.net/php.internals/90726).
> 
> The  dominant  objections  to  the  CoC  did  not  focus on relatively
> apolitical  cases  like  calling  someone  a habitual liar or implying
> non-augmented  humans  can  write bug-free code. Yet the point remains
> that there is no doc whose letter or spirit can be debated, AFAIK.

May I point to the headline "Mailing List Posting Guideline" at the
Mailing-List page[0]? Especially the references to the
README.MAILINGLIST_RULES[1] right at the end? Which in turn references
RFC 1855[2]?

So I'd say there actually *is* even more than one doc whose letter or
spirit can be debated. But debating is one thing, taking action is
another one.

Just my 0.02€

Cheers

Andreas

[0] http://php.net/mailing-lists.php
[1]
http://git.php.net/?p=php-src.git;a=blob_plain;f=README.MAILINGLIST_RULES;hb=HEAD
[2] http://www.faqs.org/rfcs/rfc1855.html
-- 
  ,,,
 (o o)
+-----ooO-(_)-Ooo-+
| Andreas Heigl   |
| mailto:andr...@heigl.org  N 50°22'59.5" E 08°23'58" |
| http://andreas.heigl.org   http://hei.gl/wiFKy7 |
+-+
| http://hei.gl/root-ca   |
+-+



signature.asc
Description: OpenPGP digital signature


Re: [PHP-DEV] [RFC] [DISCUSSION] Scalar Pseudo-type

2017-12-26 Thread Andreas Heigl
Hey All. 

> Am 26.12.2017 um 14:38 schrieb Sebastian Bergmann <sebast...@php.net>:
> 
>> Am 24.12.2017 um 15:34 schrieb Fleshgrinder:
>> I prepared a PR to add the `scalar` pseudo-type to PHP after the
>> discussions around adding a `mixed` pseudo-type. I strongly believe that
>> it makes sense to provide the most common primitive union types with
>> handy aliases even if we are going to add union types in the future to PHP.
> 
> Thank you, Richard, for working on this.
> 
> I spent a lot of time this year introducing scalar type declarations into
> existing code bases. In quite a few cases I was not able to do so because
> the existing code works with parameters that can be of two or more scalar
> types. With PHP 7.2, I can only document this outside of the code using
> @param annotations (until the code has been refactored to work with only
> one parameter type).
> 
> With a "scalar" type declaration I would not have to fall back to @param
> annotations and could express the type in actual syntax.

Just a stupid question from someone that isn't following all the discussions 
here. So forgive me if the question was already asked and answered. 

What would be wrong with a "composed type hint"? Something like 
int|float|double $numeric. Or array|Traversable $iterator? 

It would allow people to add "mixed" typehints without having to introduce 
multiple typehints that combine different scalar typehints. And it could even 
allow typehinting different Objects in one function. 

Yes, it allows people to shoot themselfes into their own feet. 

And I'd only allow that for parameter types and never ever for return types. 

But it might be an idea. 

Cheers

Andreas 


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



Re: [PHP-DEV] [RFC] Mixed Typehint

2017-12-22 Thread Andreas Hennings
> I think that a "scalar" type that "groups together" bool, float, int, and 
> string would make more sense. This would allow the expression that something 
> is not an array, not an object, and not a resource.

Why would this be an either/or?
I don't mind a "scalar" type hint. But this could be a separate
discussion, and is not in conflict with "mixed".

On 20 December 2017 at 13:56, Sebastian Bergmann  wrote:
> On 12/19/2017 04:34 AM, Michael Moravec wrote:
>>
>> I'd like to propose and discuss Mixed Typehint RFC for PHP 7.3:
>> https://wiki.php.net/rfc/mixed-typehint
>
>
> "mixed" is too unspecific. I understand the reasoning behind wanting
> "mixed": to express explicitly that a type declaration was not forgotten.
>
> I think that a "scalar" type that "groups together" bool, float, int, and
> string would make more sense. This would allow the expression that something
> is not an array, not an object, and not a resource.
>
>
> --
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: http://www.php.net/unsub.php
>

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



Re: [PHP-DEV] instanceof survives non-object variables, but crashes on non-object constants.

2017-12-19 Thread Andreas Hennings
We can still do this as a follow-up.
The current fix is easy and straighforward.
What you suggest might be a good idea, but I think deserves more discussion.

On 19 December 2017 at 23:09, Michael Morris <tendo...@gmail.com> wrote:
> What would it hurt to allow instanceof to return types other than object?
>
> $x instanceof NULL
> $x instanceof string
>
> and so on.  This would be more powerful and useful than throwing an error
> where one wasn't being thrown before. It also would let one operator detect
> all the types, rather than the plethora of detect functions we currently
> have.
>
> On Tue, Dec 19, 2017 at 4:48 PM, Nikita Popov <nikita@gmail.com> wrote:
>
>> On Sat, Dec 9, 2017 at 7:28 AM, Andreas Hennings <andr...@dqxtech.net>
>> wrote:
>>
>> > The following (https://3v4l.org/A2Tp6) is ok, it simply returns false:
>> >
>> > $x = 1;
>> > $x instanceof \stdClass;
>> >
>> >
>> > The following (https://3v4l.org/IdSBu) gives a fatal error:
>> >
>> > 1 instanceof \stdclass;
>> >
>> > t think this behavior is inconsistent, and we should consider changing
>> it.
>> >
>> > There are two options, but only one is BC.
>> >
>> > - Let 1 instanceof \stdClass return false, instead of crashing. -> seems
>> BC
>> > - Let $x instanceof \stdClass crash, if $x is not an object. -> BC break.
>> >
>> > So it seems the first would the option we should take.
>> > This is also what hhvm does, according to https://3v4l.org/IdSBu.
>> >
>>
>> I've prepared a PR for this change: https://github.com/php/php-
>> src/pull/2978
>>
>> From the discussion I'm understanding that our consensus is to implement
>> this change, so if there are no further objection I'll merge this in a few
>> days.
>>
>> Nikita
>>

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



Re: [PHP-DEV] [RFC] Mixed Typehint

2017-12-19 Thread Andreas Hennings
> For correctness: `callable` is not the union `string | array | object` 
> because only certain kinds of strings, arrays, and objects are accepted.

Correct.

> this thread is about `mixed`
> which I would vote against. As our type-system stands it provides
> almost no value

The argument, which I support, is that "mixed" would allow to
distinguish against cases of "developer forgot to add a type hint" or
"no type hint due to legacy / BC reasons".
Also, with a "mixed" type hint, you know it is not "void" (this is
still the same argument).


On 19 December 2017 at 18:38, li...@rhsoft.net <li...@rhsoft.net> wrote:
> IMHO the wrong question, the right ones would be
>
> a) how much work is it to implement
> b) does it any harm
> c) is it maintainable and does it bring relevant maintainance cost

I think we do need to explain whether a feature "provides value", so
Levi's question is not wrong.
Simply "does no harm" is not enough.
We just disagree on the answer, we actually do think it provides value.


On 19 December 2017 at 18:30, Levi Morrison <le...@php.net> wrote:
> On Tue, Dec 19, 2017 at 10:05 AM, Andreas Hennings <andr...@dqxtech.net> 
> wrote:
>> We already have other "meta" types.
>> E.g. "callable" can be a string, an array, an object with __invoke().
>> A "numeric" can be float or int.
>> A "iterable" can be an array or an traversable object.
>
> For correctness: `callable` is not the union `string | array | object`
> because only certain kinds of strings, arrays, and objects are
> accepted.
>
>> Personally I don't think we need every possible union, let alone 
>> intersections.
>
> How many do we need to have for us to make the conclusion we should
> stop making special-cases in the engine and generalize it?
>
> In any case we are straying off-topic: this thread is about `mixed`
> which I would vote against. As our type-system stands it provides
> almost no value. If our type system ever changes and it suddenly
> provides value then it should be proposed at that point.

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



Re: [PHP-DEV] [RFC] Mixed Typehint

2017-12-19 Thread Andreas Hennings
We already have other "meta" types.
E.g. "callable" can be a string, an array, an object with __invoke().
A "numeric" can be float or int.
A "iterable" can be an array or an traversable object.

Technically you are right, my "anything that could be an array index"
would be equivalent to "string|int".

Personally I don't think we need every possible union, let alone intersections.
I am not strictly opposed to them, but don't find them as necessary.
Most well-written functions will have one return type.
But there are some cases of naturally occuring union or meta types,
which might deserve their own meta type name.



On 19 December 2017 at 16:28, Levi Morrison <le...@php.net> wrote:
> On Tue, Dec 19, 2017 at 4:47 AM, Andreas Hennings <andr...@dqxtech.net> wrote:
>> On 19 December 2017 at 08:06, Fleshgrinder <p...@fleshgrinder.com> wrote:
>>> What is really needed are `scalar`, `number`, union types, intersection
>>> types, and all that together with generics.
>>
>> Do we have ongoing discussions or RFCs for those already?
>> I know we have one for generics, which seems somehow stuck,
>> https://wiki.php.net/rfc/generics
>
> No. Work is quietly being done on parameterized types (aka generics) here:
>
> https://github.com/morrisonlevi/php-src/tree/parameterized_traits
>
> There really isn't a lot to discuss at this stage anyway; the
> technical implementation is paramount.
>
>> What would "scalar" mean exactly? string+int+float?
>
> Scalar and number are just ways of naming certain union types which
> feature was already declined. Maybe a single RFC which targets both
> union and intersection types would pass. Our `is_scalar` function
> returns true for integer, float, string or boolean; a scalar type
> should mirror that definition: int | float | string | bool.
>
>> I would sometimes like a string+int, for "everything that can be an array 
>> key".
>
> This is just another named union for `string | int`.

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



Re: [PHP-DEV] [RFC] Mixed Typehint

2017-12-19 Thread Andreas Hennings
On 19 December 2017 at 08:06, Fleshgrinder  wrote:
> What is really needed are `scalar`, `number`, union types, intersection
> types, and all that together with generics.

Do we have ongoing discussions or RFCs for those already?
I know we have one for generics, which seems somehow stuck,
https://wiki.php.net/rfc/generics

What would "scalar" mean exactly? string+int+float?
I would sometimes like a string+int, for "everything that can be an array key".

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



Re: [PHP-DEV] [RFC] Mixed Typehint

2017-12-19 Thread Andreas Hennings
Perhaps this is the same reason why we add "public" keyword, even
though a member is implicitly public by default.

On 19 December 2017 at 12:34, Andreas Hennings <andr...@dqxtech.net> wrote:
> I agree with Michael Kliewe.
> When looking at code, I want to distinguish between:
> - Developer forgot to add a type hint, or it was left out for legacy /
> BC reasons.
> - The function can really return various types, at least too many for
> any more specific type hint.
>
>
> On 19 December 2017 at 04:57, li...@rhsoft.net <li...@rhsoft.net> wrote:
>> no, mixed is used in phpdoc comments to say "no type specified at all" when 
>> a param accepts anything and in case of "@return mixed" that it can return 
>> void, array, int.
>
> I think "mixed" should not include "void".
> A well-written method/function either has a return value or not. It it
> is type-hinted as "mixed", then we should expect it to have a return
> value.
>
> On 19 December 2017 at 08:06, Fleshgrinder <p...@fleshgrinder.com> wrote:
>> What is really needed are `scalar`, `number`, union types, intersection
>> types, and all that together with generics.
>
> I would like to see those too, but they are not mutually exclusive
> with "mixed" and should rather be discussed separately.
>
>
>
> On 19 December 2017 at 11:01, Michael Kliewe <i...@phpgangsta.de> wrote:
>> Am 19.12.2017 um 07:32 schrieb Stanislav Malyshev:
>>>
>>>> I'd like to propose and discuss Mixed Typehint RFC for PHP 7.3:
>>>> https://wiki.php.net/rfc/mixed-typehint
>>>>
>>>> The purpose of this RFC is to introduce "mixed" typehint on language level
>>>> to be used
>>>> as a valid typehint. PHP currently forces users to not use any type in case
>>>> the
>>>> type is mixed/unclear. This makes code inconsistent and less explicit. With
>>> I'm not sure what's the point of it. "mixed" means "any type". Not
>>> writing a type means "any type". So why waste space and add something
>>> that contributes nothing when everybody is already using the current
>>> convention and the new one does not add anything at all?
>> A "mixed" type hint says that it's really "mixed", and the developer who
>> wrote that code did not forget to add a type hint.
>> If you see a place where a type hint is missing, you don't know if it's
>> mixed, or the developer/you missed to write the correct type hint.
>>
>> That's the benefit I see. I would explicitly write "mixed" everywhere in
>> a fully type-hinted codebase, to eliminate this thought while reading:
>> Is it really mixed, or was this place overseen and it's not mixed, but
>> something else...
>> Because it's optional, nobody is hurt, but some people (like me) could
>> add this explicit information.
>>
>> Michael
>>
>> --
>> PHP Internals - PHP Runtime Development Mailing List
>> To unsubscribe, visit: http://www.php.net/unsub.php
>>

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



Re: [PHP-DEV] [RFC] Mixed Typehint

2017-12-19 Thread Andreas Hennings
I agree with Michael Kliewe.
When looking at code, I want to distinguish between:
- Developer forgot to add a type hint, or it was left out for legacy /
BC reasons.
- The function can really return various types, at least too many for
any more specific type hint.


On 19 December 2017 at 04:57, li...@rhsoft.net  wrote:
> no, mixed is used in phpdoc comments to say "no type specified at all" when a 
> param accepts anything and in case of "@return mixed" that it can return 
> void, array, int.

I think "mixed" should not include "void".
A well-written method/function either has a return value or not. It it
is type-hinted as "mixed", then we should expect it to have a return
value.

On 19 December 2017 at 08:06, Fleshgrinder  wrote:
> What is really needed are `scalar`, `number`, union types, intersection
> types, and all that together with generics.

I would like to see those too, but they are not mutually exclusive
with "mixed" and should rather be discussed separately.



On 19 December 2017 at 11:01, Michael Kliewe  wrote:
> Am 19.12.2017 um 07:32 schrieb Stanislav Malyshev:
>>
>>> I'd like to propose and discuss Mixed Typehint RFC for PHP 7.3:
>>> https://wiki.php.net/rfc/mixed-typehint
>>>
>>> The purpose of this RFC is to introduce "mixed" typehint on language level
>>> to be used
>>> as a valid typehint. PHP currently forces users to not use any type in case
>>> the
>>> type is mixed/unclear. This makes code inconsistent and less explicit. With
>> I'm not sure what's the point of it. "mixed" means "any type". Not
>> writing a type means "any type". So why waste space and add something
>> that contributes nothing when everybody is already using the current
>> convention and the new one does not add anything at all?
> A "mixed" type hint says that it's really "mixed", and the developer who
> wrote that code did not forget to add a type hint.
> If you see a place where a type hint is missing, you don't know if it's
> mixed, or the developer/you missed to write the correct type hint.
>
> That's the benefit I see. I would explicitly write "mixed" everywhere in
> a fully type-hinted codebase, to eliminate this thought while reading:
> Is it really mixed, or was this place overseen and it's not mixed, but
> something else...
> Because it's optional, nobody is hurt, but some people (like me) could
> add this explicit information.
>
> Michael
>
> --
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: http://www.php.net/unsub.php
>

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



Re: [PHP-DEV] Covariance, again

2017-12-18 Thread Andreas Hennings
> I really think we ought to tackle covariant returns and contravariant 
> parameters

My "algorithm" could be extended for contravariance:
Whenever a method has a parameter type hint that differs from the
parent type hint, autoload the class of the parent type hint.

I think I know too little about the internal workings of PHP to
understand why your examples would break.
I think we should give it a try, and write your examples as unit tests
to try to crash it.

If we indeed can produce circularity problems, then I might have more ideas.
I think the main idea in my algorithm about which classes needs to be
autoloaded and which don't is good.
Maybe at some point we need to write a class into the table of defined
classes, before it is fully verified.

At some point, for a different purpose, I thought about "stub"
classes, which have all the information from the declaration itself,
but not from any parent class. So we could write classes into the stub
table and then later write the completed thing into the actual class
table/list.
But maybe we don't need to go that far.

If I were to do this, it would be my first shot on the php engine
itself. Not going to happen today, but maybe I will find time for it
in a future month or so.
I am sure if/when I have done this, I can write more knowledgeable
posts here on this mailing list.
Of course if someone else wants to step up, go ahead.

I think the goal and spec is pretty clear. So once we have a
proof-of-concept implementation and show that it can be done and the
problems can be solved, it would be straightforward to make an RFC.
If we would do the RFC first, people would have to vote on something
which is unclear if it can be implemented.


On 18 December 2017 at 21:48, Levi Morrison <le...@php.net> wrote:
> On Mon, Dec 18, 2017 at 11:52 AM, Andreas Hennings <andr...@dqxtech.net> 
> wrote:
>>> I believe your algorithm fails on this simple setup:
>>
>> Another comment I want to make here:
>> The examples you give each have multiple class declarations per file.
>> I would personally not care much, if these result in fatal error.
>> All of this code used to be illegal until now (because no covariance
>> support), so it would not be a BC problem if some of it continues to
>> be illegal.
>
> Just because it isn't a backwards compatibility break doesn't mean
> it's a good way forward. Right now people have covariant returns -
> they just don't express it in the signature because we don't allow it.
> Wouldn't it seem odd that if the bodies of the methods stayed the same
> and all they did was update the signature that it somehow breaks their
> code?
>
> I have some ideas about minimizing this impact but I really think we
> ought to tackle covariant returns and contravariant parameters at the
> same time. Any endeavor to add one should add the other to create a
> cohesive design that works in both cases.

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



Re: [PHP-DEV] Covariance, again

2017-12-18 Thread Andreas Hennings
> I believe your algorithm fails on this simple setup:

Another comment I want to make here:
The examples you give each have multiple class declarations per file.
I would personally not care much, if these result in fatal error.
All of this code used to be illegal until now (because no covariance
support), so it would not be a BC problem if some of it continues to
be illegal.


This being said: I think we can probably construct examples that have
one-class-per-file, but that still have a circularity problem due to
covariance.
Or possibly even with class_exists()?
I am going to play around a bit.


>
> 
> interface A {
> function foo(): X;
> }
>
> interface B extends A {
> function foo(): Y;
> }
>
> interface X {
> function bar(): A;
> }
>
> interface Y extends X {
> function bar(): B;
> }
>
> ?>
>
> If I correctly typed this from memory there is no way to order this
> such that all units are defined ahead of time as needed for verifying
> correctness. This means we trigger the autoloader even though the type
> is defined in the same file. Even if we do some more complicated
> compile-time passes we'd fail on things like this:
>
> 
> interface A {
> function foo(): X;
> }
>
> interface B extends A {
> function foo(): Y;
> }
>
> if (getenv("ENABLE_X")) {
> interface X {
> function bar(): A;
> }
> }
> ?>
> 
> interface Y extends X {
> function bar(): B;
> }
>
> ?>
>
> This case shows that care needs to be taken to get the order down
> correctly even if we autoload:
>
>  interface A {
> function foo(): X;
> }
>
> interface B extends A {
> function foo(): Y;
> }
> ?>
>  interface X {
> function bar(): A;
> }
> ?>
> 
> interface Y extends X {
> function bar(): C;
> }
> // At this point the engine will need to verify A and C but we may not
> have finished verifying A and B yet
> ?>
>
> All-in-all I don't think we can resolve every case cleanly because we
> do not have purely ahead-of-time compilation for all units involved. I
> think every method of implementing this feature has drawbacks and we
> need to thoughtfully evaluate them.

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



Re: [PHP-DEV] Covariance, again

2017-12-18 Thread Andreas Hennings
Ok, I think I missed the circularity aspect in your examples.
Inheritance by itself is never circular.
However, return types can make this entire thing circular.

So the problem would be if we try to autoload the same thing that is
currently in the process of being being defined.

Maybe we could generate similar circularity problems with class_exists() calls?

On 18 December 2017 at 15:58, Andreas Hennings <andr...@dqxtech.net> wrote:
> Let me address the simple example first.
>
> On 18 December 2017 at 15:45, Levi Morrison <le...@php.net> wrote:
>>
>> I believe your algorithm fails on this simple setup:
>>
>> >
>> interface A {
>> function foo(): X;
>> }
>>
>> interface B extends A {
>> function foo(): Y;
>> }
>>
>> interface X {
>> function bar(): A;
>> }
>>
>> interface Y extends X {
>> function bar(): B;
>> }
>>
>> ?>
>>
>> If I correctly typed this from memory there is no way to order this
>> such that all units are defined ahead of time as needed for verifying
>> correctness. This means we trigger the autoloader even though the type
>> is defined in the same file. Even if we do some more complicated
>> compile-time passes we'd fail on things like this:
>
> You need to compile all classes in the file, and then do the autoloading.
> So maybe my description of the algorithm is too simple.
>
> However, this is not really new, and is not really a problem I would say.
> What about this: https://3v4l.org/5klJQ
>
>  class C implements I {}
>
> interface I {}
> ?>
>
> Here the interface I is declared after the class C that implements the
> interface.
> This means the autoloading for identifiers in "extends" or
> "implements" clauses already need to wait for the current file to be
> fully processed.
>
> So yes, we need to process the entire file before autoloading anything.
> But we already do that for inheritance. So it is nothing new.

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



Re: [PHP-DEV] Covariance, again

2017-12-18 Thread Andreas Hennings
Let me address the simple example first.

On 18 December 2017 at 15:45, Levi Morrison  wrote:
>
> I believe your algorithm fails on this simple setup:
>
> 
> interface A {
> function foo(): X;
> }
>
> interface B extends A {
> function foo(): Y;
> }
>
> interface X {
> function bar(): A;
> }
>
> interface Y extends X {
> function bar(): B;
> }
>
> ?>
>
> If I correctly typed this from memory there is no way to order this
> such that all units are defined ahead of time as needed for verifying
> correctness. This means we trigger the autoloader even though the type
> is defined in the same file. Even if we do some more complicated
> compile-time passes we'd fail on things like this:

You need to compile all classes in the file, and then do the autoloading.
So maybe my description of the algorithm is too simple.

However, this is not really new, and is not really a problem I would say.
What about this: https://3v4l.org/5klJQ



Here the interface I is declared after the class C that implements the
interface.
This means the autoloading for identifiers in "extends" or
"implements" clauses already need to wait for the current file to be
fully processed.

So yes, we need to process the entire file before autoloading anything.
But we already do that for inheritance. So it is nothing new.

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



[PHP-DEV] Covariance, again

2017-12-18 Thread Andreas Hennings
There were discussions about covariance and contravariance in the past.
https://externals.io/message/98085#98105
Unfortunately I was not subscribed back then, so I cannot respond to anything.
So, here it goes again.

WIth co- and contravariance, the following would be possible:
- contravariance.php - https://3v4l.org/I3v0u
- covariance.php - https://3v4l.org/i79O5

(from guilhermeblanco's older email in "PHP's support to
contravariance and covariance")

The main problem was expressed by Levi Morrison in this older thread.

Currently we do not autoload classes in type hints.
https://3v4l.org/sFsDd
In the example I can declare "UnknownClass" as a return type hint, and
PHP won't care.

However, to validate if a return type matches with the parent
definition, the class must be autoloaded first.
Or rather:
- If the return type is identical with the parent, PHP can say "yes"
with no class loading required.
- If the return type is different from the parent:
-- Currently, PHP simply says "no" (Fatal error: Declaration of
C::foo(): C must be compatible with I::foo()).
-- To support covariance, PHP would have to autoload the class in the
type hint, and then check the hierarchy.


## Solutions proposed in old thread

Levi Morrison:

> You need to adjust the passes over the code to register symbols and
> their declared relationships, and then in a separate pass validate
> them. After that if the class isn't found then you trigger an
> autoload.
>
> It's doable, it just hasn't been done.

Christoph M. Becker:

> An alternative might be forward class declarations:


## What I propose instead

I think it is not so complicated actually, and can be done without BC
break, and without forward type hints.
This only gives us covariance. Contravariance is another story.

When a class declaration is executed, do the following:
- Parse the class AST (obviously).
- Autoload all identifiers in "extends" and "implements".
- Autoload all identifiers in return type hints that are not identical
with the parent return type hint.

If such a class is not found, report "Return type must either be
identical with the parent, or it must be an existing or autoloadable
class or interface."
Well, or any message that clarifies why this one was autoloaded, while
other type hint classes are not autoloaded.

So, this behavior is the same as today, except for the case of return
type hints that differ from the parent, which currently result in
fatal error.

Does this sound doable? Am I missing something else?

-- Andreas

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



Re: [PHP-DEV] [RFC] Namespace-scoped declares, again

2017-12-12 Thread Andreas Hennings
On 13 December 2017 at 05:04, Michał Brzuchalski  wrote:
>
> If we're going to introduce someday a namespace file, then IMO it should not
> be putted outside namespace folder.
> For eg class Acme\Animal\Cat in src/Acme/Animal/Cat.php should have
> namespace file in src/Acme/Aniimal/namespace.php
> or even more src/Acme/Animal/ns.php
> Why? Because users use PSR-4 so then they're src folder looks more like:
> src/Cat.php <-- class Acme\Animal\Cat
> src/ns.php <-- that should be then a place for namespace declare or even
> function and constants.

You are right, my previous proposal src/Acme/Animal.namespace.php
would not work universally.

But your proposal, src/Acme/Animal/ns.php clashes with the class file
for class \Acme\Animal\ns.

We would need something other than NAME.php.
E.g. src/Acme/Animal/ns.inc.php

But then Composer would still need to make sure that this file is
always included before any class files from this directory.
On language level we cannot assume that Composer is being used, and
that it is being used correctly.

So again this would be fragile.

>
> Such namespace file can be a good place for namespace function and constants
> declaration.
> Also I think there is no need for another global function named
> `namespace_declare` if we had namespace file
> then we can utilise declare for that.
> Lets imagine such syntax:
>
> // src/Acme/Animal/ns.php
> 
> namespace Acme\Animal declare(strict_types=1,another_option=0);
> const CAT = 1;
> function createCat() : Cat {}

This means you are changing the meaning of existing declare() to apply
to the entire namespace?
Or to the entire directory?

Or maybe the difference here is that there is no semicolon directly
after the namespace declaration?

I am not convinced by this syntax.
But even if we would find a good syntax, the behavioral problems
pointed out by Stanislav still apply.

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



Re: [PHP-DEV] [RFC] Namespace-scoped declares, again

2017-12-12 Thread Andreas Hennings
I agree with all of Stanislav's emails in this thread so far.

On 12 December 2017 at 14:43, Nikita Popov  wrote:
> On Tue, Dec 12, 2017 at 8:46 AM, Stanislav Malyshev 
> wrote:
>
>> Hi!
>>
>> > The idea is to allow specifying declare directives for a whole library or
>> > project using:
>> >
>> > namespace_declare('Vendor\Lib', ['strict_types' => 1]);
>>
>> I am not sure I like this. Namespace is a prefix to a class name.
>> Anybody can declare a class with any name, and the side-effect that they
>> would inherit some context, which is completely invisible and would
>> magically exist somewhere globally, does not seem like a good idea to
>> me. Moreover, what if something - like older version of the same library
>> or test or something like that - would have different idea about what
>> that global state should be? How nice would it be if a piece of
>> unrelated code could completely change how my code is interpreted? How
>> nice would it be if whether it works or not would depend on in which
>> order classes were loaded in this particular request?
>>
>
> The way PHP works, it's not possible to have two versions of a library
> loaded at the same time.

Really?
PHP does not even know what a "library" is. PHP sees files,
directories and namespaces. But it does not know how to conceptualize
any of this as a "library".

With Composer you get the notion of a "package".
In general, Composer would prevent you from using different versions
of the same package.
But you could manually download two versions of a package, and wire up
the class loader in a way that it would load some classes from one
version, and some classes from another version.
E.g. if a class does not exist in version 2, load the class from
version 1 instead.

PHP as a language should not assume that someone is using Composer correctly.

And even if we avoid two package versions coexisting: There could
easily be two distinct packages that use the same namespace.
We could discuss if this is a good idea, but it should not be the job
of PHP as a language to make this situation difficult.

>
> There is no dependence on loading order. The implementation is careful to
> ensure that the used declare state is consistent. It's not possible to call
> namespace_declare() twice on the same namespace. It's not possible to first
> load some files from a namespace, do the namespace_declare() call and then
> load some more files. If a namespace_declare() call succeeds without
> throwing an error, then that is the ground truth, without any dependence on
> order or other calls.

So by "is not possible", in fact you mean "will trigger an error".

I imagine with Composer we would have to agree on a canonical file
name where a namespace_declare() would be found.
Maybe something like in src/Acme/Animal.namespace.php.

The class loader would then have to make sure that this file is
included before the first class from that namespace is included.
Or alternatively, Composer init script would have to include all such
files at the beginning of the process.

If Composer (or whichever tool one wants to use) would include class
file src/Acme/Animal/Cat.php without prior inclusion of the
Animal.namespace.php, the class file would be interpreted without the
desired setting.
If the process then continues without ever including
Animal.namespace.php, it will silently misbehave.
If, however, Animal.namespace.php is included some time later in the
process, then it would notice that something went wrong, and trigger
an error.

> I haven't thought too carefully about whether having an option for the
> explicit-send-by-ref feature *specifically* would be beneficial, but I
> think it's very important to at least have the option on the table. Too
> many issues in PHP cannot be solved for reasons of backwards-compatibility.
> We need to have *some* way to evolve the language without BC breaks, and I
> think namespace-declares are an elegant way to do this.


So if you want a setting for explicit-send-by-ref, why not do this per
file, as we already do for strict_types?

If at some day in the future we find that the declares become too
verbose, we could bundle multiple declares into a new setting.
E.g. something like "declare(php=8.1);" to combine all the declares
that would be considered default in PHP 8.1.

Or introduce some other shortcut like "http://www.php.net/unsub.php



Re: [PHP-DEV] Reflection API: Add ::getFullName() method.

2017-12-11 Thread Andreas Hennings
>> >
>> > Obviously, the `\0` is horrible and can probably be improved: depends on
>> > whether the API is intended for human or machine consumption. If it is
>> > machine consumption, strings are the wrong approach anyway.
>>
>> Machine or human?
>> One goal is that these names can be used as array keys or unique
>> identifiers whenever we deal with a collection of reflectors of mixed
>> type.
>> At the same time, the name is designed to be very close to what is
>> printed in exception messages, @see doc comment, etc.
>> In this case, I don't see a conflict between human-readable and
>> machine-readable.
>>
>> Maybe when you say "machine consumption" you are thinking of something
>> else?
>
>
> Machine consumption would be VOs, not strings ;-)

One purpose of such names would be that they can be saved in a file or
database, and read in another process.

If you want a value object, then why not use the reflector object directly?
Ok, because "side effects" - I agree.

If we want a value object, it should be named like "ReflectorHandle",
and then "ClassHandle", "FunctionHandle" etc.
These would provide the name of a class, but not any information about it.

But this should be in a separate method, e.g.
ReflectionClass->getHandle(), and it would be a separate feature for a
separate thread.

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



Re: [PHP-DEV] Reflection API: Add ::getFullName() method.

2017-12-11 Thread Andreas Hennings
See http://php.net/manual/en/language.namespaces.rules.php

What you mean is a "qualified name" so it would be a QN.

On 11 December 2017 at 10:28, Marco Pivetta <ocram...@gmail.com> wrote:
> Weird, that looks wrong to me, so I may be wrong here.
>
> When receiving a string containing a symbol, the only sensible approach is
> to consider it a FQN, as no context is provided with the string.
>
> Marco Pivetta
>
> http://twitter.com/Ocramius
>
> http://ocramius.github.com/
>
> On Mon, Dec 11, 2017 at 10:23 AM, Andreas Hennings <andr...@dqxtech.net>
> wrote:
>>
>> On 11 December 2017 at 10:16, Marco Pivetta <ocram...@gmail.com> wrote:
>> > On Mon, Dec 11, 2017 at 10:03 AM, Andreas Hennings <andr...@dqxtech.net>
>> > wrote:
>> >>
>> >> On 11 December 2017 at 09:16, Marco Pivetta <ocram...@gmail.com> wrote:
>> >> > If you really want to expose a symbol's FQN,
>> >>
>> >> Just to clarify: For me, "FQN" means "fully-qualified name", which
>> >> begins with "\\".
>> >> This is specifically not what I propose here. I want the name without
>> >> the leading namespace separator.
>> >> So maybe "getFullName()" is misleading.
>> >
>> >
>> > A FQN does not start with `\`. In strings, you always use the FQN
>>
>> I was following the FQN definition from php-fig group like here,
>>
>>
>> https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-4-autoloader.md
>>
>> Maybe this is wrong?
>
>

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



Re: [PHP-DEV] Reflection API: Add ::getFullName() method.

2017-12-11 Thread Andreas Hennings
On 11 December 2017 at 10:16, Marco Pivetta <ocram...@gmail.com> wrote:
> On Mon, Dec 11, 2017 at 10:03 AM, Andreas Hennings <andr...@dqxtech.net>
> wrote:
>>
>> On 11 December 2017 at 09:16, Marco Pivetta <ocram...@gmail.com> wrote:
>> > If you really want to expose a symbol's FQN,
>>
>> Just to clarify: For me, "FQN" means "fully-qualified name", which
>> begins with "\\".
>> This is specifically not what I propose here. I want the name without
>> the leading namespace separator.
>> So maybe "getFullName()" is misleading.
>
>
> A FQN does not start with `\`. In strings, you always use the FQN

I was following the FQN definition from php-fig group like here,

https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-4-autoloader.md

Maybe this is wrong?

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



Re: [PHP-DEV] Reflection API: Add static factories on ReflectionType

2017-12-11 Thread Andreas Hennings
On 11 December 2017 at 08:58, Marco Pivetta <ocram...@gmail.com> wrote:
> What's the use-case for creating a userland `ReflectionType` instance,
> besides mocking the reflection API itself?
> Consider that the subclassing in userland already provides an easy way to
> perform these operations (although ugly):
> https://github.com/Roave/BetterReflection/blob/2.0.1/src/Reflection/Adapter/ReflectionType.php

You are right.
And it does not even need BetterReflection library, it only needs one
single class which can also be defined locally.
It only needs $this->name, $this->allowsNull and $this->isBuiltin as
private properties.

(nothing against the library, just in case someone only needs this one feature)



Still, I think having a documented native constructor and/or static
factories would make this API more complete.
Without this, it seems like someone walked away from a construction site.

Also, inheriting from core reflection classes, I imagine always
carries some baggage.
(as opposed to implementing an interface)



>
> Not trying to drag down your proposal, but as you can see this is already
> being done and works very well and is very well tested for BC compliance
> (should new methods land into `ReflectionType`).
>
> Also, I'd add that a the proposed API should accept
> `InternalType|ReflectionClass|null`, and not `string` (separate named
> constructors would be best) which is basically the reason for most
> hair-pulling around the PHP lang.
>
> A small `InternalType` VO that throws on `InternalType::fromString() : self`
> would be extremely beneficial to avoid the continuously growing list of edge
> cases and additions required to accommodate for new internal types being
> added to the language.
>
> On 11 Dec 2017 08:25, "Andreas Hennings" <andr...@dqxtech.net> wrote:
>
> Currently there is no (documented) way to directly create a
> \ReflectionType object.
> The class has no documented constructor.
>
> I propose that static factory methods shall be added for this purpose.
>
> This will be useful for code that wants to dynamically create and pass
> around reflection type objects.
>
>
> /** @var bool $allowsNull */
>
> $t1 = \ReflectionType::fromBuiltinType('string', $allowsNull);
> $t2 = \ReflectionType::fromClassName(\stdClass::class, $allowsNull);
>
> assert(true === $t1->isBuiltin());
> assert(false === $t2->isBuiltin());
>
> assert('string' === $t1->getName());
> assert(\stdClass::class === $t2->getName());
>
>
> To be discussed:
> - method names
> - Whether to return ReflectionNamedType or ReflectionType or something else.
>
> (I don't find ReflectionNamedType documented in
> http://php.net/manual-lookup.php?pattern=ReflectionNamedType)
>
> --
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: http://www.php.net/unsub.php
>
>

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



Re: [PHP-DEV] Reflection API: Add ::getFullName() method.

2017-12-11 Thread Andreas Hennings
On 11 December 2017 at 09:16, Marco Pivetta  wrote:
> If you really want to expose a symbol's FQN,

Just to clarify: For me, "FQN" means "fully-qualified name", which
begins with "\\".
This is specifically not what I propose here. I want the name without
the leading namespace separator.
So maybe "getFullName()" is misleading.

> I suggest exposing the internal
> name as per `(array)` cast semantics.

This distinction is not needed here.
The semantics for array keys in array-to-object casting are to
distinguish overshadowed private properties from parent classes.
This is because values for these properties can coexist within one object.

E.g.

class B {
  private $x = 'b';
}

class C extends B {
  private $x = 'c';
}

var_export((array)(new C));


Output: https://3v4l.org/0QE3s

array (
 '' . "\0" . 'C' . "\0" . 'x' => 'c',
 '' . "\0" . 'B' . "\0" . 'x' => 'b',
 )


For ReflectionClass->getProperties() and ->getProperty($name) only
gives us the version of each property that is visible on the top
level.

https://3v4l.org/LWWSf

E.g.

$obj = new

(new \ReflectionClass(C::class)->getProperty('x')



>
> namespace A {
> class B {
> public $c;
> private $d;
> private $e;
> }
> }
>
> That would be:
>
> "A\B#\$c"
> "A\B#\0*\0\$d"
> "A\B#\0A\\B\0\$e"
>
> Obviously, the `\0` is horrible and can probably be improved: depends on
> whether the API is intended for human or machine consumption. If it is
> machine consumption, strings are the wrong approach anyway.

Machine or human?
One goal is that these names can be used as array keys or unique
identifiers whenever we deal with a collection of reflectors of mixed
type.
At the same time, the name is designed to be very close to what is
printed in exception messages, @see doc comment, etc.
In this case, I don't see a conflict between human-readable and
machine-readable.

Maybe when you say "machine consumption" you are thinking of something else?


>
> I'd also add that this would be (fucking finally!) a good way to fix PHP's
> documentation horrible usage of `::` for both instance and static members.

Ok, tbh, so far I thought of using the same "::" for both :)
So for all properties it would be Cat::$color.

Maybe instead we could do Cat->color for instance members?

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



Re: [PHP-DEV] ReflectionContext for imports and namespace

2017-12-11 Thread Andreas Hennings
On 11 December 2017 at 09:23, Andreas Hennings <andr...@dqxtech.net> wrote:
>>> These side effects would be that the class loader loads files which can
>>> break things?
>>
>>
>> Yes. Reflecting over a codebase which contains even just polyfills
>> (duplicate classes) can already lead to unexpected crashes. Reflecting over
>> non-PSR-2 code can even lead to worse things such as starting a DB
>> connection and performing unwanted operations.
>>
>
> My own use case avoids this problem.
> Instead of randomly scanning anything, you need to tell the annotation
> parser explicitly which namespace directory you want to scan.
> It is the caller's responsibility that all class files in this
> directory are nicely shaped, and can be safely autoloaded.
>
> In fact I did use a userland parser in the past, but then decided that
> native reflection is safe with the above assumption.


Maybe one fragile edge case would be if one of the files causes the
autoloader to include a different file, outside of the library, due to
ambiguous namespace mapping.
But this problem would also occur during everyday use of the library,
if this class is used.

So the condition is: Only scan namespace directories where you know
that every class can be safely autoloaded.
In fact I do not explicitly include the class file, but let the class
loader do this, to be sure that the same version of the class is used
that would be used in a regular request / process.

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



Re: [PHP-DEV] ReflectionContext for imports and namespace

2017-12-11 Thread Andreas Hennings
>> These side effects would be that the class loader loads files which can
>> break things?
>
>
> Yes. Reflecting over a codebase which contains even just polyfills
> (duplicate classes) can already lead to unexpected crashes. Reflecting over
> non-PSR-2 code can even lead to worse things such as starting a DB
> connection and performing unwanted operations.
>

My own use case avoids this problem.
Instead of randomly scanning anything, you need to tell the annotation
parser explicitly which namespace directory you want to scan.
It is the caller's responsibility that all class files in this
directory are nicely shaped, and can be safely autoloaded.

In fact I did use a userland parser in the past, but then decided that
native reflection is safe with the above assumption.

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



Re: [PHP-DEV] ReflectionContext for imports and namespace

2017-12-11 Thread Andreas Hennings
On 11 December 2017 at 09:05, Marco Pivetta  wrote:

> On 11 December 2017 at 08:46, Marco Pivetta  wrote:
> > Indeed that already exists at
> > https://github.com/Roave/BetterReflection/blob/2.0.1/docs/
> features.md#analysing-types-from-docblocks
> > - relatively new lib, so it probably didn't get noticed upfront in here.
>
>
> Yes, parser / userland solutions exist for this purpose.
> (I have seen BetterReflection)
>
> I just thought since this information is already available, a library
> that uses reflection API should not need a userland parser to get it.
>
>
> Unless the codebase being analyzed is trusted and not legacy
> (wordpress-style) any tool based on the current reflection API is basically
> a potential security issue or a set of potentially harmful side-effects.
> The reason for me and James building BetterReflection was essentially that,
> since the current API is flawed and not really fixable without BC breaks
> (removing the side-effect), so I strongly encourage any code analysis tool
> to just use the userland adapters we wrote, and only switch to core
> reflection when performance is more critical than security.
>

These side effects would be that the class loader loads files which can
break things?


>
> This also means that if your addition makes it into the language it will
> be implemented also by those adapters BTW, so push on 
>


Re: [PHP-DEV] ReflectionContext for imports and namespace

2017-12-10 Thread Andreas Hennings
>
> Documentation tools shouldn't run the code IMO, that means they won't have
> access to that feature.

By "documentation tools" do you mean libraries like phpDocumentor?
You are right, those need to parse anyway, they cannot use reflection API.

But tools for annotation discovery may want to use native reflection
instead of parsing, it is an implementation choice.


>
> Nikic's PHP parser already contains a tool that resolves all namespaces, you
> can probably write a similar visitor for the Ast that also works for PHPdoc
> blocks.
>
> Regards, Niklas

On 11 December 2017 at 08:46, Marco Pivetta  wrote:
> Indeed that already exists at
> https://github.com/Roave/BetterReflection/blob/2.0.1/docs/features.md#analysing-types-from-docblocks
> - relatively new lib, so it probably didn't get noticed upfront in here.


Yes, parser / userland solutions exist for this purpose.
(I have seen BetterReflection)

I just thought since this information is already available, a library
that uses reflection API should not need a userland parser to get it.

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



[PHP-DEV] Reflection API: Add static factories on ReflectionType

2017-12-10 Thread Andreas Hennings
Currently there is no (documented) way to directly create a
\ReflectionType object.
The class has no documented constructor.

I propose that static factory methods shall be added for this purpose.

This will be useful for code that wants to dynamically create and pass
around reflection type objects.


/** @var bool $allowsNull */

$t1 = \ReflectionType::fromBuiltinType('string', $allowsNull);
$t2 = \ReflectionType::fromClassName(\stdClass::class, $allowsNull);

assert(true === $t1->isBuiltin());
assert(false === $t2->isBuiltin());

assert('string' === $t1->getName());
assert(\stdClass::class === $t2->getName());


To be discussed:
- method names
- Whether to return ReflectionNamedType or ReflectionType or something else.

(I don't find ReflectionNamedType documented in
http://php.net/manual-lookup.php?pattern=ReflectionNamedType)

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



[PHP-DEV] Re: Add \Reflection*::getHash()

2017-12-10 Thread Andreas Hennings
On 11 December 2017 at 04:03, Andreas Hennings <andr...@dqxtech.net> wrote:
> So far this proposal only discusses reflections of PHP declarations / symbols.
>
> What would we do for e.g. ReflectionObject?
> Return the spl_object_hash()?
> Or return the hash of the instantiated class?
> Or a hash of the serialized object?
> We need to return something, because ReflectionObject extends ReflectionClass.

If the method is instead named ::getDeclarationHash(), it will be
clear that ReflectionObject->getDeclarationHash() will be the same as
for the instantiated class.

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



[PHP-DEV] Re: Add \Reflection*::getHash()

2017-12-10 Thread Andreas Hennings
So far this proposal only discusses reflections of PHP declarations / symbols.

What would we do for e.g. ReflectionObject?
Return the spl_object_hash()?
Or return the hash of the instantiated class?
Or a hash of the serialized object?
We need to return something, because ReflectionObject extends ReflectionClass.


On 11 December 2017 at 03:11, Andreas Hennings <andr...@dqxtech.net> wrote:
> I propose to add a new method ::getHash() to reflection API classes.
>
> Such that:
>
> Two reflectors return the same hash, if and only if:
>
> 1. the reflected items have the same type (class, method, parameter etc), AND.
> 2. the reflected items have the same names, AND.
> 3. the reflected items have the same PHP code (e.g. for distinct
> processes), AND.
> 4. optionally: Every base class, every implemented interface and every
> used trait has the same PHP code (and thus, the same hash).
> 5. optionally: The PHP version and PHP settings are the same. (*)
>
> Such an id can be used as a cache key between requests.
>
> It would automatically change / become invalid, if:
> - new code changes are deployed, OR.
> - different processes include different files that each declare the
> same class, OR.
> - php is upgraded, or php settings change. (*)
>
> Currently the best way (for practicality and performance) to achieve
> something like this is to get the timestamp of the file that defines
> the class.
>
> Note: The behavior of a function can change if the code of another
> function that is being called is modified.
> The hash would still be the same, because it does not look at
> functions being called.
>
> (*) Maybe for the php version and settings there should instead be a
> global hash, which can be used as salt for a combined cache key.
>
>
> I was first going to propose to add this new method directly on
> \Reflector interface.
> But this would be a BC break, because userland classes that implement
> this interface would break.
>
> So instead, either
> - add it to each class separately, or
> - add a new interface \Reflector2 extends \Reflector (yeah, versioned
> interfaces!), and let all reflection classes implement that.

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



[PHP-DEV] Reflection API: Add ::getFullName() method.

2017-12-10 Thread Andreas Hennings
I propose a new method ::getFullName() for all methods that implement
\Reflector.
(I would add it to the \Reflector interface, but this would be a BC break.)

The full name would be, depending on the type:

function: "str_replace()", "Acme\foo()".
class: "Acme\Animal\Cat", "stdClass".
method: "Acme\Animal\Cat::meow()".
property: "Acme\Animal\Cat::$color".
etc.

I don't know if we can cover all reflection API classes in a meaningful way.
E.g. for ReflectionObject, the full name would be the same as for the
class, otherwise it would get complicated.

Currently the ::__toString() and ::export() return something else,
which is not really useful.

The goal is to have something that is different for different items.
E.g. a class and a function with the same name need to have a
different "full name", hence the added "()" for functions and methods.

As a rule of thumb, the "full name" is what one would put after a @see
tag in phpDoc, but without the leading "\\".
For consistency with the rest of PHP and reflection API, we should use
QN and not FQN as return value.


Related: I started another thread proposing a ::getHash() method.
I originally though to propose the two things in the same thread, but
I now think they should be discussed independently.

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



[PHP-DEV] Add \Reflection*::getHash()

2017-12-10 Thread Andreas Hennings
I propose to add a new method ::getHash() to reflection API classes.

Such that:

Two reflectors return the same hash, if and only if:

1. the reflected items have the same type (class, method, parameter etc), AND.
2. the reflected items have the same names, AND.
3. the reflected items have the same PHP code (e.g. for distinct
processes), AND.
4. optionally: Every base class, every implemented interface and every
used trait has the same PHP code (and thus, the same hash).
5. optionally: The PHP version and PHP settings are the same. (*)

Such an id can be used as a cache key between requests.

It would automatically change / become invalid, if:
- new code changes are deployed, OR.
- different processes include different files that each declare the
same class, OR.
- php is upgraded, or php settings change. (*)

Currently the best way (for practicality and performance) to achieve
something like this is to get the timestamp of the file that defines
the class.

Note: The behavior of a function can change if the code of another
function that is being called is modified.
The hash would still be the same, because it does not look at
functions being called.

(*) Maybe for the php version and settings there should instead be a
global hash, which can be used as salt for a combined cache key.


I was first going to propose to add this new method directly on
\Reflector interface.
But this would be a BC break, because userland classes that implement
this interface would break.

So instead, either
- add it to each class separately, or
- add a new interface \Reflector2 extends \Reflector (yeah, versioned
interfaces!), and let all reflection classes implement that.

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



[PHP-DEV] Reflection API: Add ->getTerminatedNamespace() method

2017-12-10 Thread Andreas Hennings
## Background / motivation

Currently a number of reflection classes have a method ->getNamespaceName().

The namespace comes in a format that is not straightforward to work with.
It requires the root namespace to be treated in a special way.

$namespace = $relfClass->getNamespaceName();
$shortname = $reflClass->getShortName();
$class = $reflClass->getName();

if ('' === $namespace) {
  assert($class === $namespace . $shortname);
  assert($class === $shortname);
  assert($class !== $namespace . '\\' . $shortname);
}
else {
  assert($class === $namespace . '\\' . $shortname;
  assert($class !== $namespace . $shortname);
}

Code that deals with namespaces therefore always needs a special case
for the root namespace.


## Proposal

I propose that reflection components that currently have a
->getNamespaceName() method get another method
->getTerminatedNamespace().
This comes with ending namespace separator, unless it is the root namespace.

namespace Acme\Animal;
class Cat {}

assert('Acme\Animal\\' === (new
\ReflectionClass(Cat::class))->getTerminatedNamespace());
assert('Acme\Animal' === (new
\ReflectionClass(Cat::class))->getNamespaceName());

assert('' === (new
\ReflectionClass(\stdClass::class))->getTerminatedNamespace());
assert('' === (new \ReflectionClass(\stdClass::class))->getNamespaceName());

foreach ([Cat::class, \stdClass::class] as $class) {
  $reflClass = new \ReflectionClass($class);
  assert($reflClass->getName() ===
$reflClass->getTerminatedNamespace() . $reflClass->getShortName());
}

This would allow all cases to be covered by the same logic.

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



[PHP-DEV] ReflectionContext for imports and namespace

2017-12-10 Thread Andreas Hennings
TLDR:
I propose to introduce a new class \ReflectionContext (or perhaps
\ReflectionScope?), to give information about imported aliases and the
namespace.


## Background / motivation

Some libraries that parse doc comment annotations, e.g. phpDocumentor,
need to know the class aliases and the namespace that are active in
the place (scope) where the class, function or method is declared.

E.g. phpDocumentor has this class:
https://github.com/phpDocumentor/TypeResolver/blob/552bf401d264a443819a66233932be6a23f59d78/src/Types/Context.php

To get this information, they parse the PHP file where the class is defined:
https://github.com/phpDocumentor/TypeResolver/blob/552bf401d264a443819a66233932be6a23f59d78/src/Types/ContextFactory.php

It would be much more pleasant if PHP would provide this information
through the reflection API.
A custom library should not need to do an expensive and fragile
parsing job for information that is already known.

Also, this external parsing might not cover all cases, depending how
it is implemented. E.g. local namespace scopes in curly brackets. (Who
uses those, btw?)


## Proposal

Make information about class aliases (imported through use statements)
and the active namespace available through the reflection API.

$reflClass = new \ReflectionClass(C::class);
$reflContext = $reflClass->getContext();
$aliases = $reflContext->getAliases();


## Details

class ReflectionContext {

  function getNamespace() : string {..}

  /**
   * @return string[]
   *   Format: $[$alias] = $qcn
   */
  function getAliases() : string[] {..}

  /**
   * @return string|null
   *   The qcn of the class, or null if it is a built-in type like "string".
   */
  function resolveAlias($alias) : ?string {..}
}

The $reflClass->getContext()->getNamespace() is the same as
$reflClass->getNamespace().

But having it all in the $context object allows this object to be
passed around to components that need it.


## Open questions

In a method doc comment, we also want to resolve the "self" keyword.
For this, the class name is needed as well, not just external imports
and namespace.

Maybe also introduce \RefllectionMethod::getContext()? Not sure.

Should it be "context" or "scope"? It is not the same. Maybe "scope"
leads to the wrong expectations.

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



Re: [PHP-DEV] [RFC] Explicit call-site send-by-ref syntax

2017-12-10 Thread Andreas Hennings
Oh wow, feature request already exists, with a link to this thread.

On 10 December 2017 at 22:41, Andreas Hennings <andr...@dqxtech.net> wrote:

>
>
> On 7 December 2017 at 03:04, Stanislav Malyshev <smalys...@gmail.com>
> wrote:
>>
>> All this to achieve no other benefit but a purely cosmetic one which a
>> good IDE could easily deliver to you for free without changing language
>> syntax. I do not think it is worth it.
>>
>
> I agree with Stanislav, this should be the IDE's job.
>
> PhpStorm can already show parameter name hints in function calls. It could
> easily add a feature to show if a parameter is by-reference.
> In fact I will request this as we speak :)
>


Re: [PHP-DEV] [RFC] Explicit call-site send-by-ref syntax

2017-12-10 Thread Andreas Hennings
On 7 December 2017 at 03:04, Stanislav Malyshev  wrote:
>
> All this to achieve no other benefit but a purely cosmetic one which a
> good IDE could easily deliver to you for free without changing language
> syntax. I do not think it is worth it.
>

I agree with Stanislav, this should be the IDE's job.

PhpStorm can already show parameter name hints in function calls. It could
easily add a feature to show if a parameter is by-reference.
In fact I will request this as we speak :)


Re: [PHP-DEV] instanceof survives non-object variables, but crashes on non-object constants.

2017-12-09 Thread Andreas Hennings
On 9 December 2017 at 16:19, Aidan Woods  wrote:

> > where the three lines return `false`, the third [...]
>
> Oops, that should say "the first two lines return `true`, the third
> `false`" (the point here being that they return something, as opposed to
> the later three, which throw).
>
>
This is interesting, I did not know that the right side is also
inconsistent :)

I think the default mental model of a programmer is that an operator or
function only sees the value of an expression, not where this value is
coming from.
There is already an exception to this for by-reference parameters, which
already feels weird e.g. for isset(null).

The inconsistency for the right side of instanceof may be justified, I
don't know. But definitely it is not good for shaping a clear mental model.

The "1 instanceof \stdClass" is nonsensical of course, but not any more
than if(true) or if (5 + 0 === 0) or unreachable code.
I would say the main use case is for a programmer to find out how
instanceof behaves on non-object values.
In this case the experiment will give the wrong answer.

It should be the IDE's job to tell the programmer if something is
nonsensical. The language should only care if it follows the rules, and
these should be as consistent as possible.

So, imo:
- we should let "1 instanceof \stdClass" return false without complaining.
- possible inconsistencies on the right side of instanceof can be discussed
separately.
- extension of instanceof to other types, e.g. "1 instanceof int" can be
discussed separately.

I think the simple change would gradually improve consistency, without
closing any doors on future changes.


Re: [PHP-DEV] instanceof survives non-object variables, but crashes on non-object constants.

2017-12-08 Thread Andreas Hennings
Why is the usage broken? It works :)
In practice, the current version of instanceof has an is_object() built-in.
This is what people could assume from trying.

Of course I don't know how it is implemented internally. Maybe a kitten
dies every time I use instanceof on non-object variables?

If we need an additional is_object() it can make some code more expensive..




On 9 December 2017 at 07:46, Kalle Sommer Nielsen <ka...@php.net> wrote:

> Hi
>
> That is fine for code that is broken in the first place. Similarly we
> added a warning some years back about array to string conversions.
>
> If your code is like the example, it should be updated and warned about as
> you are doing something illogical by first checking the type and or value
> of the operand you are passing to instanceof after.
>
> The impact should be minimal as is, so persevering bc for broken usage is
> a poor argument imo
>
>
>
> On 9 Dec 2017 07.38, "Andreas Hennings" <andr...@dqxtech.net> wrote:
>
>> Adding a warning to something that used to be ok would break existing
>> code.
>> I remember a number of cases where I used instanceof on possibly
>> non-objects.
>>
>> if ($x instanceof C) {
>>   return $x;
>> }
>> elseif ($x === NULL) {
>>  ...
>> }
>>
>> All such code would then produce warnings.
>>
>>
>> On 9 December 2017 at 07:35, Kalle Sommer Nielsen <ka...@php.net> wrote:
>>
>>> Hi
>>>
>>> We should just add a warning to the first example, it seems like an
>>> oversight that it was left silent
>>>
>>> On 9 Dec 2017 07.29 <20%2017%2007%2029>, "Andreas Hennings" <
>>> andr...@dqxtech.net> wrote:
>>>
>>>> The following (https://3v4l.org/A2Tp6) is ok, it simply returns false:
>>>>
>>>> $x = 1;
>>>> $x instanceof \stdClass;
>>>>
>>>>
>>>> The following (https://3v4l.org/IdSBu) gives a fatal error:
>>>>
>>>> 1 instanceof \stdclass;
>>>>
>>>> t think this behavior is inconsistent, and we should consider changing
>>>> it.
>>>>
>>>> There are two options, but only one is BC.
>>>>
>>>> - Let 1 instanceof \stdClass return false, instead of crashing. ->
>>>> seems BC
>>>> - Let $x instanceof \stdClass crash, if $x is not an object. -> BC
>>>> break.
>>>>
>>>> So it seems the first would the option we should take.
>>>> This is also what hhvm does, according to https://3v4l.org/IdSBu.
>>>>
>>>
>>


Re: [PHP-DEV] instanceof survives non-object variables, but crashes on non-object constants.

2017-12-08 Thread Andreas Hennings
Adding a warning to something that used to be ok would break existing code.
I remember a number of cases where I used instanceof on possibly
non-objects.

if ($x instanceof C) {
  return $x;
}
elseif ($x === NULL) {
 ...
}

All such code would then produce warnings.


On 9 December 2017 at 07:35, Kalle Sommer Nielsen <ka...@php.net> wrote:

> Hi
>
> We should just add a warning to the first example, it seems like an
> oversight that it was left silent
>
> On 9 Dec 2017 07.29, "Andreas Hennings" <andr...@dqxtech.net> wrote:
>
>> The following (https://3v4l.org/A2Tp6) is ok, it simply returns false:
>>
>> $x = 1;
>> $x instanceof \stdClass;
>>
>>
>> The following (https://3v4l.org/IdSBu) gives a fatal error:
>>
>> 1 instanceof \stdclass;
>>
>> t think this behavior is inconsistent, and we should consider changing it.
>>
>> There are two options, but only one is BC.
>>
>> - Let 1 instanceof \stdClass return false, instead of crashing. -> seems
>> BC
>> - Let $x instanceof \stdClass crash, if $x is not an object. -> BC break.
>>
>> So it seems the first would the option we should take.
>> This is also what hhvm does, according to https://3v4l.org/IdSBu.
>>
>


[PHP-DEV] instanceof survives non-object variables, but crashes on non-object constants.

2017-12-08 Thread Andreas Hennings
The following (https://3v4l.org/A2Tp6) is ok, it simply returns false:

$x = 1;
$x instanceof \stdClass;


The following (https://3v4l.org/IdSBu) gives a fatal error:

1 instanceof \stdclass;

t think this behavior is inconsistent, and we should consider changing it.

There are two options, but only one is BC.

- Let 1 instanceof \stdClass return false, instead of crashing. -> seems BC
- Let $x instanceof \stdClass crash, if $x is not an object. -> BC break.

So it seems the first would the option we should take.
This is also what hhvm does, according to https://3v4l.org/IdSBu.


Re: [PHP-DEV] C++-like function-try-block proposal

2017-12-02 Thread Andreas Hennings
So to summarize, this feature would save us brackets and one indentation
level.
Saving an indentation level can be quite useful to reduce a git commit
footprint.

On the other hand, it might confuse some people. It would blur the concept
of a function body scope, and thus the mental model of how the language
works.
E.g. are local variables and parameters shared between the try {} and the
catch {} block?

It would also mean that userland PHP parsers and IDEs need to support the
syntax.

So personally I am undecided or skeptical. It does feel alien to me.
Usually if I want to avoid the extra indentation, I will put the try {}
part into a separate function.
But this is just me.


On 2 December 2017 at 14:27, Alexei Gerasimov 
wrote:

> > > I did (using this e-mail address), and got the message: "The user has
> been created and the password was sent by email." However, I did not
> receive any e-mail with the password.
> >
> > Sorry for the trouble, seems like nobody tested the sign up process
> after the server migration yet. It seems like the e-mail sender
> configuration is missing.
> >
> >
> > Unfortunately, I don't know the right config, so I can't simply fix it,
> but I've sent a message to Hannes, he probably knows.
>
> Any update? The reset password feature of wiki.php.net doesn't work
> either, I receive no e-mail.
>
> --
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: http://www.php.net/unsub.php
>
>


Re: [PHP-DEV] Re: PHP's mail servers suck

2017-11-07 Thread Andreas Heigl
Am 07.11.17 um 16:40 schrieb Eli White:
> On Tue, Nov 7, 2017 at 9:07 AM, Peter Lind <peter.e.l...@gmail.com> wrote:
> 
>> Might be worth noting that fixing the mailing lists does not amount to
>> taking on the php.net mail servers. The two are separate - just in case
>> someone should be up for one, but not both tasks.
>>
> 
> In this case I believe that they are one and the same Peter.   As the
> issues with the mailing list(s), are actually issues with the mail server
> itself.And Andreas is correct.   Multiple times in the past people have
> stepped up and offered to help out.  But they've either not been given any
> information how to do so (silence).  Or in a couple cases where I know
> someone was brought into discussion, they were shipped off with a 'talk to
> person X', and person X ended up being "don't need help, I've got it".
> 
> Really seems we have an issue here of "failure of democratic rule".  No-one
> is empowered to tell someone that they can take it on.  No-one even knows
> who/how to give access to someone to take it on.  And in the rare case that
> someone does have the ability to give someone access, it's never granted.
> 
> We need a way for infrastructure stuff like like to have a solid point
> person, who can give others power to handle things.   Sounds like we have
> some people willing to help out.   (Andreas?  Sara?) — People just need to
> give them access and let things happen.

I'm (still) in!

Cheers

Andreas

-- 
  ,,,
         (o o)
+-ooO-(_)-Ooo-+
| Andreas Heigl   |
| mailto:andr...@heigl.org  N 50°22'59.5" E 08°23'58" |
| http://andreas.heigl.org   http://hei.gl/wiFKy7 |
+-+
| http://hei.gl/root-ca   |
+-+


0x5BFCE472.asc
Description: application/pgp-keys


signature.asc
Description: OpenPGP digital signature


Re: [PHP-DEV] Re: PHP's mail servers suck

2017-11-07 Thread Andreas Heigl
Hey all.

Am 07.11.17 um 14:48 schrieb Eli White:
> Just chiming in that I have constantly had issues (since you asked for
> hands), get emails denied (let's see if this one goes through), and
> semi-constant threads of being auto-removed because of bounces that have
> nothing to do with me (see above gmail discussion).
> 
> Yeah, it sucks.  And it's been brought up in the past.  And invariably it
> all falls back to "Oh, only one person really knew how to maintain that
> random mail server and they aren't active anymore, and now no-one really
> does, so it just keeps running and no-one wants to take the effort to try
> to update/fix/move it"

Just a reminder: There where offers from people to help out (me
included) but the response was so overwhelming that not one of
them knew which answer to read first …

When people offer help and the only reply they get is no reply at all
that is not really a good thing to happen. So should PHP-internals want
other people than the current usual suspects (that only a limited number
of people by now know of) to help managing the infrastructure it would
be great when they'd at least signal a "thanks, offer noted, we might
come back to you". Even better with actually getting back…

But as it is currently the chances are that we will have to live with a
messy list-server and over time probably move somewhere else for
discussions as the old system becomes more and more unreliable…

Just my (frustrated) 0.02€

Cheers

Andreas
> 
> Eli
> 
> PS. Not it
> 
> 
> On Tue, Nov 7, 2017 at 8:38 AM, Sara Golemon <poll...@php.net> wrote:
> 
>> Biweekly reminder that PHP mail servers suck.
>>
>> On Wed, Oct 25, 2017 at 10:30 AM, Sara Golemon <poll...@php.net> wrote:
>>> Quick show of hands: Who's had a "looks like spam" bounce from php.net
>>> mail servers in the past... lets say the past month.
>>> Or how about the fact that new users tend to have a very hard time
>>> even subscribing to this list?
>>> This isn't directed at any one person because AFAICT, the maintainer
>>> of those systems is "nobody".
>>> Is it time to pick someone to actually maintain that pile of mierde?
>>> Maybe replace the pieces that haven't worked since the 90s?
>>>
>>> Fed up with something this basic not working,
>>> -Sara
>>
>> --
>> PHP Internals - PHP Runtime Development Mailing List
>> To unsubscribe, visit: http://www.php.net/unsub.php
>>
>>
> 


-- 
  ,,,
 (o o)
+-ooO-(_)-Ooo-+
| Andreas Heigl   |
| mailto:andr...@heigl.org  N 50°22'59.5" E 08°23'58" |
| http://andreas.heigl.org   http://hei.gl/wiFKy7 |
+-+
| http://hei.gl/root-ca   |
+-+


0x5BFCE472.asc
Description: application/pgp-keys


signature.asc
Description: OpenPGP digital signature


[PHP-DEV] Proposal: Rename image functions

2017-11-04 Thread Andreas Treichel
For a better readability of the gd functions I would like to rename them 
so that they contain underscores to separate the words. The only 
exception is image2wbmp which is renamed to image_to_wbmp. The order of 
the parameters of all functions whould be unchanged.


Due to the unchanged parameters it should be easyly possible to create 
wrappers for forward / backward compatiblity to use the new function 
names in old versions of PHP and via versa.


This was already part of the (inactive?) RFC Consistent Function Names
https://wiki.php.net/rfc/consistent_function_names. But this seems to be 
too big change for a single RFC.



Step 1:
I create a patch with the new aliases.

Step 2:
Merge the changes with next minor release of PHP 7.x.
Soft deprecation of old function names in the manual.

Step 3:
Deprecated old function names with PHP 8.0.


What is your opinion for this change?
Did you prefer "image_" or "gd_" as a common prefix?


New nameOld name
image_affineimageaffine
image_affine_matrix_concat  imageaffinematrixconcat
image_affine_matrix_get imageaffinematrixget
image_alpha_blendingimagealphablending
image_antialias imageantialias
image_arc   imagearc
image_bmp   imagebmp
image_char  imagechar
image_char_up   imagecharup
image_color_allocateimagecolorallocate
image_color_allocate_alpha  imagecolorallocatealpha
image_color_at  imagecolorat
image_color_closest imagecolorclosest
image_color_closest_alpha   imagecolorclosestalpha
image_color_closest_hwb imagecolorclosesthwb
image_color_deallocate  imagecolordeallocate
image_color_exact   imagecolorexact
image_color_exact_alpha imagecolorexactalpha
image_color_match   imagecolormatch
image_color_resolve imagecolorresolve
image_color_resolve_alpha   imagecolorresolvealpha
image_color_set imagecolorset
image_color_transparent imagecolortransparent
image_colors_for_index  imagecolorsforindex
image_colors_total  imagecolorstotal
image_convolution   imageconvolution
image_copy  imagecopy
image_copy_mergeimagecopymerge
image_copy_merge_gray   imagecopymergegray
image_copy_resampledimagecopyresampled
image_copy_resized  imagecopyresized
image_createimagecreate
image_create_from_bmp   imagecreatefrombmp
image_create_from_gdimagecreatefromgd
image_create_from_gd2   imagecreatefromgd2
image_create_from_gd2_part  imagecreatefromgd2part
image_create_from_gif   imagecreatefromgif
image_create_from_jpeg  imagecreatefromjpeg
image_create_from_png   imagecreatefrompng
image_create_from_stringimagecreatefromstring
image_create_from_wbmp  imagecreatefromwbmp
image_create_from_webp  imagecreatefromwebp
image_create_from_xbm   imagecreatefromxbm
image_create_from_xpm   imagecreatefromxpm
image_create_truecolor  imagecreatetruecolor
image_crop  imagecrop
image_crop_auto imagecropauto
image_dashed_line   imagedashedline
image_destroy   imagedestroy
image_ellipse   imageellipse
image_fill  imagefill
image_fill_to_borderimagefilltoborder
image_filled_arcimagefilledarc
image_filled_ellipseimagefilledellipse
image_filled_polygonimagefilledpolygon
image_filled_rectangle  imagefilledrectangle
image_filterimagefilter
image_flip  imageflip
image_font_height   imagefontheight
image_font_widthimagefontwidth
image_ft_bbox   imageftbbox
image_ft_text   imagefttext
image_gamma_correct imagegammacorrect
image_gdimagegd
image_gd2   imagegd2
image_get_clip  imagegetclip
image_gif   imagegif
image_grab_screen   imagegrabscreen
image_grab_window   imagegrabwindow
image_interlace imageinterlace
image_is_truecolor  imageistruecolor
image_jpeg  imagejpeg
image_layer_effect  imagelayereffect
image_line  imageline
image_load_font imageloadfont
image_open_polygon  imageopenpolygon
image_palette_copy  imagepalettecopy
image_palette_to_truecolor  imagepalettetotruecolor
image_png   imagepng
image_polygon   imagepolygon
image_rectangle imagerectangle
image_resolutionimageresolution
image_rotateimagerotate
image_save_alphaimagesavealpha
image_scale imagescale
image_set_brush imagesetbrush
image_set_clip  imagesetclip
image_set_interpolation imagesetinterpolation
image_set_pixel imagesetpixel
image_set_style imagesetstyle
image_set_thickness imagesetthickness

Re: [PHP-DEV] fputcsv() and $escape character

2017-09-22 Thread Andreas Hennings
On Fri, Sep 22, 2017 at 1:20 PM, Christoph M. Becker  wrote:
>> please make sure the behaviour of common applications, most notably
>> Excel, is considered and tested. In my experience it has its own quirks,
>> and it's likely that a large proportion of users require
>> interoperability with it. It may be there's nothing relevant to
>> consider, but I thought I'd mention it, in case people get too caught up
>> with a specification that nobody actually follows.
>
> That's exactly the point of this proposal.  As it is, fputcsv() outputs
> CSV that won't be understood by Excel (or any other CSV aware
> implementation I'm aware of), as soon as the escape character is
> actually part of any string.  So being able to avoid any such escaping
> would be helpful wrt. major CSV implementations, and making that the
> default even more so.

The other problem that this proposal wants to fix is that CSV cannot
currently be used reliably to store or transport data between
different PHP scripts, due to this bug:
https://bugs.php.net/bug.php?id=74713=2

> If one cell of the data sent to fputcsv() contains 
> "{$enclosure}{$escape_char}{$escape_char}{$enclosure}{$delimiter}", this cell 
> will be split after a round trip of fputcsv() + fgetcsv().


>
> The only other issue that I can see is that currently our fputcsv()
> hard-codes the line endings to LF (while RFC 4180 demands CRLF), but
> that may not be a real problem anymore.  (Well, there might be issues
> with non ASCII compatible character encodings as well).

I have opened a lot of php-generated CSV files with LibreOffice Calc,
and the line endings have not been a problem.
I assume Excel and OpenOffice would also be ok with it.
I'd say stick with existing behavior for BC reasons, or discuss it separately.

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



Re: [PHP-DEV] fputcsv() and $escape character

2017-09-21 Thread Andreas Hennings
On Thu, Sep 21, 2017 at 1:43 PM, Christoph M. Becker  wrote:
> I don't think the current behavior is a bug, but rather the escape
> character is an extension to the CSV "standard" (RFC 7111).

Are you sure you mean RFC 7111 ?
I was just parrotting the number in my previous email, but now I
looked it up and only find this:
https://tools.ietf.org/html/rfc7111
This talks about uri fragments with CSV, not CSV itself.

RFC 4180 seems to be closer to what we are looking for:
https://tools.ietf.org/html/rfc4180#section-2

fputcsv() and fgetcsv() already have a number of extensions to this
format, which I think are not harmful and that we should keep:
- option to choose a different delimiter
- option to choose a different enclosure
- option to have a different number of cells per row.
- fgetcsv() has some tolerance for broken CSV, that we should continue
to support.

In the stackoverflow discussion, someone argues that line breaks are
not part of the standard / not portable:
https://stackoverflow.com/questions/44427926/data-gets-garbled-when-writing-to-csv-with-fputcsv-fgetcsv/46342634#comment75882780_44427926
However, the RFC 4180 that I found clearly mentions them:

> 6. Fields containing line breaks (CRLF), double quotes, and commas should be 
> enclosed in double-quotes.

So, all we would change is the escape behavior. In RFC 4180, it says:

> If double-quotes are used to enclose fields, then a double-quote appearing 
> inside a field must be escaped by preceding it with another double quote.

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



Re: [PHP-DEV] fputcsv() and $escape character

2017-09-21 Thread Andreas Hennings
On Thu, Sep 21, 2017 at 11:08 PM, Dan Ackroyd  wrote:
> On 21 September 2017 at 12:43, Christoph M. Becker  wrote:
>> Hi everybody!
>>
>> There are several bug reports regarding "broken" fputcsv() behavior in
>> our tracker, namely, because the $escape parameter causes unexpected
>> results.  For instance:
>
>
> I looked at fixing some of the CSV related bugs about a year or so
> ago. My conclusions were:
>
> i) There is no way to fix the problems that wouldn't cause horrible BC
> breaks for code that is only coincidentally working currently.

How so?
What we can do:
If $escape_char !== '', fputcsv() should work exactly as it does now.
It can even use the same C code.
If $escape_char === '', fputcsv() will have a different behavior than
currently, where no character is treated as special.

If we want to be 100% sure, these two cases can use completely
separate C code, with one if() at the entry point.

>
> ii) Handling strings in C is much more error prone than handling them in PHP.
>
> I'm reasonably certain that trying to fix the current functions is the
> wrong approach, and one of the following would be much better.
>
> Either, find a C library that has already been proven to handle CSV
> parsing/generating 'correctly' and bring that into PHP core under
> either new function names or namespace.

Yeah why not. But it will require a lot more work and design decisions
than just introducing a new allowed value for $enclosure parameter.

>
> Or, write the code in PHP (or just use
> https://github.com/thephpleague/csv) and find a way to make that fast
> enough for people to use.

It can never be as fast as native functions.
I vaguely remember something like factor 2 or 3 when I tried it, but
for now treat this as hearsay.

>
> Touching the existing code is pretty certain to bring a lot of pain,
> without resulting in a fully compliant csv parser/generator.
>
> cheers
> Dan
> Ack
>
> --
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: http://www.php.net/unsub.php
>

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



Re: [PHP-DEV] fputcsv() and $escape character

2017-09-21 Thread Andreas Hennings
So empty string would enable the standard behavior RFC 7111 with no escape char.
If so, I support this.

I don't know if '' or true / false / null should be this "special value".
It has to be something that was not legal before, and that people
should use intentionally and not by accident.
I guess '' is good enough for this, or not worse than other options.

One question: Does this also require a change in fgetcsv()?
So it can read csv without escape character?
I remember that fgetcsv() does currently tolerate some broken CSV. It
should continue to do so for BC reasons.

For the record, here are some links:
https://stackoverflow.com/questions/44427926/data-gets-garbled-when-writing-to-csv-with-fputcsv-fgetcsv/46342634#46342634
https://bugs.php.net/bug.php?id=74713=2

On Thu, Sep 21, 2017 at 1:43 PM, Christoph M. Becker  wrote:
> Hi everybody!
>
> There are several bug reports regarding "broken" fputcsv() behavior in
> our tracker, namely, because the $escape parameter causes unexpected
> results.  For instance:
>
>  $row = ['a\\"', 'bbb'];
>
> $fp = fopen('php://memory', 'w+');
> fputcsv($fp, $row);
> rewind($fp);
> echo stream_get_contents($fp);
> fclose($fp);
> ?>
>
> outputs
>
> "a\"",bbb
>
> instead of the expected
>
> "a\""",bbb
>
> I don't think the current behavior is a bug, but rather the escape
> character is an extension to the CSV "standard" (RFC 7111).  One can
> practically disable the escape character by passing any character that
> is not contained in any of the strings in the array; "\0" is usually a
> good choice, so changing line 5 in the script above to the following
> gives the desired behavior:
>
> fputcsv($fp, $row, ',', '"', "\0");
>
> Cf.  vs. .
>
> It is, however, not possible to pass an empty string as $escape
> argument, because fputcsv() bails out in this case raising
>
>   Warning: fputcsv(): escape must be a character
>
> I suggest to allow an empty string instead, and to consider making this
> the default in a future version, probably after some time of deprecating
> any other $escape argument.
>
> Thoughts?
>
> --
> Christoph M. Becker
>
> --
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: http://www.php.net/unsub.php
>

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



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

2017-09-09 Thread Andreas Treichel

Hi,

Something like:

function match($x) {
switch(true) {
case $x === 1:
return 'Tiny';
case is_numeric($x) && $x <= 10:
return 'Small';
case is_numeric($x) && $x <= 20:
return 'Medium';
case is_numeric($x) && $x <= 30:
return 'Large';
case is_numeric($x) && ($x >= 31 || $x <= 100):
return 'Enormous';
case $x instanceof Foo:
case $x instanceof Bar:
return 'What?';
default:
return 'Unknown';
}
}

the problem is you need is_numeric because no type safe version of <= 
and >= exists.



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



Re: [PHP-DEV] Consider only ignoring newlines for final ?> in a file

2017-09-07 Thread Andreas Treichel

I always assumed that this is the reason why we do this in the first place.


I think the main reason was that old versions of ie go into quirksmode 
if the doctype is not in the first line of the output e.g.:





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



Re: [PHP-DEV] [VOTE] UUID

2017-09-05 Thread Andreas Heigl
Hey Richard

Am 05.09.17 um 19:29 schrieb Fleshgrinder:
> On 9/5/2017 7:01 PM, Andreas Heigl wrote:
>> Hey Richard, Hey all.
>>
>> Thanks for putting up the RFC and the implementation!
>>
>> Having UUIDs in the core would be awesome. One of the reasons would be
>> that it's in C. That'd be faster but would also allow easier integration
>> with system-calls to be easier able to get the MAC-Address for a type-1
>> UUID f.e.
>>
>> But why limit UUIDs to type 3 through 5? Having security in mind is good
>> IMHO but not implementing type 1 and 2 limits the usability and
>> therefore the usefullness. Let the users decide whether they need it or
>> not. As long as people can create SQL-Injections in PHP we should not
>> use the security argument to limit usability or not implement
>> standardized functionality.
>>
>> Especially when there is a full-fledged reference-implementation in
>> userland available. In the RFC you reference ramsey/uuid yourself. But
>> why should one use the internal UUID-class/functionality when there is a
>> more powerful one in userland available?
>>
>> And limiting the usability and extendability of the UUID-Class itself by
>> declaring it final means that userland-code can only wrap the class but
>> not extend it. So userland code can not typehint for the UUID-class when
>> special features are necessary that would need extending the class. And
>> as there's no interface, I can't typehint for that either.
>>
>> So all in all for me that's
>>
>> * less functionality than the reference-implementation
>> * missing UUID-types (the ones that are easier to implement in C)
>> * missing extendability
>>
>> and a naging feeling that the imlementation decides what I as a user
>> actually need.
>>
>> That's why I can't vote "yes".
>>
>> Sorry.
>>
>> Thanks for putting in the effort and coming up with a first implementation.
>>
>> Cheers
>>
>> Andreas
>>
>> PS: Personally I don't like a "uuid_4_create" as that would also mean
>> there should be a "uuid_1_create" through "uuid_5_create" as well and
>> then there also would need to be a "uuid_1_verify" through "uuid_5_verify"…
>>
> 
> Hi Andreas!
> 
> Thanks for your feedback.
> 
> We can easily add v1 and v2 because the class is final. It would not be
> a breaking change, or anything. v2 is pretty much useless imho, but v1
> if done right would not even harm your privacy.

I'm with you there in so far that I personally don't see a value in a
type 2 UUID. But there might be people that need exactly that. And as
adding functionality usually isn't a BC-break that's OK.

> 
> Composition is more powerful than inheritance. You mention that you
> cannot extend it to add functionality, at the same time you want to
> type-hint against it. Well, in order to use the extended functionality
> you need to type-hint against your extended version. Hence, there is
> zero value for you in extending it other than having some place using
> the extended version, and others the core version without noticing that
> it got the extended version.

I'm well aware of that and perhaps I didn't express myself as clear as I
should have.

Imagine a use-case where a UUID-class is needed. But alongside the
toString, toHex and toBinary there's also the need for a further
function (let's call it toArray). So currently I need to create a
wrapper arround UUID that then needs to implement all the public methods
of UUID as well as the new toArray. So it works identically to UUID but
it isn't UUID. And I have no way of using my own UUID-Class - as it
doesnt' extend UUID - as replacement for UUID. I'd need to expose the
wrapped UUID-Class to be able to retrieve it whenever some libray
expects a UUID. Perhaps this gist can make it clearer:
https://gist.github.com/heiglandreas/452dae591d071cbdfb78b431cb6597fa

> 
> The thing is, you should create your own value objects for your
> identifiers and hide the fact what it wraps. In C, and many other
> languages, we have type aliases. In PHP, and many other OO languages, we
> use composition to achieve tha>
> Whether to make it final or not was discussed, and especially Ocramius
> agreed with me on this. I believe that it is the right choice.

I'm not saying it's the wrong choice. I for myself would probably not
immediately use it as the ramsey/uuid-package is widely in use, but I
could f.e. think, that that package might start to use the UUID-class
under the hood. And then that would be a case where extending could be
helpful as a \Ramsey\UUID would be an instance of \UUID.

The alternative would be to implement 

Re: [PHP-DEV] [VOTE] UUID

2017-09-05 Thread Andreas Heigl
Am 02.09.17 um 09:01 schrieb Fleshgrinder:
> Hello Internals!
> 
> I just started the voting for the inclusion of a UUID value object in
> PHP's core, targeting PHP 7.3. I wanted to start earlier, but was sick
> the whole week.
> 
> The voting is open starting now and until September 16. (2 weeks).
> 
Hey Richard, Hey all.

Thanks for putting up the RFC and the implementation!

Having UUIDs in the core would be awesome. One of the reasons would be
that it's in C. That'd be faster but would also allow easier integration
with system-calls to be easier able to get the MAC-Address for a type-1
UUID f.e.

But why limit UUIDs to type 3 through 5? Having security in mind is good
IMHO but not implementing type 1 and 2 limits the usability and
therefore the usefullness. Let the users decide whether they need it or
not. As long as people can create SQL-Injections in PHP we should not
use the security argument to limit usability or not implement
standardized functionality.

Especially when there is a full-fledged reference-implementation in
userland available. In the RFC you reference ramsey/uuid yourself. But
why should one use the internal UUID-class/functionality when there is a
more powerful one in userland available?

And limiting the usability and extendability of the UUID-Class itself by
declaring it final means that userland-code can only wrap the class but
not extend it. So userland code can not typehint for the UUID-class when
special features are necessary that would need extending the class. And
as there's no interface, I can't typehint for that either.

So all in all for me that's

* less functionality than the reference-implementation
* missing UUID-types (the ones that are easier to implement in C)
* missing extendability

and a naging feeling that the imlementation decides what I as a user
actually need.

That's why I can't vote "yes".

Sorry.

Thanks for putting in the effort and coming up with a first implementation.

Cheers

Andreas

PS: Personally I don't like a "uuid_4_create" as that would also mean
there should be a "uuid_1_create" through "uuid_5_create" as well and
then there also would need to be a "uuid_1_verify" through "uuid_5_verify"…

-- 
  ,,,
 (o o)
+-ooO-(_)-Ooo-+
| Andreas Heigl   |
| mailto:andr...@heigl.org  N 50°22'59.5" E 08°23'58" |
| http://andreas.heigl.org   http://hei.gl/wiFKy7 |
+-+
| http://hei.gl/root-ca   |
+-+



signature.asc
Description: OpenPGP digital signature


Re: [PHP-DEV] Contravariance and the "empty type"

2017-08-24 Thread Andreas Hennings
This discussion made me have another look at the Generics RFC,
https://wiki.php.net/rfc/generics

It seems to me that the proposal violates LSP, because it does not
correctly implement contravariance.
Look at the part where it talks about instanceof.

interface Feline {}
class Cat implements Feline {}
class Tiger implements Feline {}

class Box {
  function entrap(T $feline) {}
}

$feline_box = new Box();
$cat_box = new Box();
$tiger_box = new Box();

$cat = new Cat();
$tiger = new Tiger();

assert($feline_box instanceof Box);  // -> ok.
assert($tiger_box instanceof Box);  // -> ok.
assert($cat_box instanceof Box);  // -> ok.

assert($cat instanceof Feline);  // -> ok.
assert($tiger instanceof Feline);  // -> ok.

$feline_box->entrap($cat);  // -> ok.
$cat_box->entrap($cat); // -> ok.
$tiger_box->entrap($cat); // -> Fatal error: Uncaught TypeError.


So, even with generics, we still need to think about contravariance.

We need to distinguish 3 types of type parameter on classes:
1. Those which are used in method return types.
2. Those which are used in method parameter types.
3. Those which are used in both.

For these 3 cases, the following rules would need to apply:
1. Contravariance.
2. Covariance
3. Identity.

E.g.

interface Fruit;
interface Banana extends Fruit;

interface Grower {
  function grow() : T;
}

interface Processor {
  function process(T $fruit) : T;
}

interface Eater {
  function eat(T $fruit);
}

// Covariance
var_dump(new Grower instanceof Grower); // => (bool) true
var_dump(new Grower instanceof Grower); // => (bool) false

// Identity
var_dump(new Processor instanceof Processor); // => (bool) false
var_dump(new Processor instanceof Processor); // => (bool) false

// Contravariance
var_dump(new Eater instanceof Eater); // => (bool) false
var_dump(new Eater instanceof Eater); // => (bool) true


The only supertype for all Eater<*> types would be Eater.
This super-eater has the absolute fruit allergy.




On Wed, Aug 23, 2017 at 9:18 AM, Michał Brzuchalski
<mic...@brzuchalski.com> wrote:
> Hi Andreas,
>
> 2017-08-22 21:11 GMT+02:00 Andreas Hennings <andr...@dqxtech.net>:
>
>> On Tue, Aug 22, 2017 at 10:39 AM, Nikita Popov <nikita@gmail.com>
>> wrote:
>> > On Tue, Aug 22, 2017 at 4:27 AM, Andreas Hennings <andr...@dqxtech.net>
>> > wrote:
>> >>
>> >> Hello list,
>> >> for a while I had this thought about contravariance and an "empty type".
>> >> I don't expect too much of it, for now I just want to share the idea.
>> >> Maybe this concept even exists somewhere in a different language, and
>> >> I am not aware of it.
>> >>
>> >> I think it has some overlap with generics,
>> >> https://wiki.php.net/rfc/generics.
>> >>
>> >> 
>> >>
>> >> I think I am not the first one to suggest allowing contravariance for
>> >> method parameters.
>> >> E.g. here, "PHP RFC: Parameter Type Widening"
>> >> https://wiki.php.net/rfc/parameter-no-type-variance
>> >>
>> >> From this RFC:
>> >> > Unfortunately “true” contravariance for class types isn't part of this
>> >> > RFC, as implementing that is far more difficult, and would require
>> >> > additional rules about autoloading and/or class compilation, which
>> might
>> >> > only be acceptable at a major release.
>> >>
>> >> For anyone not familiar with the term:
>> >>
>> >> interface I {
>> >>   function foo(J $arg);
>> >> }
>> >>
>> >> interface J extends I {
>> >>   function foo(I $arg);
>> >> }
>> >>
>> >> So: While return types in a child method should be either the same or
>> >> more narrow, the parameter types should be either the same or more
>> >> permissive.
>> >> Without this it would break Liskov substitution.
>> >>
>> >> ---
>> >>
>> >> Now for my actual proposal: The "empty type".
>> >> We can think of a type (class/interface or primitive) as a set or a
>> >> constraint on the kind of values that it allows.
>> >> There is a special type, "mixed", which allows all values. We could
>> >> also think of it as the union of all types.
>> >>
>> >> A natural extension of this concept, on the other end, would be a type
>> >> "nothing" or "empty", which would allow no values at all.
>> >> We could think of this as the intersection 

Re: [PHP-DEV] Contravariance and the "empty type"

2017-08-22 Thread Andreas Hennings
On Tue, Aug 22, 2017 at 10:39 AM, Nikita Popov <nikita@gmail.com> wrote:
> On Tue, Aug 22, 2017 at 4:27 AM, Andreas Hennings <andr...@dqxtech.net>
> wrote:
>>
>> Hello list,
>> for a while I had this thought about contravariance and an "empty type".
>> I don't expect too much of it, for now I just want to share the idea.
>> Maybe this concept even exists somewhere in a different language, and
>> I am not aware of it.
>>
>> I think it has some overlap with generics,
>> https://wiki.php.net/rfc/generics.
>>
>> 
>>
>> I think I am not the first one to suggest allowing contravariance for
>> method parameters.
>> E.g. here, "PHP RFC: Parameter Type Widening"
>> https://wiki.php.net/rfc/parameter-no-type-variance
>>
>> From this RFC:
>> > Unfortunately “true” contravariance for class types isn't part of this
>> > RFC, as implementing that is far more difficult, and would require
>> > additional rules about autoloading and/or class compilation, which might
>> > only be acceptable at a major release.
>>
>> For anyone not familiar with the term:
>>
>> interface I {
>>   function foo(J $arg);
>> }
>>
>> interface J extends I {
>>   function foo(I $arg);
>> }
>>
>> So: While return types in a child method should be either the same or
>> more narrow, the parameter types should be either the same or more
>> permissive.
>> Without this it would break Liskov substitution.
>>
>> ---
>>
>> Now for my actual proposal: The "empty type".
>> We can think of a type (class/interface or primitive) as a set or a
>> constraint on the kind of values that it allows.
>> There is a special type, "mixed", which allows all values. We could
>> also think of it as the union of all types.
>>
>> A natural extension of this concept, on the other end, would be a type
>> "nothing" or "empty", which would allow no values at all.
>> We could think of this as the intersection of all types.
>> In fact it is already sufficient to intersect just two distinct
>> primitive types to get this empty type:
>> "All values that are at the same time string and integer" clearly is
>> an empty type.
>>
>> How would this ever be useful?
>> If we write a base class or interface for a category of interfaces
>> that have a similar signature.
>>
>> interface Fruit {..}
>> interface Apple extends Fruit {..}
>> interface Banana extends Fruit {..}
>>
>> interface AbstractFruitEater {
>>   function eat(EMPTY_TYPE $fruit);
>> }
>>
>> interface BananaEater extends AbstractFoodEater {
>>   function eat(Banana $banana);
>> }
>>
>> interface AppleEater extends AbstractFoodEater {
>>   function eat(Apple $apple);
>> }
>>
>> One could imagine a component that has a list of AbstractFruitEater
>> objects, and chooses one that is suitable for the given fruit, using
>> instanceof.
>> I think the correct term is "chain of responsibility".
>>
>> function eatApple(array $fruitEaters, Apple $apple) {
>>   foreach ($fruitEaters as $eater) {
>> if ($eater instanceof AppleEater) {
>>   $eater->eat($apple);
>>   break;
>> }
>>   }
>> }
>>
>> 
>>
>> We can go one step further.
>>
>> The natural parameter type to use for param $fruit in
>> AbstractFruitEater::foo() would not be the global EMPTY_TYPE, but
>> something more specific:
>> The projected intersection of all real and hypothetical children of
>> interface Fruit.
>> Obviously this does not and cannot exist as a class or interface.
>>
>> Practically, for the values it allows, this is the same as the global
>> EMPTY_TYPE.
>> But unlike the EMPTY_TYPE, this would poses a restriction on the
>> parameter type in child interfaces.
>>
>> What would be the syntax / notation for such a projected hypothetical
>> subtype?
>> I don't know. Let's say INTERSECT_CHILDREN
>>
>> So, would the following work?
>>
>> interface Food {..}
>> interface Fruit extends Food {..}
>> interface Banana extends Fruit {..}
>>
>> interface AbstractFoodEater {
>>   function eat(INTERSECT_CHILDREN $food);
>> }
>>
>> interface AbstractFruitEater extends AbstractFoodEater {
>>   function eat(INTERSECT_CHILDREN $fruit);
>> }
>>
>> interface BananaEater extends Abst

[PHP-DEV] Contravariance and the "empty type"

2017-08-21 Thread Andreas Hennings
Hello list,
for a while I had this thought about contravariance and an "empty type".
I don't expect too much of it, for now I just want to share the idea.
Maybe this concept even exists somewhere in a different language, and
I am not aware of it.

I think it has some overlap with generics, https://wiki.php.net/rfc/generics.



I think I am not the first one to suggest allowing contravariance for
method parameters.
E.g. here, "PHP RFC: Parameter Type Widening"
https://wiki.php.net/rfc/parameter-no-type-variance

>From this RFC:
> Unfortunately “true” contravariance for class types isn't part of this RFC, 
> as implementing that is far more difficult, and would require additional 
> rules about autoloading and/or class compilation, which might only be 
> acceptable at a major release.

For anyone not familiar with the term:

interface I {
  function foo(J $arg);
}

interface J extends I {
  function foo(I $arg);
}

So: While return types in a child method should be either the same or
more narrow, the parameter types should be either the same or more
permissive.
Without this it would break Liskov substitution.

---

Now for my actual proposal: The "empty type".
We can think of a type (class/interface or primitive) as a set or a
constraint on the kind of values that it allows.
There is a special type, "mixed", which allows all values. We could
also think of it as the union of all types.

A natural extension of this concept, on the other end, would be a type
"nothing" or "empty", which would allow no values at all.
We could think of this as the intersection of all types.
In fact it is already sufficient to intersect just two distinct
primitive types to get this empty type:
"All values that are at the same time string and integer" clearly is
an empty type.

How would this ever be useful?
If we write a base class or interface for a category of interfaces
that have a similar signature.

interface Fruit {..}
interface Apple extends Fruit {..}
interface Banana extends Fruit {..}

interface AbstractFruitEater {
  function eat(EMPTY_TYPE $fruit);
}

interface BananaEater extends AbstractFoodEater {
  function eat(Banana $banana);
}

interface AppleEater extends AbstractFoodEater {
  function eat(Apple $apple);
}

One could imagine a component that has a list of AbstractFruitEater
objects, and chooses one that is suitable for the given fruit, using
instanceof.
I think the correct term is "chain of responsibility".

function eatApple(array $fruitEaters, Apple $apple) {
  foreach ($fruitEaters as $eater) {
if ($eater instanceof AppleEater) {
  $eater->eat($apple);
  break;
}
  }
}



We can go one step further.

The natural parameter type to use for param $fruit in
AbstractFruitEater::foo() would not be the global EMPTY_TYPE, but
something more specific:
The projected intersection of all real and hypothetical children of
interface Fruit.
Obviously this does not and cannot exist as a class or interface.

Practically, for the values it allows, this is the same as the global
EMPTY_TYPE.
But unlike the EMPTY_TYPE, this would poses a restriction on the
parameter type in child interfaces.

What would be the syntax / notation for such a projected hypothetical subtype?
I don't know. Let's say INTERSECT_CHILDREN

So, would the following work?

interface Food {..}
interface Fruit extends Food {..}
interface Banana extends Fruit {..}

interface AbstractFoodEater {
  function eat(INTERSECT_CHILDREN $food);
}

interface AbstractFruitEater extends AbstractFoodEater {
  function eat(INTERSECT_CHILDREN $fruit);
}

interface BananaEater extends AbstractFruitEater {
  function eat(Banana $banana);
}

I'm not sure.
Liskov would not care. Both AbstractFoodEater and AbstractFruitEater
are useless on their own.
Maybe there are other logical conflicts which I don't see.


--

Obviously with generics this base interface would no longer be relevant.
https://wiki.php.net/rfc/generics

interface FruitEater {
  function eat(FruitType $fruit);
}

// This is not really necessary.
interface BananaEater extends FruitEater {
  function eat(Banana $banana);
}

So, would the "empty type" become obsolete? Maybe.
I did not arrive at a final conclusion yet. It still seems too
interesting to let it go.

-- Andreas

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



[PHP-DEV] Slow DateTimeZone::getTransitions with no argument

2017-08-15 Thread Andreas Treichel

Hi,

Is the first entry in the return value of 
http://php.net/manual/en/datetimezone.gettransitions.php with the 
timestamp PHP_INT_MIN / ZEND_LONG_MIN intended?


The difference with no arguments is over 100 times slower on 64 bit systems:

DateTimeZone::getTransitions()
Duration: 0.075577

DateTimeZone::getTransitions(-62135596800)
Duration: 0.000587

https://3v4l.org/8osB8#output

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



Re: [PHP-DEV] Happy World Elephant Day

2017-08-12 Thread Andreas Heigl
Am 12.08.17 um 17:55 schrieb Midori Koçak:
> Hi Internals,
> 
> Happy world elephant day for all of internals community. Did you know there
> are 400.000 elephants left all around the world and every year 40.000 of
> them are dying  for the ivory trade.

Whoever wants to help the elephants: I've found this:

https://gifts.worldwildlife.org/gift-center/gifts/Species-Adoptions/African-Elephant.aspx
https://gifts.worldwildlife.org/gift-center/gifts/Species-Adoptions/Pygmy-Elephant.aspx

Any possibility the Communtiy can fund one or two adotions? Ping me (or
the list) for interest…

And some back-story for the WorldElephantDay:

http://worldelephantday.org

Cheers

Andreas
> 
> Happy world elephant day again,
> Midori Kocak
> 


-- 
  ,,,
 (o o)
+-----ooO-(_)-Ooo-+
| Andreas Heigl   |
| mailto:andr...@heigl.org  N 50°22'59.5" E 08°23'58" |
| http://andreas.heigl.org   http://hei.gl/wiFKy7 |
+-+
| http://hei.gl/root-ca   |
+-+



signature.asc
Description: OpenPGP digital signature


Re: [PHP-DEV] [RFC][DISCUSSION] Allow default value in list() syntax

2017-08-11 Thread Andreas Hennings
This is true, I remember having done it in the past.

I still think it would be nice and feel natural to have the default
values directly built into the list construct.

It would be a bit faster, because it does not have to allocate a new
temporary array.

Whether this difference matters depends on the case.
In my own philosophy, every code that I write to be reusable, could at
some point be used in a situation where it is repeated a lot, and thus
has a performance impact. So for my taste, it does matter.

This said, I understand it not having the greatest priority.




On Fri, Aug 11, 2017 at 7:46 PM, Andreas Treichel <gmb...@gmail.com> wrote:
> You can merge the result with default values like this:
>
> [$foo, $bar, $foobar] = explode(':', 'foo:bar') + [23, 42, 1337];
> var_dump($foo, $bar, $foobar);
>
>
>
>
> --
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: http://www.php.net/unsub.php
>

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



Re: [PHP-DEV] [RFC][DISCUSSION] Allow default value in list() syntax

2017-08-11 Thread Andreas Treichel

You can merge the result with default values like this:

[$foo, $bar, $foobar] = explode(':', 'foo:bar') + [23, 42, 1337];
var_dump($foo, $bar, $foobar);



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



Re: [PHP-DEV] [RFC][DISCUSSION] Allow default value in list() syntax

2017-08-10 Thread Andreas Hennings
On Fri, Aug 11, 2017 at 12:01 AM, Devnuhl Unnamed  wrote:
> Would isset($suffix) not suffice here?

You mean like so?

list($prefix, $suffix) = explode(':', 'string_without_suffix');
if (!isset($suffix)) {
  ..
}

The isset() is too late here, because the list() will already cause an error.


> Other concerns fall around list() already being a difficult thing for people 
> to understand

I fail to understand what is difficult about it..
And "destructuring" is a common concept in programming languages.
https://www.startpage.com/do/search?query=destructuring=web=chrome=english
https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment

The following already works in Javascript:
[a, b, c, d = 'else'] = ['aa', 'bb', 'cc'];
I just tried it in my Chromium console.

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



Re: [PHP-DEV] [RFC][DISCUSSION] Allow default value in list() syntax

2017-08-10 Thread Andreas Hennings
I don't have a strong opinion about the nested list() construct which
is also part of the RFC.
I never had a situation where I wanted this.

On Thu, Aug 10, 2017 at 11:21 PM, Andreas Hennings <andr...@dqxtech.net> wrote:
> Hello list,
>
> I found this RFC, describing a feature I wanted for a long time:
> https://wiki.php.net/rfc/list_default_value
> https://marc.info/?l=php-internals=144707619509724
>
> (I don't know how to correctly reply to old emails that are not in my
> inbox, sorry for that. I don't like mailing lists.)
>
> I regularly want this kind of feature when unpacking a string with explode():
>
> list($prefix, $suffix = NULL) = explode(':', $string);
> if (NULL !== $suffix) {
>   ...
> }
>
> This is for situations where a string is coming from somewhere, we
> hope it has the format "aaa:bbb", but we cannot be sure.
>
> Sometimes I use a workaround like this:
>
> list($prefix, $suffix) = explode(':', $string . ':');
> if ('' !== $suffix) {
>   ...
> }
> Which works, but means a new string will be allocated in memory.
>
> I find the list() with default values to be a decent and
> understandable language feature.
>
> -- Andreas

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



Re: [PHP-DEV] [RFC][DISCUSSION] Allow default value in list() syntax

2017-08-10 Thread Andreas Hennings
Hello list,

I found this RFC, describing a feature I wanted for a long time:
https://wiki.php.net/rfc/list_default_value
https://marc.info/?l=php-internals=144707619509724

(I don't know how to correctly reply to old emails that are not in my
inbox, sorry for that. I don't like mailing lists.)

I regularly want this kind of feature when unpacking a string with explode():

list($prefix, $suffix = NULL) = explode(':', $string);
if (NULL !== $suffix) {
  ...
}

This is for situations where a string is coming from somewhere, we
hope it has the format "aaa:bbb", but we cannot be sure.

Sometimes I use a workaround like this:

list($prefix, $suffix) = explode(':', $string . ':');
if ('' !== $suffix) {
  ...
}
Which works, but means a new string will be allocated in memory.

I find the list() with default values to be a decent and
understandable language feature.

-- Andreas

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



[PHP-DEV] Re: [PHP-WEBMASTER] Subscribe Function Seems to be down for several days

2017-08-03 Thread Andreas Heigl
Seems like the mailinglist needs some love… again…

Cheers

Andreas


Am 03.08.17 um 17:02 schrieb Alan Feuerbacher:
> I've been trying for several days to subscribe to a PHP mailing list,
> but I keep getting the message "We were unable to subscribe you due to
> some technical problems. Please try again later."
> 
> Is there any way to fix this?
> 


-- 
  ,,,
 (o o)
+-----ooO-(_)-Ooo-+
| Andreas Heigl   |
| mailto:andr...@heigl.org  N 50°22'59.5" E 08°23'58" |
| http://andreas.heigl.org   http://hei.gl/wiFKy7 |
+-+
| http://hei.gl/root-ca   |
+-+



signature.asc
Description: OpenPGP digital signature


Re: [PHP-DEV] New functions: string_starts_with(), string_ends_with()

2017-08-01 Thread Andreas Hennings
Thanks!
I did not find those, maybe the emails need to be enriched with keywords.
Like SEO-aware email authoring.

Ok. I am looking at the RFC and the old discussions at
https://marc.info/?l=php-internals=147017797404339=2

I don't know how to follow up on old threads that I don't have in my
email inbox.


So here is my feedback.

The RFC seems mostly fine as it is.
It does not contain anything like the string_clip_suffix() /
string_clip_prefix(), but I think these should be discussed
separately.

About the naming:
The "i" in str_ibegin and str_iend() seems ok to me.
I also strongly support separate functions instead of a parameter for
case sensitivity.

I also support the underscore. str_begin() is better than strbegin().




Whether to have an "s" at the end:

https://marc.info/?l=php-internals=147017797404339=2
(Yasuo Ohgaki)

> It might be okay  to have "s" in function names, but if we want to be
> consistent,
> str_replace -> str_replaces
> str_ireplace -> str_ireplaces

I disagree with this analogy.

The "s" in str_begins() would be for "haystack beginS with needle".
An "s" in str_replaces() would stand for what?
Both "begin" and "replace" are verbs, but they have a different role
in the function name.
"begin" describes a state or condition we want to verfiy, whereas
"replace" is a command we give to the machine.

So to me it would make sense to have str_begins() and str_ends()
instead of str_begin() and str_end().

To me, str_end() means either "End the string!" (command) or "Give me
the end of the string!" (noun).

In fact Rowan Collins made the same argument here,
https://marc.info/?l=php-internals=147017844704431=2

> I think those names mean something different: "str_begin" sounds like an
> imperative "make this string begin with X"; "str_begins" is more of an
> assertion "the string begins with X". Ruby would spell it with a ? at
> the end. It's also the same form, grammatically, as the common "isFoo".
>
> Note that this logic holds for "str_replace", which *is* an imperative -
> you are not saying "tell me if X replaces Y", you are saying "please
> replace X with Y".

But then Will talks about consistency again.
https://marc.info/?l=php-internals=147018700406320=2

> I think like
> having an "s" at the end of the function names reads better, but
> omitting the "s" fits better with the existing function names and does
> not read bad. Therefore, I am in favor of dropping the "s".

Honestly, looking at the existing string functions at
http://php.net/manual/en/ref.strings.php
I don't see a lot of consistency here. Just a long list of garbled
abbreviations.

I also don't see any existing function where the verb has a similar
role as the "begin" in str_begin().
For all the existing string functions, the verb is a command.

I think a better comparison would be
file_exists()
function_exists()
class_exists()
is_subclass_of()
extension_loaded()
ncurses_has_colors()
ncurses_can_change_color()

What these functions have in common:
- The return value is boolean.
- The verb is not a command, but it describes a state or condition.

The verb is not always at the end of the function name, and it does
not always end with -s.
But the form and ending of the verb follows its grammatical role in
the sentence.

I think this is a much better guideline than following a wrong idea of
consistency.

-

Finally, I don't know why everything needs to be abbreviated.
Having str_* instead of string_* seems ok to me, and is consistent
with existing string functions.
But my first idea would have been more complete phrases like
str_ends_with, str_has_ending(), str_has_suffix(). Instead of just
str_end(), or str_ends().

On the other hand, shorter function names have their benefits. So.. no
strong opinion here.

--


-- Andreas






On Tue, Aug 1, 2017 at 8:29 AM, Michał Brzuchalski
<mic...@brzuchalski.com> wrote:
> Hi Andreas,
>
> 2017-08-01 6:57 GMT+02:00 Andreas Hennings <andr...@dqxtech.net>:
>>
>> Hello list,
>> a quite common use case is that one needs to find out if a string
>> $haystack begins or ends with another string $needle.
>> Or in other words, if $needle is a prefix or a suffix of $haystack.
>>
>> One prominent example would be in PSR-4 or PSR-0 class loaders.
>> Maybe the use case also occurs when writing parsers..
>> In each of these two examples (parsers, class loaders), we care about
>> performance.
>>
>> (forgive me if this was discussed before, I did not find it anywhere
>> in the archives)
>>
>> --
>>
>> Exist

[PHP-DEV] New functions: string_starts_with(), string_ends_with()

2017-07-31 Thread Andreas Hennings
Hello list,
a quite common use case is that one needs to find out if a string
$haystack begins or ends with another string $needle.
Or in other words, if $needle is a prefix or a suffix of $haystack.

One prominent example would be in PSR-4 or PSR-0 class loaders.
Maybe the use case also occurs when writing parsers..
In each of these two examples (parsers, class loaders), we care about
performance.

(forgive me if this was discussed before, I did not find it anywhere
in the archives)

--

Existing solutions to this problem feel non-trivial, and/or are
suboptimal in performance.
https://stackoverflow.com/questions/2790899/how-to-check-if-a-string-starts-with-a-specified-string
https://stackoverflow.com/questions/834303/startswith-and-endswith-functions-in-php
This answer compares different solutions,
https://stackoverflow.com/a/7168986/246724

Existing solutions:
(Let's focus on string_starts_with(), the other case is mostly
equivalent / symmetric)

if (0 === strpos($haystack, $needle)) {..}
I have often seen this presented as the preferable solution.
Unfortunately, this searches the entire string, not just the
beginning. Especially if $haystack is really long, this can be a
waste.
E.g. if (0 === strpos(file_get_contents('some_source_file.php'),
'https://stackoverflow.com/a/10473026/246724
The author says that it will be outperformed by strncmp() - so..

if (preg_match('/^' . preg_quote($needle, '/') . '/', $haystack)) {..}
Clearly gonna be slower than other options.

As said, all these solutions do work, but they are either suboptimal,
or they add clutter and overhead, or feel a bit like mind acrobatics.

-

So, I wonder if it would be worthwhile to add new functions
string_starts_with() / string_has_prefix(), and string_ends_with() /
string_has_suffix().

(Or maybe change strncmp(), so that the 3rd parameter $len is
optional. If $len is NULL / not provided, it would use the length of
the second (or first?) string.
(idea was that second parameter = needle).)

For me personally, I am sure that I would use a new
string_starts_with() a lot more often than a lot of the other existing
string functions.
I don't think it is an exotic or niche use case.

--

Spinning this further:
A lot of times if I want to check if $haystack begins with $needle, I
will then need the rest of the string after $needle.
So
if (string_starts_with($haystack, $needle)) {
$suffix = substr($haystack, strlen($needle));
}
or
if (string_ends_with($filename, '.php')) {
$basename = substr($filename, 0, -4);
}

I wonder if this could be somehow combined.
E.g.
if (FALSE !== $basename = string_clip_suffix($filename, '.php')) {
// Do something with $basename.
}

--

One flaw of these new functions would be that they are less versatile
than other string functions.
They solve this problem, and nothing else.
On the other hand, this is the point, to avoid unnecessary overhead.

The other problem would be, of course, "feature creep" aka "we have so
many string functions already".
This is a matter of opinion.
I would imagine the "cost" of new native functions is:
- global namespace pollution
- increased mental load to learn and remember all of them
- higher memory footprint of php engine?
- more C code to maintain
- a new doc page.
Did I miss something?

--

-- Andreas

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



Re: [PHP-DEV] Don't add simple objects to GC's roots

2017-07-30 Thread Andreas Treichel

Hi,


So I propose to make the gc_disable function accept one zval reference as
parameter. And if gc_disable get that zval, gc_disable just drop the zval’s
GC_COLLECTABLE flag, which will hint the PHP gc not to trace that zval.


i dont know if this is a good idea or not. But for the "s" in solid, 
create a new function like gc_exclude to exclude variables from the 
garbage collector and do not add a parameter to gc_disable.



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



Re: [PHP-DEV] http_cookie_set and http_cookie_remove

2017-07-24 Thread Andreas Treichel

Hi Andrey,


1. The wording here implies that these are the *only* attributes
allowed. In the interest of forward-compatibility, I'd allow arbitrary
attributes as well.


I just try to implement something like this, to allow arbitrary 
attributes. Is this what you prefer?


http_cookie_set('foobar', '1337', [
'foo' => 23,
'bar' => 42
]);

Set-Cookie: foobar=1337; foo=23; bar=42


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



Re: [PHP-DEV] http_cookie_set and http_cookie_remove

2017-07-23 Thread Andreas Treichel

Hello Andrey,


That's what I was afraid of, and what I suggested be changed.

If we had a similar, array-of-attributes API that did NOT ignore or
trigger warnings for unknown attributes, everybody using PHP would've
been able to use SameSite already.


I think it is necessary to trigger a notice or warning for unknown 
options for troubleshooting.




On another note, I'd also move the 'expire' option to a separate
parameter and remove $options to $attributes.

'expire' is not a known cookie attribute; PHP uses it to calculate the
Expires and Max-Age attributes ...


The "attribute" expires (not expire) existing in the header Set-Cookie.



I liked your proposal, because it's a chance to have a shiny new API

> that doesn't come with all the legacy stuff already built into
> setcookie().

I hope to meet your expectations.



But if we want an array-based setcookie() alternative without changing
anything else, we can just change setcookie() to accept arrays.


No this is just the only the first step for additional extensions.


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



Re: [PHP-DEV] http_cookie_set and http_cookie_remove

2017-07-23 Thread Andreas Treichel

Hi Michał,


As an average developer, I see providing new functions with http_ prefix
more meaningful and their API more simple because of fewer parameters I
need to pass.



Although however, I see the naming convention you've used is rarely used.
Looking in the docs, there are few other HTTP sapi related functions which
don't follow that convention, like:
header() - Send a raw HTTP header
header_remove() - Remove previously set headers
header_register_callback() - Call a header function
headers_sent() - Checks if or where headers have been sent - this function
http_response_code() - Get or Set the HTTP response code - which is THE
ONLY ONE function prefixed this way


This might be one of my next RFCs if my first RFC is well received.


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



<    1   2   3   4   5   6   >