Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:115739 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 76903 invoked from network); 15 Aug 2021 11:09:20 -0000 Received: from unknown (HELO php-smtp4.php.net) (45.112.84.5) by pb1.pair.com with SMTP; 15 Aug 2021 11:09:20 -0000 Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 2513B1804BD for ; Sun, 15 Aug 2021 04:41:04 -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-io1-f53.google.com (mail-io1-f53.google.com [209.85.166.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, 15 Aug 2021 04:41:03 -0700 (PDT) Received: by mail-io1-f53.google.com with SMTP id e186so19302104iof.12 for ; Sun, 15 Aug 2021 04:41:03 -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=s2xwz8Ogw983fWy3Jvf0ekNzfH2y/VVkYMrFuV2W9hY=; b=diyjp0q+mTwADH7PEKXSp+wFne/ZY2fZkKjztfGSRvxXhl1DpAcv3JoPBl8twbQdU2 r1oAXndu0r0Uups7ph1lT+IHG94Y4i/NfbM8U8X299VRBsqZM2DCDHj7+stYLaOe7DZ/ iCU0FR3UYPw2aB4zhYzv2eb9oKZ1+WCZDWgtMSV6qGG7hLWjJOMRqn9yqaybH1eN+zZf KxUA9NZ9ycMrCR8+wwdeZeN8qR62BzJHzsrimJyXWJ99hC02rZyGEoGxhoLcGbQdqxqh DHVeX5SYV+mZqJ7wMtynElQfi+1/G+5MdUNU4HdP5GgQ6qXcM51ksGh2vH53b/nvVhe7 wCiQ== 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=s2xwz8Ogw983fWy3Jvf0ekNzfH2y/VVkYMrFuV2W9hY=; b=OkPtXnVvUO4/yVdU59iTV6vZlW+aBgYeWLfs2GtZNDOb/9aLx8nGa18gccwIKj1plU bj96kplHLUkctD3ApQGPeYUuwAap9oQwzlWhQ61U4qhb3udxj4lt6S++cc8egG9wQS34 a+kIamOLe17se3+14xSGm7WUVXhfmK6TheImXI7w8pWCdtTsxvRb2U5Y4z5PuoZvl9Vv f1NX/svfiuC2euBCk+P5UVX9X+QCsOeDkJarZ1SxlC1JcvCVY+EYjs89kxHkj+lpkXOj ejlb4wmH2CnmgZqvQwYFnwTW7Mw19+10SwqLg2BsJPRcfmwNnhWfhLu+v/M3nkhLHnOd qLkw== X-Gm-Message-State: AOAM530le2HoovbYU/wrspF6Rxi4vpSAEp7AM4vQGhDJbA3cWgtIMSS/ ekQfuy8UJrcS8JjvXUd5DCPCiilhWLGSLOGbweE= X-Google-Smtp-Source: ABdhPJwFdgUI9ouM1R5TR7ekzrKPxVvf8JFskawcS4Fkf3ILw5jO/BWlxYeSPuAPL+nUPB6LGmodK2ai07rOTzDi4Uc= X-Received: by 2002:a5e:961a:: with SMTP id a26mr8745357ioq.90.1629027661588; Sun, 15 Aug 2021 04:41:01 -0700 (PDT) MIME-Version: 1.0 References: In-Reply-To: Date: Sun, 15 Aug 2021 13:40:36 +0200 Message-ID: To: Jordan LeDoux Cc: PHP internals Content-Type: multipart/alternative; boundary="000000000000192c4a05c9978f15" Subject: Re: [PHP-DEV] [RFC] Never For Argument Types From: kjarli@gmail.com (Lynn) --000000000000192c4a05c9978f15 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable On Sun, Aug 15, 2021 at 1:11 PM Jordan LeDoux wrote: > > So your intuition is correct. `foo(never $something)` will result in a > `TypeError` if you try to call it directly. The only way it can be called > is by being overridden with a wider type, which is why most of the focus = is > around inheritance. Technically, you *could* use it in a function and tha= t > would make the function uncallable, because any function with a parameter > of type never is uncallable unless it is overridden and widened. > > This is in line with type theory for how bottom types work in other > languages as well. > > My biggest worry about using something besides `never` is that it *is* th= e > bottom type already. It's only usable in return types, but within the > engine it *is* the bottom type. That's what the bottom type in a type > system generally means: this can't be used and/or the program stops if th= is > is used. If we made a bottom type for returns (which we have), and then > made a *different* bottom type for arguments, we'd be in a situation that > is unique in programming languages as far as I can tell. I have done a bi= t > of research into this as part of the RFC, and I haven't found a single > language with multiple bottom types. :/ > > TypeScript, Elm, and PHP have the bottom type `never`. Ceylon, Kotlin, an= d > Scala have the bottom type `Nothing`. Rust has the bottom type `!`, > JavaScript with Closure Compiler annotations has `!Null` (which is intend= ed > to mean a non-null member of the null type), Julia has `Union{}`, Python > has `typing.NoReturn`, and Lisp has `NIL`. > > None of them (so far) have multiple bottom types for different > circumstances. > > And the meaning of the type isn't *exactly* "any". It's more like "none". > But the type `string` contains the "none" concept also. You take "none" a= nd > then you add the parts that make a string type to "none", and what you're > left with is just the string type. That's why it can be broadened to > anything, because *all* types contain `never`, just like you can subtract= 0 > from any integer. > > I have been focusing on the use cases, which are about how this interacts > with widening and inheritance. But the type itself I would argue is fully > descriptive where it is defined: that code can never be called due to the > type on the parameter being never. It must be inherited. If we did > something like `any`, that would indicate that the intent for inheritance > more clearly, but think about the code it's actually defined in. If you h= ad > the following code: > > ``` > class A { > public function doSomething(any $var): string { > } > } > ``` > > Would you expect calling that method to result in a `TypeError`? Because > that's what *should* happen. The code it is actually written in cannot > accept `any` type, in fact it can `never` accept a type. > > Jordan > > So the `never` just tells the developer "extend/implement me with a type", that makes sense to me. Having multiple bottom types (and thus most likely aliases) would probably make it even more confusing, you're right that this is probably the best course of action =F0=9F=91=8D --000000000000192c4a05c9978f15--