[PHP-DEV] [RFC] Nullable Casting
Hello internals, David and I would like to open the discussion on our joint RFC: https://wiki.php.net/rfc/nullable-casting Mainly, it would enable to use e.g. `(?int)$x` besides `(int)$x`. We are looking forward to your feedback and, if possible, help to fill in the "RFC Impact" subsections (hopefully "None" to all) as well as a review of the proposed implementation: https://github.com/php/php-src/pull/3764 Thank you, -- Guilliam Xavier -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] Wiki RFC karma request
On Mon, Mar 11, 2019 at 11:47 AM Nikita Popov wrote: > > Hi, > > I've granted you rfc karma on the wiki. Please check if it works. Yes, now I can edit pages under /rfc, thank you :) -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
[PHP-DEV] Wiki RFC karma request
Hello, I'd like to do some work on the Nullable Casting RFC (encouraged by its author). Could someone grant the wiki user guilliamxavier the necessary karma? Thanks in advance. -- Guilliam Xavier -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [RFC] Nullable Casting
OK, I'll try to sum up a bit the recent messages (since Nikita's one): Mark Randall wrote: > As is implied from the name, an implicit cast is done because the code > needs it to, not because it has been told to by the caller. It is > natural to be more conservative when doing something that has not been > explicitly specified. > > I expect a difference in the behaviour of function arguments vs casts > for the reason that although they share a type syntax, they do have two > very different behaviours. That makes sense! > I don't think it would go down very well to have non-nullable casts > throwing TypeErrors for common cases, without an elegant > could-not-convert fallback that doesn't require a 5 line try-catch block. I agree (and even for nullable casts). I'm also fine with the current `(int)null === 0`, `(string)null === ""`, `(array)null === []` etc. (Now maybe things like `(int)"abc" === 0` *could* emit some Notice like already the case for `(string)[] === "Array"`, but that's another discussion...) Benjamin Morel wrote: > Of course there could be helper functions with different semantics, that > would perform a cast-or-null-on-failure, such as `to_int("abc") === null` There was a "Safe Casting Functions" RFC, which was rejected (but that was in 2014, before PHP 7 and scalar type declarations, so who knows how it would go if re-proposed today...) Mark Randall wrote: > $nullable_number = $maybe_null ^?? (int)$maybe_null; That's an... "interesting" idea ^^ (though I would not propose it). > $nullable_number = (null|int)$input; This is explicit, but I worry that `null|int` and `int|null` will be different (since you propose *ordered*) whereas they're the same in phpDoc as well as in the (rejected) "Union Types" RFC. (I also fear things like `(null|float|int|string)$x`...) *** The initial motivation behind the RFC was mainly to have an explicit equivalent of "nullability-preserving" implicit *valid* conversions in symmetry with nullable scalar type declarations and weak-typing mode (e.g. `(?string) $int_or_null` or `(?int) $numeric_string_or_null`) for use in strict-typing mode. But there are indeed various combinations of "invalid" conversions (although one could argue they are programming errors or bugs to fix), and people seem to expect different things from a new "(?type)" cast syntax (not to speak of the existing "(type)" cast) as how to handle those "failures"... Honestly as a newbie here I'm feeling more tired than I had expected and I'm not sure if we'll find a syntax+semantics pair that will reach a consensus... Suggestions and comments very welcome! -- Guilliam Xavier -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [RFC] Nullable Casting
On Mon, Apr 8, 2019 at 11:55 PM M. W. Moe wrote: > > [redacted] > > On Mon, Apr 8, 2019 at 7:44 AM Dan Ackroyd wrote: > > > On Mon, 8 Apr 2019 at 04:21, M. W. Moe wrote: > > > > > > [redacted] > > > > [redacted] > > As the initiator of this thread (who hasn't had the time to answer questions yet, sorry), I would ask everyone to please try to avoid sarcasm and provocation (intentional or not), especially if you actually like the idea =( Thank you in advance -- Guilliam Xavier -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [RFC] Nullable Casting
Dan Ackroyd wrote: > > I'm guessing you don't actually have ths function getIntOrNull() in > your code-base? To help me understand where this would be useful, > could you provide some 'real-world' code where this would be useful? Hello, thanks for digging in :) Here's a "real-world" situation I happened to come across (*NOTE: simplified for sanity*): vendor/bar/api/src/Dest.php (code we don't own): send(/* FIXME */ $source->getNumber(), $source->getName(), /* ... */); } } As you can see, it's actually pretty close to the RFC example; I'm not sure it's worth to add complexity... > But please can you post the actual use-case you _need_ this for. Or > possibly update the RFC with that example. Currently, imo, the RFC is > just presenting an alternative syntax for something that is not 100% > needed. You have a point, but all the current alternatives I can think of (namely: use a ternary (or an `if`), possibly with a temporary variable; write (and autoload) custom casting functions; or give up on strict typing) suffer one or more of the following downsides: - increased risk of mistakes - verbosity / more maintenance - performance overhead > I do kind of like the idea in the RFC, but I think it needs a better > argument for it. For your other points, I find that Claude Pache has given pretty good arguments in the meantime (thanks!) =) (By the way, I also thought about say, "nullable_intval()", "nullable_strval()" etc. but we're missing "arrayval()" and "objectval()"...) Best regards, -- Guilliam Xavier -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [RFC] Strict operators directive
On Tue, Jun 25, 2019 at 3:09 PM Arnold Daniels wrote: > > Hi all, > > I would like to open the discussion for RFC: "Strict operators directive". > > This RFC proposes a new directive 'strict_operators'. When enabled, operators > may cast operands to the expected type, but must comply to; > > * Typecasting is not based on the type of the other operand > > * Typecasting is not based on the value of any of the operands > * Operators will throw a TypeError for unsupported types > > Reasoning; The current rules for type casting done by operators are > inconsistent and complex, which can lead to surprising results where a > statement seemingly contradicts itself. > > Using a directive means that backwards compatibility is guaranteed. > > https://wiki.php.net/rfc/strict_operators > > Yours, > Arnold Daniels > > [Arnold Daniels - Chat @ > Spike](https://www.spikenow.com/?ref=spike-organic-signature&_ts=1mzl6) > [1mzl6] Hello, thanks for the impressive work... I have just one interrogation: why disallow `~` for strings? (e.g. currently `~"\x00\x01\x02"` gives `"\xFF\xFE\xFD"`) -- Guilliam Xavier -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [RFC] Nullable Casting
On Wed, Apr 10, 2019 at 4:34 PM Mark Randall wrote: > > (Continuing from my previous post in a different thread...) > > IMHO a cast such as ([?]type) would be better described as passing a > mixed value through a function which has a return type of whatever is in > the cast... the mechanics of that function determine what is returned, > so long as it conforms to the cast type. > > A cast should always either return a value that would be accepted by a > function argument of an identical type to the cast, or it should throw > an exception. > > function x(T $value) { ... } > x(T) - Always OK > x((T)$var) - Always OK > x($var) - Function may throw a TypeError if it cannot be converted in a > very strict manner. > > To my mind, (?int) is quite explicit, in that it returns an integer or > null, and it is quite logical to expect it to return null in lieu of > throwing a TypeError if a conversion is not possible. Naturally, > (?int)null would return null. > > I see a lot of potential use in (?int)$value ?? $default. > > Equally I see a lot of use in the following to nullify unexpected inputs > such as if $_GET['something'] was an array: > > $input = (?string)$_GET['input'] ?? ''; So, for example: ```php $obj = (object) ["foo" => 42]; (function (int $x) { var_dump($x); })($obj); // TypeError (function (?int $x) { var_dump($x); })($obj); // TypeError var_dump((function ($x): int { return $x; })($obj)); // TypeError var_dump((function ($x): ?int { return $x; })($obj)); // TypeError var_dump((int) $obj); // Notice, then prints `int(1)` var_dump((?int) $obj); // would you want it to print `NULL`? (function (string $x) { var_dump($x); })($obj); // TypeError (function (?string $x) { var_dump($x); })($obj); // TypeError var_dump((function ($x): string { return $x; })($obj)); // TypeError var_dump((function ($x): ?string { return $x; })($obj)); // TypeError var_dump((string) $obj); // Recoverable fatal error var_dump((?string) $obj); // would you want it to print `NULL`? ``` I have no clear answer myself (other than the current proposal)... -- Guilliam Xavier -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [RFC] Nullable Casting
On Wed, Apr 10, 2019 at 12:52 PM Nikita Popov wrote: > > I'm a bit concerned that there are two possible semantics for what (?int) > does: > > 1. What I would intuitively expect: A fallible integer cast. I.e. try to > cast to integer and if not possible return null. So (?int) "foobar" becomes > null rather than 0. > 2. What this RFC proposes: A normal integer cast that leaves null alone. > > Both behaviors make sense to me generally ... and if there are two ways to > interpret a piece of syntax, I'd say the syntax is not explicit enough. The syntax mirrors nullable type declarations, but the thing is implicit and explicit conversions don't always behave the same today: ```php http://www.php.net/unsub.php
[PHP-DEV] Re: [RFC] Nullable Casting
On Sat, Apr 6, 2019 at 9:52 AM Guilliam Xavier wrote: > > Hello internals, > > David and I would like to open the discussion on our joint RFC: > > https://wiki.php.net/rfc/nullable-casting > > Mainly, it would enable to use e.g. `(?int)$x` besides `(int)$x`. > > We are looking forward to your feedback [...] > > Thank you, Hello again internals, Thanks everyone for your valuable feedback. I have updated the RFC with a new Discussion section to [try to] summarize the various arguments raised in this thread. -- Guilliam Xavier -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] Stop replacing dots with underscores in query, post and cookie parameters for PHP 8?
On Tue, Jul 16, 2019 at 4:39 AM Sara Golemon wrote: > > On Mon, Jul 15, 2019 at 8:39 PM Arnold Daniels > wrote: > > PHP replaces dots with underscores for $_GET, $_POST and $_COOKIE. > > This behavior once made sense because of Register globals. > > The explanation in the manual also still implies that query and > > post parameters are converted to variables > > (see > https://php.net/manual/en/language.variables.external.php#language.variables.external.dot-in-names > ). > > Register globals has been removed since 5.4.0 and thus this behavior > serves little purpose. > > > > I think it would be good to remove the conversion in PHP 8, as it's a > general cause of confusion and annoyance for anyone who comes across it. > > > > Is there a good reason to keep this behavior in PHP 8? > > > IMO, we can safely kill this. If anyone needs this behavior preserved, it > can be mimicked with half a dozen lines of PHP, or heck we can include a > function to call. I will, however, be very surprised if anyone misses this > by now. > > -Sara Indeed, it seems that people are rather strugling to work around the current behavior (and have been for years)... Some examples: - https://bugs.php.net/bug.php?id=4 - https://stackoverflow.com/questions/68651/get-php-to-stop-replacing-characters-in-get-or-post-arrays - https://github.com/symfony/symfony/issues/9009 - https://github.com/api-platform/core/issues/509 - https://github.com/api-platform/core/blob/v2.4.5/src/Util/RequestParser.php -- Guilliam Xavier -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] Let's allow eval() to be turned off in PHP 8
For the record, a few months ago, https://github.com/php/php-src/pull/4084 (extending `disable_functions` to handle `eval`) was first merged but finally reverted (requested by Xdebug), and the feature request https://bugs.php.net/bug.php?id=62397 was closed (with an explanation). -- Guilliam Xavier -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [RFC]
On Wed, Feb 12, 2020 at 4:58 AM Mike Schinkel wrote: > > Or best would be to add ::nameof for functions, method, classes, interfaces > and traits One problem is how would `x::nameof` resolve when you have several `x` symbols (of distinct kinds) in scope? ``` namespace Theirs { class Foo {} const BAR = 2; function qux() { return '3'; } } namespace Mine { use Theirs\Foo as x; use const Theirs\BAR as x; use function Theirs\qux as x; var_dump(new x); // object(Theirs\Foo)#1 var_dump(x); // int(2) var_dump(x()); // string(1) "3" // *** hypothetical: *** assert(x::class === 'Theirs\Foo'); assert(x::const === 'Theirs\BAR'); assert(x::function === 'Theirs\qux'); assert(x::nameof === ???); } ``` > Returning a _closure_ instead of a string would be providing a feature we > _already_ have instead of one we do _not_ have. > > If we had ::function returning a string we could use Closure::fromCallable() > to get a closure. Or today just use fn() => myfunc(). > > But if ::function instead returned a closure then there still would be no way > to extract the name of a function as a string from a symbol where PHP can > throw a warning if it does not recognize the symbol, such as in the case of a > typo. > > Seems to me having a shorter syntax to get a closure is an orthogonal concern. > > If we want a shorthand for closure we should create an additional syntax for > it but still provide a way to extract a function's name as a string from its > symbol since that is currently _not_ possible. Getting a closure from a > function symbol currently _is_ possible. > > Much better to provide ::function to return the name of the function and > ::closure get a closure that can call the function. > > Or have ::function to return the name of the function and provide a syntax > something like ${myfunc} to return a closure, which has been suggested later > in this thread. That might deserve consideration indeed... -- Guilliam Xavier -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] Re: [RFC] "arrayable" pseudo type hint
On Tue, Feb 4, 2020 at 1:48 PM Aimeos | Norbert Sendetzky wrote: > > [...] > > interface Arrayable extends ArrayAccess, Countable, Traversable > { > public function toArray() : array; > } > > [...] > > If union data types are available and "iterable" is implemented as > alias, an alias "arrayable" for "array|Arrayable" may be added as well. About that last point: it would not be possible to have both the `Arrayable` interface and the `arrayable` reserved word because PHP is case-insensitive for those things (the same way you cannot declare an `interface Iterable` because of the `iterable` reserved word, <https://3v4l.org/Fhqar>), so you would need another name (if you want the alias) -- Guilliam Xavier -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] Warn when declaring required parameter after optional one
Hi, On Wednesday, February 5, 2020, Nikita Popov wrote: > > > I like this idea and have updated the pull request to ignore the "Type > $param = null" case, so the deprecation should now just catch the > "definitely" incorrect signatures. > > So to summarize the current state: > > function test($foo = "bar", $baz) {} > // Deprecated: Required parameter $baz follows optional parameter $foo > > function test(Abc $foo = null, $baz) {} > // No warnings, works fine! > > With that adjustment made, are there any further concerns about this > change? Can you please just clarify which of the following will emit a deprecation? function f1($a = null, $b) {} function f2(A $a = null, $b) {} function f3(?A $a = null, $b) {} (I think f1 will, f2 won't, but f3?) Thanks > > Regards, > Nikita > -- Guilliam Xavier
Re: [PHP-DEV] [VOTE] declare(function_and_const_lookup='global')
> declare(strict_qualify=1); > > namespace foo; > > use function \{array_diff, var_dump}; > use const \bar\{a, b}; [Off-topic] All coding standards I've seen forbid writing a leading backslash in "use" and in strings. Indeed, `use \Ns\Klass;` gives the false impression that the leading backslash be required to avoid relative resolution, but `use Ns\Klass;` is already absolute. And for strings, `\Ns\Klass::class` (or `get_class(new \Ns\Klass())`) is equal to `'Ns\Klass'`, not `'\Ns\Klass'`. -- Guilliam Xavier
Re: [PHP-DEV] [RFC]
Hi, On Tue, Feb 11, 2020 at 1:09 PM Manuel Canga wrote: > > I was thinking about 'function' or 'func'. 'function' is more > semantic, but 'func' is used with "short functions"( PHP 7.4 ) and > these will be used for callbacks. Then I think 'func' will be more > consistent. Actually PHP 7.4's short closures / array functions use `fn`, not `func`. But `::fn` would look... weird. I agree with Diogo that `::function` would be more consistent. -- Guilliam Xavier -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [RFC] Adding a "Stringable" interface to PHP 8
On Tue, Feb 11, 2020 at 2:11 PM Michał Brzuchalski wrote: > > wt., 11 lut 2020 o 13:59 Guilliam Xavier > napisał(a): >> >> On Tue, Feb 11, 2020 at 1:12 PM Nicolas Grekas >> wrote: >> > >> > > >> > > Just so someone has mentioned it... is "Stringable" really the best name >> > > for this interface? Reddit really didn't like it ;) Some possible >> > > alternatives: ToString, HasToString, CastsToString. >> > > >> > >> > Naming things... >> > I'm not sure reddit is the way to lobby php-internals... >> > I proposed Stringable because it is the most consistent to me: >> > Traversable, Serializable, Countable, Throwable, JsonSerializable >> > all are related to some special engine behavior, which this ones also is. >> >> But one could argue that "string" is not a verb like "traverse", >> "serialize", "count", "throw" etc. >> Potential alternatives would be Stringifyable (or Stringifiable?), >> StringCastable, StringConvertible... >> (Even though I personally have no problem with "Stringable") >> > > Maybe StringObject? We do already have ArrayObject. But ArrayObject is not a interface (ArrayAccess is). -- Guilliam Xavier -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [RFC] Adding a "Stringable" interface to PHP 8
On Tue, Feb 11, 2020 at 1:12 PM Nicolas Grekas wrote: > > > > > Just so someone has mentioned it... is "Stringable" really the best name > > for this interface? Reddit really didn't like it ;) Some possible > > alternatives: ToString, HasToString, CastsToString. > > > > Naming things... > I'm not sure reddit is the way to lobby php-internals... > I proposed Stringable because it is the most consistent to me: > Traversable, Serializable, Countable, Throwable, JsonSerializable > all are related to some special engine behavior, which this ones also is. But one could argue that "string" is not a verb like "traverse", "serialize", "count", "throw" etc. Potential alternatives would be Stringifyable (or Stringifiable?), StringCastable, StringConvertible... (Even though I personally have no problem with "Stringable") -- Guilliam Xavier -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] Proposal for a new basic function: str_contains
On Fri, Feb 14, 2020 at 11:14 AM G. P. B. wrote: > > Moreover, checking for a substring to start/end a string seems > to be > fitting for the current strpos functions. Maybe in terms of semantics (`0 === strpos($haystack, $needle)`), but suboptimal in terms of performance, especially when $haystack is a *very long* string which *doesn't* contain $needle, strpos() will vainly search along the whole string, while a specialized function would stop as soon as possible (which is also the case of existing strncmp() but you need to write `0 === strncmp($haystack, $needle, strlen($needle))`, arguably not really the cleanest code...). For "contains" you have to search along the whole string anyway, so `str_contains()` is "just" `false !== strpos()` but cleaner. To be clear, I'm not against the current proposal (rather for actually) [I just would want `str_{starts,ends}_with` even more (without case-insensitive nor multibyte variants)] -- Guilliam Xavier On Fri, Feb 14, 2020 at 11:14 AM G. P. B. wrote: > > On Fri, 14 Feb 2020 at 10:58, Aegir Leet wrote: > > > I generally like the idea, but it seems many (most?) real-world > > implementations actually use mb_strpos() !== false by default. > > > > > > https://github.com/danielstjules/Stringy/blob/df24ab62d2d8213bbbe88cc36fc35a4503b4bd7e/src/Stringy.php#L206-L215 > > > > https://github.com/illuminate/support/blob/6eff6cff19f7ad5540b9a61a9fb3612ca8218c19/Str.php#L157-L166 > > > > So there should definitely be an mb_str_contains in ext/mbstring in > > addition to the regular str_contains proposed here. > > > > The biggest reason to have an mb_* variant if for when comparing with case > insensitivity. > The only other reason is if you need to check a string which is in a > different encoding, > which is, I'm assuming, is a quasi non-existent problem as everything > things is UTF-8 > nowadays. > > The reason why I personally voted no on the previous RFC was that I don't > see the > value of having functions checking if a string starts/ends with a sequence > but not a > general one. Moreover, checking for a substring to start/end a string seems > to be > fitting for the current strpos functions. > > This function on it's own is way more reasonable and useful to add IMHO > > Best regards > > George P. Banyard -- Guilliam Xavier -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [RFC] Static return type
Hi, After reading all the thread: I'm +1 for `: static` as proposed by this RFC. I'm also +1 for `: $this`, preferably also in PHP 8.0, but that could be a separate RFC: - I like the idea to check it at compile time (like `: void`), i.e. that all the return points of the method be syntactically `return $this;` (maybe also allow `return $this->otherMethod(/*...*/);` where the forwarded method is itself declared `: $this`). - Regarding covariance, `$this` should probably be treated like a "subtype" of `static`. - I don't like the idea of making an implicit `return $this;` in addition to the check. I'm -1 for `: fluent` or `fluent function` as an alternative to `: $this`. I'm -0.5 for `: new` / `: clone`. About "what comes out is the same type as what goes in", I would wait for generics. -- Guilliam Xavier -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [RFC] Allow ::class on objects
Hi, On Thu, Jan 9, 2020 at 10:02 PM Kalle Sommer Nielsen wrote: > > [...] > > use Interfaces; > if(!$object instanceof Interfaces\MyInterface) > { > // Notice the ! is right associative and instanceof is non > associative, hence the lack of parantheses > } Sorry for off-topic but that comment is incorrect: the fact that `!$x instanceof Foo` is evaluated as `!($x instanceof Foo)` (which I find more readable with explicit parentheses, by the way) is not due to the *associativity* of the operators but to their relative *precedence*. For instance, `===` is non-associative too but `!$x === 42` is evaluated as `(!$x) === 42` (not as `!($x === 42)`). According to the docs, associativity only matters for operators of equal precedence, e.g. `4 - 3 - 2` is evaluated as `(4 - 3) - 2`, and `4 ** 3 ** 2` is evaluated as `4 ** (3 ** 2)`. -- Guilliam Xavier -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] What to do with "$array[foobar]"?
Hi, On Thu, Jan 9, 2020 at 1:05 PM Nikita Popov wrote: > > [...] we already support > "$string" and "$object->prop", so it is in a way natural that > "$array['key']" is also supported, as the last of the "fundamental" > variable syntaxes. What about rather deprecating "$object->prop" too? The current situation can be surprising: "$object->foo()" // $object->foo . '()' "$object->obj->bar" // $object->obj . '->bar' "$object->arr[qux]" // $object->arr . '[qux]' "$array[arr][bar]" // $array['arr'] . '[bar]' "$array[obj]->qux" // $array['obj'] . '->qux' In any case, I'm +1 for deprecating "$array[key]", and "$array[0]" to avoid introducing another inconsistency. -- Guilliam Xavier -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] Re: [RFC] Allow trailing comma in parameter lists
On Thu, Apr 9, 2020 at 10:02 AM Nikita Popov wrote: > > On Thu, Mar 26, 2020 at 7:52 PM Nikita Popov wrote: > > > Hi internals, > > > > This has been declined in the past, but I just keep making this mistake, > > and believe it deserves reconsideration... > > > > https://wiki.php.net/rfc/trailing_comma_in_parameter_list > > > > Heads up: I plan to move this to voting tomorrow. Don't think there's much > to discuss here... > > Nikita Hello Nikita, I'm personally favorable, but since some concern has been raised that it *might* be interpreted as "encouraging" functions with many parameters (and I fear that could be taken as a motive for voting "no"), I would just suggest (again) that you could add an example (or even replace the current one) of a function with only two/three parameters that would still exceed 120 columns if on a single line (with e.g. descriptive names, [union] type declarations for parameters and/or return, and/or a class constant as default value for the last parameter, that's not so uncommon)... Just my two cents ;) Best regards, -- Guilliam Xavier -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] Type hints in array destructuring expressions
On Thu, Apr 16, 2020 at 12:20 PM Enno Woortmann wrote: > > Hi together, > > as the voting for the "Type casting in array destructuring expressions" > shows a clear direction to be declined (sad faces on my side, I really > would've liked it as a feature completion of the casting feature set > without the need for a really new syntax, as the parser also already > coverred it, but ok, time to continue :D ), combined with a strong > interest for the topic "type checks in array destructuring expressions" > (as well in the discussion as in the vote) I've set up a first draft of > an RFC covering this topic: > > https://wiki.php.net/rfc/typehint_array_desctructuring > > The discussion around the casting in array destructuring brought up the > idea to perform regular type checks in array destructuring expressions. > This RFC proposes a new syntax to type hint a variable inside an array > destructuring expression: > > $data = [42, 'Example', 2002]; > [int $id, string $data, int $year] = $data; > > The type hints behave identically to the type hints used in method > signatures (compare https://wiki.php.net/rfc/scalar_type_hints_v5). This > especially includes a behaviour depending on the strict_types directive. > > Additionally to scalar type hints also object type hints are possible. > > I've not yet started an implementation draft but I think this one will > be more tricky than the type cast implementation approach. As the parser > re-uses the array definition for array destructuring expressions (which > also leads to the type cast implementation without touching the parser) > adding type hints to the definition would also affect other parts of the > language eg. something like: > > $x = [int $a, string $b]; > > would be parsed by the parser. I'm currently not able to grasp the > impact of such a change. But that's another topic. > > Let's focus on the idea itself instead of the implementation first. > Thoughts on the first draft? > > Cheers, Enno > > -- > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: http://www.php.net/unsub.php > Hi, thanks for proposing, I guess it could be useful (or convenient at least). Just 2 thoughts: - It has been requested several times on this list to stop using the wording "type hint" and instead write "type declaration" ;) - When I see this example in the RFC: ``` $years = [["now", 2020], ["future", 2021]]; foreach ($years as [string $description, int $year]) { ``` I immediately think of a similar: ``` $years = ["now" => 2020, "future" => 2021]; foreach ($years as string $description => int $year) { ``` or: ``` $foos = [new Foo("one"), new Foo("two")]; foreach ($foos as Foo $foo) { ``` Now I remember this has already been requested (e.g. https://externals.io/message/104485#104488), but that's not really the same use case, so I don't know if it could/should be included... Regards, -- Guilliam Xavier -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [RFC] [DISCUSSION] Ensure correct magic methods' signatures when typed
On Sun, Apr 5, 2020 at 4:02 PM Gabriel Caruso wrote: > > Hello, internals. > > Hereby you can find the RFC Document that I want to discuss as suggested > via https://externals.io/message/109416 and > https://externals.io/message/107990: > > https://wiki.php.net/rfc/magic-methods-signature > > Best regards, > > -- Gabriel Caruso Hello, Thank you, this seems a sensible thing to add. Just an interrogation: the following magic methods (from the documentation) aren't mentioned at all in the RFC: - `__sleep(): array` - `__wakeup(): void` - `__unserialize(array $data): void` - (`__invoke` is basically untyped) - `__set_state(array $properties): object` - `__debugInfo(): array` Is there a reason for leaving them out? Related, the RFC mentions that `__serialize` and `__toString` already have a *runtime* check that they respectively return an `array` and a `string` (when called), but why not check their signature (if typed) at *compile time* too (i.e. make https://3v4l.org/ZPrVi an error)? Regards, -- Guilliam Xavier -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] Re: [RFC] Attributes v2
On Fri, Apr 17, 2020 at 6:11 PM Theodore Brown wrote: > > the RFC says that the alternate T_ATTRIBUTE `@:` token has the > downside "that it does not permit whitespace in attribute names to > allow detecting the ending of the declaration." Can you provide an > example of an attribute name containing whitespace that would be allowed > with the shift left/right tokens but not with the attribute token? >From what I saw in the related PRs (esp. https://github.com/beberlei/php-src/pull/2#issuecomment-609466083), the main reason is that if `@:` were defined as a standalone token, then the following sequence (with whitespace everywhere possible, like in https://3v4l.org/NRYbp): function ( @: A \ B $x ) would be ambiguous between two possible interpretations: function ( @:A \B $x ) // A attribute, \B type declaration function ( @:A\B $x ) // A\B attribute, untyped equivalent to respectively: function ( <> \B $x ) function ( <> $x ) which permit whitespace (unambiguous because delimited): function ( << A >> \ B $x ) function ( << A \ B >> $x ) (although I've never seen code with spaces around namespace separators). -- Guilliam Xavier -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [RFC] Mixed type
On Mon, Apr 20, 2020 at 5:17 PM Larry Garfield wrote: > > With union types and stringable already on the way, I'm not sure what other > non-hypothetical use cases would still be that fugly that you'd now need to > fall back to `mixed`. For instance: - the parameter of [a wrapper around] gettype() or an is_* function - the return of [a generic implementation of] ArrayAccess::offsetGet() or Iterator::current(), or of a userland array_value_first() or array_value_last() function To me, especially the return type declaration can be useful to ensure that [every code path of] the implementation returns a value. -- Guilliam Xavier -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [RFC] Mixed type
On Tue, Apr 21, 2020 at 11:10 AM Côme Chilliet wrote: > > Le lundi 20 avril 2020, 09:15:24 CEST Sara Golemon a écrit : > > use mixed = null|bool|int|float|string|array|object|resource; > > use scalar = null|bool|int|float|string; > > I’m wondering if null should maybe be left out of these, since ?mixed and > ?scalar can be used for this? For mixed, this has been discussed several times, it's defined as the union of *all* value types (void aside), *including* null, according to its usage in phpDoc (and in Hack, which also has a nonnull type such that mixed is equivalent to ?nonnull, cf https://docs.hhvm.com/hack/types/nullable-types). For scalar, I already replied (https://externals.io/message/109715#109723) that it should not include null indeed (according to https://www.php.net/manual/en/language.types.intro.php and https://www.php.net/manual/en/function.is-scalar.php). -- Guilliam Xavier -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [RFC] Mixed type
On Mon, Apr 20, 2020 at 4:15 PM Sara Golemon wrote: > > For the long term good of the language I'd prefer type aliases (or typedefs > or usings or whatever you want to call them. > > use mixed = null|bool|int|float|string|array|object|resource; > use scalar = null|bool|int|float|string; > use number = int|float; > > That said, baking 'mixed' in as an implicit alias of the above isn't > problematic for that future. The `scalar` example should be `bool|int|float|string`, without `null`. And for `mixed`, as already said, we cannot use `resource` in union types. All the more reason to standardize those "aliases" in core? -- Guilliam Xavier -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] PHP 7.4.5 Released!
On Thu, Apr 16, 2020 at 12:02 PM Derick Rethans wrote: > > The PHP development team announces the immediate availability of PHP > 7.4.5. This is a security bug fix release. > > All PHP 7.4 users are encouraged to upgrade to this version. > > For source downloads of PHP 7.4.5 please visit our downloads page. > Windows binaries can be found on the PHP for Windows site. The list of > changes is recorded in the ChangeLog. > > A migration guide is available in the PHP Manual. Please consult it for the > detailed list of new features and backward incompatible changes. > > Release Announcement: <http://php.net/releases/7.4.5.php> > Downloads:<http://www.php.net/downloads> > Windows downloads:<http://windows.php.net/download> > Changelog:<http://www.php.net/ChangeLog-7.php#7.4.5> > Migration guide: <http://php.net/manual/migration74.php> > > Many thanks to all the contributors and supporters! Thanks, just noticed the "Release Announcement" link is dead, the working one is: <http://php.net/releases/7_4_5.php> -- Guilliam Xavier -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [RFC][DISCUSSION] Change var_export() array syntax touse short hand arrays
On Wed, Apr 8, 2020 at 3:12 PM Sherif Ramadan wrote: > > So to recap on what's been discussed so far, because I plan to bring this > to a vote next week... > > I am updating the RFC to reflect that the change will no longer break > backwards compatibility. I will be adding an flags argument with the > following 3 optional bitwise flags for var_export: > > - VAR_EXPORT_SHORT_ARRAY [Triggers short-array syntax] > - VAR_EXPORT_NO_INDEX [Discards numbered indexes in arrays (only if they > are sequential from 0)] > - VAR_EXPORT_NO_WHITESPACE [For one-liners] > > This complicates the implementation slightly, but I think it brings a > greater net-benefit. Hello, First, thank you for proposing this RFC. I have no strong opinion either way, but anyway it cannot work as is, because var_export already has a second optional parameter (bool $return = false). You could add the flags as a third optional parameter (int $options = 0), or maybe make it replace (extend) the existing one and add an extra constant, say VAR_EXPORT_RETURN = 1, so that it can be combined (although I'm not sure that changing the type from bool to int (or maybe bool|int) would be BC-compliant...) Moreover the RFC currently says that var_export([1, 2, 3]) produces ``` array(1, 2, 3) ``` but it actually produces ``` array ( 0 => 1, 1 => 2, 2 => 3, ) ``` Regards, -- Guilliam Xavier -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [RFC] [VOTE] str_contains is accepted
On Mon, Mar 16, 2020 at 10:43 AM Philipp Tanlak wrote: > > Hello internals! > > Two weeks have passed since the voting on the str_contains RFC started. > https://wiki.php.net/rfc/str_contains > With a result of 43 (Yes) to 9 (No), the RFC was accepted and the voting > phase has been closed. > > If there are no issues with the implementation, the change can be merged > into the PHP source. > https://github.com/php/php-src/pull/5179 > <https://wiki.php.net/rfc/str_contains> > Kind regards > Philipp Tanlak Great! :) Now can we hope to have str_starts_with and str_ends_with in PHP 8 too? -- Guilliam Xavier -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] Re: [VOTE] Userspace operator overloading
On Thu, Mar 26, 2020 at 5:37 PM wrote: > > The overloaded concat operator has higher priority than the __toString() > method. > So if Class A overloades the concat operator, then calling $a . $b means > ClassA::__concat($a, $b); (Note that both operands are passed in their > original form) > If you want to concat the string representations, you will have to explicitly > convert the objects to strings: > $ret = (string) $a . (string) $b; This first part seems legit to me. > If the concat operator is not overloaded, the behavior is like now, and the > objects are converted implicitly to strings (so $a . $b actually means > (string) $a . (string) $b). > Furthermore an notice is triggered, hinting the user that he could overload > the concat operator. (Maybe here a different message than for the other > operators would be useful). I fear that "hint" notice could break Symfony apps... Couldn't you just not trigger it in this case? -- Guilliam Xavier -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [RFC] Allow trailing comma in parameter lists
On Sun, Mar 29, 2020 at 11:31 PM Jakob Givoni wrote: > > Hi Rowan, > > On Sat, Mar 28, 2020 at 4:01 PM Rowan Tommins wrote: > > > > While I'd personally be fine with this change, I think we should > > understand why the previous proposal failed rather than just hoping the > > vote goes differently this time. > > I think you have a good point here. > I've only been around for a short time so I can't comment on historical > reasons. > And though I agree the proposal is logical and consistent, I have this > nagging feeling in the back of my brain: > Are we encouraging functions with long lists of parameters so that > they need to be on their own lines? Just to say, with descriptive names and type declarations (and now union types), even a method with just two or three parameters can need to be wrapped to keep lines below 120 characters ;) Maybe the RFC could include an example? But I am curious too about why it failed last time. -- Guilliam Xavier -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] RFC Raised for str_starts_with and str_ends_with
On Thu, Mar 26, 2020 at 9:54 AM Nikita Popov wrote: > > On Thu, Mar 26, 2020 at 3:36 AM wrote: > > > Hi, > > > > Hope everyone is doing alright. I just raised a new RFC > > (https://wiki.php.net/rfc/add_str_starts_with_and_ends_with_functions , > > github patch: https://github.com/php/php-src/pull/5300) for adding > > str_starts_with and str_ends_with to PHP. I would like to open this RFC > > up to discussion. > > > > I raised a similar RFC about 9 months ago > > (https://wiki.php.net/rfc/add_str_begin_and_end_functions) that was > > narrowly rejected. A major criticism of that RFC was the inclusion of > > case-insensitive versions of str_starts_with and str_ends_with. I have > > incorporated feedback from that experienced and narrowed the new RFC to > > only propose str_starts_with and str_ends_with. > > > > I was in favor of the previous RFC, so also in favor of this one :) These > are going to complement the recently added str_contains() nicely. > > Notes on text: > > > After that RFC was closed, a code freeze was in place for PHP8's release. > PHP8 has now been released and several individuals have requested the > str_starts_with and str_ends_with functionality again. This is a simple but > highly desired functionality for PHP. > > I think you mean PHP 7.4 here. PHP 8.0 is not yet released, and not in > feature freeze either. > > > Add str_starts_with, and str_starts_with_ci() functions > > The second function should probably be str_ends_with() :) > > Nikita Hi Will, First, thank you for re-working on this, I would love to see it happen! :) Nevertheless, apart from some typos (already reported), I still think the RFC needs a "Motivation" section with actual examples of userland implementations (using functions like str[r]pos/strncmp/substr[_compare]... often with strlen, or even preg_match/fnmatch... [with escaping]) and the downsides of each (e.g. CPU-inefficient, memory-inefficient, error-prone, hard to understand...) plus how they handle empty strings. (And also probably shorten the introduction ^^ or move parts into a new subsection) PS: you could also add a link to the str_contains RFC Best regards, -- Guilliam Xavier -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] Re: [RFC] [DISCUSSION] Locale-independent float to string cast
On Tue, Apr 21, 2020 at 10:01 PM Máté Kocsis wrote: > > That said, we'd like to open the vote on Thursday, unless serious concerns > arise > in the meanwhile. > > Cheers, > Máté Hi, thanks for the work, Shouldn't the RFC mention the open question of printf formats %e/%E and %g/%G (and possible %H)? -- Guilliam Xavier -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [RFC] Function pipe operator
On Tue, Apr 21, 2020 at 4:44 PM Larry Garfield wrote: > > On Mon, Apr 20, 2020, at 11:20 PM, Stanislav Malyshev wrote: > > Just a small pedantry note - in a comparison section, the RFC compares > > this syntax to function composition. But this is not function > > composition. This is a syntax sugar for calling two functions one after > > another, not operator that produces a function. It sounds pedantic but > > it's rather important distinction - if |> is composition, than $foo |> > > $bar is a new callable provided $foo and $bar are callable (but no > > function is actually being called here!). If |> is call syntax, it's > > actually the result of calling $bar($foo). > > > > So comparing it to function composition is a bit confusing. Otherwise it > > looks OK to me, except the syntax for calling functions and methods is a > > bit awkward, but it's not the problem of this RFC I imagine. > > I'm not sure I follow. The only place composition is mentioned is in the F# > section, where it calls out specifically that we're implementing "pipe > forward" and *not* the composition operators ( >> ). Is that unclear? Actually it's also mentioned in the Haskell section, but as "function concatenation" (which adds to the confusion I guess). Speaking of Haskell, that reminded me of http://learnyouahaskell.com/a-fistful-of-monads#walk-the-line where the author defines a custom `-:` operator such that `x -: f` desugars to `f x` (equivalent to how `$x |> $f` would desugar to `$f($x)` with the RFC), which allows to write e.g. `xs -: sort -: reverse` instead of `reverse (sort xs)` or `(reverse . sort) xs`. -- Guilliam Xavier -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [RFC] Function pipe operator
On Wed, Apr 22, 2020 at 11:32 PM Bruce Weirdan wrote: > > Haskell has & operator in Data.Function module which is exact equivalent of > the proposed feature. > Link: > https://hackage.haskell.org/package/base-4.8.0.0/docs/Data-Function.html#g:2 > Example: https://repl.it/repls/KindLightsalmonApplicationserver Ah, thanks for the intel! (I see it was added in 2015, i.e. a few years after the publication of LYAHFGG in 2011) -- Guilliam Xavier -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: Re: [PHP-DEV] [RFC] Mixed type
On Wed, Apr 22, 2020 at 11:10 PM Barney Laurance wrote: > > The union of all other types is the top type, but I think as used in phpDoc > mixed is often really a dynamic type, rather than a top type. > > The top type (e.g. Typescript's 'unknown') is the supertype of all other > types, > while the dynamic type (e.g. Typescripts 'any') is simultaneously a > supertype > and a subtype of all other types. In Typescript (statically typed), both `any` and `unknown` are "supertype", but the former basically disables compile-time type checking (and opens for runtime errors) while the latter requires you write type checks/assertions. I guess `undefined` would be the actual "subtype". (By the way, unlike PHP, Typescript considers `void` a data type, i.e. you can have a "void variable" and assign it the value `undefined`.) Anyway, <https://docs.phpdoc.org/latest/guides/types.html> defines `mixed` as "A value with this type can be literally anything; the author of the documentation is unable to predict which type it will be" (even if some also use it where a union of a subset of types would be more accurate). > Taking a random example, arguments to str_replace documented as mixed > accept string|array and not anything else. Indeed, <https://www.php.net/manual/en/language.pseudo-types.php#language.types.mixed> currently says that, in the PHP documentation, "`mixed` indicates that a parameter may accept multiple (but not necessarily all) types", and gives two examples: <https://www.php.net/manual/en/function.gettype.php> is accurate, but <https://www.php.net/manual/en/function.str-replace.php> IMO should just use `string|array` rather than `mixed` (that's already the case in <https://github.com/php/php-src/blob/master/ext/standard/basic_functions.stub.php#L649-L655>). > So maybe the LSP rules shouldn't apply as described in the RFC to mixed. If > str_replace was a class method it might be OK for a subclass to change the > param type to e.g. array|string|int. > > That would leave scope for adding a real top type in a later RFC. I'd rather have the docs "fixed" (but I suspect `str_replace` is not the only place where `mixed` is used in an "approximate" fashion). `mixed` as defined by this RFC (i.e. equivalent to the currently-impossible-to-write union of all primitive types, including resource and null [but not void that is not a data type]) is LSP-conformant. Regards, -- Guilliam Xavier -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: Re: [PHP-DEV] [RFC] Mixed type
Hi Christoph and Rowan (your replies kind of overlap), On Thu, Apr 23, 2020 at 12:21 PM Christoph M. Becker wrote: > > On 23.04.2020 at 11:26, Guilliam Xavier wrote: > > > On Wed, Apr 22, 2020 at 11:10 PM Barney Laurance > > wrote: > > > >> Taking a random example, arguments to str_replace documented as mixed > >> accept string|array and not anything else. > > > > Indeed, > > <https://www.php.net/manual/en/language.pseudo-types.php#language.types.mixed> > > currently says that, in the PHP documentation, "`mixed` indicates that > > a parameter may accept multiple (but not necessarily all) types", and > > gives two examples: > > <https://www.php.net/manual/en/function.gettype.php> is accurate, but > > <https://www.php.net/manual/en/function.str-replace.php> IMO should > > just use `string|array` rather than `mixed` (that's already the case > > in > > <https://github.com/php/php-src/blob/master/ext/standard/basic_functions.stub.php#L649-L655>). > > Besides that PhD does not yet properly support union types[1], it's not > quite as simple. array|string would cause failure in strict mode if, > for instance, an int is passed; however, str_replace() has no issues > with this[2]. This is the reason why the stub file declares the types > of $search and $replace only in the doc block comment. > > [1] <https://github.com/php/phd/pull/25> > [2] <https://3v4l.org/R7Iac> Thanks for the clarification (and your PRs!). I guess internal functions can be "fuzzy" :/ On Thu, Apr 23, 2020 at 12:33 PM Rowan Tommins wrote: > > > On Wed, Apr 22, 2020 at 11:10 PM Barney Laurance > wrote ... > > I don't seem to have this message, and can't find it in any archives; was > it sent off-list by mistake? I don't know why Barney's email didn't make it to the list... In my box, it seems to have correct headers, notably: Subject: Re: Re: [PHP-DEV] [RFC] Mixed type To: Guilliam Xavier , "Côme Chilliet" Cc: internals@lists.php.net From: Barney Laurance Message-ID: <663b9713-ad05-47de-3efe-9343cc609...@redmagic.org.uk> In-Reply-To: > On Thu, 23 Apr 2020 at 10:26, Guilliam Xavier > wrote: > > > I'd rather have the docs "fixed" (but I suspect `str_replace` is not > > the only place where `mixed` is used in an "approximate" fashion). > > Don't forget how recent support for union types in PHP itself is; while the > manual could have come up with a richer notation, the invention of "mixed" > is itself simply a convenience to fit the DocBook template. A change to > that convention would need to be discussed with the editors of the manual > (including nuances like "string|bool" vs "string|false", and edge cases > where null is a rare error return), so calling any use of mixed right now > "wrong" is overstating the case. (Note that I didn't use that word ;) and surrounded "fixed" with quotes, but maybe should have said "improved" or "clarified".) Actually there's one precedent of union-like notation in the manual: `array|object`, but admittedly special-cased (https://www.php.net/manual/en/language.pseudo-types.php#language.types.array-object), and apparently hardly used (I found https://www.php.net/manual/en/mongodb-driver-bulkwrite.update.php as one instance). And you make a valid point about convention change. > It turns out DocBook itself didn't actually have a notation for union types > until Richard Quadling asked for it for future use in the PHP manual; it's > been accepted but would require tooling updates to actually make use of. > See https://news-web.php.net/php.doc/969386777 and > https://github.com/docbook/docbook/issues/91 Interesting history, thanks. > All of which is to say, I wouldn't use the conventions used in the manual > as any kind of guide to type system design. The best we can say is that > there's existing usage of "mixed" in the PHP manual and in docblocks > understood by many tools, so to avoid confusion, the new pseudo-type should > either behave roughly in line with that usage, or have a new name I concur (but I can't think of a different definition that would work with LSP, and this name is already soft-reserved waiting to be used). So, do you agree that the RFC is fine as is? -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [RFC] [DISCUSSION] Ensure correct magic methods' signatures when typed
Hi, just chiming in on a specific question/answer: On Tue, Apr 14, 2020 at 3:46 PM Gabriel Caruso wrote: > > On Tue, 14 Apr 2020 at 15:24, Nicolas Grekas > wrote: > > > > > > Foo::__isset(string $name): bool; > > > Foo::__unset(string $name): void; > > > > Same comment about LSP, but also about the type: isn't it allowed to have > > integers as keys? How does this play with strict_type and array access? > > > Thanks for raise this. Nowadays, you can't: https://3v4l.org/pPJDt. But, if > you call as a method, yes: https://3v4l.org/0VmYQ. Actually there are ways to use integers as property names, but they are converted to strings on creation: https://3v4l.org/0k4LS and https://3v4l.org/HhPZP (also https://3v4l.org/Ts42B). ArrayAccess doesn't use magic __isset(string $name) but interface offsetExists(mixed $offset). Regards, -- Guilliam Xavier -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [VOTE] Voting opens for str_starts_with and ends_with functions
On Mon, Jul 22, 2019 at 10:54 AM Nikita Popov wrote: > > On Fri, Jul 5, 2019 at 4:13 AM wrote: > > > Hello all, > > > > After 15 days of discussion I have opened up voting on the following RFC > > (https://wiki.php.net/rfc/add_str_begin_and_end_functions) . > > > > You can access the voting page here: > > https://wiki.php.net/rfc/add_str_begin_and_end_functions/vote > > > > I have never set up a vote on doku-wiki so please let me know if I made > > the vote incorrectly! > > > > Thanks, > > > > Will > > > > As we're already two days past the announced end, I've closed the RFC vote. > The final outcome is 26 in favor vs 20 against for str_starts_with and > friends, and 4 in favor to 36 against for mb_starts_with and friends. > Because a 2/3 majority is required, both parts of the proposal are declined. > > Based on the discussion during voting, I think that trying this again with > just str_starts_with+str_ends_with without the case-insensitive variants > might pass, as that's where the main controversy seems to be -- though some > people also expressed the view that these functions are too trivial to add > to the standard library. > > In any case, thanks for driving this through the RFC process! > > Nikita Hello Will, More than 6 months have passed, and in the meantime the related str_contains RFC has been accepted for the next PHP 8.0 (<https://externals.io/message/109050>). Would you be willing to reboot your RFC with just str_starts_with and str_ends_with (and a stronger case of how people keep implementing them using the inefficient and/or error-prone currently available alternatives)? Best regards, -- Guilliam Xavier -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] Putting the match expression in constant expressions in PHP 8.0 or 8.1
On Sat, Aug 8, 2020 at 2:22 AM tyson andre wrote: > Hi internals, > > The match expression can be thought of as a much more concise/readable > equivalent to chained ternary operators. > I'm proposing allowing matches in constant expressions when all parts of > the match are constant expressions. > > For example, these two class constants would have equivalent behaviors if > match expressions were allowed in constant expressions. > > ``` > class MyClass { > const CONFIG_SETTING = (APP_ENVIRONMENT == 'dev' || APP_ENVIRONMENT == > 'stage') ? 'development-config' : > (APP_ENVIRONMENT == 'prod' ? 'production-config' : null); > > const CONFIG_SETTING = match(APP_ENVIRONMENT) { > 'dev', 'stage' => 'development-config', > 'prod' => 'production-config', > default => null, > }; > } > ``` > > https://github.com/php/php-src/pull/5951 implements the main part of the > change. > Hi, thanks, just noticed that your examples should use `===` not `==`. Regards -- Guilliam Xavier
Re: [PHP-DEV][RFC] Rename T_PAAMAYIM_NEKUDOTAYIM to T_DOUBLE_COLON
> So please, let the parser tell me not only the line of the error, but also the colum. > Other information currently missing from the message - e.g. column > number, hints about unclosed blocks - is likely to be far more useful >> a) Character count (at line 456, character 23) > >> > >> b) Quote either the remainder or the parsed section on the line (MySQL > >> quotes the remainder, for example) > >> > >> c) Quote the whole line with an indicator where the error occurred. I'm > >> not sure what the best way to do this would be - generically this could > >> be encapsulated in several values: The line content, token start > >> character count, token length / end character count > >> > > > > I really like the combination of A + C. After using php for 13 years the > > If we could do the same as, for example, clang does: just display some > indication where the problem happened within the code, with the line > that caused it. Certainly not displaying internal token names, unless I > am debugging the parser they are useless. > Could this be discussed rather in the "Improvement to errors" thread? https://externals.io/message/110276
Re: [PHP-DEV] [RFC] Draft - Closure self reference
On Fri, Nov 20, 2020 at 5:02 PM David Rodrigues wrote: > > Is it `returnType as $thing` ? That doesn't read well, but I don't see > us making return type movable. as/use should be placable in either order, > but maybe we give them required order anyway? > > I don't know if that would be a problem, because today we can have it > "function(): Type use($x)", so "Type use($x)"? > No we can't, try it (Parse error). The correct order is "function() use($x): Type". -- Guilliam Xavier
Re: [PHP-DEV] Re: [RFC] var_representation() : readable alternative to var_export()
On Thu, Feb 4, 2021 at 3:36 PM tyson andre wrote: > Hi internals, > > > I've created https://wiki.php.net/rfc/readable_var_representation based > on > > my original proposal in https://externals.io/message/112924 > > > > [...] > > A reminder that voting on the var_representation RFC starts in a day. > This RFC proposes adding a new function `var_representation(mixed $value, > int $flags=0): string` with multiple improvements on `var_export()`. > > Any other feedback? > Hi, I think the "though strings with embedded newlines will still cause newlines in the output" part is obsolete (since `\r` and `\n` are escaped now). Apart from that, since var_export (and var_dump) can't really be "fixed" for BC reasons, I'm +1 for the new function. Thanks -- Guilliam Xavier
Re: [PHP-DEV] Re: [RFC] Under Discussion: Add Random class and RandomNumberGenerator interface
> Indeed, the current implementation appears to have several problems. So, > how about the following implementation? > > ```php > interface RandomNumberGenerator > { > public function generate(): int; > } > > final class Random > { > private RandomNumberGenerator $rng; > public function __construct(?RandomNumberGenerator $rng = null) > { > $this->rng = $rng ?? new XorShift128Plus(random_int(PHP_INT_MIN, > PHP_INT_MAX)); > } > public function nextInt(): int {} > public function getInt(int $min, int $max): int {} > public function getBytes(int $length): string {} > public function shuffleArray(array $array): array {} > public function shuffleString(string $string): string {} > public function __serialize(): array {} > public function __unserialize(array $data): void {} > } > > class XorShift128PlusNumberGenerator implements RandomNumberGenerator > { > public function generate(): int {} > public function __serialize(): array {} > public function __unserialize(array $data): void {} > } > > class MT19937NumberGenerator implements RandomNumberGenerator > { > public function generate(): int {} > public function __serialize(): array {} > public function __unserialize(array $data): void {} > } > > class SecureNumberGenerator implements RandomNumberGenerator > { > public function generate(): int {} > } > ``` > > This is an approach similar to Nikita's `createDefault`. If the > constructor has a null argument, it uses the default, XorShift128+, > internally. > > Also, whether the Random class is serializable or clonable depends on the > instance of RandomNumberGenerator being used. This means that when the > Random class clone is called, the `$rng` member will be implicitly cloned. > > How about this? > Hello, thanks for thinking again. A few editorial notes: - I guess that would be "new XorShift128PlusNumberGenerator" (like the class name)? - The non-Secure implementations' stubs are probably missing `public function __construct(?int $seed = null) {}`? - The Random class' and non-Secure implementations' stubs are probably missing `public function __clone(): void {}` (like `__serialize()`)? That would let us use the API like this: 1. Construction: one of: - default RNG and seed: `$random = new Random();` - chosen RNG, default seed: e.g. `$random = new Random(new MT19937NumberGenerator());` - chosen RNG and seed: e.g. `$random = new Random(new MT19937NumberGenerator(1234));` (no "default RNG, chosen seed", but the default RNG can be documented, and one could argue that a chosen seed only makes sense with a chosen RNG anyway) 2. Usage: `$int = $random->nextInt();`, `$percent = $random->getInt(0, 100);`, `$dword = $random->getBytes(4);`, `$shuffledList = $random->shuffleArray($list);` etc. I think this is well-consistent with the "pure design" described by Nikita, and I personally find it both flexible/extensible and easy-to-use =) (Just beware that the namespace question will probably pop up again.) PS: I feel like my numerous questions/suggestions (in this thread and the previous ones) may also have caused some deviations, so I hope that I won't need more and that other participants will reach a consensus... Best regards, -- Guilliam Xavier
Re: [PHP-DEV] Re: [RFC] Under Discussion: Add Random class and RandomNumberGenerator interface
> > Couldn't the Random class simply implement `public function __clone(): > void` (that would internally do like `$this->algo = clone $this->algo;`)? > Sorry I meant like `$this->rng = clone $this->rng;`. PS: Please don't reply to this erratum, but rather to the previous message ;)
Re: [PHP-DEV] Re: [RFC] Under Discussion: Add Random class and RandomNumberGenerator interface
uestion? > > > I would like to answer a few unanswered questions. > > > > > What is bias? > > > > I' ve confirmed that the bias issue in mt_rand has already been fixed and > > is no longer a problem. > > > > This implementation copies most of it from mt_rand. Therefore, this > > problem does not exist. > > > > Therefore, an equivalent method to mt_getrandmax() is no longer provided. > Great! > > > > > uint64 & right-shift > > > > This is a specification of the RNG implementation. PHP does not have > > unsigned integers, but RNG handles unsigned integers (to be precise, even > > the sign bit is random). > > > > As mentioned above, PHP does not have unsigned integers, which means that > > using the results generated by RNGs may cause compatibility problems in > the > > future. To avoid this, a 1-bit right shift is always required (similar to > > mt_rand()). > Good to know, thanks. Regards, -- Guilliam Xavier
Re: [PHP-DEV] Re: [RFC] Under Discussion: Add Random class and RandomNumberGenerator interface
On Wed, Jun 9, 2021 at 3:16 PM Go Kudo wrote: > Thanks Guilliam. > > > I'm not sure you really addressed > https://externals.io/message/114561#114680 ? > > I thought I had solved this problem by implementing the > `RandomNumberGenerator` interface. > > Accepting strings and objects as arguments is certainly complicated, but I > thought it met the necessary requirements. > From the aspect of static analysis, there seems to be no problem. > > Reverting to a full object-based approach would increase the cost of > providing new RNGs from extensions. I think the string approach is superior > in this respect. > How much more "costly" would it be to define a class (implementing RandomNumberGenerator) and use its (full) name as the algo identifier? > Nikita's `createDefault()` approach is certainly good, but I think it is > still difficult for beginners to understand. > > I also thought about it for a while after that, and I think that the > current implementation is the most appropriate for now. What do you think? > I still agree with Nikita that there's a discrepancy between e.g. `new Random(RANDOM_XXX, $seed)` and `new Random(new CustomRNG(/*custom args*/))`, which also poses additional questions, e.g.: - (already pointed out by Jordi) `new Random(new CustomRNG(/*custom args*/), $seed)` is "illogical" (the passed $seed won't be used) but "possible" (even if your current implementation throws a ValueError when $seed is non-null); - This opens the possibility of "leaking" the RNG "source" (even if no `public function getRNG()`), e.g.: ``` $rng = new CustomRNG(/*custom args*/); $r1 = new Random($rng); $r2 = new Random($rng); var_dump($r1->nextInt() === $r2->nextInt()); // false (not true), I suppose? ``` or: ``` $rng = new CustomRNG(/*custom args*/); $r = new Random($rng); var_dump($r->nextInt()); // 1st of sequence $rng->generate(); var_dump($r->nextInt()); // 3rd of sequence (not 2nd), I suppose? ``` (possibly in less obvious ways), which may be considered bad or not (but still a discrepancy vs extension-provided algos). Again, taking a class name and optional extra args (or an $options array, like password_hash(), maybe even including 'seed' only for the algos that need one) to construct, rather than an already constructed object, might be better? But that would also "split" the constructor args from the class (increasing the risk of "mismatch"), and make using anonymous classes less easy, and maybe we haven't considered all the uses cases (e.g. what about `Random::getAlgoInfo(CustomRNG::class)`?)... So that might also be worse :/ It would be great to have more insights! (if nobody else speaks up then let's keep it as is of course) > > Couldn't the Random class simply implement `public function __clone(): > void` (that would internally do like `$this->rng = clone $this->rng;`)? > > Implicitly cloning in areas where the user cannot interfere may cause > problems when using objects that cannot be cloned. > However, this may be overthinking it. The reason is that a > `RandomNumberGenerator` that cannot be cloned should be implemented as algo > in the first place. > If there are no objections, I will change the implementation. > Ah, true, I hadn't thought about non-clonable implementations... But that's already the case for `__serialize()` and non-serializable implementations, right? (But let's wait a bit for possible objections, indeed) > > Indeed, a decision has to be made. If you throw an exception, we > wouldn't have the "issue" of different results on 32- vs 64-bit machines, > but XorShift128+ and Secure would be unusable on a 32-bit machine, right? > > I don't see any problem with the current implicit truncation behavior for > this. Even if a user switches to a 64-bit environment, compatibility can be > maintained by explicitly truncating the generated values. In addition, most > of the other methods only use 32bit internally. > If you are concerned about this, you should probably be concerned about > the incompatibility with MT_RAND_PHP. > That problem can also be compensated for with an extension that adds algo. > I thought you were "struggling with [this implicit truncation] behavior when calling nextInt() in a 32-bit environment using a 64-bit RNG [...] which means that the code loses compatibility with the result of running on a 64-bit machine"? And you asked if throwing an exception would be preferable? Anyway, I personally don't care about 32-bit (but other people may). > Regards, > Go Kudo > Regards, -- Guilliam Xavier
Re: [PHP-DEV] [RFC] Partial Function Application, take 2
On Wed, Jun 2, 2021 at 7:47 PM Larry Garfield wrote: > Hi folks. After much off-list discussion, iteration, and consideration, > we have a new draft of PFA ready for review. > > The URL is the same: > > https://wiki.php.net/rfc/partial_function_application > Hi, thanks all for the reworks! I just thought to something: does it support nullsafe calls, e.g. `$foo?->bar(?)`? and if yes, what is the signature of the Closure when `$foo === null` (and does it make a difference if, inside a function, it was created as a local variable `$foo = null;` vs received as a typed parameter `?Foo $foo`)? Related, for `$null === null`, is `$c = $null->bar(?);` / `$c = $null::baz(?);` an immediate error, or only later when calling `$c($arg)`? Regards, -- Guilliam Xavier
Re: [PHP-DEV] [RFC] Partial Function Application, take 2
On Thu, Jun 10, 2021 at 7:32 PM Guilliam Xavier wrote: > > Since `$null?->whatever(1, 'a')` currently always returns null without > error, shouldn't `$null?->whatever(?, 'a')` return a closure (with a > signature built from the placeholders only) that will return null when > called (i.e. equivalent to `fn (mixed $arg1) => null` here)? > Ah, we can also see `$foo?->bar(?)` as simply "desugaring" to `$foo === null ? null : $foo->bar(?)`, so the current behavior makes sense too (and maybe even "more")... I guess I was confused to get a "null-implying error" despite using a "null-safe" call syntax :s (There's also the possibility of not supporting it, but I guess that would be a lose-lose...) -- Guilliam Xavier
Re: [PHP-DEV] [RFC] Partial Function Application, take 2
On Thu, Jun 10, 2021 at 4:34 PM Larry Garfield wrote: > On Thu, Jun 10, 2021, at 3:17 AM, Guilliam Xavier wrote: > > On Wed, Jun 2, 2021 at 7:47 PM Larry Garfield > > wrote: > > > > > https://wiki.php.net/rfc/partial_function_application > > > > for `$null === null`, is `$c = $null->bar(?);` / `$c = > > $null::baz(?);` an immediate error, or only later when calling > `$c($arg)`? > > That dies with "call to member function on null" when trying to create the > partial: > > https://3v4l.org/E6MgK/rfc#focus=rfc.partials > That makes sense (eager evaluation of non-placeholder "arguments", including the called-on object). > > does it > > support nullsafe calls, e.g. `$foo?->bar(?)`? and if yes, what is the > > signature of the Closure when `$foo === null`? > > I just checked, and it... sort of supports nullsafe. Rather, if you try > to partial a method on a null object, you get null back for your closure. > Then when you try to call it, you get a "cannot invoke null" error. > Which... I think makes sense. > > cf: https://3v4l.org/4XeB3/rfc#focus=rfc.partials Well I find that unexpected :/ > As a cute side effect, Joe pointed out you could do this: > > https://3v4l.org/ERRdY/rfc#focus=rfc.partials So there's a "workaround", although I wouldn't call it precisely "cute"... > I wouldn't really call that a feature, but more of a side effect of the > implementation. Please don't count on that behavior. > I'd rather not indeed ;) Since `$null?->whatever(1, 'a')` currently always returns null without error, shouldn't `$null?->whatever(?, 'a')` return a closure (with a signature built from the placeholders only) that will return null when called (i.e. equivalent to `fn (mixed $arg1) => null` here)? Thanks, -- Guilliam Xavier
Re: [PHP-DEV] Re: [RFC] is_literal
On Fri, Jun 18, 2021 at 12:10 PM Pierre wrote: > Le 18/06/2021 à 08:00, Craig Francis a écrit : > > As there’s been no issues raised with supporting integers, and doing so > > will help adoption, the implementation will be updated to allow them. > > > > Now to choose the name, with the options is_known() from Joe and > > is_trusted() from Moritz: > > > > https://strawpoll.com/bd2qed2xs > > > > Keep in mind it might also become a dedicated type in the future. > > > > Craig > > If I'm understanding this correctly, what you call a literal value is a > statically written and compiled string, which doesn't originate from a > user given value, but was hardcoded at some point. If so, even if the > primary use is of course for security concerns, the realty of what it > does is not, it's mostly about how a certain variable was defined / > assigned. How about is_static() or is_value_static() ? Or even > is_statically_defined() ? There's many options in this path. > IIUC, with the addition of integers, the function will return true for e.g. `'SELECT * FROM foo LIMIT ' . (int)$limit` even if $limit doesn't come from a "static" value (e.g. random_int() or even `$_GET['limit']`) -- Guilliam Xavier
Re: [PHP-DEV] [RFC] Name issue - is_literal/is_trusted
On Tue, Jun 22, 2021 at 8:11 PM Craig Francis wrote: > > The Function: > - Is a security-based function that prevents Injection Vulnerabilities in > PHP. > - Flags strings written by the developer, including when concatenated. > - Also accepts integer values, which as purely numerical cannot contain > code/dangerous characters. (Due to technical limitations within PHP, it's > not possible for these to be flagged as user or developer in the codebase > itself without performance issues). > - `is_safe_from_injections()`? - `is_secure_against_injections()`? - `can_be_trusted_to_not_contain_injection_vulnerabilities()`? (okay not this one) Alternatively, if integers are too controversial, how about reverting the implementation to `is_literal()` but provide a function like `to_literal(int $int): string` (or just a "polyfill" for userland, could be a one-liner `implode(array_map(fn ($c) => ['0','1','2','3','4','5','6','7','8','9','-'=>'-'][$c], str_split((string)$int)))`), so that those `implode(',', [1,2,3])` could use `implode(',', array_map('to_literal', [1,2,3]))`? Regards, -- Guilliam Xavier
Re: [PHP-DEV] Introduce str_left/right In 8.1
On Wed, Jun 23, 2021 at 6:49 PM Sara Golemon wrote: > On Wed, Jun 23, 2021 at 9:15 AM Hamza Ahmad > wrote: > > > > > Since feature freeze for 8.1 is approaching, I want to request two useful > > string functions that exist in various languages-especially those that > run > > on web servers and used in databases. These are respectively `left();` > and > > `right();` > > > > > Sorry, you spent several paragraphs insisting that these are > common functions, but you didn't explain what they're meant to actually do. > > Using some context, I would assume you mean this: > > function str_left(string $str, int $len): string { > return substr($str, 0, $len); > } > > function str_right(string $str, int $len): string { > return substr($str, -$len); > } > I assume the same. > > If that's the case, then why? As you can see, the existing > functionality available is trivial to write. You don't even need to know > any particular amount of math (which I've been recently informed shouldn't > be a prerequisite to writing software -- shakes fist at clouds). > > Am I misunderstanding what these proposed functions should do, or am I > underestimating the difficulty of typing a zero or negative sign on certain > keyboards? > I think that's more about "semantics" ("conveying intent to readers") than typing... That said, I tend to agree with George (but maybe I'm "too" used to seeing substr()?) Regards, -- Guilliam Xavier
Re: [PHP-DEV] [Vote] make Reflection*#setAccessible() no-op
Meanwhile, if anybody knows why the RFC isn't listed on `/rfc`, lemme know > :D > You have to add it manually, cf https://wiki.php.net/rfc/howto 3.4 (yeah...) Cheers -- Guilliam Xavier
Re: [PHP-DEV] Introduce str_left/right In 8.1
On Thu, Jun 24, 2021 at 1:17 PM Kamil Tekiela wrote: > I am against adding these functions, but for different reasons than Sara > and George. > If we add str_left and str_right then there should be a corresponding > variant in mbstring. The byte-string functions are rarely useful. Adding > these functions to mbstring unnecessarily complicates the extension for > little to no gain. > So you seem to relate to Christoph's (and Rowan's) point. > Another point is that if we decide to add them, then we will bikeshed > forever in an unresolvable manner about the name. Should it be called > str_left or strleft? Current functions don't have a naming convention, so > using either variant will be wrong. > To be fair, most "strxxx" functions were historically more-or-less copied from C; most recent additions have been "str_xxx". > Personally, I find substr to be more clear about the intent. I know that I > am asking for a part of the string. Whereas str_left doesn't convey an > action immediately. Without knowing its purpose I wouldn't know if it will > pad the string from the left, strip characters from left, or take the > leftmost part of the string. > True, I can also imagine bikeshed like "str_leftmost", "str_start", "str_first[_n]" (and same for rightmost/end/last)... > Don't take it the wrong way, but I think it's a waste of time to implement > a function that doesn't even need a polyfill in the userland. > > Regards, > Kamil > -- Guilliam Xavier
Re: [PHP-DEV] [RFC] Pipe Operator, take 2
Hi, On Tue, Jun 8, 2021 at 12:09 AM Larry Garfield wrote: > On Mon, Jun 7, 2021, at 4:00 PM, Eugene Leonovich wrote: > > On Mon, Jun 7, 2021 at 9:03 PM Larry Garfield > > wrote: > > > > > https://wiki.php.net/rfc/pipe-operator-v2 > > > > > FTR, there are several typos in the "Hello World" examples > (*strto*t*upper, > > htmlent*i*ties*). Also, these examples will not work as written because > > explode() expects two arguments and will fail if you pass only one: > > https://3v4l.org/tLO0s. > > Hm. You're right. It used to, but it's been a very long time since > explode() allowed an empty split, apparently. I updated the example to use > str_split, which is what I'd intended to do in this case. Thanks. > Are you thinking to implode()? Anyway, you forgot to update one `explode(?)` to `str_split(?)`, and also, the first `fn($v) => 'strtoupper'` should be just `'strtoupper'`. About Haskell, rather than (or in addition to) the function composition [not "concatenation"] (.), I would mention the reverse application operator (&): https://hackage.haskell.org/package/base-4.15.0.0/docs/Data-Function.html#v:-38- One thing I note is that even with PFA, some examples still need an arrow function, e.g. the PSR-7 one: ``` ServerRequest::fromGlobals() |> authenticate(?) |> $router->resolveAction(?) |> fn($request) => $request->getAttribute('action')($request) /* ... */; ``` while in Hack you would write it as: ``` ServerRequest::fromGlobals() |> authenticate($$) |> $router->resolveAction($$) |> $$->getAttribute('action')($$) /* ... */; ``` Also, quoting from https://wiki.php.net/rfc/first_class_callable_syntax#partial_function_application : """ Both approaches to the pipe operator have their advantages. The $$ based variant allows using more than plain function calls in each pipeline step (e.g. you could have $$->getName() as a step, something not possible with PFA), and is also trivially free. A PFA-based optimization would entail significant overhead relative to simple function calls, unless special optimization for the pipe operator usage is introduced (which may not be possible, depending on precise semantics). """ Could you (or Nikita) expand a bit on this (esp. the advantages of the PFA approach / disadvantages of Hack's approach)? Regards, -- Guilliam Xavier
Re: [PHP-DEV] [RFC][DISCUSSION] Match expression v2
On Fri, Jun 18, 2021 at 4:24 PM Larry Garfield wrote: > On Thu, Jun 17, 2021, at 1:49 PM, Mark Tomlin wrote: > > Please excuse the year long bump, but I was hoping to draw some more > > attention to the implicit "match (true)" case. I'm just a regular user of > > PHP, nothing too fancy, just one of the many, many people around the > world > > who use PHP. When I first started using match statements, I thought it > was > > a natural thing that an implicit "match (true)" would just work. I do > hope > > that this makes it into PHP 8.1, as that seems like the most obvious next > > step here and it would be nice for it to make it into the very next > release. > > > > That is all. Thank you very much to Ilija Tovilo for adding the match > > keyword to the language, and the whole PHP dev team for making this > > incredible language. PHP has given me a whole career, and I am deeply > > grateful to you all. > > I wrote a separate small RFC for implicit-true match statements ( > https://wiki.php.net/rfc/short-match). There didn't seem to be a great > deal of interest, though (https://externals.io/message/112496). > > There's not much else to do with that RFC beyond bring it to a vote and > let the chips fall where they may. If folks think that's worth doing I can > do so. It's not going to be able to scope creep much beyond its current > minimalism. > Before going to vote, I think the RFC should be updated to at least mention the strict-VS-loose comparison choice (for things like `match { preg_match(/*...*/) => /*...*/ }`). Regards, -- Guilliam Xavier
Re: [PHP-DEV] [RFC] Pipe Operator, take 2
On Tue, Jun 8, 2021 at 4:09 PM Larry Garfield wrote: > On Tue, Jun 8, 2021, at 5:41 AM, Guilliam Xavier wrote: > > > you forgot to update one > > `explode(?)` to `str_split(?)`, and also, the first `fn($v) => > > 'strtoupper'` should be just `'strtoupper'`. > > I deliberately made that example extra verbose to show how ugly it can > get, but I can shorten it. > Extra verbose would have been `fn($v) => strtoupper($v)`, there was obviously a typo (already correct in the second equivalent code fragment). Anyway, I see you fixed it, and also updated the Haskell section :thumbsup: > > > Also, quoting from > > > https://wiki.php.net/rfc/first_class_callable_syntax#partial_function_application > > : > > > > """ > > Both approaches to the pipe operator have their advantages. The $$ based > > variant allows using more than plain function calls in each pipeline step > > (e.g. you could have $$->getName() as a step, something not possible with > > PFA), and is also trivially free. A PFA-based optimization would entail > > significant overhead relative to simple function calls, unless special > > optimization for the pipe operator usage is introduced (which may not be > > possible, depending on precise semantics). > > """ > > > > Could you (or Nikita) expand a bit on this (esp. the advantages of the > PFA > > approach / disadvantages of Hack's approach)? > > It's true PFA doesn't cover every possible RHS of pipes. In practice, I > think using the piped value as an object on which to invoke a method is the > only major gap. Normally in functional code you would use a lens in that > case, which (if I am understanding those correctly; that's roughly at the > edge of my functional understanding) is essentially a function call that > wraps accessing a property or calling a method so that it feels more > functional, and thus pipes cleanly. > > However, piping with callables has a number of advantages. > > 1) The implementation is vastly simpler. It's simple enough that even I > can manage it, whereas Hack-style would be more considerably implementation > work. > > 2) I would argue it's more flexible. Once you start thinking of > callables/functions in a first class way, producing functions on the fly > that do what you want becomes natural, and fits better with a > pipe-to-callable model. For instance, the comprehension-esque example > (which I suspect will be one of the most common use cases of pipes) is far > cleaner with a callable, as it can obviate any question about parameter > order. > > Another example I threw together last night is this proof of concept last > night, which works when pipes, enums, and partials are combined. I don't > think Hack-style would be capable of this, at least not as elegantly. > > https://gist.github.com/Crell/e484bb27372e7bc93516331a15069f97 > > (That's essentially a "naked either monad".) > > 3) I disagree that the overhead of arbitrary callables is "significant." > It's there, but at that point you're talking about optimizing function call > counts, mostly on partials; unless you're using pipes for absolutely > everything, go remove an SQL query or two and you'll get a bigger > performance boost. > > 4) Far more languages have callable pipes. Hack is, as far as I am aware, > entirely alone in having pipes be combined with a custom expression syntax > rather than just using functions/callables. That isn't conclusive proof of > anything, but it's certainly suggestive. > > I'm going to be moving forward with this approach one way or another (if > for point 1 if nothing else). I do believe it is the more flexible, more > robust approach, and fits with the general strategy I recommend of small, > targeted changes that combine with other small, targeted changes to offer > more functionality than either of them alone. That's exactly what we're > doing here. > All good points IMHO. Thanks! -- Guilliam Xavier
Re: [PHP-DEV] [RFC] Partial Function Application, take 2
Sorry, me again :s I have tested the examples from https://wiki.php.net/rfc/partial_function_application on https://3v4l.org/#focus=rfc.partials and several of them currently give an error: - Ex 10: on the line `$c = stuff(?, ?, f: 3.5, ..., p: $point);` => Fatal error: Named arguments must come after all place holders (typo I guess, `$c = stuff(?, ?, ..., f: 3.5, p: $point);` is OK) - (Ex 11: no error but a typo: `'hi'` vs `'foo'`) - Ex 16: for the last call `(four(..., d: 4, a: 1))(2, 3);` => Fatal error: Uncaught ArgumentCountError: four(): Argument #2 ($b) not passed (on the function definition line) (`(four(..., d: 4, a: 1))(2, 3, 5, 6);` idem, but `(four(..., d: 4, a: 1))(b: 2, c: 3);` throws an "Unknown named parameter $b" Error on the call line) (weird) - func_get_args() and friends: one the last line `$f(1, 2);` (after `$f = f(?);`) => Fatal error: Uncaught Error: too many arguments for application of f, 2 given and a maximum of 1 expected (can make sense, e.g. https://externals.io/message/114532#114554 ) - (Callable reference: no error but a typo: `$f` vs `$foo`) - Optimizations: on the line `$boo = $baz(4, ...);` => Fatal error: Uncaught Error: too many arguments and or place holders for application of Closure::__invoke, 1 given and a maximum of 0 expected (`$boo = $baz(?);` throws the same error, but `$boo = $baz(4);` throws a "not enough arguments for implementation of foo, 4 given and exactly 5 expected" Error, and `$boo = $baz(...);` makes the subsequent `$boo(5);` throw a "not enough arguments ..." Error) (weird, looks like `$bar = $foo(2, ...);` and/or `$baz = $bar(3, ...);` dropped too many params) Regards, -- Guilliam Xavier
Re: [PHP-DEV] Trait constants
On Sun, Jun 28, 2020 at 2:34 PM Nikita Popov wrote: > On Sat, Jun 27, 2020 at 3:53 PM Stephen Reay > wrote: > > > Hi, > > > > It’s always struck me as slightly odd that traits don’t support constants > > the way classes and interfaces do. > > I tried to find an explanation of the lack of support in the original > RFC, > > and came up empty. > > > > A consequent discussion in R11 has led me here. > > Can anyone working on internals explain why traits don’t allow constants > > (either technically or philosophically)? > > Moreover, what’s the opinion(s) of the list, on adding support for this? > > Would an RFC be needed? > > > > Sounds like a reasonable addition. An RFC will be needed to specify the > details, which tend to be tricky whenever traits are involved. Some > suggestions: > > * Constants mustn't be accessible directly on the trait, i.e. > TraitName::FOOBAR throws. > Sorry for asking so late, but: why? Note that currently both TraitName::$foobar and TraitName::foobar() work: https://3v4l.org/eGlYm Thanks, -- Guilliam Xavier
Re: [PHP-DEV] Re: [RFC] [Discussion] Final constants
On Tue, May 18, 2021 at 1:23 AM Gabriel Caruso wrote: > On Sun, 16 May 2021, 15:52 Máté Kocsis, wrote: > > > As I've fully finished the implementation, I intend to bring this to a > vote > > on Wednesday if no new concerns come up (besides the usual question about > > the usefulness of the feature). > > > > Máté > > > Interesting RFC Maté, thanks for bringing it. > > How would we know if a given constant is overwritable? > > Would we need something like `ReflectionConstant::isOverwritable()`? > Hi Gabriel, see https://wiki.php.net/rfc/final_class_const#reflection > A `ReflectionClassConstant::isFinal()` method is added in order to be able to retrieve if a constant is final. Regards =) -- Guilliam Xavier
Re: [PHP-DEV] Trait constants
On Wed, May 12, 2021 at 12:22 PM Stephen Reay wrote: > > Any thoughts on > https://github.com/stephenreay/php-rfcs/blob/master/trait-constants.md ? > Hi Stephen, I agree with what has already been said, i.e.: that's a desirable feature, but probably needs a proper RFC for more discussion. Regards, -- Guilliam Xavier
Re: [PHP-DEV] [RFC][Draft] Body-less __construct
On Mon, May 10, 2021 at 10:29 AM Matīss Treinis wrote: > Hi everyone, > > Since constructor property promotion is now implemented, and it looks > like it could become a widely used feature, I am proposing a small, > cosmetic change in syntax for constructors in concrete classes to do > away with empty constructor body. > > Here's an example of how this would work: > > namespace App; > > class Foo { > public function __construct( > private Bar $bar, > private Baz $baz > ); > } > > Some notes to this: > > - Since this is similar to already existing syntax for body-less > methods, parser should not be affected that much. I hope. I really have > no idea. > - Syntax would be optional - meaning, you can as well continue using > empty body, just that in this case the body would be implied empty. > > Thoughts? > Regards, > - Matīss > > Hi, To me `;` means not "empty body" (that's `{}`) but really "no definition, only declaration" (or "no body, only signature", and also "no code executed"), i.e. an *abstract* method (either explicitly declared so in a class, or implicitly in an interface). Granted, property promotion is already special (cannot be used in an abstract constructor), but it can also be mixed with non-promoted parameters and body, so I feat that your proposed alternative syntax would bring more confusion than convenience :s Regards, -- Guilliam Xavier
Re: [PHP-DEV] [RFC] Partial function application
On Mon, May 17, 2021 at 6:58 AM Mike Schinkel wrote: > > > On May 16, 2021, at 10:43 PM, Hossein Baghayi > wrote: > > > > On Sat, 15 May 2021 at 09:03, Hossein Baghayi > > > wrote: > > > >> Providing ? as a means of placeholder for some arguments and ignoring > the > >> rest could complicate the readability in my opinion. > >> Maybe we should move (?) out of the arguments list as a means of > creating > >> a partial. > >> > >> What I realized is that we need a way of signaling partial function > >> creation. Be it foo(?) or foo(?, ?, ?) or however many ? is added there, > >> which does not convey any meaning and also doesn't produce any sort of > >> error! > >> > >> Say instead of foo(?) we had ?foo(). > >> Since we have named parameters it could help us in providing some of the > >> arguments and deferring the rest. > >> > >> For instance: > >> ``` > >> function foo($x, $y, ...$z) {} > >> > >> ?foo(); // causes a partial > >> ?foo(y: '..'); // also causes a partial > >> ``` > >> > >> This way we wouldn't need to worry about the number of ? added to > >> arguments list. > >> It may also help in avoiding future PSRs in telling us how many ? we > >> should put in there :) > >> > > > > In addition to these, I was thinking of 2 other cases in which changing > the > > current proposal might be helpful. > > > > 1- When there is a parameterless function (an expensive operation maybe). > > 2- When all parameters are passed but the function is not expected to be > > called yet. > > > > In the case of a parameterless function, maybe it is an expensive > function > > call and we need to defer calling it. > > Maybe all we need is to hold a reference to it and pass it around? > > With the current proposal, I do not know if it is possible or not. Since > > there are no parameters defined. > > ``` > > function with_expensive_operations_lurking_inside() {...} > > > > Can we or should we call this function this way: > > ``` > > $ref = with_expensive_operations_lurking_inside(?); > > ``` > > It feels odd having to provide parameters when there is none needed. > > > > > > For the other use case where all parameters are passed but is not > expected > > to be called yet: > > Maybe providing parameters and setting it up is not our responsibility. > > ``` > > function expensive_or_not($a, $b, $c) {...} > > $do_not_get_called_please = expensive_or_not(1, 2, 3, ?); // with an > extra > > parameter as to mark as partial! > > $do_not_get_called_please = expensive_or_not(?, 1, 2, 3); // or maybe > this > > way?! > > ``` > > > > Well, I was thinking that by changing the proposed syntax we could > achieve > > what is proposed and a little bit more. > > Also we wouldn't need to worry about the number of ? needed as arguments. > > Since all we need is to mark the return type as partial (closure) on the > > fly and grab hold of what is passed as arguments. > > > > There are some different syntaxes that come to my mind: > > We could still use ? but outside of the arguments list? > > ``` > > $partial = xyx?(..); > > $partial = ?xyx(..); > > ``` > > or maybe different symbols: > > ``` > > $partial = :xyz(..); > > ``` > > > > We might be able to even cast the return type: > > ``` > > $partial = (?) xyz(..); > > $partial = (partial) xyz(..); > > $partial = (fn) xyz(..); > > ``` > > Casting is another interesting approach that does feel more consistent > with the existing language. > > Since it *is* creating a closure, wouldn't this make the most sense? > > $partial = (closure) abc(); > Ouch! definitely NOT! > $partial = (closure) xyz(?,24); > > -Mike > > -- > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: https://www.php.net/unsub.php > > But I agree that these two cases "don't feel quite right": ``` function noParam() {/*...*/} $p = noParam(?); /* looks like there's 1 param, to be passed on call */ ``` ``` function threeParams($a, $b, $c) {/*...*/} $p = threeParams(1, 2, 3, ?); /* looks like there's 4 params, with the last one to be passed on call */ ``` (both would be called as `$p()`, i.e. without any arg). Here we had to add a `?` only for "technical" reasons. More generally I also agree that `?` having two different meanings/behaviors in e.g. `f(?, 2)` [or `f(1, ?, 3)`] vs `f(1, ?)` -- namely: "exactly 1 arg" vs "0+ args" -- is confusing. I think I too would prefer `?` to only mean "exactly 1 arg", and - either have another token for "0+ args" (e.g.: `f(?, 2)` [and `f(1, ?, 3)`] vs `f(1, ...)`, and also `noParam(...)` and `threeParams(1, 2, 3, ...)` ) - or have another syntax like Hossein first suggested (e.g.: `*f(?, 2)` [and `*f(1, ?, 3)`] vs `*f(1)`, and also `*noParam()` and `*threeParams(1, 2, 3)`). Unless there are compelling (or at least convincing) reasons against? Thanks, -- Guilliam Xavier
Re: [PHP-DEV] [RFC] Partial function application
On Mon, May 17, 2021 at 5:16 PM Mike Schinkel wrote: > > > On May 17, 2021, at 10:50 AM, Guilliam Xavier > wrote: > > > > On Mon, May 17, 2021 at 6:58 AM Mike Schinkel wrote: > >> > >> > Well, I was thinking that by changing the proposed syntax we could >> achieve >> > what is proposed and a little bit more. >> > Also we wouldn't need to worry about the number of ? needed as >> arguments. >> > Since all we need is to mark the return type as partial (closure) on the >> > fly and grab hold of what is passed as arguments. >> > >> > There are some different syntaxes that come to my mind: >> > We could still use ? but outside of the arguments list? >> > ``` >> > $partial = xyx?(..); >> > $partial = ?xyx(..); >> > ``` >> > or maybe different symbols: >> > ``` >> > $partial = :xyz(..); >> > ``` >> > >> > We might be able to even cast the return type: >> > ``` >> > $partial = (?) xyz(..); >> > $partial = (partial) xyz(..); >> > $partial = (fn) xyz(..); >> > ``` >> >> Casting is another interesting approach that does feel more consistent >> with the existing language. >> >> Since it *is* creating a closure, wouldn't this make the most sense? >> >> $partial = (closure) abc(); >> > > Ouch! definitely NOT! > > >> $partial = (closure) xyz(?,24); > > > > Mind if I ask for you to elaborate on your aversion? > > Asking for general understanding, not to debate the point. > > -Mike > Sorry I was too "raw". I mean that the cast syntax `$p = (whatever) f();` already very clearly means/does "evaluate f() [i.e. call it], then convert the evaluation result to whatever, then assign the conversion result to $p", and I think it would be a **very bad idea** to "reuse" the same syntax for something that wouldn't call f() immediately. I'm favorable to other syntaxes, but which don't look like a cast. Regards, -- Guilliam Xavier
Re: [PHP-DEV] [RFC] Partial function application
On Mon, May 17, 2021 at 5:01 PM Levi Morrison wrote: > Joe Watkins has successfully worked out some bugs that also enable > more powerful behavior. Thanks to Nikita and any others who worked > with Joe on fixing these issues and reviewing the PR. > > The short of it is that re-ordering parameters when using named > placeholders is now technically possible. We will send an update when > the RFC and implementation are ready for re-review. > That's great news! By the way, I forgot to add that another syntax might also be clearer when binding a value to a named parameter, e.g.: ``` function f($a, $b, $c, $d, $e) {/*...*/} /* We want to bind value 4 to param "d" */ // with current syntax: $p = f(?, d: 4); /* or f(?, ?, ?, 4) */ // with another hypothetical syntax: $p = *f(d: 4); ``` Anyway, looking forward to your update =) Thanks, -- Guilliam Xavier
Re: [PHP-DEV] [RFC] Partial function application
On Mon, May 17, 2021 at 5:47 PM Alexandru Pătrănescu wrote: > > On Mon, May 17, 2021 at 6:36 PM Guilliam Xavier > wrote: > >> On Mon, May 17, 2021 at 5:01 PM Levi Morrison < >> levi.morri...@datadoghq.com> >> wrote: >> >> > Joe Watkins has successfully worked out some bugs that also enable >> > more powerful behavior. Thanks to Nikita and any others who worked >> > with Joe on fixing these issues and reviewing the PR. >> > >> > The short of it is that re-ordering parameters when using named >> > placeholders is now technically possible. We will send an update when >> > the RFC and implementation are ready for re-review. >> > >> >> That's great news! >> >> By the way, I forgot to add that another syntax might also be clearer when >> binding a value to a named parameter, e.g.: >> >> ``` >> function f($a, $b, $c, $d, $e) {/*...*/} >> >> /* We want to bind value 4 to param "d" */ >> >> // with current syntax: >> $p = f(?, d: 4); /* or f(?, ?, ?, 4) */ >> >> // with another hypothetical syntax: >> $p = *f(d: 4); >> ``` >> >> Anyway, looking forward to your update =) >> >> Thanks, >> >> -- >> Guilliam Xavier >> > > Hey Guilliam, > > adding a special character like * or ? before the function name is > not going to work. > It might look good for *f() but it has the same issues as casting. > > You should be able to have with the current version a code like > $actionGenerator->getDriveAction()('home', ?) > You can't really put the * or ? before the function name here. > > Maybe having it just before the parenthesis would work. > > Regards, > Alex > > > > Hey Alex, I was thinking of a (special) new unary [prefix] operator (e.g. `*` which currently only exists as binary) with a higher precedence than `()` (if that makes sense), which indeed means that e.g. `*f(1)(2)` would be like current `f(1, ?)(2)`, and `f(1)(2, ?)` would require wrapping as `*(f(1))(2)`. A lower precedence would require wrapping as `(*f)(1)` for the simple case (i.e. most of the time), which moreover would probably be problematic if you have both a `function f` and a `const f`. Just before the affected `(` might also work indeed, but with another symbol, as `f(1)*(2)` [and `f*(1)`] already means `f(1) * 2` [and `f * 1`]. Maybe `!`, `@` or `~` would be unambiguous at that position? (For both, there's also the possibility of choosing not a symbol but a keyword...) Alternatively, `f(..., d: 4)` or probably rather `f(d: 4, ...)` would arguably still be clearer than the current `f(?, d: 4)`, but still wouldn't really solve the "weirdness" of `noParam(...)` and `threeParams(1, 2, 3, ...)`. Sorry, I didn't intend to diverge so much. The gist is that I (too) don't like the current "duality" of `?`. PS: when I write "current" I really mean "in the current state of the RFC". Regards, -- Guilliam Xavier
Re: [PHP-DEV] [RFC][Draft] Body-less __construct
On Tue, May 11, 2021 at 5:07 PM Pierre wrote: > Le 10/05/2021 à 18:58, Larry Garfield a écrit : > > > I agree that in the grand scheme of things this would be a minor matter, > but aesthetically I would prefer it as well. The {} annoys me, CS tools or > no. > > > > Related: I feel the same way about empty-classes and interfaces, which > is often the case for exceptions where all you're doing is declaring a > type. I figure that would get even more pushback, though. :-) > > > > As a data point, you can already do the same "semi-colon for no body" > for foreach, for, and while loops. I've only ever done it on foreach to > runout an iterator, but it works on all three today. > > > > --Larry Garfield > > I didn't saw this answer at first, but I agree that: > > ``` > > interface MyLibraryException; > > > class DefaultMyLibraryException extends \RuntimeException implements > MyLibraryException; > > ``` > > Is an excellent use case for this! > > I'm probably biased by my C++ background but to me this looks like "forward declarations" (i.e. just declares types but doesn't *define* them) :/ Regards, -- Guilliam Xavier
[PHP-DEV] Re: [RFC] [Draft] Add Randomizer class (before: Add RNG extension)
On Tue, May 25, 2021 at 5:36 PM Go Kudo wrote: > Hi, Thanks for the response. > > The RFC has been revised based on the points you pointed out. > > https://wiki.php.net/rfc/rng_extension > Thanks, it looks like you have addressed all previous points (for me at least). But also introduced a new one ;) with the new `static function getNonBiasedMax(string $algo): int`... (Note: I think some questions below could be answered by the list in general, not only Go Kudo.) Let's compare these two equivalent functions: function f1(int $seed): void { mt_srand($seed); $a = mt_rand(); $b = mt_rand(); var_dump($a, $b); } function f2(int $seed): void { $random = new Random(RANDOM_MT19937, $seed); $max = Random::getNonBiasedMax(RANDOM_MT19937); $a = $random->getInt(0, $max); $b = $random->getInt(0, $max); var_dump($a, $b); } In particular, note that we did *not* need to write the explicit/long version of f1: function f1_explicit(int $seed): void { mt_srand($seed); $max = mt_getrandmax(); $a = mt_rand(0, $max); $b = mt_rand(0, $max); var_dump($a, $b); } But what would happen with the implicit/short version of f2? function f2_implicit(int $seed): void { $random = new Random(RANDOM_MT19937, $seed); $a = $random->getInt(); $b = $random->getInt(); var_dump($a, $b); } Would we get "biased" results (by the way, what does that mean exactly)? like `mt_rand(PHP_INT_MIN, PHP_INT_MAX)`? Couldn't the default min/max be made "safe"? or maybe "dynamic" depending on the algo/implementation? Also, let's consider this: function g(Random $random): void { $max = /* ??? */; $a = $random->getInt(0, $max); $b = $random->getInt(0, $max); var_dump($a, $b); } Here, how to get the "non-biased max" for this Random instance (unknown algo)? Moreover, what would `Random::getNonBiasedMax(RANDOM_USER)` return? I think we would rather want/need to call e.g. `FixedNumberForTest::getNonBiasedMax()` (potentially overridden)? Maybe you could add a (non-static) `function getAlgo(): string`, so we could at least call `$random::getNonBiasedMax($random->getAlgo())`? (maybe it could also be more generally useful, possibly along with a `getSeed()`, akin to `password_get_info(string $hash)`?) or a non-static `function getNonBiasedMax(): int`, and rename the static one? (or even drop it after all? how often will we need it without having an instance? and if needed, is `new Random($algo, 0)` a costly operation?) or some other solution someone can think of? Ah that made me think: should some methods better be `final`? Finally, the current "Open Issues" section should probably renamed to "Discussion" or even "FAQ" here? Regards, -- Guilliam Xavier
Re: [PHP-DEV] Disable autovivification on false
On Tue, May 25, 2021 at 10:27 PM Dusk wrote: > On May 25, 2021, at 09:23, Kamil Tekiela wrote: > > I'd like to start a discussion on the following RFC > > https://wiki.php.net/rfc/autovivification_false > > Particularly, I am looking for opinions on whether this behaviour should > be > > left alone, should be disabled on false, or should be disabled on null > and > > false, and left only for undefined variables. > > It seems to me there are two different sorts of autovivification which can > happen. (They may actually be the same thing under the hood, but they feel > different to me.) > > One is autovivification within an array, e.g. > > $x = ["b" => null, "c" => false]; > $x["a"][] = 1; // from unset > $x["b"][] = 2; // from null > $x["c"][] = 3; // from false > > The other is autovivification on values outside arrays, e.g. > > $b = null; $c = false; $d = new stdClass(); > $a[] = 1; // from unset > $b[] = 2; // from null > $c[] = 3; // from false > $obj->a[] = 4; // from unset on an object property, same idea > > (The same behavior occurs in each case if an explicit key is used instead > of [].) > > From my perspective, the latter is much more concerning than the former. > Adding dimensions to an existing array feels like less of a > type-correctness violation than calling an entire array into existence > where a non-array value (or no value at all) existed before. > I agree to that last point. I think the cases so far where I have relied on autovivification were all like: ``` function f(iterable $xs) { $map = []; // initialization foreach ($xs as $x) { // $map[foo($x)] ??= []; not needed // $map[foo($x)][bar($x)] ??= []; not needed $map[foo($x)][bar($x)][] = qux($x); // autovivification } // Then e.g.: foreach ($map as $foo => $submap) { foreach ($submap as $bar => $quxes) { /* ... */ } } } ``` All other cases I can remember were arguably bugs (missing initialization). That said, deprecating it on false would already be a +1. Regards, -- Guilliam Xavier
Re: [PHP-DEV] [RFC] First-class callable syntax
On Fri, May 21, 2021 at 10:08 AM Rowan Tommins wrote: > > Everyone: please let's keep this thread for talking about first-class > callables, and focus on the semantics not just the syntax - are there > edge cases we need to consider, downsides to the proposed > implementation, etc? > Well the semantics seem rather clear? We could say one "downside" is that new-expressions are not supported, but the RFC explains why ( https://wiki.php.net/rfc/first_class_callable_syntax#object_creation, I think it makes sense), and special-casing can always be added later (or in PFA). Regards, -- Guilliam Xavier
Re: [PHP-DEV] [RFC] First-class callable syntax
On Fri, May 21, 2021 at 11:09 AM Andreas Leathley wrote: > [...] > > About the bikeshedding: Using "..." as a symbol does make sense to me, > as variadic unpacking/variadic arguments have a similar connotation > (referring to an unknown/arbitrary amount of elements). * was also > suggested (as in "somefunction(*)" instead of "somefunction(...)"), and > I like that too - * in regex is any amount of elements (even zero), and > ? is exactly one placeholder in SQL. As many PHP developers know regex > and SQL this would make PFA code a lot easier to understand even if > someone is not that familiar with it yet. > FWIW: In this context, ? and * remind me of shell wildcards (used by glob() and fnmatch()), which makes sense too. Also, at least one person is opposed to "...". -- Guilliam Xavier
Re: [PHP-DEV] Consensus Gathering: is_initialized
On Wed, May 26, 2021 at 4:09 PM Larry Garfield wrote: > On Wed, May 26, 2021, at 8:24 AM, Rowan Tommins wrote: > > On 26/05/2021 11:13, Joe Watkins wrote: > > > Hi internals, > > > > > > In response to: https://bugs.php.net/bug.php?id=78480 > > > > > > I implemented: https://github.com/php/php-src/pull/7029 > > > > > > My general feeling remains that the "uninitialized" state is an awkward > > hack that we should be working to eliminate with better constructor > > semantics. A variable that remains uninitialised after the constructor > > almost always indicates a bug in the constructor, not a state that the > > rest of the application should care about. > > I am inclined to agree here. What I don't know about is the cases noted > in the bug, such as GraphQL or other serialization cases where "null" and > "absent" are not quite the same thing. That is probably sufficiently > edge-case to not deal with directly, especially when the more verbose > alternative still exists, but that's the only reason I'd even consider > making uninitialized something other than "your constructor is bad and you > should feel bad." > I think you said the word: serialization. And especially *deserialization*, e.g. from a JSON payload into a typed DTO *without* calling the constructor (then the DTO is passed through validation, which must handle uninitialized typed properties "gracefully"). -- Guilliam Xavier
Re: [PHP-DEV] [RFC] [Draft] Add RNG extension and deprecate mt_srand()
On Thu, May 20, 2021 at 2:42 PM Go Kudo wrote: > Sorry. I couldn't make it in time for my lunch break. > No worries, there was quite a lot to read/reply ;) > > How many bytes is `Source::next()` supposed to generate? Is it even > intended to be called directly (vs `Randomizer::generateBytes(int > $length)`)? > > No, this is not intended to be used directly. > In fact, as many people have pointed out, I think it would be more > appropriate to merge it into a single class. > > As per the original implementation (ext/orng), I didn't think it needed to > be separated originally. One of the comments on a previous RFC suggested > that it would probably be better to separate them, and I took that into > account. > I see. Sorry that you had so many back-and-forth suggestions :s I guess that the simplest-to-use API (for the main intended/expected use cases) is more likely to get acceptance. > > About the `MT19937PHP` variant: The PHP manual for `mt_srand()` > describes the `MT_RAND_PHP` mode like this: "Uses an *incorrect* Mersenne > Twister implementation which was used as the default up till PHP 7.1.0. > This mode is available for backward compatibility."; do we really need/want > to port it to this new extension? > > This is for backward compatibility. If it is not needed, we would like to > eliminate the implementation itself. > Well, to keep the language core clean, maybe this should be provided by an > appropriate external extension. > Yes, I think that a new core extension for PHP 8.1 needn't [or even shouldn't] provide BC for an incorrect implementation that is not used anymore since PHP 7.1 (unless someone here argues?). > > - `PlatformProvided` feels like the "odd one out" here: its constructor > [assuming same as previous RFC] doesn't take a seed, and it isn't > serializable; I understand why, but the main point of the RFC is "RNG > reproducibility", which this class cannot achieve. > > You're absolutely right. I would like to remove this. > *Caution though:* after your recent discussion with Rowan, if you remove the "change shuffle()/str_shuffle()/array_rand()'s internal RNG from mt_rand()-like to random_bytes()-like" part from the proposal, then this class becomes potentially "useful" again, not for reproducibility but for shuffling an array/string by a "truly random" [actually CSPRNG] algorithm, isn't it? > > > Technical, about `Randomizer::generateFloat()`: Is the returned float > guaranteed to be finite (i.e. never NAN nor +/-INF)? And may it ever return > -0.0 (negative zero)? and even if not, is 0.0 twice as likely as other > floats? > Also, no `generateFloat(float $min, float $max)` variant like for > `generateInt()`? > > As a matter of fact, we believe that the functions provided by this class > are sufficient for `mt_rand()`, `shuffle()`, `str_shuffle()`, and > `array_rand()` equivalents. At most, the equivalent of `random_byte()` > might be provided. > I'll reorganize these. > Sorry I'm not sure to understand your answer here, are you planning to remove generateFloat() and generateBool()? Well if generateBool() is a shorthand for `(bool) generateInt(0, 1)` [or `generateInt(PHP_INT_MIN, PHP_INT_MAX) >= 0`] then it's not necessary, but maybe convenient? As for generateFloat(), I didn't know if you intended something like `(float) generateInt(PHP_INT_MIN, PHP_INT_MAX) / PHP_INT_MAX` or rather "call generateBytes(8) then reinterpret those 64 bits as an IEEE 754 double [in C, not PHP]"? But it's true that I haven't seen many people requesting new "random_bool()" and/or "random_float()" functions, so... By the way, for `generateInt()` (without explicit $min/$max args), I assume that $max defaults to PHP_INT_MAX, but does $min default to PHP_INT_MIN or actually 0 [if it's like [mt_]rand() I guess that the answer is probably 0, but that could be written clear in the RFC]? > > Thanks for the detailed remarks. Based on these, I would like to clean up > the RFC. > > Regards, > Go Kudo > Regards, -- Guilliam Xavier
Re: [PHP-DEV] [RFC] First-class callable syntax
On Thu, May 20, 2021 at 5:12 PM Nikita Popov wrote: > On Thu, May 20, 2021 at 4:16 PM Ondřej Mirtes wrote: > > > Hi, I’m confused by the syntax, when I read it, I think to myself “I know > > this, this is just a method call… oh wait, it’s actually a callable”. It > > really makes my head hurt. > > > > Yes, I can see how that could be confusing. The current syntax is chosen to > be a subset of the partial function application proposal. However, I would > also be happy with some other syntax that makes it clearer that this is > acquiring a callable and not performing a call. > Hi, several other syntaxes have been proposed to consideration in the PFA thread, and I wouldn't want to start new bikeshedding here; is there a place that would be more appropriate to gather the possibilities (like a kind of updatable list)? Thanks, -- Guilliam Xavier
Re: [PHP-DEV] Consensus Gathering: is_initialized
On Thu, May 27, 2021 at 3:55 PM Andreas Leathley wrote: > Also, is_initialized cannot be done in > userland, as passing an unitialized property to a function already leads > to an error > The feature request was indeed `is_initialized($foo->bar)` (language construct, akin to isset); but the PR was only proposing `is_initialized($foo, 'bar')` (regular function, akin to property_exists). Anyway, that's a "Wont fix". (PS about previous messages: I actually don't write custom serializers myself) -- Guilliam Xavier
Re: [PHP-DEV] json_encode indent parameter
Hello, I have seen a similar discussion for var_export(), and the answer was basically "use a regex". E.g.: $json = preg_replace_callback( '/^(?: {4})+/m', fn ($m) => str_repeat($indent, strlen($m[0]) / 4), json_encode($data, JSON_PRETTY_PRINT) ); That said, I wouldn't mind a new indent parameter (but note that allowing an arbitrary string [not limited to whitespace] might result in invalid JSON). Regards, -- Guilliam Xavier
Re: [PHP-DEV] Re: Injection vulnerabilities
On Fri, May 21, 2021 at 11:21 PM Craig Francis wrote: > [...] > > We need something that libraries will (in the future) be able to use to > protect themselves against these mistakes... by all programmers, especially > those who aren't using static analysis. > Hi, Not sure what kind of answer you expect... Are you suggesting to provide one or both of: 1. a way to forbid "dynamic" strings (or at least detect them)? 2. "safe" HTML, SQL and OS-command builder/generator/executor APIs (that would internally restrict/validate their "static" parts and quote/escape the dynamic parameters)? Regards, -- Guilliam Xavier
[PHP-DEV] Re: [RFC] [Draft] Add Randomizer class (before: Add RNG extension)
On Sat, May 22, 2021 at 10:57 PM Go Kudo wrote: > Hi, Internals and all participated in the previous discussion. > > RFCs have been cleaned up and the proposal has been substantially changed. > > https://wiki.php.net/rfc/rng_extension > > First of all, I apologize for not checking out the implementation of > password_hash(), which is a precedent to learn from. > > I think I've answered all the questions I've been getting on Open Issues. > If I have left anything out, please let me know. > > Regards, > Go Kudo > Hi, This really looks like a different proposal indeed (simpler and clearer), thanks! A few (new) remarks/questions: - Naming: "Randomizer", but some have suggested just "Random", or "RNG" (or "PRNG"). - [I was about to say "If typical usage is expected to provide a seed (for reproducibility) more often than choosing a non-default algorithm, maybe the [optional] constructor parameters should be in the according order ($seed, $algo)?", but actually I'm not sure of "expected typical usage", and the current order ($algo, $seed) seems more "logical" (e.g. I think RANDOMIZER_SECURE will ignore $seed?), and we can use named arguments like `new Randomizer(seed: 1234)` if needed, so...] - Does `?int $seed = null` default to `time()` internally? or to something else? [not sure if important...] - Does `?int $min = PHP_INT_MIN` default to `PHP_INT_MIN` even if we pass `null`? But, given that we can use named arguments, do $min/$max really need to be nullable? - About `shuffle(array|string $target): array|string`: I think just "value" would be better than "target", and I'm not sure about the union type (notably for static analysis)... Ideally it should be distinct `(array $value): array` and `(string $value): string`, but that probably requires two distinct names? - For internal implementation, isn't there a signed/unsigned "mismatch" between PHP `function next(): int` and C `uint64_t (*next)(void)` return types? Regards, -- Guilliam Xavier
Re: [PHP-DEV] Introduce str_left/right In 8.1
On Wed, Jun 23, 2021 at 11:54 PM Rowan Tommins wrote: > On 23/06/2021 22:28, Christoph M. Becker wrote: > > substr() is about bytes, not characters. They all may have upvoted the > > wrong answer. The only correct answer has just 17 upvotes. > > > Just to out-pedant you, I'll point out that what most people would think > of as a "character" is neither a byte nor a code point, but a grapheme, > so I would say *none* of the answers on that page is correct. > > $string = 'Zoë'; // "Zoe\u{0308}" not "Zo\u{00EB}" > > var_dump(substr($string, -1)); > var_dump(mb_substr($string, -1)); > var_dump(grapheme_substr($string, -1)); > > string(1) "�" > string(2) "̈" > string(3) "ë" > > https://3v4l.org/IMoWQ > I thought about the same during the night! Just to complete: there's also iconv_substr() (but with the same result as mb_substr()), and here are two links to compare: https://3v4l.org/kU9D5 vs https://3v4l.org/pAvB0 Regards, -- Guilliam Xavier
Re: [PHP-DEV] Introduce str_left/right In 8.1
On Thu, Jun 24, 2021 at 12:51 AM Sara Golemon wrote: > > [...] I'm > not going to vote for it though, because it belongs in composer/packagist > land, not in core. I've listed the reasons for this in the str_contains() > threads, feel free to reference those, they're still valid and correct. > Sorry I can't find your past message (searched for each of your first name, last name, username) :/ Anyway, I think you always get the same retort, "if it isn't in core it won't be used" basically? PS: I forgot in my previous reply: thank you for writing the polyfills clear =) Regards, -- Guilliam Xavier
Re: [PHP-DEV] [RFC] Name issue - is_literal/is_trusted
On Thu, Jun 24, 2021 at 9:14 AM Scott Arciszewski wrote: > On Thu, Jun 24, 2021 at 2:10 AM Stephen Reay > wrote: > > > I would absolutely make use of a function that tells me if the string > given is in fact from something controlled by the developer. But once that > same string can also include input from the request or the environment or > whatever by nature of integers, the function becomes useless for the stated > purpose. > > Why not two functions then? > > - is_noble_string() -- more restrictive > - is_noble() -- YOLO > I was going to ask basically the same [with different names] a few days ago ("why can't we have both?"), but then remembered https://externals.io/message/114835#114951 , esp. the end: """ And to support having 2 functions, we would need 2 flags on strings. These flags are limited, and managing 2 flags would affect performance. """ Regards, -- Guilliam Xavier
Re: [PHP-DEV] [Vote] Partial Function Application
(Extracted from the "Pipe Operator, take 2" thread) On Tue, Jun 29, 2021 at 12:54 AM Larry Garfield wrote: > On Mon, Jun 28, 2021, at 5:30 PM, Olle Härstedt wrote: > > > Would a slimmed down version have more support? How about removing the > > variadic operator, and let the user manually add the lambda for those > > cases? > > I talked with Joe about this, and the answer is no. Most of the > complexity comes from the initial "this is a function call, oops no, it's a > partial call so we switch to doing that instead", which ends up interacting > with the engine in a lot of different places. > Are you saying that the implementation complexity is mainly due to chosing a syntax that looks like a function call? If yes, is it also the case for the "First-class callable syntax" RFC? And does it mean that a different syntax (e.g. with a prefix operator) would result in a simpler implementation? Regards, -- Guilliam Xavier
Re: [PHP-DEV] [Vote] Partial Function Application
On Tue, Jun 29, 2021 at 11:04 AM Côme Chilliet < come.chill...@fusiondirectory.org> wrote: > Le Thu, 17 Jun 2021 08:30:43 -0500, > "Larry Garfield" a écrit : > > > > The ? character was chosen for the placeholder largely because it was > > > > unambiguous and easy to implement. Prior, similar RFCs (such as the > > > > original Pipe Operator proposal from several years ago) used the $$ > > > > (lovingly called T_BLING) sigil instead. So far no compelling > argument > > > > has been provided for changing the character, so the RFC is sticking > > > > with ?. > > > > > > The main argument for $$ is to be able to have partial methods with > $$->, > > > this should be stated in this paragraph. > > > > That's not something that was ever brought up in the discussion. > > Finally found where I read that, it’s in an other RFC: > > https://wiki.php.net/rfc/first_class_callable_syntax#partial_function_application > For the record, Larry replied on this subject: https://externals.io/message/114770#114785 (second part). Note that for `$$->foo(/*whatever*/)` the signature couldn't be extracted (because the class of $$ is unknown). Regards, -- Guilliam Xavier
Re: [PHP-DEV] [RFC] Alternative syntax for Nowdoc.
Hi, Maybe other syntax could be used, but I don't know which. In javascript > only a backtick is used: > https://developers.google.com/web/updates/2015/01/ES6-Template-Strings . > But in PHP this is used as eval. > Just a precision, because you keep referring to it as "eval", which makes me "tick" (haha): `$cmd` (i.e. $cmd wrapped in a pair of backticks) is the same as shell_exec($cmd), not eval($cmd). (BTW, one of JS "template strings" main selling points is string substitution / variable interpolation, which is explicitly *not* wanted with nowdoc [VS heredoc].) As for the proposal, overall I agree with Rowan -- well, that would not be exactly like single quotes (regarding [not] escaping them), but still "yet another way" to write a nowdoc string literal. PS: "amusingly", the code samples are hard to understand after rendered on https://externals.io/message/115213 -- Guilliam Xavier
Re: [PHP-DEV] [Vote] Partial Function Application
On Tue, Jun 29, 2021 at 10:32 PM Levi Morrison via internals < internals@lists.php.net> wrote: > On Tue, Jun 29, 2021 at 12:05 PM Larry Garfield > wrote: > > > > On Tue, Jun 29, 2021, at 1:00 PM, Larry Garfield wrote: > > > On Tue, Jun 29, 2021, at 12:30 PM, Guilliam Xavier wrote: > > > > (Extracted from the "Pipe Operator, take 2" thread) > > > > > > > > On Tue, Jun 29, 2021 at 12:54 AM Larry Garfield < > la...@garfieldtech.com> > > > > wrote: > > > > > > > > > [...] Most of the > > > > > complexity comes from the initial "this is a function call, oops > no, it's a > > > > > partial call so we switch to doing that instead", which ends up > interacting > > > > > with the engine in a lot of different places. [...] > > > > > > > > Are you saying that the implementation complexity is mainly due to > chosing > > > > a syntax that looks like a function call? [...] > > > > > > From what I understand from Joe, most of the complexity comes from > > > producing something that isn't a closure but shares the same interface > > > as a closure (at least that's what it would be in PHP terms), which > > > then requires lots of special handling throughout the engine. I don't > > > fully understand it all myself, TBH. > > > > > > I've been pondering if a completely different approach with a prefix > > > symbol would be able to be less complex, and the simple answer is I > > > have absolutely no idea. But we are running low on symbols... > > > > Ah, I found the technical details that Joe gave me (right after I hit > send, of course). Quoting Joe: > > > > "the engine expects certain things to happen, and is designed and then > optimized around those assumptions ... for example, a stream of INIT, SEND, > DO_FCALL is not meant to be interrupted, the first fundamental change you > have to make is making the engine aware that stream of INIT, SEND, + are > not always followed by DO_FCALL " > > > > So yes, it sounds like hooking into the function call process is where > the complexity comes from. Which suggests that an approach that works > using a different syntax that desugars to a closure would avoid that issue, > but then we need a syntax that wouldn't be ambiguous, and that's getting > harder and harder to find. (Nikita's first-class-callables RFC notes some > of the issues with available symbols, and they're essentially the same for > partials either way.) And I've been told that creating closures in the AST > compiler is Hard(tm)... > > Based on what you said, the syntax isn't really the issue. Rather, the > issue is assumptions about how function calls work at the opcode > level. Any implementation of only _partially_ doing a function call > will have to deal with such things in some form. To a degree this is > inherent complexity. > Thanks for clarifications. IIUC, whatever the syntax, any PFA implementation will need either to hook into the function call process (current approach) or to create a closure "from scratch" (which may be actually more complex); and some degree of [implementation] complexity is conceptually inherent anyway. (FCC doesn't need to bind values so might have other options? maybe not...) > Maybe separate opcodes for every piece of the call would be better in > that optimizers, etc, won't have expectations around the new opcodes > and we don't change assumptions about the existing opcodes? I doubt > that it would be much simpler, but I am curious to know. > -- Guilliam Xavier
Re: [PHP-DEV] [VOTE] Deprecations for PHP 8.1
On Mon, Jul 5, 2021 at 1:39 PM Mike Schinkel wrote: > > On Jul 5, 2021, at 7:14 AM, Rowan Tommins > wrote: > > > > On 05/07/2021 11:46, Patrick ALLAERT wrote: > >> Did we ever deprecated something without the immediate intention of > >> removing it? > > > > > > What would that even mean? > > It would mean that although the functions are available and allowed, they > are not recommended[1]. > > > > Surely a deprecation, by definition, is a notice that something is going > to be removed. > > I know that you, and others on this list, have chosen to define > deprecation as including removal, but that is actually not the accepted > definition on the web, nor is it in any way a requirement, it is just your > preference. > > Indirectly from Wikipedia and voted as the top answer on StackOverflow > here[2] (emphasis MINE): > > "deprecation is a status applied to software features to indicate that > they should be avoided, typically because they have been superseded. > Although deprecated features remain in the software, their use may raise > warning messages recommending alternative practices, and deprecation MAY > indicate that the feature will be removed in the future." > > So I am arguing for the legitimacy of retaining "deprecated" features if > their removal would cause significant BC breakage, I'm not just trying to > be a pendant. > > -Mike > [1] https://whatis.techtarget.com/definition/deprecated > [2] https://stackoverflow.com/questions/8111774/deprecated-meaning > Hi Mike, Your links speak *in general*. However this is *specifically for PHP*: https://www.php.net/manual/en/errorfunc.constants.php#errorfunc.constants.errorlevels.e-deprecated-error (*emphasis* mine) E_DEPRECATED: Run-time notices. Enable this to receive warnings about code that *will not work in future versions*. As for "significant BC breakage", isn't that what major versions are for? (and with the current release plan, 9.0 would be for end 2025, i.e. 4 years after 8.1) Regards, -- Guilliam Xavier
Re: [PHP-DEV] [RFC] [Draft] Add RNG extension and deprecate mt_srand()
On Tue, May 18, 2021 at 6:19 PM Go Kudo wrote: > Hello internals. > > I have created a draft of the RFC. > > https://wiki.php.net/rfc/rng_extension > Hello Go Kudo, First of all, thank you for the (re)work. I think the API looks better, but I still have some remarks/questions (roughly in order of appearance, with some overlap): - How many bytes is `Source::next()` supposed to generate? Is it even intended to be called directly (vs `Randomizer::generateBytes(int $length)`)? - The stubs in "Proposal" should show `__construct()` signatures for the classes implementing `Source`. - About the `MT19937PHP` variant: The PHP manual for `mt_srand()` describes the `MT_RAND_PHP` mode like this: "Uses an *incorrect* Mersenne Twister implementation which was used as the default up till PHP 7.1.0. This mode is available for backward compatibility."; do we really need/want to port it to this new extension? - I think you said in the past that `XorShift128Plus` should be the preferred/default implementation, and `MT19937` is only provided for compatibility/migration? But if so, that's not clear at all in the RFC. - `PlatformProvided` feels like the "odd one out" here: its constructor [assuming same as previous RFC] doesn't take a seed, and it isn't serializable; I understand why, but the main point of the RFC is "RNG reproducibility", which this class cannot achieve. Also, we already have `random_bytes()`/`random_int()`, and you're proposing to change `shuffle()`/`str_shuffle()`/`array_rand()`'s internal RNG from `mt_rand()`-like to `random_bytes()`-like, so what reason would there be to use this class? only `generateFloat()`? but couldn't that be a new global function `random_float()`? All in all, wouldn't it be simpler to drop `PlatformProvided`, and have all `Source` implementations take a seed on construction and be serializable? - Technical, about `Randomizer::generateFloat()`: Is the returned float guaranteed to be finite (i.e. never NAN nor +/-INF)? And may it ever return -0.0 (negative zero)? and even if not, is 0.0 twice as likely as other floats? Also, no `generateFloat(float $min, float $max)` variant like for `generateInt()`? - **About main usage of the API:** To get e.g. $n (say 3) pseudo-random integers between $min (say 0) and $max (say 100) using the "best" implementation (which we have to know/guess is XorShift128+, isn't it?), we must: *first* choose a $seed (`time()`, maybe?), *then* do `$source = new XorShift128Plus($seed);` *and* `$rng = new Randomizer($source);` [even if $source (and $seed) could be inlined, that's still several "steps"], *then* we can finally call `$rng->generateInt($min, $max);` $n times. Is that correct? If so, it may make sense from the implementer side, but from the user side it doesn't look like the most friendly. Also, that lets the possibility of constructing a second Randomizer using the same $source (or `$rng->getSource()`), which could be undesirable for reproducibility, isn't it? Wouldn't it be better to "merge" Randomizer into the interface/classes? Actually I see that's the case in your other project ext/orng ( https://github.com/zeriyoshi/php-ext-orng/blob/master/rng/rnginterface.stub.php and https://github.com/zeriyoshi/php-ext-orng/blob/master/rng/xorshift128plus.stub.php ), why the different approach for ext/rng? Maybe even better (and already suggested), have Randomizer constructor take an *optional* algorithm (string, default XorShift128Plus::class?) and an *optional* seed (int, default time()?) and construct the source internally (and don't expose it)? So we could do just `$rng = new Randomizer();` to rely on the defaults (then call `$rng->generateInt($min, $max);` $n times). - Finally, I think the vote should be split into 3 parts: the new classes, the deprecations (which itself could be split between [mt_]srand and [mt_]rand), and the change of internal RNG for shuffle/str_shuffle/array_rand. Best regards, -- Guilliam Xavier
Re: [PHP-DEV] [RFC][Draft] Sealed Classes
Hi, On Mon, Apr 26, 2021 at 9:54 AM Christian Schneider wrote: > Am 25.04.2021 um 05:47 schrieb Larry Garfield : > ... > > sealed class Maybe permits Some, None { > ... > > } > > > > final class None extends Maybe {} > > This is exactly the thing I'm worried about. > > Say I want to add something like logging to the None type. > Now your sealed and final classes prevent me from defining MyNone > extending None even though it would be 100% compatible with None. > I just want to note that this has nothing to do with Maybe made sealed (which seems legit), only with None made final (which... could be debated, but unrelated to the RFC at hand). Regards, -- Guilliam Xavier
Re: [PHP-DEV] [RFC][Draft] Sealed Classes
On Sat, Apr 24, 2021 at 12:55 PM Saif Eddin Gmati wrote: > Hello Internals, > > I'm sending this email to open discussion about sealed classes, > interfaces, and traits feature for PHP 8.1. > > I have create a Draft RFC here: https://wiki.php.net/rfc/sealed_classes > > A major concern for few people have been the syntax, in which it > introduces 2 new keywords into the languages, therefor, i have added a > section about alternative syntax which could be used to avoid this problem. > > Regards, > > Saif. > Hello, To me the first sentence of the RFC is debatable: > The purpose of inheritance is code reuse, for when you have a class that shares common functionality, and you want others to be able to extend it and make use of this functionality in their own class. That sounds like [abstract] base classes, which certainly permit that, but I wouldn't state that "the purpose" of [designing] class hierarchies is "code reuse", which can also (better?) be achieved with traits or even simply composition (by the way, the introduction then mentions that "PHP has the `Throwable` interface, which defines common functionality between `Error` and `Exception` and is implemented by both", but there is no "code reuse" in an interface). I also agree with others that Shape is probably not a good example, and the ResultInterface example feels like an enum/ADT (and the FilesystemTrait example I guess is to replace `@internal` phpDoc). I'm not saying that this RFC is bad, but probably not as convincing as it could be. Regards, -- Guilliam Xavier
Re: [PHP-DEV] [RFC][Draft] Sealed Classes
Forwarding to the list, and answering: On Wed, Apr 28, 2021 at 9:51 AM Tony Marston wrote: > On 27/04/2021 17:22, Guilliam Xavier wrote: > > On Sat, Apr 24, 2021 at 12:55 PM Saif Eddin Gmati > > > wrote: > > > > > > To me the first sentence of the RFC is debatable: > > > >> The purpose of inheritance is code reuse, for when you have a class that > >> shares common functionality, and you want others to be able to extend it > >> and make use of this functionality in their own class. > > > > That sounds like [abstract] base classes, which certainly permit that, > but > > I wouldn't state that "the purpose" of [designing] class hierarchies is > > "code reuse", which can also (better?) be achieved with traits or even > > simply composition > > I completely disagree that the first sentence of that RFC is debatable > as I consider it to be totally accurate. When you use inheritance via > the 'extends' keyword then every method in the superclass is shared by > the subclass. In the subclass you have the option to override the > implementation of any method in the superclass, or you can add new > methods of your own. But does that necessarily mean that "The purpose of inheritance is code reuse"? This superclass may be abstract, but it need not > be. The methods it contains may be abstract, but they need not be. > I didn't say that they need (the brackets meant "optionally"). And does it really matter actually? > According to the Gang of Four the way to avoid the problems caused by > the overuse of inheritance is to only inherit from an abstract class, > which is precise what I do. I am famous for having an abstract table > class in my framework which contains hundreds of methods and thousands > of lines of code, and because each of my 400 concrete table classes > inherits from the same abstract table class that is a LOT of code which > is shared. This abstract table class also allows me to use the Template > Method Pattern (which is mentioned in the Gang of Four book) so that all > the invariant methods are defined in the abstract class which means that > each subclass need only contain the variable "hook" methods for which it > needs to provide an implementation. > Well, PHP is flexible. I have seen many combinations of (one or several of) interface, [abstract] class, trait, composition... depending on the context. > When you say that code reuse can be better achieved with traits or > object composition I have to disagree. I said "also (better?)", not just "better". But one can think "no" to "better?" ;) Object composition is used only > by those idiots who overuse inheritance, :/ and there is no evidence that > traits are "better" than inheritance. > By the way, is there evidence to the contrary? (genuine question) > Inheritance, when used sensibly, is still the best way to share code. > Your opinion, maybe not unanimity (nor absolute truth). > Regards, > > Tony Marston > > Regards, -- Guilliam Xavier
Re: [PHP-DEV] [RFC][Draft] Sealed Classes
On Wed, Apr 28, 2021 at 10:18 PM Dan Ackroyd wrote: > On Wed, 28 Apr 2021 at 14:30, Guilliam Xavier > wrote: > > > > Forwarding to the list, and answering: > > > > Please don't do that. > > He was blocked from the list for repeatedly derailing conversations. > > After someone has been banned from the mailing list, forwarding their > emails to the list is not a good thing to do. > Sorry, I didn't know. But so, when in a thread I receive a private reply that, for some reason (e.g. somewhat rude but/or of public interest and maybe they clicked "Reply" by inadvertance), I feel it should be forwarded to the list (which I have seen done here several times and I don't remember you objecting), how am I supposed to know that they're banned and that I should just ignore them? > cheers > Dan > Ack > Regards, -- Guilliam Xavier
Re: [PHP-DEV] [RFC][Draft] Sealed Classes
Re-forwarding to the list (please stop replying to me in private, thanks). Also re-answering but I will stop there because that's too much digression for a partial quote of my initial message. On Wed, Apr 28, 2021 at 5:30 PM Tony Marston wrote: > On 28/04/2021 14:30, Guilliam Xavier wrote: > > Forwarding to the list, and answering: > > > > On Wed, Apr 28, 2021 at 9:51 AM Tony Marston > > wrote: > > > >> On 27/04/2021 17:22, Guilliam Xavier wrote: > >>> On Sat, Apr 24, 2021 at 12:55 PM Saif Eddin Gmati < > azj...@protonmail.com > >>> > >>> wrote: > >>> > >>> > >>> To me the first sentence of the RFC is debatable: > >>> > >>>> The purpose of inheritance is code reuse, for when you have a class > that > >>>> shares common functionality, and you want others to be able to extend > it > >>>> and make use of this functionality in their own class. > >>> > >>> That sounds like [abstract] base classes, which certainly permit that, > >> but > >>> I wouldn't state that "the purpose" of [designing] class hierarchies is > >>> "code reuse", which can also (better?) be achieved with traits or even > >>> simply composition > >> > >> I completely disagree that the first sentence of that RFC is debatable > >> as I consider it to be totally accurate. When you use inheritance via > >> the 'extends' keyword then every method in the superclass is shared by > >> the subclass. In the subclass you have the option to override the > >> implementation of any method in the superclass, or you can add new > >> methods of your own. > > > > > > But does that necessarily mean that "The purpose of inheritance is code > > reuse"? > > Can you show me any description of OOP which says that the purpose of > inheritance is anything other than code reuse? I suspect it won't convince you but you can find quotes like: "The point of inheritance is to take advantage of polymorphic behavior NOT to reuse code, and people miss that, they see inheritance as a cheap way to add behavior to a class." (not that I endorse it absolutely, but that's an example of different opinion). What other purose could > it possibly serve? > Modeling a problem domain? Enforcing a contract? > > This superclass may be abstract, but it need not > >> be. The methods it contains may be abstract, but they need not be. > >> > > > > I didn't say that they need (the brackets meant "optionally"). And does > it > > really matter actually? > > Yes. If you inherit any abstract methods you are not actually inheriting > anything. Not only do you have to manually define in the subclass any > method which is defined as abstract, you also have to provide the > implementation. > My bad, I should have inserted the reply one sentence earlier: I was referring to "[abstract] base classes" (from my original quote), not abstract methods. Of course if the goal is to share implementation there must be concrete methods in the base class... > >> According to the Gang of Four the way to avoid the problems caused by > >> the overuse of inheritance is to only inherit from an abstract class, > >> which is precise what I do. I am famous for having an abstract table > >> class in my framework which contains hundreds of methods and thousands > >> of lines of code, and because each of my 400 concrete table classes > >> inherits from the same abstract table class that is a LOT of code which > >> is shared. This abstract table class also allows me to use the Template > >> Method Pattern (which is mentioned in the Gang of Four book) so that all > >> the invariant methods are defined in the abstract class which means that > >> each subclass need only contain the variable "hook" methods for which it > >> needs to provide an implementation. > >> > > > > Well, PHP is flexible. I have seen many combinations of (one or several > of) > > interface, [abstract] class, trait, composition... depending on the > context. > > The fact that there are now several ways of reusing code does not > detract from the original statement that "The purpose of inheritance is > code reuse". > See above, plus a quick web search for things like "inheritance misuse" or "class SplStack extends SplDoublyLinkedList" I think shows it's a controversial subject (hence "debatable" at least). > >> When you say that code reuse can be better achieved with traits or
Re: [PHP-DEV] Interaction between finally blocks and exit()
Executing finally blocks after a die was discussed in https://externals.io/message/107497 "exit() via exception", but https://github.com/php/php-src/pull/5243 "Make exit() unwind properly" wasn't merged in 8.0, just https://github.com/php/php-src/pull/5768 "... (minimal version)". The change of behavior for https://3v4l.org/HGKHS "yield - finally" that occurred in PHP 7.1.14 and 7.2.2 is probably related to https://bugs.php.net/bug.php?id=75396 "Exit inside generator finally results in fatal error". Maybe the behavior changed back in PHP 8.0.0 because of an unexpected interaction of those two things? (adding Nikita to the CC list) -- Guilliam Xavier
Re: [PHP-DEV] [VOTE] PHP\iterable\any() and all() on iterables
Hi, On Tue, Feb 9, 2021 at 7:33 PM Larry Garfield wrote: > On Mon, Feb 8, 2021, at 6:48 PM, Levi Morrison via internals wrote: > > On Mon, Feb 8, 2021 at 5:15 PM tyson andre > wrote: > > > > > > Hi Larry Garfield, > > > > > > > > Hi Larry Garfield, > > > > > > > > > > > > Hi internals, > > > > > > > > > > > > > > Voting has started on > https://wiki.php.net/rfc/any_all_on_iterable and > > > > > > > ends on 2021-02-22. > > > > > > > > > > > > > > This RFC proposes to add the functions > `PHP\iterable\any(iterable > > > > > > > $input, ?callable $callback = null): bool` and > `PHP\iterable\all(...)` > > > > > > > to PHP's standard library's function set, using the namespace > preferred > > > > > > > in the previous straw poll. > > > > > > > > > > > > > > [...] <https://www.php.net/unsub.php> > > > > > > > > > > > > > > > > > > Ak! I literally just finished reading it and wanted to note a > lack of clarity on one point. :-) > > > > > > > > > > > > The signature of the callback is never specified explicitly. > The ternary is a bit confusing. I assume the signature is > > > > > > > > > > > > callable(mixed): bool > > > > > > > > > > > > But that's not made explicit. It's also not made explict that > omitting the callable collapses to "is truthy". That's a sensible thing to > do, but it's not stated explicitly anywhere, just inferred from the code > sample. > > > > > > > > > > > > [...] > > > > > > > > > > If there is a callable, it allows `callable(mixed): mixed`, > > > > > and converts the callable's return value to a boolean. > > > > > So omitting the callable is the same as passing in the callable > `fn($x) > > > > > => $x`, which is equivalent to `fn($x) => (bool)$x`. > > > > > This is exactly what the reference implementation would do. > > > > > > > > > > [...] > > > > > > > > Oof. I'm glad I asked, because I don't like that at all. If > available, the callable should be returning bool, not "anything that may be > truthy/falsy." If you have an explicit function, it should have an > explicit return type. A truthy check is a reasonable default, but not for > when you're opting in to specifying the logic. > > > > > > > > I am in favor of the RFC, but I will have to consider if that > changes my vote to No. > > > > > > > > --Larry Garfield > > > > > > This was a deliberate choice and is consistent with the weak type > comparison behavior of array_filter() and other functions that default to > using weak type checks internally. > > > > > > I'd agree that I'd prefer to see callbacks returning booleans in code > I'm reviewing, > > > but a truthiness check seems more practical and consistent with the > rest of the language > > > than throwing a TypeError or checking the predicate return value using > `!== true` > > > > > > This was made to make PHP more widely accessible and free of surprises. > > > e.g. `(bool)array_filter($arr, $predicate)` can be safely converted to > `any($arr, $predicate)` without introducing a TypeError or behavior change. > > > > > > [...] > > > > For what it is worth, in C++ it is fairly normal to use a convertible > > to bool type. For instance, having an overload on a < b for iterators > > can return whatever type it wants, as long as it is contextually > > convertible to bool. > > Yet in 8.0, a non-[ 1 | 0 | -1 ] return from a comparison function as just > converted to a warning. So the trend in the language seems to be the other > direction. > Are you referring to this frequent mistake? ``` $list = [2,4,1,3]; usort($list, fn ($a, $b) => $a < $b); /* Deprecated: usort(): Returning bool from comparison function is deprecated, return an integer less than, equal to, or greater than zero */ echo json_encode($list); // [4,3,2,1] ``` (That's probably because PHP user comparison functions were modelled from C (e.g. strcmp()), not C++ (e.g. std::less).) Of course here the "correct" thing is to return `$a <=> $b` (or `$b <=> $a` for descending order), but you can also return `$a - $b` (not necessarily in [-1,0,1]), or even a string `"foo"` still without any warning in 8.0.2 (just a certainly wrong result)... Anyway, to me it feels natural that any()/all() would "work" like array_filter(). @Tyson by the way, in the any()/all() case (vs the any_value()/all_values() and potential any_key()/all_keys() etc.), wouldn't it be preferable to add the optional `int $flags = 0` (or "$mode") parameter right from the start (even if not used yet), as adding it in a later release would apparently pose some BC concerns (ArgumentCountError, polyfills etc.)? -- Guilliam Xavier
Re: [PHP-DEV] [RFC] Short functions, take 2
On Thu, Mar 25, 2021 at 4:23 AM Levi Morrison via internals < internals@lists.php.net> wrote: > [...] > Instead of writing this: > > ``` > class A > { > public function method($arg1) > { > return expr($arg1); > } > } > ``` > > I can write this: > > ``` > class A { > function method($arg1) { return expr($arg1); } > } > ``` > For what it's worth (probably not much), when fiddling with quick test code samples (e.g. on 3v4l with "quick preview"), more than once I have written things like this: ``` class A { function method($arg1) { expr($arg1); } } ``` i.e. I initially forgot the "return " (and had to go back and add it). I would surely not have this problem anymore with this: ``` class A { function method($arg1) => expr($arg1); } ``` (It also seems I don't have this problem when writing a return on its own line :/) Regards, -- Guilliam Xavier