[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