Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:110012 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 74306 invoked from network); 5 May 2020 18:44:12 -0000 Received: from unknown (HELO php-smtp4.php.net) (45.112.84.5) by pb1.pair.com with SMTP; 5 May 2020 18:44:12 -0000 Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id E0624180505 for ; Tue, 5 May 2020 10:19:08 -0700 (PDT) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on php-smtp4.php.net X-Spam-Level: X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM,HTML_MESSAGE, RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H2,SPF_HELO_NONE,SPF_PASS autolearn=no autolearn_force=no version=3.4.2 X-Spam-ASN: AS15169 209.85.128.0/17 X-Spam-Virus: No X-Envelope-From: Received: from mail-io1-f50.google.com (mail-io1-f50.google.com [209.85.166.50]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (P-256) server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by php-smtp4.php.net (Postfix) with ESMTPS for ; Tue, 5 May 2020 10:19:08 -0700 (PDT) Received: by mail-io1-f50.google.com with SMTP id k6so2382679iob.3 for ; Tue, 05 May 2020 10:19:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=twvvDtSxGPioxa1mxrjuqvKOTeft15tazibTQZQmPRc=; b=GYOX8yENPP6wtWdd6lxw13uukgBlMEYqXhcOUDIrGnyv1dBLPh5Qv9eRSKUrUVEdiv QbtjpIQFzPMJUESimQbEynnAsMLXvkVByI3CnK2dgGieUq6LNAqcMEgY9XAr70RxxmyF AgzENacdeCvTCLTXCCRHj/BVWbI6HMGNYKIgEvn79jTRx1UHAJNKms/plpSLXvZPFYBA oPPv8eHDSdw+ORH2aln4hwV+8MTzRq48Fp8kzg+03/xjbZ70bBYJf+0m4+a36befNcET e7fysMw/yTrvDOTOxpSKtxGBSKjsugzZYFS4ACfCLmAKmRAuokZeUC6gZHuNIFp40Ewx n5gQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=twvvDtSxGPioxa1mxrjuqvKOTeft15tazibTQZQmPRc=; b=RwTKZpLc7yxjbhLllDAMa6m4NxzC/pBVbc41BVw6HKVr1Vz9sUs/SI5suXJ3kZDWtM t6FMnXjOox5DNVbhlX9DOpsIGQ62UKz59NU1CwfTsZK1R3P6IhKkyPG7vYmICYBQsgAI B3bc4Jyns43wynqi318WucRlibmcJ7z2kIRuWcn5sBNPZoVZWT7sAXiQbc2YBN1kAtjz QapH5zO2rv+YMwI95r42dVany3VSXZXAwoE3Dv9XjpkC1NKh7IKTekUZ3EJSP52N5LNA TXZoXdGGvpAGX7dunYebhsb/rj94btLtSdA7RFsbNwqxCc4UK82difQYyyJSp5t4Xhb3 JP3A== X-Gm-Message-State: AGi0PuaMMpCFMVj/chjT2VMMv9am5DVM8Jq5Tvvg0r6Hf7OUQTEyc15Y EguybeXgX0lkzXlS5WI35upWWA9NFAsqbG3vAPc= X-Google-Smtp-Source: APiQypKahZynEr/dy4j9lwbhFPlDwuLt5WVHHefT/jOSboMNMw20PrFaoX9topwbLUCPbZSa4J/GhFUap+mLy1RV3I8= X-Received: by 2002:a02:9f8b:: with SMTP id a11mr4546223jam.122.1588699143932; Tue, 05 May 2020 10:19:03 -0700 (PDT) MIME-Version: 1.0 References: In-Reply-To: Date: Tue, 5 May 2020 19:18:52 +0200 Message-ID: To: Theodore Brown Cc: Nikita Popov , PHP internals Content-Type: multipart/alternative; boundary="0000000000002116e405a4e9d810" Subject: Re: [PHP-DEV] [RFC] Named arguments From: ocramius@gmail.com (Marco Pivetta) --0000000000002116e405a4e9d810 Content-Type: text/plain; charset="UTF-8" Hey Theodore, On Tue, May 5, 2020 at 6:59 PM Theodore Brown wrote: > On Tue, May 5, 2020 at 9:11 AM Marco Pivetta wrote: > > > As mentioned some days ago, I see named parameters as an added liability, > > rather than values. > > The rationale of my negativity around the topic being that a diff like > > following is now to be considered a BC break: > > > > ```diff > > -function foo($parameterName) { /* ... */ } > > +function foo($newParameterName) { /* ... */ } > > ``` > > If the function is part of your own codebase, BC Breaks that are intra-codebase are rarely every a problem nor a point of discussion. > an IDE can automatically > update function calls when renaming a parameter. For functions that are > part of a public API, yes, parameters shouldn't be renamed outside of > major versions. But in my experience, it's rare for function parameters > that are part of public APIs to be renamed. Do you have many real-world > examples of where this had to happen? > Parameter name changes are very much normal, since (as I already posted in /r/php), naming is hard, and getting it right is not a one-shot effort. Also, I haven't heard of this being a big problem in other languages > with named arguments like Python. > Good question: I guess parameter renames are avoided on purpose? Not familiar with the python community myself, sorry. Why do you say that? For me this feature would be extremely helpful > when calling constructors that have several optional arguments (e.g. > similar to the `ParamNode` example in the RFC). Maybe you consider > this a bad API, I do in fact consider the `ParamNode` example in that API to be a bad candidate for named parameters, since I'd make all of the arguments in that signature required anyway: defaults aren't meaningful anyway, as the AST library where it comes from has all the context to instantiate them all (the caller, being the parser, will have all the parameters anyway). If you were to instantiate a `ParamNode` from, for example, a `ReflectionParameter`, you would probably add named ctor (or an indepentent factory, if in external supporting domain) to pass all parameters as well. If you were to add more optional fields, or use this in a context of an AST builder (BTW, nikic/php-parser has facilities for that already) a mutator would be efficient too: ```php class ParamNode extends Node { public function asReference(): static { $instance = clone $this; $instance->byRef = true; return $instance; } ``` but it's a very common pattern, and named arguments > will make it far easier to work with than the typical alternative of > converting arguments to an options array (which is itself a BC break > and has many other downsides as the RFC points out). > You can add as many named constructors as you want: adding `ParamNode::fromArray()` is possible. > > In practice, the issues around bad API (in this case, bad = lots of > > optional parameters, maybe even ordered arbitrarily) are fixed by > > using proper value types and structs or value objects > > How can lots of optional parameters be "fixed" in practice with structs? > E.g. how would they improve the `ParamNode` example in the RFC? Would > it even be possible to migrate existing classes like this to structs > without a BC break? > It is possible to add more named constructors in a BC compliant way, while it is hard to change existing public constructors: * `::fromArray()` * `::fromReflectionProperty()` * `::make(string $name, ?ExprNode $default, ?TypeNode $type, bool $byRef, bool $variadic)` * `::makeForPHP53(string $name, ?ExprNode $default, ?TypeNode $type, bool $byRef)` - no variadic support? No problem :-) * `::makeWithCodeLocation(string $name, ?ExprNode $default, ?TypeNode $type, bool $byRef, bool $variadic, CodeCoordinates $coordinates)` All of the above are possible BC-friendly growth directions for such kind of data structure. They also provide better type definitions, context, naming and invariants than a single signature that has to cover all use-cases at once. Personally I think it's a lot simpler and more consistent to have named > arguments which can be used anywhere, including in attributes, vs. > having to implement and learn a new syntax for structs which only works > for that one use case (and may not be easy to migrate to). > No new syntax: we already have the tools. Marco Pivetta http://twitter.com/Ocramius http://ocramius.github.com/ --0000000000002116e405a4e9d810--