Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:115260 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 77815 invoked from network); 1 Jul 2021 14:54:26 -0000 Received: from unknown (HELO php-smtp4.php.net) (45.112.84.5) by pb1.pair.com with SMTP; 1 Jul 2021 14:54:26 -0000 Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id DEDCD180556 for ; Thu, 1 Jul 2021 08:14: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=-1.7 required=5.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,NICE_REPLY_A,RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL,SPF_HELO_NONE,SPF_NONE autolearn=no autolearn_force=no version=3.4.2 X-Spam-Virus: No X-Envelope-From: Received: from mail-oo1-f48.google.com (mail-oo1-f48.google.com [209.85.161.48]) (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 ; Thu, 1 Jul 2021 08:14:54 -0700 (PDT) Received: by mail-oo1-f48.google.com with SMTP id bc18-20020a0568201692b029024c6dbc2073so1654286oob.8 for ; Thu, 01 Jul 2021 08:14:54 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ralphschindler-com.20150623.gappssmtp.com; s=20150623; h=subject:to:cc:references:from:message-id:date:user-agent :mime-version:in-reply-to:content-language:content-transfer-encoding; bh=AZgLytPojT0djHp23fyEoKZl5RhGVwOX1Y9wM0Hbsck=; b=kOch35B0wrKCsd7TeLc7nv7nSTW48mZrKI5G/AyLYMnlGbo7ujIQKfnry8LA55s8yr /0zECSM45HL1yR7MwNO3pmXZnedOkgCu2CXBcdlieIJDWzuscn5ulyyIT+TfGlZ6jMf5 ebdokozFYGoQOEPS8DGbbP/KO7jMEVp4w5oakO9QkUGvpCA1XP0Dfnut9qDhzu/gaYzj XR8/5pu4WrG+AgC7sbIY5JoFyj99Hn9t+PuXbbYfPJri3tyHHiLS0CxTfecXxaggEEn5 PhJLH1QBfI+5OYLQxjpjkNcO3+5OJlDXPENL9s+nsyDaQfdeouYpBXQ7iWwVj2ZvCPly BNQQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:subject:to:cc:references:from:message-id:date :user-agent:mime-version:in-reply-to:content-language :content-transfer-encoding; bh=AZgLytPojT0djHp23fyEoKZl5RhGVwOX1Y9wM0Hbsck=; b=j8HIz5Bncrrdk0RvN1KZBKzQZYhblSG3hqul9SNGWZrp9quAJtkjNmwUgD6A2itiiZ KmJQUqI/ufxF3+PpqjLSI9WELsIjF2NBJDEakq9To2HnmnzW/gzWQd+5+6stihTYgCor e9lox+CFfvZekavf2yJylwRi+iUI4BuHd77p4HN2kBOEqSELCGO6qLhI4ygqNn2Q3njP be0LtGaV6+zv6DYvlcCNFEEZB6N0WDID6mtG6bA8pFhSfbfDMF/yGDdKOGBuGKjUnKGL xXBVFhGUJuuImfGv5Tk9DGL/Fm/gUvQEezmooa4U009qujvljjjRA+lo4odkHq4byLmY 2ufg== X-Gm-Message-State: AOAM5320cIXe3roG8ahCQ8FLINgw6NtTcX+rrGqIusv2HiA/xo1h6zkv SlC6MVGUEEDVsp3V6hI9w14iiw== X-Google-Smtp-Source: ABdhPJyKQCaAtm5BdJB1KRO0qHfp1N20UPp9q6FTxOgqlGiff3aLHIOSpUBg1q5jVNnplT0kL9PJGg== X-Received: by 2002:a4a:d781:: with SMTP id c1mr315689oou.23.1625152493604; Thu, 01 Jul 2021 08:14:53 -0700 (PDT) Received: from Ralphs-ZiffBook-Pro.local (ip72-204-153-233.no.no.cox.net. [72.204.153.233]) by smtp.gmail.com with ESMTPSA id b11sm1793031otl.55.2021.07.01.08.14.52 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Thu, 01 Jul 2021 08:14:53 -0700 (PDT) To: PHP internals Cc: Nikita Popov References: <1ae611cb-b077-3db0-3237-c7ffa1c6e745@ralphschindler.com> Message-ID: Date: Thu, 1 Jul 2021 10:14:52 -0500 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:78.0) Gecko/20100101 Thunderbird/78.11.0 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset=utf-8; format=flowed Content-Language: en-US Content-Transfer-Encoding: 7bit Subject: Re: [PHP-DEV] [Proposal] call_user_func_map(): flexible named parameter mapping for call_user_func* From: ralph@ralphschindler.com (Ralph Schindler) (Jump to bottom for alternative suggestion that achieves same goals) > Just to make sure I got this right: call_user_func_map() is the same as > call_user_func_array(), but a) only accepts named params Yes, only accepts named parameters (associative array), > and b) silently ignores unknown named params? I would characterize this as "explicitly doesn't pass unrequested parameters" > I'm not really convinced by your use-case here. This seems like a rather > odd way to design an API, which goes against commonplace assumptions. If I didn't invest a lot of thought in the use case to make the argument, ha. That said, I disagree with "odd way to design an API" sentiment... This is a common idiom in a few different places found inside frameworks. Laravel and Symfony both do named argument mapping when dispatching controller actions. Additionally, both containers do a significant amount of work with Reflection to map named arguments with potential parameters. I am not discrediting the fact that they don't also do more complex stuff, but I think this supports the argument that this method of parameters mapping does not go against commonplace assumptions. Eg: https://github.com/symfony/http-kernel/blob/5.3/HttpKernel.php#L149-L157 https://github.com/symfony/dependency-injection/search?q=reflectionMethod https://github.com/laravel/framework/blob/8.x/src/Illuminate/Container/Container.php#L649 > you pass a closure somewhere, the general expectation is that the > parameter names you use are irrelevant and only the order matters. This > creates a very unusual API contract, and while I can't prevent you from > doing that, I'm pretty sure this is not something we want to endorse > with additional library support. > (The same question for named parameters in general is answered by > https://wiki.php.net/rfc/named_params#what_are_the_benefits_of_named_arguments > > -- notably none of the arguments made there are relevant in this > context, the only benefit I see is saving a few keystrokes.) Named mapping is arguably better than forced ordered mapping for all the reasons laid out in the above link. One of the primary benefits being you get type checking and better language supported analysis from tooling (like your IDE knowing the type of the parameter). This is the effective way of accomplishing what you suggested today, you can skip parameters here but get no type checking: $f = function ($params) { [$foo, $baz] = null; extract($params, EXTR_IF_EXISTS); var_dump($foo, $baz); // }; $f(['foo' => 'a', 'bar' => 'b', 'baz' => 'c']); // string(1) "a" // string(1) "c" > What's wrong with good old fn($params) => $params['a'] + $params['b']? ...Maybe nothing, perhaps if instead of adding parameters or new functions to call_user_func_* (language construct functions) we instead can add some type checking and destructuring to it ;) # Alternative Suggestion An alternative suggestion would be to follow Javascript's lead to accomplish something similar and allow parameter destructuring, but in a more PHP way: $f = function (...[string $foo, string $baz]) { var_dump($foo, $baz); }; $f(['foo' => 'a', 'bar' => 'b', 'baz' => 'c']); // string(1) "a" // string(1) "c" -ralph