Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:120089 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 35142 invoked from network); 20 Apr 2023 20:26:44 -0000 Received: from unknown (HELO php-smtp4.php.net) (45.112.84.5) by pb1.pair.com with SMTP; 20 Apr 2023 20:26:44 -0000 Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id A94C81804D4 for ; Thu, 20 Apr 2023 13:26:42 -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, 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-yb1-f170.google.com (mail-yb1-f170.google.com [209.85.219.170]) (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 ; Thu, 20 Apr 2023 13:26:42 -0700 (PDT) Received: by mail-yb1-f170.google.com with SMTP id 3f1490d57ef6-b9268714fdfso1213089276.0 for ; Thu, 20 Apr 2023 13:26:42 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20221208; t=1682022401; x=1684614401; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:from:to:cc:subject:date:message-id:reply-to; bh=1sAplm9mfq+DCvPqP7hfVFNCRM3kEfMCqRH4xGWHai4=; b=RpOLKQCD6jjHKI6ANe76WhpJ+UNBqYl29Elup7kaShvIw2+0Qc+ZDUTZy4ayeL8pG3 AEDp+b4K9UTRIVndtyjk5C2c6b92YXqWZ5a4hFUYUBkrgyXHfwuQ5WQQfHjlSkoqURbx puJnl44KbhyFD3MrX7LYiKPGaPziCcEEAifQwlsQQ8W+J0rjbJPWBOUslawunh4HtHJg 8rlOGXSzAi0uj2/C0qKzmX/XWSbrlhXSg2zJiROSlI0UlV2EPFaJmi7IgRgMK+9hvNC5 gtZwX/sGLEg83gHiC6UMj7lxJv3fm+GGor6+0M4X5GA8D3LH3xF+9bcWJR8aRQtFBl1K kJ1w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1682022401; x=1684614401; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=1sAplm9mfq+DCvPqP7hfVFNCRM3kEfMCqRH4xGWHai4=; b=X2xFcQf60bYp9euakeI7QAy+IjOc9C84r0QJt0hCQ4+4+Y5wGp4APhmxI+SA0alUZ4 cEjCuOcGuee/uyc57E2Klw86e8/c+Of8xJvD7P57aJrYaQVC40Tw8PVWOzDZJYUDbps7 H/94G2bACqyUoUzwnArfCfwbny9xiHFh8cveMajLPIipmFLhuKUFaN9QHcrJ3kk/MeQP pvujPa2U3jjxZlTidZk+dz00+bSSRpyyjg4cDLillQIhjtUSHzy/K48hVO9xj64LwhG1 2VvUJ/Ikd2s40TpH4tyl9xJyCckCZC8h6hroBUK01zzPlDUN8d6BHPdgtpmuepfFC3yy rPXQ== X-Gm-Message-State: AAQBX9evvzB+TdJAn6A63Gr5Rx59OdPaAbjdeOR5rsq0T19m4zV6PMZc c5lH2Ybk1vcpvbswkoLPMlPw4s9DceoLq3EjqAm5t6mq97meQBSz X-Google-Smtp-Source: AKy350bBpoz5s5zHixFKHVDvu08YNQ1PFSCOZq7EWsC+oeljTj74GbHxa4MFIzNilX+KZj7cuNWU5wHjHsShohmwrJc= X-Received: by 2002:a81:ed5:0:b0:54f:6f2e:b3f5 with SMTP id 204-20020a810ed5000000b0054f6f2eb3f5mr165378ywo.13.1682022401285; Thu, 20 Apr 2023 13:26:41 -0700 (PDT) MIME-Version: 1.0 References: <6b5de716-d769-4f0b-b3e6-5a5a211f035a@app.fastmail.com> In-Reply-To: <6b5de716-d769-4f0b-b3e6-5a5a211f035a@app.fastmail.com> Date: Thu, 20 Apr 2023 22:26:30 +0200 Message-ID: To: Larry Garfield Cc: php internals Content-Type: multipart/alternative; boundary="000000000000bba25105f9ca5b52" Subject: Re: [PHP-DEV] [Discussion] Callable types via Interfaces From: michal.brzuchalski@gmail.com (=?UTF-8?Q?Micha=C5=82_Marcin_Brzuchalski?=) --000000000000bba25105f9ca5b52 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Hi > There is one loophole, in that an interface may require an __invoke() > method: > > interface TwoInts > { > public function __invoke(int $a, int $b): int; > } > > I was playing around with the code and parser for this in 2020 but my idea was to introduce a new syntax that is inspired by C# - Delegates [1] delegate Reducer (?int $sum, int $item =3D 0): int; class Foo implements Reducer { public function __invoke(?int $sum, int $item =3D 0): int { } } function reduce(Reducer $reducer) { var_dump($reducer(0, 5)); } reduce(new Foo()); reduce(fn(?int $sum, int $item =3D 0): int =3D> 8); At the same time, I assumed structural typing for closures would be used. I assumed the delegate will resolve into interface Reducer { public function __invoke(?int $sum, int $item =3D 0): int {} } I also noticed that once checked closure doesn't have to be checked against the argument types and return type because it won't change which gives some possibility to cache this type check. > The usual discussion has involved a way to specify a callable type's > signature, like so: > > function takeTwo(callable(int $a, int $b): int $c) > { > return $c(1, 2); > } > > But that runs quickly into the problem of verbosity, reusability, and typ= e > aliases, and the discussion usually dies there. > > This is why initially I thought about Delegates as in C# there are not type aliases. The delegate essentially resolves to an interface with `__invoke(?int $sum, int $item =3D 0): int` method. > ### Structural typing for closures > > The third option would necessitate having similar logic in the engine to > the first. In this case, we take a "structural typing" approach to > closures; that is, "if the types match at runtime, it must be OK." This = is > probably closest to the earlier proposals for a `callable(int $x, int $y)= : > int` syntax (which would by necessity have to be structural), but > essentially uses interfaces as the type alias. > > function takeTwo(TwoInts $c): int > { > return $c(1, 2); > } > > $result =3D takeTwo(fn(int $x, int $y): int =3D> $x + $y); > I'd love to see this happening. [1] https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/delegates= / Cheers, Micha=C5=82 Marcin Brzuchalski --000000000000bba25105f9ca5b52--