Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:110009 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 16212 invoked from network); 5 May 2020 17:20:59 -0000 Received: from unknown (HELO php-smtp4.php.net) (45.112.84.5) by pb1.pair.com with SMTP; 5 May 2020 17:20:59 -0000 Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id B52AE1804E4 for ; Tue, 5 May 2020 08:55:54 -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-f52.google.com (mail-io1-f52.google.com [209.85.166.52]) (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 08:55:54 -0700 (PDT) Received: by mail-io1-f52.google.com with SMTP id d7so1137489ioq.5 for ; Tue, 05 May 2020 08:55:54 -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=LgmjVWk9pEo1bOg7OGst/kvybQL9lj1I8f7sIxET/VA=; b=Qc00IAzjPYorDNguervlNiTj4mUb19QxBQ11/yKfnv+kYyURbYM9K3wRmadbMU/IVq AUieDKoWEdS3YhN1SMdP4YtdW3gLSOH8jzXVYyF9TM2C9eXphsXis4kAVyeN12acxdLK yYW1jepSq5NccjxO/gZNC22qk0HQi3AOmRjZjc43nf09ZiJQwd0YWYp+qNbTPqTgh9Fj lCNHvfsuXmJf/BwbG0DefT6Vq49lKBHVwjoVcQ+zxeJ+LxaD4xXTZ1e7bAey+9Pq6u4y T39R0we/XD5/Zq0+gyKcQ+atcGeOz00yotAv+dgpAwnYosxgGE5u417++HdAOCl08UJN dxag== 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=LgmjVWk9pEo1bOg7OGst/kvybQL9lj1I8f7sIxET/VA=; b=Ibn9Qts1mrLe0rwQF6bOu0NT4j5RHFoIEoH9lPerY5mMddFkzvC3nraovGSK2sfNCN ROOVJNPOYgoGK2NfXbqxxX0JBKCW6HhAhnq3vAbU3vxmnVzk7Qsbh56aOiKPPDJZig3R 9ojKfQsihHBTTI9tljBL63kx8KldtrNPZpwCHQIr8j+1D6+AZEjlmfdhwmUWEwWF9o3h uWEjfntL1TX/VCxaWHiqkvbp9/WnfeDL9dIQJSBRXkvUIzKv3Gn2A29BoskwYHXvuMIM 3iIgjBUqLYt7CP4H6FZaM5+eaUk8pv5esUU4H1tMIX+tQuy75n0lrioC2sD1PJAx5CvZ vMYQ== X-Gm-Message-State: AGi0PuZEx6e9ClC+Ikw5tb0qpVOJzaVMEPNFRa88T7zNwNFmk4zt4dMB 9FAhq7w+a6uTxt32B0fYT/vAmdC+UUjsg3BgaTE= X-Google-Smtp-Source: APiQypJvOSEYiAcEfhrZR15CxCPMKqBmI4wCGsu1O2WlW4sQGCFs9TmnurFBJIY5PtVBZKAtqfc75kfSOr/pDiREScc= X-Received: by 2002:a5d:8715:: with SMTP id u21mr3964288iom.46.1588694152893; Tue, 05 May 2020 08:55:52 -0700 (PDT) MIME-Version: 1.0 References: In-Reply-To: Date: Tue, 5 May 2020 17:55:40 +0200 Message-ID: To: Benjamin Eberlei Cc: Nikita Popov , PHP internals Content-Type: multipart/alternative; boundary="000000000000a3db7d05a4e8aed8" Subject: Re: [PHP-DEV] [RFC] Named arguments From: ocramius@gmail.com (Marco Pivetta) --000000000000a3db7d05a4e8aed8 Content-Type: text/plain; charset="UTF-8" Hey Benjamin, On Tue, May 5, 2020 at 5:44 PM Benjamin Eberlei wrote: > I see the PHP internal API as the main benefactor of this feature over > userland code imho. Internals realistically couldn't get "smaller APIs" > without adding many new functions instead, for example htmlspecialchars. > It takes a couple minutes to write a non-broken `htmlspecialchars` function to use in your own project. Besides that, designing a language feature to accommodate pre-existing bad design smells a lot. There are libraries out there trying to provide better API to what is provided by PHP-SRC, such as https://github.com/thecodingmachine/safe: that's an easy win, by creating **adapters** for bad API, instead of **language-level constructs** that will haunt us forever. > The trade off from API design perspective is either providing a more > complex API by having function permutations or an OOP API, which in turn > developers have more trouble remembering. Or the more beginner approachable > way is providing a single function that is easy to remember exists, but in > turn does more things and may require a look into the documentation to see > all the options. Given we have this API already in PHP and this will not > realistically change, I think named params will be a big win. > Sorry, but no: you provide multiple constructors, each with a limited set of arguments, each guaranteeing constraints that depend on context. For instance, a `fromArray()` may check for key existence, while `fromJson()` may use a JSON-Schema definition to check that all is as required, and `fromXmlPayload()` may apply an XSD validator, and so on... Number, type and lifecycle/mutability of parameters may change depending on named constructor, and the reduced scope makes it very easy to document requirements, and to make the API ergonomic (yes, it's actually easier to use: surprise!). In this example $stuff is an array which has keys. Presumably > $parameterName => $newParameterName would be equivalent to a change of key > names. Or property names on > MyInfiniteSequenceOfParametersAsProperValidatedStructure. So you get the BC > break of renaming anyways in your example. > Correct: that's a BC break on my `MyInfiniteSequenceOfParametersAsProperValidatedStructure` which does not depend on the definition of `myHorribleLegacyAndOrganicallyGrownApi()`. It is still a very well isolated BC scenario on a single `::fromArray()` named ctor, compared to introducing a language-level BC boundary that crosses all existing code out there. Now as a provider of a public API (library, framework) you can still > counter this with a BC layer: > > function foo($newParameterName, $parameterName = null) { > if ($parameterName !== null) { > $newParameterName = $parameterName; > trigger_error("Using paramaterName as named parameter is > deprecated, use newParameterName instead.", E_USER_DEPRECATED); > } > /... > } > > this looks ugly (because we haven't seen it before), but is not more or > less complex than the same BC / deprecation layer in fromArray with changed > option: > > public static function fromArray(array $options) { > if (isset($options['parameter_name'])) { > $options['new_parameter_name'] = $options['parameter_name']; > trigger_error("Using paramaeter_name as option is deprecated, use > new_parameter_name instead.", E_USER_DEPRECATED); > } > } > > So nothing much would technically change for someone who cares about BC > for their users. > In first place, I would rarely ever design a `::fromArray()` API that isn't related to serialization or configuration loading (which is another kind of serialization, after all). I would not look forward to maintaining BC compliance like with `foo($newParameterName, $parameterName = null)`, and I do not see which added value counters this massive amount of maintenance overload. We're chasing a non-existing problem (or feature requirement) by adding other problems that are far greater. Marco Pivetta http://twitter.com/Ocramius http://ocramius.github.com/ --000000000000a3db7d05a4e8aed8--