Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:120093 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 48309 invoked from network); 20 Apr 2023 23:23:31 -0000 Received: from unknown (HELO php-smtp4.php.net) (45.112.84.5) by pb1.pair.com with SMTP; 20 Apr 2023 23:23:31 -0000 Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id CA55D1804AA for ; Thu, 20 Apr 2023 16:23:26 -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,RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2,SPF_HELO_NONE,T_SCC_BODY_TEXT_LINE,T_SPF_TEMPERROR 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-wm1-f51.google.com (mail-wm1-f51.google.com [209.85.128.51]) (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 16:23:26 -0700 (PDT) Received: by mail-wm1-f51.google.com with SMTP id 5b1f17b1804b1-3f191c1a8a7so732805e9.1 for ; Thu, 20 Apr 2023 16:23:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=datadoghq.com; s=google; t=1682033005; x=1684625005; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:from:to:cc:subject:date :message-id:reply-to; bh=392aposod3b8sBMLFOW2g0yVh9FDYa0s73TygoWl8LM=; b=bIXzbTNxwujy8u4d5+MKYchD0O8wR0fYyjpWP0t20WR8PxzVxbD/DqfMEcpPt2Jqgm Iqu+bKHXT33D9iY206wPylAH5XkVpnzXhzTX/5jAMtCZuHaxhQOCQasdgYx1y7tjyUly hG4isv4A8rCYDu25nw3Arz7fwPYCIaO4MY7NQ= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1682033005; x=1684625005; h=content-transfer-encoding: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=392aposod3b8sBMLFOW2g0yVh9FDYa0s73TygoWl8LM=; b=HwqKyk27Lmztm+CFKZDbrLG7q3DHrIAsCjhwRM3ssLMy+VJzpIPcbZDMObNk1r06XH Hn9JwcKA4ES7IYd5/L5luZcV9uhzmgdS8y/bimXqBd6irqAngMfzlZAG0APSji3bIri1 GWcOFMYnhRtxEd8xNnDmyLtnAXd3/0aaVVjbVGFdIz3l3kBoXo/qZhSDgVC0X49TZ/4X XnRWGiTqUjW5svpLZvpMNK0Pq9Ow/35aSn9c1RhYi2PjNoMVz390SYwRnzE38zj15E6Q /mL4Pc1lxtR4r8B8RsEcl/g/b7NWcVPFpiqj+UnacEKlwx7P0nPE89fm+9KzGB3+g36X xFUg== X-Gm-Message-State: AAQBX9eHmjhtoWLgqvulvtDtse9Tu2YI7ankBR0Ah7R2qDNZEv3mCAho raYokgAsTRXGXmwdDSnBTXTVTbmrM9uMNb7x5y0rlJw2YPwND6wSjiWRBr8B X-Google-Smtp-Source: AKy350ZbIhcefD0vSlTYKHiqnbGrg3bXunZkTHl+9uxkpFN1MdVxP7+uAE9eepsHf42inQCKSs0imKv59tkw9rYS+Uw= X-Received: by 2002:a5d:428f:0:b0:2d4:751d:675b with SMTP id k15-20020a5d428f000000b002d4751d675bmr2359094wrq.35.1682033004763; Thu, 20 Apr 2023 16:23:24 -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> Reply-To: Levi Morrison Date: Thu, 20 Apr 2023 17:23:13 -0600 Message-ID: To: Larry Garfield Cc: php internals Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Subject: Re: [PHP-DEV] [Discussion] Callable types via Interfaces From: internals@lists.php.net ("Levi Morrison via internals") On Thu, Apr 20, 2023 at 11:25=E2=80=AFAM Larry Garfield wrote: > > Hi folks. This is a pre-discussion, in a sense, before a formal RFC. Ni= colas Grekas and I have been kicking around some ideas for how to address t= he desire for typed callables, and have several overlapping concepts to con= sider. Before going down the rabbit hole on any of them we want to gauge t= he general feeling about the approaches to see what is worth pursuing. > > We have three "brain dump" RFCs on this topic, although these are all sti= ll in super-duper early stages so don't sweat the details in them at this p= oint. We just want to discuss the basic concepts, which I have laid out be= low. > > https://wiki.php.net/rfc/allow_casting_closures_into_single-method_interf= ace_implementations > https://wiki.php.net/rfc/allow-closures-to-declare-interfaces-they-implem= ent > https://wiki.php.net/rfc/structural-typing-for-closures > > ## The problem > > function takeTwo(callable $c): int > { > return $c(1, 2); > } > > Right now, we have no way to statically enforce that $c is a callable tha= t takes 2 ints and returns an int. We can document it, but that's it. > > There is one loophole, in that an interface may require an __invoke() met= hod: > > interface TwoInts > { > public function __invoke(int $a, int $b): int; > } > > And then a class may implement TwoInts, and takeTwo() can type against Tw= oInts. However, that works only for classes, which are naturally considera= bly more verbose than a simple closure and represent only a subset of the p= ossible callable types. > > The usual discussion has involved a way to specify a callable type's sign= ature, 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. > I'm going to stop here. Two big things: 1. I think reducing verbosity can be left for the future. We don't have to solve that right now. 2. I think there's another more important reason previous attempts failed: they will inevitably burden the programmer without type inference.For the moment, let's assume this signature: function takeTwo(callable(int $x, int $y): int $c); What happens if I pass a short-closure? takeTwo(fn ($x, $y) =3D> $x + $y); I would be annoyed if I had to write the type info, but particularly the return type. Today, if I just used a static analysis tool, there's no problem: /** @param callable(int $x, int $y): int $c */ function takeTwo(callable $c); takeTwo(fn ($x, $y) =3D> $x + $y); 3. And another reason they failed: callables are going to want generic types pretty commonly. Think array_filter, array_map, etc. So, I think these brain dump RFCs are all focusing on the wrong problems.