Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:118398 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 66955 invoked from network); 10 Aug 2022 13:52:19 -0000 Received: from unknown (HELO php-smtp4.php.net) (45.112.84.5) by pb1.pair.com with SMTP; 10 Aug 2022 13:52:19 -0000 Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 979C41804BA for ; Wed, 10 Aug 2022 08:54:07 -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.6 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_ENVFROM_END_DIGIT, FREEMAIL_FROM,FREEMAIL_REPLYTO_END_DIGIT,HTML_MESSAGE, RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H3,RCVD_IN_MSPIKE_WL,SPF_HELO_NONE, SPF_PASS,T_SCC_BODY_TEXT_LINE 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-pj1-f47.google.com (mail-pj1-f47.google.com [209.85.216.47]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (P-256) server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by php-smtp4.php.net (Postfix) with ESMTPS for ; Wed, 10 Aug 2022 08:54:07 -0700 (PDT) Received: by mail-pj1-f47.google.com with SMTP id c19-20020a17090ae11300b001f2f94ed5c6so3535565pjz.1 for ; Wed, 10 Aug 2022 08:54:07 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=cc:to:subject:message-id:date:from:reply-to:in-reply-to:references :mime-version:from:to:cc; bh=GRvbWRk+O4Bzn+WH+BSjID+8SCSbVmGSUdsnKPVLv5A=; b=RskEBSzYfyXrWxuWLAWzw7jQEjT49PnmenIUebS74KP+Y0RoQOqMSJ24l25OlVUsJ+ 26cgmU5zjqXhcN4YTWqsFgt6WP63XC1oY3UBO8/4l3XVkZ+bD50c8bHCxilbM6vhz+vU vYaLOb2jchac0cpZLdAU9vmftbJu8reF/VtOOgbUAeyw28+/ZSV4VTHSVKSMRAXVxOsR je0bQpH0fSbVHQQvBgfDcnvQmTcWH/hFNjO2MTS1+rCRK58JOBbgNkVtWSMHJcQ8J0wg tGsGEA3dUdAyniJqAtRrgtptb2lHhFwyZrpl8jRTrFg3PLiIOmqUtIfDehNnpZfE6uwp /GrQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:subject:message-id:date:from:reply-to:in-reply-to:references :mime-version:x-gm-message-state:from:to:cc; bh=GRvbWRk+O4Bzn+WH+BSjID+8SCSbVmGSUdsnKPVLv5A=; b=4cKZMH19MnNgkuHCxh5UzDZMzBSUUXt1yqcpSq36RZdsynsl5i26s6I4UM4j42vcYH fpP2j+oUCY0SWQsNj7kg6qfhr3RGk2hE16ZUXxxVHTZuXZ8Ss4+CUI7MsYKlYEnZ1z4S pgLgL7Z2K8wT4YDEyt+54N9Hj/Eqk8Vzz0QtJ9zj8qfphfNx7263OO24C6Wl3QquM1Vl ld/kNDS508Im40cg6CWqahDPIIHbnnPwp52ijof9G4J2czA1qQo0gXE8/rf8TEbS4RIw PHICLmr/rRLLgS2Rvy5hpTmyLWCbpS+LBoxpO812HnMtCr0ETOQrLzAJEN2XNRA7tjmX MAtA== X-Gm-Message-State: ACgBeo3m3xED5ovDL2U0JpnvSXlUlOPQuetlUYnIUbybZTzGRzkHCmc4 3Uq/Ipnb4mak7s8LUgHvUY5YAXM3oDV7VZmkryM= X-Google-Smtp-Source: AA6agR7SmnI8yroK3NQd8UFDQiByCxCNaDzXi44mnGAOnYeSPFjbTit5sA6Wm1aruDFCeWoqZVyZUHF6Clz8FpIfSdQ= X-Received: by 2002:a17:90a:6007:b0:1f3:3527:609e with SMTP id y7-20020a17090a600700b001f33527609emr4449101pji.52.1660146846077; Wed, 10 Aug 2022 08:54:06 -0700 (PDT) MIME-Version: 1.0 References: In-Reply-To: Reply-To: autaut03@gmail.com Date: Wed, 10 Aug 2022 18:53:54 +0300 Message-ID: To: Deleu Cc: Levi Morrison , internals@lists.php.net Content-Type: multipart/alternative; boundary="0000000000000916d405e5e50fd0" Subject: Re: [PHP-DEV] [Concept] Extension methods From: autaut03@gmail.com (Alex Wells) --0000000000000916d405e5e50fd0 Content-Type: text/plain; charset="UTF-8" I believe disallowing multiple extensions on one type defeats one of the purposes of the feature - extending from outside. Let's say you have a vendor package for manipulating strings which defines an extension on `string` type. It works, but then you need one more custom extensions - some kind of `replaceLastRegex` method. You define it in your own extension, but then you're either missing the vendor package methods or your own extensions. This might even make people avoid extensions, because there would be no way to use both extensions, hence making them extract those into functions. I think that if the goal is to avoid the confusion and/or mess, we could force specifying the when using the extension. It would then be crystal clear where the method is coming from and also it'd be trivial to check whether method names are conflicting between extensions. The syntax is just a demonstration: `use extension App\Whatever\CollectionExtension as Illuminate\Collection::map;` On Wed, Aug 10, 2022 at 6:28 PM Deleu wrote: > > > On Wed, Aug 10, 2022 at 5:16 PM Levi Morrison via internals < > internals@lists.php.net> wrote: > >> > What are your thoughts? >> >> It's a fantastic feature that I've used in Rust, although there are >> some differences. First, it doesn't work for regular methods -- they >> have to be part of a trait. Secondly, in general a trait can only be >> implemented for a given type if it is in the package which defines >> that type, or in the package which defines the trait. Third, the trait >> must be in scope. These rules help people understand where the methods >> are coming from, which is particularly helpful for large code bases or >> teams. >> >> PHP doesn't really have tools for these kinds of restrictions, but I >> think it's necessary. You'd need some way to manage where extension >> methods are loaded, how they are found, and without pessimizing >> performance of method calls in general just because this feature >> exists. >> >> -- >> PHP Internals - PHP Runtime Development Mailing List >> To unsubscribe, visit: https://www.php.net/unsub.php >> >> > As I was thinking about how this feature would be cool, I was also worried > about how big of a mess it could become, given the lack of restrictions you > pointed out here. However, knowing how PHP works, I wonder if the following > could be made possible: > > ``` > // Vendor File > namespace Illuminate\Support; > > class Collection {} > > // Extension File > namespace App\Whatever; > > extension LaravelCollection on Collection {} > > // Usage File > namespace App\Business; > > use App\Whatever\Laravelcollection; > > $collection = (new Collection())->extensionMethodAvailableHere(); > ``` > > The goal here is to > 1- Disallow `use Class; use ExtensionClass` simultaneously (conflicting > symbols on compile-time?) > 2- Bind the Base-class Symbol through the ExtensionClass symbol > 3- Disallow two extensions to compete with each other > 4- The user would always know that a symbol has a method either via > 1-level extension or from the original class directly - it doesn't come > from unknown places > > I feel like this would be powerful enough to solve a lot of usability on > PHP OOP while not being crazy enough to create a nightmare on codebases and > the internals of the PHP Engine. Does this make sense? > > -- > Marco Deleu > --0000000000000916d405e5e50fd0--