Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:97226 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 30933 invoked from network); 29 Nov 2016 17:14:05 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 29 Nov 2016 17:14:05 -0000 Authentication-Results: pb1.pair.com smtp.mail=me@kelunik.com; spf=permerror; sender-id=unknown Authentication-Results: pb1.pair.com header.from=me@kelunik.com; sender-id=unknown Received-SPF: error (pb1.pair.com: domain kelunik.com from 81.169.146.219 cause and error) X-PHP-List-Original-Sender: me@kelunik.com X-Host-Fingerprint: 81.169.146.219 mo4-p00-ob.smtp.rzone.de Received: from [81.169.146.219] ([81.169.146.219:9942] helo=mo4-p00-ob.smtp.rzone.de) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id B2/91-20013-A57BD385 for ; Tue, 29 Nov 2016 12:14:04 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; t=1480439640; l=6261; s=domk; d=kelunik.com; h=Content-Type:Cc:To:Subject:Date:From:References:In-Reply-To: MIME-Version; bh=COB6ID7XR2M7+0Yc90Lo1htPdDVbLhOCGgX1L+pprP4=; b=KNPrlHcNc/QEujaQeK1g21gXFoSaA4iq23vkjbDQFgY5beFiMuU0Zbs4jsgUAlUFt5 3gHkmwLV8eUAnXOVCClKi62SWxGylzPh4D4rZzio0aJjyu5Qz8kHqpm292SRdZjBKLKu HQUbo3jSbqAr6ZhZd2smMwMiCtfK2WR0bzrrk= X-RZG-AUTH: :IWkkfkWkbvHsXQGmRYmUo9mls2vWuiu+7SLDup6E67mzuoNPBqD/tkM= X-RZG-CLASS-ID: mo00 Received: from mail-wj0-f176.google.com ([209.85.210.176]) by smtp.strato.de (RZmta 39.9 AUTH) with ESMTPSA id q07663sATHDxX3F (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (curve secp384r1 with 384 ECDH bits, eq. 7680 bits RSA)) (Client did not present a certificate) for ; Tue, 29 Nov 2016 18:13:59 +0100 (CET) Received: by mail-wj0-f176.google.com with SMTP id mp19so151559033wjc.1 for ; Tue, 29 Nov 2016 09:13:59 -0800 (PST) X-Gm-Message-State: AKaTC01AhrvvEpUcOvz6hBcPh+egJMSAp6lxEweSOe8nJVqazW46IoP+YEhWQv/SD2WMQ8QcHj74W1PGGWzAUA== X-Received: by 10.194.2.79 with SMTP id 15mr23832566wjs.225.1480439639605; Tue, 29 Nov 2016 09:13:59 -0800 (PST) MIME-Version: 1.0 Received: by 10.80.140.245 with HTTP; Tue, 29 Nov 2016 09:13:59 -0800 (PST) In-Reply-To: References: Date: Tue, 29 Nov 2016 18:13:59 +0100 X-Gmail-Original-Message-ID: Message-ID: To: Rasmus Schultz Cc: PHP Internals Content-Type: multipart/alternative; boundary=047d7b3a8c3ad48e4b054273b6ed Subject: Re: [PHP-DEV] [RFC] Parameter No Type Variance From: me@kelunik.com (Niklas Keller) --047d7b3a8c3ad48e4b054273b6ed Content-Type: text/plain; charset=UTF-8 > > But this leads to code that can't pass static inspections? > No. > interface Joiner { > public function join(array $array): string; > } > > class WideJoiner implements Joiner { > public function join($iterable): string { > $array = is_array($iterable) ? $array : > iterable_to_array($iterable); > > return implode(", ", $array); > } > } > > function joinWith(Joiner $joiner, $iterable) { > return $joiner->join($iterable); // <-- invalid argument ? > } > Yes, a static analysis engine should report invalid argument. If you depend on another thing being accepted, you shouldn't declare just Joiner but instead an extending interface or an implementation directly. > According to the Joiner abstraction, only array is accepted, and that's > all a static analysis tool can know about the $joiner argument in the > joinWith() function. > Correct, that's why the static analysis engine should throw a warning on that code. > Being unable to pass static inspections is one thing, but this also makes > the code generally difficult to explain > How so? > there's a contract, Joiner, which states that an array is required - to a > person reading the joinWith() function, that's all they can know about a > Joiner instance > Correct. > it isn't safe for anybody to depend on a specific implementation of Joiner > with a widened argument-type > It is safe as long as you depend on the specific implementation or an extended interface with the widened argument type. > unless they read through the entire codebase and happen to know about the > WideJoiner implementation, but even then, someone using the joinWith() > function would also need to know which implementation of Joiner is being > passed > You'd just declare that you depend on a Joiner that accepts also iterables. > which seems to defeats the purpose of even having an abstraction in the > first place? > So your argument is basically that contra-variance is never needed? Regards, Niklas --047d7b3a8c3ad48e4b054273b6ed--