Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:92813 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 29835 invoked from network); 26 Apr 2016 18:38:48 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 26 Apr 2016 18:38:48 -0000 Authentication-Results: pb1.pair.com header.from=inefedor@gmail.com; sender-id=pass Authentication-Results: pb1.pair.com smtp.mail=inefedor@gmail.com; spf=pass; sender-id=pass Received-SPF: pass (pb1.pair.com: domain gmail.com designates 209.85.215.68 as permitted sender) X-PHP-List-Original-Sender: inefedor@gmail.com X-Host-Fingerprint: 209.85.215.68 mail-lf0-f68.google.com Received: from [209.85.215.68] ([209.85.215.68:33653] helo=mail-lf0-f68.google.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id D6/E8-20013-6B5BF175 for ; Tue, 26 Apr 2016 14:38:47 -0400 Received: by mail-lf0-f68.google.com with SMTP id p64so4060420lfg.0 for ; Tue, 26 Apr 2016 11:38:46 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=to:subject:references:date:mime-version:content-transfer-encoding :from:message-id:in-reply-to:user-agent; bh=OqiM+qO4DwHg6+tgNcmCxlbB5sinXn2BTtSerE8nawc=; b=MQkGZMToEPO2qK2Qc0rHLvKdWaqysdJ3e5f23dqBixD+Lv4FDvMkEhZAZ889FyVPZq E90fGAyVtX7IocBVIGKQJHGSy8jy6RtpPSGD36gar+foaBMyYQXRy6j0wDRLy4APtSAe QaAXP9acInjq2x4kEm9yPq78dtC2LJLbD5pvpRcjbqHrCpcMHIZdd/7pBu1g2M7aTXy2 EeMlnftP7jH6uvJfDIye3nEQxXQG4DgO2I3si9MHESsluZQCEhIM2DCaNV+pvrGYMAY0 Ps3XaoiigpopSs1pbrPLST8OiZ/eMNm0yjZKfNOSyvFGMfjW4iqlCKCmcHsjU4Q8P2IR +Vqw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:to:subject:references:date:mime-version :content-transfer-encoding:from:message-id:in-reply-to:user-agent; bh=OqiM+qO4DwHg6+tgNcmCxlbB5sinXn2BTtSerE8nawc=; b=mDx4cqJ/moAmuJGF/zwK9pydFWkNRYNhUfLC5r2lODZszm9WLBwSn/dipeTYC9c/Nc fLjc9wg7Nekw3tWe5y56hz00qbQIxCcxSN5rn4VW5BG2ZBJoEGoRzPDU8tHiS0Uezn4y BNximSPN59VIlwkZYksOYr9rRCdN+Z7kideprk3uKs5ZFvmjpLfNgTqG1TVr/6mWpCB3 FogSg83FP2MnV8rdit6otfEH6+HiMJMNUq4oemTlipgj1xu4dibEGUWTt51/6DR3+Z8g mB5hqX71a0UN2AdAZqq04rzpdVf3obEdj1gmSLZnsjL5FF71yzqrGnctsdAWRfGVRSLO NWuA== X-Gm-Message-State: AOPr4FVN7AYXLQ/HDZMeIdiky5MR4LCb6SjevUt051Rg4sZeR8vORDF/4fnPvpFmjWVW3g== X-Received: by 10.112.143.163 with SMTP id sf3mr1812618lbb.117.1461695922830; Tue, 26 Apr 2016 11:38:42 -0700 (PDT) Received: from nikita-work-box ([185.62.192.230]) by smtp.gmail.com with ESMTPSA id dw3sm687902lbc.2.2016.04.26.11.38.41 (version=TLS1 cipher=AES128-SHA bits=128/128); Tue, 26 Apr 2016 11:38:41 -0700 (PDT) Content-Type: text/plain; charset=utf-8; format=flowed; delsp=yes To: "Mathieu Rochette" , "PHP internals" References: Date: Tue, 26 Apr 2016 21:38:33 +0300 MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Message-ID: In-Reply-To: User-Agent: Opera Mail/12.16 (Linux) Subject: Re: [PHP-DEV][RFC] Callable Types From: inefedor@gmail.com ("Nikita Nefedov") Bringing this thread to the main one On Sun, 24 Apr 2016 06:27:39 +0300, Mathieu Rochette wrote: > I've seen someone mentioning variadics so I made a few small tests, I > think those two should work (they currently don't): > > https://3v4l.org/eZgR9/rfc#rfc-callable_typehint > https://3v4l.org/N7i0u/rfc#rfc-callable_typehint > > and this one should not: > > https://3v4l.org/fcRlT/rfc#rfc-callable_typehint Hey, You're right, this code should be valid function foo(callable() $a) { $a(); } foo(function (...$args) {}); But it gets into the same problems like optional params when it is typed function foo(callable() $a) { $a(123); } foo(function (A ...$args) {}); Now to the question why would `foo()` call `$a` with additional arguments even though it assumes `$a` is of type `callable()`? Well at first because it can - this is enough for it to be not type safe :P Long answer is: in the real life there will definitely be cases where this would allow users to shoot their feet, take this example: function map(/* array | Traversable */ $collection, callable($value, $index) $mapper) { $out = []; foreach ($collection as $index => $value) { $out[] = $mapper($value, $index); } return $out; } ... function renderPost(Post $p, bool $asAdmin = false) { return render("post_template", ["post" => $p, "asAdmin" => $asAdmin]); } ... $renderedPosts = map($posts, "renderPost"); // here developer would get fatal at the line `$out[] = $mapper($value, $index);` // if optional parameters were supported // Without them though, he gets TypeError when he passes "renderPost" to map() // And it says nicely what exactly he has done wrong Even now though, he could get into this situation if `$asAdmin` parameter was not properly typed, but that would be on him as he'd need to voluntarily drop those types for which I don't see a reason to do so. Now talking about an immediate solution to hypothetical problem we are facing there is an easy solution - if you have a functional library, you'll probably have there `partial_any` function of some kind (ex. [0]), so what you could instead do is: $renderedPosts = map($posts, f\partial_any("renderPost", f\placeholder(), true)); This would always pass `true` to a second parameter, but leave the first one. [0] https://github.com/lstrojny/functional-php/blob/master/docs/02-partial-application.md#partial_any