[responding to multiple people instead of spamming multiple emails, I hope
that is okay]
----

On Mon, Mar 10, 2025 at 12:38 PM Eugene Sidelnyk <zsidel...@gmail.com>
wrote:

>
> Yet, do you think it's reasonable that  "never" type should be used rather
> than "void"? From what I know, never - is a special type used when function
> never returns, and always dies or throws an exception.
>

Never is a bottom type that means "absolutely no value is possible" - for
function returns, since `return;` implicitly means `return null;` in terms
of what the caller receives (https://3v4l.org/TNBFE), the only way that
this type is usable is when the function never returns (dies or throws).

On the other hand, void is just an indication that function never returns
> (but doesn't die).
>

>From my understanding, `void` is an indication that a function returns no
value, but from a

>
> In my opinion, it would make more sense to use void parameters.
>
> Also, I remember that in C / C++ language there's such a concept as "void
> pointer", - a completely legitimate structure (likely the same concept as
> here) that could point to address of the data of any type.
>

A void pointer that can point to the address of any type is essentially the
opposite of what I am trying to accomplish - coming from C/C++, I would
assume a `void` parameter would therefore be the *top* type, allowing
anything, while `never` is meant to be the *bottom* type, allowing nothing.

----

On Mon, Mar 10, 2025 at 2:44 PM Ilija Tovilo <tovilo.il...@gmail.com> wrote:

I would have slightly preferred to investigate associated types first.
> They mostly solve the same problem, except they can express
> relationships between other parameters or return types. For example:


I had never heard of associated types before this email thread - google
suggests that they are a feature of rust and swift, neither of which I have
used.
While it certainly sounds interesting, it looks like a lot more work, and
since if we introduce associated types later we can change BackedEnum
without a BC break, I don't think a future possibility of associated types
should stand in the way of `never` types now.

----

On Mon, Mar 10, 2025 at 3:11 PM John Bafford <jbaff...@zort.net> wrote:

>
> I would point out that `never` can be conceptually represented as a
> caseless enum. Right now, code like this is valid (as in, does not produce
> errors, though in practice, it's also not callable):
>

While a caseless enum might represent the concept of a parameter than can
never be valid, subclasses cannot just widen a caseless-enum-never to just
(e.g.) an `int`, it would need to be `Never|int`. I'll leave further
discussion of caseless enums for another thread since they are not
equivalent from a type-theory perspective.

----

 On Mon, Mar 10, 2025 at 3:59 PM Rob Landers <rob@bottled.codes> wrote:

This looks interesting. I'm not sure that I like "never" as a parameter
> type and while it "technically" doesn't violate LSP, it seems like a
> backdoor to doing just that:


So the initial inspiration for this was the BackedEnum class, where it
isn't a technicality - LSP is violated when the interface allows both
strings and ints, but no actual enum can use both. I think odd code like
subclasses of `Point` not accepting reasonable things is something that
should be caught by other developers doing code review, not enforced on a
language level.

For example (https://3v4l.org/pTdMg)
```
abstract class Point {
    abstract public function add(Point $other);
    abstract public function subtract(Point $other);
}

class Vector2 extends Point {
    public function add(Point|Banana $other) {
        if (!$other instanceof Banana) {
            throw new TypeError("Point only allowed to prevent compiler
errors");
        }
        // ...rest of the function
    }
    public function subtract(Point|Football $other) {
        if (!$other instanceof Football) {
            throw new TypeError("Point only allowed to prevent compiler
errors");
        }
        // ...rest of the function
    }
}
```

There's basically only a gentleman's agreement that a subclass will
> implement things in a way that makes sense.


I think that this agreement is present for any method that isn't final, and
that doesn't change now - the only difference is that now the PHP compiler
won't get in the way

I would also personally prefer associated types: ... This at least lets you
> ensure the "other point" is the same type in both functions, though
> personally, I'd rather just have generics.


I'd also like to have generics, but that isn't something I can implement
myself. Associated types would be interesting, but I don't think that
associated types would remove the entire use-case for `never` parameters,
just perhaps the specific example of BackedEnum.

----
- Daniel

Reply via email to