Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:111851 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 3383 invoked from network); 13 Sep 2020 18:50:50 -0000 Received: from unknown (HELO php-smtp4.php.net) (45.112.84.5) by pb1.pair.com with SMTP; 13 Sep 2020 18:50:50 -0000 Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 77ED81804C3 for ; Sun, 13 Sep 2020 10:58:29 -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.9 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,HTML_MESSAGE,RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H2, SPF_HELO_NONE,SPF_NONE autolearn=no autolearn_force=no version=3.4.2 X-Spam-Virus: No X-Envelope-From: Received: from mail-wr1-f53.google.com (mail-wr1-f53.google.com [209.85.221.53]) (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 ; Sun, 13 Sep 2020 10:58:28 -0700 (PDT) Received: by mail-wr1-f53.google.com with SMTP id e16so16298512wrm.2 for ; Sun, 13 Sep 2020 10:58:28 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=beberlei-de.20150623.gappssmtp.com; s=20150623; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=B3yNV3Ud20/QOLMi0LUULogrPqMxZTaN72q1/CvGF9A=; b=t27ezO6tFJ5RQbY8hvzO30+2nfOhWvboHpJoamp9YIRKQKz+Ghu5O1xWZ5g4ge6VXe kGG4blSw7eQxEpZROuimXhj47Hz16Ro4VkueWOgfqFKMyld+UDaRYtvQfPh49Y1CDaCP e/E2CeWnnv0x1UPbnwj3N/MuPL5pAQfWgI91x6Jpk6GGUCUQm59qpdDi4UtHgfzRJSJW Q6ODL/LE1/mNqle/6n8bZ8Vq+aiRMd8jDDmnNlg9zdswQMd9VanhogRYNYVYD5jy35hr 3szUhMxNhL37bFpESmPRWAwIWu9oz3Vmobt5Q3a6KkrpDrPl+j8O8YqHYHmD4DaxKYO9 MKXw== 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=B3yNV3Ud20/QOLMi0LUULogrPqMxZTaN72q1/CvGF9A=; b=hf9vw3RbjiL4WjT0Gd9y4AjJ0fYR8CIIvB/+75yi5rYfQptw1Z2Y+tstwcsL4lhhaI bMqz3DlqPnljl2KS+i7TKmkImCfLe5UNNz1DvPpQQSAd8L4pISkoWeCZ9hy78Zy+e4wc NdqavvQVw7uD+6ixxjKajXPHaz6FzEUCxer/nPjR8Hse3ZnUo0JSLhXE3vo/pIWkoRq4 SsWOFwZx7OQFs8mwUYreQOepwMQ1Yun3AiOeaPhqtBU5BciAKLwFKwC+ymRsyq4FCE15 4P9SNrRbvGn9/yERtgZy36wsPZLqapqlYefhMoQ0VE8crlDFj86y762oKm/3/QzXXPld vzVw== X-Gm-Message-State: AOAM5334xQGOn442a7iX2BGvqxlueaLakms8X6/f0R8uEhPBdyW25Q6P +j1EdGXQT09+l+sRiYK/x3ChX2QA0zu4GQc0zXwj4Q== X-Google-Smtp-Source: ABdhPJyPIRvTvlj4bgZFldmnWN6ruhlnogWeD8uSbUhBqHhyuGNlsXzPxo8lLJpn9qrN+VaUtLfz3ii26Xuj+fIUv1M= X-Received: by 2002:adf:e488:: with SMTP id i8mr12740385wrm.116.1600019903069; Sun, 13 Sep 2020 10:58:23 -0700 (PDT) MIME-Version: 1.0 References: In-Reply-To: Date: Sun, 13 Sep 2020 19:58:12 +0200 Message-ID: To: =?UTF-8?Q?Olle_H=C3=A4rstedt?= Cc: PHP Internals Content-Type: multipart/alternative; boundary="000000000000f4d73405af35a90b" Subject: Re: [PHP-DEV] Add interface implementation to class in separate file From: kontakt@beberlei.de (Benjamin Eberlei) --000000000000f4d73405af35a90b Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable On Sat, Sep 12, 2020 at 10:23 PM Olle H=C3=A4rstedt wrote: > Hi internals! > > Separation of data and behaviour is both a fun and hard discussion, > especially considering: > > * "It should be possible to add new features without touching old code"; > and > * "Principle of Least Privilege" (never expose more than you have to) > (https://en.wikipedia.org/wiki/Principle_of_least_privilege). > > There should (could) be a way to add new behaviour to old data without > touching the old data (class). Traits won't work in this use-case, > since they assume the same internal structure for all trait-using > classes. Imagine the `stringable` interface and a `toString` trait. A > __toString() method needs knowledge about the internal structure of a > class Foo. Yet if we want to keep adding behaviour to Foo, we'll end > up with either exposing too much of Foo, or expanding the class file > indefinitely. Please note that composition is not a proper solution, > since it requires exposure of Foo; composition leads to lack of proper > encapsulation, or representation exposure. > > In Haskell it's possible to split instance implementation of > type-classes into separate files. In Rust you can have a struct with > private fields and put impl of behaviour in different files (but same > crate). > > A similar feature in PHP could look like (using new keyword `expand` > but could be anything, or even `extend` in new context): > > ``` > // File FooStringable.php > expand Foo implements stringable { > public function __toString() { > // Full access to Foo's all private fields here. > // Assumes you can autoload Foo. > // Assumes usage of $foo->__toString(); will be configured with > autoload to dynamically find the correct behaviour of Foo. > } > } > ``` > > If you'd use composition instead, you'd maybe have a formatter class > with a method `$formatter->toString(stringable $foo)`. This has the > problem I mentioned with exposing too much of $foo; it breaks > encapsulation. It has the benefit of being able to provide multiple > toString methods with different formats, but would have to assume > similar structure of the objects passed to it (defined with an > interface), which is not always possible or desirable. > > The other way is inheritance, which doesn't scale over multiple > behaviours. `FooWithStringable extends Foo`? No. > > Was I clear here? Do you understand the issues that this design > pattern is trying to solve? Its purpose is to solve "keep adding new > feature to old data" in a clean and proper way, while keeping > information encapsulation. > Do I understand you correctly, it would be somewhat like "opening" up a class and making changes to it in another file? Certainly a powerful concept, but I would be very interested in the details how that would interact with autoloading. If I have a class Foo loaded, and its "extension" FooString with toString method not, then it would lead to the "toString" code missing. > > Enjoy the weekend! > Olle > > -- > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: https://www.php.net/unsub.php > > --000000000000f4d73405af35a90b--