Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:115759 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 81103 invoked from network); 16 Aug 2021 14:27:48 -0000 Received: from unknown (HELO php-smtp4.php.net) (45.112.84.5) by pb1.pair.com with SMTP; 16 Aug 2021 14:27:48 -0000 Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id ECAD51804C8 for ; Mon, 16 Aug 2021 07:59:48 -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-lf1-f47.google.com (mail-lf1-f47.google.com [209.85.167.47]) (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 ; Mon, 16 Aug 2021 07:59:48 -0700 (PDT) Received: by mail-lf1-f47.google.com with SMTP id c24so34964623lfi.11 for ; Mon, 16 Aug 2021 07:59:48 -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=RqOIM3OioPEX4x2s4CR/C56Moxg6BKH/axOvDdSGg9s=; b=d1CdV4jXLANiBgwtpNa+YR7Yr9+64/k/dWUR0Qn4zTBvs6ibmwuFWRVNHszBtkOQV8 Hn2Ot5Mjg7cScJ1dFTTO/e7tlgj/u4SEVpebFlXcnMMu2aQNKhHyw/7LcrF9iMy8jQat /cken3L8GRntKgLVVDzHRTpakUlGw9BZ2Lr8y+ckBhQkrHOKpZ+ukvGk4nDOWxseA6St M3IeQGhLE3Zqt4sd8NgGtdtSXbWNDwV/6zGOu6vV6dYUZCt74jQxGEyyI7Tjl/ckf8LA ZGR89yfHv4VVZNlRHdrqihXZWMuaCAPzWDZrufo5hshXR/AFj8u2CNjNPKA5Q0QyW/Hw x/Cg== 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=RqOIM3OioPEX4x2s4CR/C56Moxg6BKH/axOvDdSGg9s=; b=H9HpOT0wmZDxy3p03qAfYKjeaD2nC5KEgCDe1JpicW3xFJ7R23MIibaj2jTHGA6NOr bu8Yrw3XZ/wb94IoN8PPKlvoCZesbPRuVcIurGhCOrJGZQb8BulRsVL3AY3L71TdzQHf 7FyJtHFnUteEPzkkTJd1Ecx5RzRSUrUo89+3grcShDGCWasK03F23Xq6kdCVkjGOGpcU z2wjyTmu8/1NJEV8uU+UBOQ8JYncF9xngv4M/Va+ci3SaiabxoAkJr3SRr8onJV4zZ7U FHoH+pQynE8vvwwf3PHn0K2Q0KbSUJXgMxgxxGS8sztvpAND4f+gN519gYfM7Jcz4xu+ 7QgA== X-Gm-Message-State: AOAM5301GTW3SxsP18mDB3wRq0/4zUEtEhEx1tBCm7A2SHQfuHkuH1ET S877CfGc7JoaBv89NSZDIeCejpQXEt2k0VFurNw= X-Google-Smtp-Source: ABdhPJyWgbbiyQfDS0x0ay6sjK6FA65yVYMDMbNUSZ1xIFchZaiFenT2RPvWEE7tDYAanxGqcuA+3gPltxXEuPQijP4= X-Received: by 2002:a19:7619:: with SMTP id c25mr4185517lff.564.1629125985964; Mon, 16 Aug 2021 07:59:45 -0700 (PDT) MIME-Version: 1.0 References: In-Reply-To: Date: Mon, 16 Aug 2021 07:59:39 -0700 Message-ID: To: Nikita Popov Cc: PHP internals Content-Type: multipart/alternative; boundary="000000000000b016df05c9ae7340" Subject: Re: [PHP-DEV] [RFC] Never For Argument Types From: jordan.ledoux@gmail.com (Jordan LeDoux) --000000000000b016df05c9ae7340 Content-Type: text/plain; charset="UTF-8" On Mon, Aug 16, 2021 at 12:51 AM Nikita Popov wrote: > We have a better way to specify markers for the engine: Magic methods. I > think some people have a mistaken notion that engine-integrated interfaces > are always better than magic methods. This is only the case if such > interfaces are actually useful from a type system perspective. For example, > Countable and Traversable are useful magic interfaces, because you can > sensibly type against them. The recently introduced Stringable interface > (for the magic method __toString) falls in the same category. > > Conversely, Serializable is actively harmful as a magic interface (apart > from the other issues with it), because whether an class implements > Serializable does not determine whether it is serializable -- all objects > are a priori serializable, the Serializable interface just gives it custom > serialization behavior. You'll note that the new __serialize/__unserialize > methods are plain magic methods without an interface. With exception of a > custom serializer implementation, user code should never be checking for > Serializable. > > What would be your thoughts for the case of ArrayAccess? The engine integration can't really be used without multiple methods being implemented, so some form of contractual implementation does make sense. Additionally, the interface does provide some useful typing features, such as ArrayAccess|array. However the interface itself doesn't guarantee much about the actual implementation while being a prime candidate for something like the never type proposed here. In the case of ArrayAccess, it sort of exists to provide operator overloading for []. But I don't think it'll be the last time that we encounter an engine feature that is best provided through multiple method implementations. > The operator overloading case is in between: The interface is not actively > harmful, but they also aren't useful. Given the lack of generics, it's not > really possible to write code against a "Multiplyable" interface that > actually provides a useful guarantee. The interface does not distinguish > whether "T * T" is valid, or only scalar multiplication "T * float" is > supported. When working with operator overloads in PHP, I expect usage to > type against a specific class implementing operator overloading, say Money, > rather than typing against something like Addable&Multiplyable. The latter > would accept both Money and Matrix, both of which have entirely different > rules on the kinds of operands they accept, even if they are, in some > sense, addable and multiplyable. > > Regards, > Nikita > To be honest, I don't imagine there are many cases where the __add() method would use the Addable interface (assuming it existed) as a way to type the second operand. That would only guarantee that the *other* operand could handle the adding if it had to, but doesn't tell the called method anything about how to access the value that the object represents which needs to be added. I think it is far more likely that it'll be typed against specific classes, like you're suggesting, in almost all uses of the feature. If for no other reason than simply the fact that different values mean different things to different objects. Perhaps it would lead to a community standard around types of values that *should* be interoperable, something like a Numberlike interface, but I have purposely avoided venturing into that so far in my draft of that RFC because it seemed too opinionated to me, and I wanted to avoid getting into the domain-specific implementations that some were suggesting. That could easily spiral into a multitude of very specific implementations ending up in core, when they more naturally belong in the context aware user space of the application they are used in. I am open to suggestions on alternatives. I will also be thinking about a form this might take that would address this concern while still providing a cleaner way for engine-like object shapes to be typed. I feel like this is one of the less disruptive ways that could be done, but less disruptive obviously means that it will inherit any lingering issues that may exist in that area. Jordan --000000000000b016df05c9ae7340--