digitalmars.D.learn - Unexpectedly nice case of auto return type
- Basile B. (29/29) Dec 02 2019 I wish something like this was possible, until I change the
- Basile B. (13/42) Dec 02 2019 Actually I think this can work because of a Tnull (internal
- Andrea Fontana (4/10) Dec 03 2019 Why not [1]?
- Basile B. (3/15) Dec 03 2019 Yeah nice, that works instead of auto.
- Basile B. (7/26) Dec 03 2019 You see what surprises me here is that we cannot express the
- Andrea Fontana (3/7) Dec 03 2019 You can still create an alias anyway :)
- mipri (24/31) Dec 03 2019 Speaking of nice stuff and aliases, suppose you want to
- mipri (5/20) Dec 03 2019 Option 4: typeof(return)
- Adam D. Ruppe (2/3) Dec 03 2019 typeof(return) is super cool for like option type things too!
- H. S. Teoh (7/11) Dec 03 2019 typeof(return) is one of the lesser known cool things about D that make
- Adam D. Ruppe (5/8) Dec 03 2019 you know i probably will write about that next week. so be sure
- Basile B. (2/29) Dec 04 2019 aha nice
- Jonathan M Davis (11/40) Dec 03 2019 The void* version doesn't work, because void* doesn't implicitly convert...
- Basile B. (6/56) Dec 03 2019 That's interesting details of D developement. Since you reply to
- Mike Parker (2/6) Dec 03 2019 https://github.com/dlang/DIPs/blob/40352337053998885fbd0fe2718c300a322d3...
- Mike Parker (3/10) Dec 03 2019 Ah, well. I meant to post the link to the PR:
- Johannes Loher (8/15) Dec 06 2019 This is everything I wished for. It basically exactly resembles
- mipri (30/47) Dec 06 2019 nice.
- Jonathan M Davis (15/82) Dec 03 2019 There isn't much point in giving the type of null an explicit name given
- Basile B. (5/19) Dec 03 2019 you're right but I see two cases:
- Jonathan M Davis (22/44) Dec 03 2019 I don't see why either of those would be a problem. For a transpiler,
- Basile B. (7/94) Dec 04 2019 I think that any internal compiler types that are also things in
- H. S. Teoh (24/35) Dec 03 2019 Just add this line somewhere in object.d and we're good to go:
- Paul Backus (5/7) Dec 03 2019 This is incorrect. `void` as a return type is a unit type; that
- H. S. Teoh (7/15) Dec 03 2019 Ah, my bad. See? This whole `void` business just throws me off. No
- Meta (12/14) Dec 03 2019 Not *quite* correct. void is not a bottom type; it's a unit type,
- Meta (2/11) Dec 03 2019 Whoops, skimmed over the post already mentioning this.
I wish something like this was possible, until I change the return type of `alwaysReturnNull` from `void*` to `auto`. --- class A {} class B {} auto alwaysReturnNull() // void*, don't compile { writeln(); return null; } A testA() { return alwaysReturnNull(); } B testB() { return alwaysReturnNull(); } void main() { assert( testA() is null ); assert( testB() is null ); } --- OMG, isn't it nice that this works ? I think that this illustrates an non intuitive behavior of auto return types. One would rather expect auto to work depending on the inner return type.
Dec 02 2019
On Tuesday, 3 December 2019 at 07:12:18 UTC, Basile B. wrote:I wish something like this was possible, until I change the return type of `alwaysReturnNull` from `void*` to `auto`. --- class A {} class B {} auto alwaysReturnNull() // void*, don't compile { writeln(); return null; } A testA() { return alwaysReturnNull(); } B testB() { return alwaysReturnNull(); } void main() { assert( testA() is null ); assert( testB() is null ); } --- OMG, isn't it nice that this works ? I think that this illustrates an non intuitive behavior of auto return types. One would rather expect auto to work depending on the inner return type.Actually I think this can work because of a Tnull (internal compiler type) inference which can always implictly be converted to the static return type (A or B, or even int*): auto alwaysReturnNull()// `auto` is translated to Tnull by inference because of `return null` then: A testA() { return alwaysReturnNull(); // Tnull can be implictly converted to A } still nice tho.
Dec 02 2019
On Tuesday, 3 December 2019 at 07:24:31 UTC, Basile B. wrote:A testA() { return alwaysReturnNull(); // Tnull can be implictly converted to A } still nice tho.Why not [1]? [1] typeof(null) alwaysReturnNull() { ... } Andrea
Dec 03 2019
On Tuesday, 3 December 2019 at 08:47:45 UTC, Andrea Fontana wrote:On Tuesday, 3 December 2019 at 07:24:31 UTC, Basile B. wrote:Yeah nice, that works instead of auto. That reminds me of the discussion about TBottom.A testA() { return alwaysReturnNull(); // Tnull can be implictly converted to A } still nice tho.Why not [1]? [1] typeof(null) alwaysReturnNull() { ... } Andrea
Dec 03 2019
On Tuesday, 3 December 2019 at 09:44:20 UTC, Basile B. wrote:On Tuesday, 3 December 2019 at 08:47:45 UTC, Andrea Fontana wrote:You see what surprises me here is that we cannot express the special type that is `TypeNull` and that can only have one value (`null`) so instead we have to use `auto` or `typeof(null)`. Making this type public would make the logic more clear: when `null` is used it's not a value but rather a value of a type that is convertible to all pointers or reference types.On Tuesday, 3 December 2019 at 07:24:31 UTC, Basile B. wrote:Yeah nice, that works instead of auto. That reminds me of the discussion about TBottom.A testA() { return alwaysReturnNull(); // Tnull can be implictly converted to A } still nice tho.Why not [1]? [1] typeof(null) alwaysReturnNull() { ... } Andrea
Dec 03 2019
On Tuesday, 3 December 2019 at 09:48:39 UTC, Basile B. wrote:You see what surprises me here is that we cannot express the special type that is `TypeNull` and that can only have one value (`null`) so instead we have to use `auto` or `typeof(null)`.You can still create an alias anyway :) alias TypeNull = typeof(null);
Dec 03 2019
On Tuesday, 3 December 2019 at 10:02:47 UTC, Andrea Fontana wrote:On Tuesday, 3 December 2019 at 09:48:39 UTC, Basile B. wrote:Speaking of nice stuff and aliases, suppose you want to return a nice tuple with named elements? Option 1: auto auto option1() { return tuple!(int, "apples", int, "oranges")(1, 2); } Option 2: redundancy Tuple!(int, "apples", int, "oranges") option2() { return tuple!(int, "apples", int, "oranges")(1, 2); } Option 3: an alias alias BadMath = Tuple!(int, "apples", int, "oranges"); BadMath option3() { return BadMath(1, 2); } It wasn't obvious to me that BadMath(...) would work. It *should* be obvious since this also works: ... return Tuple!(int, "apples", int, "oranges")(1, 2); But the convenience of tuple() helped to mask that. I was going with silly stuff like ... return cast(BadMath) tuple(1, 2);You see what surprises me here is that we cannot express the special type that is `TypeNull` and that can only have one value (`null`) so instead we have to use `auto` or `typeof(null)`.You can still create an alias anyway :) alias TypeNull = typeof(null);
Dec 03 2019
On Tuesday, 3 December 2019 at 10:13:30 UTC, mipri wrote:Speaking of nice stuff and aliases, suppose you want to return a nice tuple with named elements? Option 1: auto auto option1() { return tuple!(int, "apples", int, "oranges")(1, 2); } Option 2: redundancy Tuple!(int, "apples", int, "oranges") option2() { return tuple!(int, "apples", int, "oranges")(1, 2); } Option 3: an alias alias BadMath = Tuple!(int, "apples", int, "oranges"); BadMath option3() { return BadMath(1, 2); }Option 4: typeof(return) Tuple!(int, "apples", int, "oranges") option4() { return typeof(return)(1, 2); }
Dec 03 2019
On Tuesday, 3 December 2019 at 23:44:59 UTC, mipri wrote:Option 4: typeof(return)typeof(return) is super cool for like option type things too!
Dec 03 2019
On Wed, Dec 04, 2019 at 01:01:04AM +0000, Adam D. Ruppe via Digitalmars-d-learn wrote:On Tuesday, 3 December 2019 at 23:44:59 UTC, mipri wrote:typeof(return) is one of the lesser known cool things about D that make it so cool. Somebody should write an article about it to raise awareness of it. :-D T -- An imaginary friend squared is a real enemy.Option 4: typeof(return)typeof(return) is super cool for like option type things too!
Dec 03 2019
On Wednesday, 4 December 2019 at 01:28:00 UTC, H. S. Teoh wrote:typeof(return) is one of the lesser known cool things about D that make it so cool. Somebody should write an article about it to raise awareness of it. :-Dyou know i probably will write about that next week. so be sure to like, comment, and subscribe so you never miss my next post and then give me all your money on patreon so i can keep bringing you content :P :P
Dec 03 2019
On Wednesday, 4 December 2019 at 03:17:27 UTC, Adam D. Ruppe wrote:On Wednesday, 4 December 2019 at 01:28:00 UTC, H. S. Teoh wrote:I've just made the refact using typeof(null) and gained 78 SLOC The pattern was: void issueError(); and then in the code, in a dozen a function returning different classes types if (...) { issueError(); return null; } now this becomes: typeof(null) issueError(); if (...) return issueError(); I wish I knew that trick before. I prefer typeof(null) in case I would translate to another language. I tend to type the static type when I know it anyway.typeof(return) is one of the lesser known cool things about D that make it so cool. Somebody should write an article about it to raise awareness of it. :-Dyou know i probably will write about that next week. so be sure to like, comment, and subscribe so you never miss my next post and then give me all your money on patreon so i can keep bringing you content :P :P
Dec 04 2019
On Wednesday, 4 December 2019 at 12:54:34 UTC, Basile B. wrote:On Wednesday, 4 December 2019 at 03:17:27 UTC, Adam D. Ruppe wrote:more -520 lines today.On Wednesday, 4 December 2019 at 01:28:00 UTC, H. S. Teoh wrote:I've just made the refact using typeof(null) and gained 78 SLOC The pattern was: void issueError(); and then in the code, in a dozen a function returning different classes types if (...) { issueError(); return null; } now this becomes: typeof(null) issueError(); if (...) return issueError(); I wish I knew that trick before. I prefer typeof(null) in case I would translate to another language. I tend to type the static type when I know it anyway.typeof(return) is one of the lesser known cool things about D that make it so cool. Somebody should write an article about it to raise awareness of it. :-Dyou know i probably will write about that next week. so be sure to like, comment, and subscribe so you never miss my next post and then give me all your money on patreon so i can keep bringing you content :P :P
Dec 06 2019
On Tuesday, 3 December 2019 at 23:44:59 UTC, mipri wrote:On Tuesday, 3 December 2019 at 10:13:30 UTC, mipri wrote:aha niceSpeaking of nice stuff and aliases, suppose you want to return a nice tuple with named elements? Option 1: auto auto option1() { return tuple!(int, "apples", int, "oranges")(1, 2); } Option 2: redundancy Tuple!(int, "apples", int, "oranges") option2() { return tuple!(int, "apples", int, "oranges")(1, 2); } Option 3: an alias alias BadMath = Tuple!(int, "apples", int, "oranges"); BadMath option3() { return BadMath(1, 2); }Option 4: typeof(return) Tuple!(int, "apples", int, "oranges") option4() { return typeof(return)(1, 2); }
Dec 04 2019
On Tuesday, December 3, 2019 12:12:18 AM MST Basile B. via Digitalmars-d- learn wrote:I wish something like this was possible, until I change the return type of `alwaysReturnNull` from `void*` to `auto`. --- class A {} class B {} auto alwaysReturnNull() // void*, don't compile { writeln(); return null; } A testA() { return alwaysReturnNull(); } B testB() { return alwaysReturnNull(); } void main() { assert( testA() is null ); assert( testB() is null ); } --- OMG, isn't it nice that this works ? I think that this illustrates an non intuitive behavior of auto return types. One would rather expect auto to work depending on the inner return type.The void* version doesn't work, because void* doesn't implicitly convert to a class type. It has nothing to do with null. auto works thanks to the fact that typeof(null) was added to the language a while back, and since class references can be null, typeof(null) implicitly converts to the class type. Before typeof(null) was added to the language, null by itself had no type, since it's just a literal representing the null value for any pointer or class reference. The result was that using null in generic code or with auto could run into issues. typeof(null) was added to solve those problems. - Jonathan M Davis
Dec 03 2019
On Tuesday, 3 December 2019 at 09:58:36 UTC, Jonathan M Davis wrote:On Tuesday, December 3, 2019 12:12:18 AM MST Basile B. via Digitalmars-d- learn wrote:That's interesting details of D developement. Since you reply to the first message I think you have not followed but in the last reply I told that maybe we should be able to name the type of null. I think this relates to TBottom too a bit.I wish something like this was possible, until I change the return type of `alwaysReturnNull` from `void*` to `auto`. --- class A {} class B {} auto alwaysReturnNull() // void*, don't compile { writeln(); return null; } A testA() { return alwaysReturnNull(); } B testB() { return alwaysReturnNull(); } void main() { assert( testA() is null ); assert( testB() is null ); } --- OMG, isn't it nice that this works ? I think that this illustrates an non intuitive behavior of auto return types. One would rather expect auto to work depending on the inner return type.The void* version doesn't work, because void* doesn't implicitly convert to a class type. It has nothing to do with null. auto works thanks to the fact that typeof(null) was added to the language a while back, and since class references can be null, typeof(null) implicitly converts to the class type. Before typeof(null) was added to the language, null by itself had no type, since it's just a literal representing the null value for any pointer or class reference. The result was that using null in generic code or with auto could run into issues. typeof(null) was added to solve those problems. - Jonathan M Davis
Dec 03 2019
On Tuesday, 3 December 2019 at 10:03:22 UTC, Basile B. wrote:That's interesting details of D developement. Since you reply to the first message I think you have not followed but in the last reply I told that maybe we should be able to name the type of null. I think this relates to TBottom too a bit.https://github.com/dlang/DIPs/blob/40352337053998885fbd0fe2718c300a322d3996/DIPs/DIP1NNN-DK.md
Dec 03 2019
On Tuesday, 3 December 2019 at 10:06:22 UTC, Mike Parker wrote:On Tuesday, 3 December 2019 at 10:03:22 UTC, Basile B. wrote:Ah, well. I meant to post the link to the PR: https://github.com/dlang/DIPs/pull/172That's interesting details of D developement. Since you reply to the first message I think you have not followed but in the last reply I told that maybe we should be able to name the type of null. I think this relates to TBottom too a bit.https://github.com/dlang/DIPs/blob/40352337053998885fbd0fe2718c300a322d3996/DIPs/DIP1NNN-DK.md
Dec 03 2019
On Tuesday, 3 December 2019 at 10:06:22 UTC, Mike Parker wrote:On Tuesday, 3 December 2019 at 10:03:22 UTC, Basile B. wrote:This is everything I wished for. It basically exactly resembles the results of the lengthy discussion H. S. Theo and I had in the review thread for Walter‘s original bottom type suggestion. And it even covers a few additional details we had not thought about. I can’t wait for this DIP to go into review. Thanks a lot to the DIP author. You have my biggest respect for writing a fleshed out proposal of this!That's interesting details of D developement. Since you reply to the first message I think you have not followed but in the last reply I told that maybe we should be able to name the type of null. I think this relates to TBottom too a bit.https://github.com/dlang/DIPs/blob/40352337053998885fbd0fe2718c300a322d3996/DIPs/DIP1NNN-DK.md
Dec 06 2019
On Friday, 6 December 2019 at 23:25:30 UTC, Johannes Loher wrote:On Tuesday, 3 December 2019 at 10:06:22 UTC, Mike Parker wrote:nice. Kotlin has this as well, with Unit as void and Nothing as noreturn. So for example this compiles without complaint: fun infinite(f: () -> Unit) { while (true) { f() } } fun main() { infinite { println(".") } println("goodbye") } Where 'infinite' has an implcit Unit return type, but this warns that the "goodbye" will never happen: fun infinite(f: () -> Unit): Nothing { while (true) { f() } } fun main() { infinite { println(".") } println("goodbye") } This might be more important for resources that never get closed, or secrets are never scrubbed from memory, due to someone putting those tasks after a function like 'infinite' without noticing. ... noreturn local variables are pretty gross, though.On Tuesday, 3 December 2019 at 10:03:22 UTC, Basile B. wrote:This is everything I wished for. It basically exactly resembles the results of the lengthy discussion H. S. Theo and I had in the review thread for Walter‘s original bottom type suggestion. And it even covers a few additional details we had not thought about. I can’t wait for this DIP to go into review. Thanks a lot to the DIP author. You have my biggest respect for writing a fleshed out proposal of this!That's interesting details of D developement. Since you reply to the first message I think you have not followed but in the last reply I told that maybe we should be able to name the type of null. I think this relates to TBottom too a bit.https://github.com/dlang/DIPs/blob/40352337053998885fbd0fe2718c300a322d3996/DIPs/DIP1NNN-DK.md
Dec 06 2019
On Tuesday, December 3, 2019 3:03:22 AM MST Basile B. via Digitalmars-d- learn wrote:On Tuesday, 3 December 2019 at 09:58:36 UTC, Jonathan M Davis wrote:There isn't much point in giving the type of null an explicit name given that it doesn't come up very often, and typeof(null) is quite explicit about what the type is. Also, anyone doing much generic programming in D is going to be well versed in typeof. They might not know about typeof(null) explicitly, but they should recognize what it means when they see it, and if someone were trying to get the type of null, it would be the obvious thing to try anyway. And typeof(null) isn't even the prime case where typeof gets used on something other than an object. From what I've seen, typeof(return) gets used far more. As for TBottom, while the DIP does give it a relationship to null, they're still separate things, and giving typeof(null) a name wouldn't affect TBottom at all. - Jonathan M DavisOn Tuesday, December 3, 2019 12:12:18 AM MST Basile B. via Digitalmars-d- learn wrote:That's interesting details of D developement. Since you reply to the first message I think you have not followed but in the last reply I told that maybe we should be able to name the type of null. I think this relates to TBottom too a bit.I wish something like this was possible, until I change the return type of `alwaysReturnNull` from `void*` to `auto`. --- class A {} class B {} auto alwaysReturnNull() // void*, don't compile { writeln(); return null; } A testA() { return alwaysReturnNull(); } B testB() { return alwaysReturnNull(); } void main() { assert( testA() is null ); assert( testB() is null ); } --- OMG, isn't it nice that this works ? I think that this illustrates an non intuitive behavior of auto return types. One would rather expect auto to work depending on the inner return type.The void* version doesn't work, because void* doesn't implicitly convert to a class type. It has nothing to do with null. auto works thanks to the fact that typeof(null) was added to the language a while back, and since class references can be null, typeof(null) implicitly converts to the class type. Before typeof(null) was added to the language, null by itself had no type, since it's just a literal representing the null value for any pointer or class reference. The result was that using null in generic code or with auto could run into issues. typeof(null) was added to solve those problems. - Jonathan M Davis
Dec 03 2019
On Tuesday, 3 December 2019 at 10:19:02 UTC, Jonathan M Davis wrote:On Tuesday, December 3, 2019 3:03:22 AM MST Basile B. via Digitalmars-d- learn wrote:you're right but I see two cases: - transpiling - header generation[...]There isn't much point in giving the type of null an explicit name given that it doesn't come up very often, and typeof(null) is quite explicit about what the type is. Also, anyone doing much generic programming in D is going to be well versed in typeof. They might not know about typeof(null) explicitly, but they should recognize what it means when they see it, and if someone were trying to get the type of null, it would be the obvious thing to try anyway. And typeof(null) isn't even the prime case where typeof gets used on something other than an object. From what I've seen, typeof(return) gets used far more. [...]
Dec 03 2019
On Tuesday, December 3, 2019 3:23:20 AM MST Basile B. via Digitalmars-d- learn wrote:On Tuesday, 3 December 2019 at 10:19:02 UTC, Jonathan M Davis wrote:I don't see why either of those would be a problem. For a transpiler, typeof(null) and an explicit type name for typeof(null) would be the same thing, and it would have to be translated to something that would work in the other language either way. As for header generation, do you mean .di files? They'd just use typeof(null) explicitly, whereas if you're talking about something like having extern(C) functions in D and declaring a corresponding .h file, typeof(null) wouldn't work anyway, because there is no equivalent in C. In either case, whether you represent the type as typeof(null) or by an explicit name in the D source code is irrelevant. It would mean the same thing regardless. Having an explicit name wouldn't really be any different from declaring an alias like alias TypeOfNull = typeof(null); The type is the same either way and would be treated the same by the compiler or by any tool that needed to translate it to another language. It's what the type is that matters, not how its represented in the D source code. The only real difference would be what the programmer would see when interacting with the D source code. It would be like arguing over whether the root class object should be called Object or Root. It would be the same thing either way, just with a different name. - Jonathan M DavisOn Tuesday, December 3, 2019 3:03:22 AM MST Basile B. via Digitalmars-d- learn wrote:you're right but I see two cases: - transpiling - header generation[...]There isn't much point in giving the type of null an explicit name given that it doesn't come up very often, and typeof(null) is quite explicit about what the type is. Also, anyone doing much generic programming in D is going to be well versed in typeof. They might not know about typeof(null) explicitly, but they should recognize what it means when they see it, and if someone were trying to get the type of null, it would be the obvious thing to try anyway. And typeof(null) isn't even the prime case where typeof gets used on something other than an object. From what I've seen, typeof(return) gets used far more. [...]
Dec 03 2019
On Tuesday, 3 December 2019 at 10:19:02 UTC, Jonathan M Davis wrote:On Tuesday, December 3, 2019 3:03:22 AM MST Basile B. via Digitalmars-d- learn wrote:I think that any internal compiler types that are also things in code should be named. Things like tuples are really a thing in the compiler (TupleExp, TypeTuple, also Tuple in dtemplate.d, ...), we still need a library type for tuples while everything there in the compiler.On Tuesday, 3 December 2019 at 09:58:36 UTC, Jonathan M Davis wrote:There isn't much point in giving the type of null an explicit name given that it doesn't come up very often, and typeof(null) is quite explicit about what the type is. Also, anyone doing much generic programming in D is going to be well versed in typeof. They might not know about typeof(null) explicitly, but they should recognize what it means when they see it, and if someone were trying to get the type of null, it would be the obvious thing to try anyway. And typeof(null) isn't even the prime case where typeof gets used on something other than an object. From what I've seen, typeof(return) gets used far more. As for TBottom, while the DIP does give it a relationship to null, they're still separate things, and giving typeof(null) a name wouldn't affect TBottom at all. - Jonathan M DavisOn Tuesday, December 3, 2019 12:12:18 AM MST Basile B. via Digitalmars-d- learn wrote:That's interesting details of D developement. Since you reply to the first message I think you have not followed but in the last reply I told that maybe we should be able to name the type of null. I think this relates to TBottom too a bit.I wish something like this was possible, until I change the return type of `alwaysReturnNull` from `void*` to `auto`. --- class A {} class B {} auto alwaysReturnNull() // void*, don't compile { writeln(); return null; } A testA() { return alwaysReturnNull(); } B testB() { return alwaysReturnNull(); } void main() { assert( testA() is null ); assert( testB() is null ); } --- OMG, isn't it nice that this works ? I think that this illustrates an non intuitive behavior of auto return types. One would rather expect auto to work depending on the inner return type.The void* version doesn't work, because void* doesn't implicitly convert to a class type. It has nothing to do with null. auto works thanks to the fact that typeof(null) was added to the language a while back, and since class references can be null, typeof(null) implicitly converts to the class type. Before typeof(null) was added to the language, null by itself had no type, since it's just a literal representing the null value for any pointer or class reference. The result was that using null in generic code or with auto could run into issues. typeof(null) was added to solve those problems. - Jonathan M Davis
Dec 04 2019
On Tue, Dec 03, 2019 at 03:19:02AM -0700, Jonathan M Davis via Digitalmars-d-learn wrote:On Tuesday, December 3, 2019 3:03:22 AM MST Basile B. via Digitalmars-d- learn wrote:[...]Just add this line somewhere in object.d and we're good to go: alias Null = typeof(null); :-) [...][...] maybe we should be able to name the type of null. I think this relates to TBottom too a bit.There isn't much point in giving the type of null an explicit name given that it doesn't come up very often, and typeof(null) is quite explicit about what the type is.As for TBottom, while the DIP does give it a relationship to null, they're still separate things, and giving typeof(null) a name wouldn't affect TBottom at all.[...] We need to tread carefully here, because of the unfortunate conflation of top and bottom types we inherited from C in the form of the keyword `void`, which greatly confuses the issue. The thing is, `void` means "no return type" (or "no type" in some contexts), i.e., void == TBottom in that case. However, `void*` does NOT mean a pointer to TBottom; rather, it's a *top type* that includes pointers of every kind (this can be seen in the fact that any pointer implicitly converts to void*). I.e., the relationship between `void` and `void*` is NOT the same as the relationship with `T` and `T*` for any other T. This unfortunate overloading of `void` to mean both top and bottom types in different contexts misleads many C (and D) programmers into the wrong understanding of what a bottom type is (or what a top type is), and how it should behave. T -- The problem with the world is that everybody else is stupid.
Dec 03 2019
On Tuesday, 3 December 2019 at 17:45:27 UTC, H. S. Teoh wrote:The thing is, `void` means "no return type" (or "no type" in some contexts), i.e., void == TBottom in that case.This is incorrect. `void` as a return type is a unit type; that is, a type with exactly one value. A function with a return type of TBottom is one that never returns at all--for example, libc's `exit` or POSIX's `execve`.
Dec 03 2019
On Tue, Dec 03, 2019 at 09:08:55PM +0000, Paul Backus via Digitalmars-d-learn wrote:On Tuesday, 3 December 2019 at 17:45:27 UTC, H. S. Teoh wrote:Ah, my bad. See? This whole `void` business just throws me off. No wonder we can never get things straight when it comes to top/bottom types in C/C++/D. T -- He who sacrifices functionality for ease of use, loses both and deserves neither. -- SlashdotterThe thing is, `void` means "no return type" (or "no type" in some contexts), i.e., void == TBottom in that case.This is incorrect. `void` as a return type is a unit type; that is, a type with exactly one value. A function with a return type of TBottom is one that never returns at all--for example, libc's `exit` or POSIX's `execve`.
Dec 03 2019
On Tuesday, 3 December 2019 at 17:45:27 UTC, H. S. Teoh wrote:The thing is, `void` means "no return type" (or "no type" in some contexts), i.e., void == TBottom in that case.Not *quite* correct. void is not a bottom type; it's a unit type, meaning that it's a type with only 1 value (as is null, interestingly). void does not mean "no return type"; it means "there's only 1 possible value that can be returned". A function returning TBottom means that the function will never return, e.g., it loops forever, or throws an exception, etc. I agree with the OP that it's silly not to give typeof(null) a name. As null is a unit type, we could easily have `null` stand in for typeof(null) as well. A type that contains only one value can be synonymous with that value (see also, Rust's unit type (), which has one value, ()).
Dec 03 2019
On Tuesday, 3 December 2019 at 22:11:39 UTC, Meta wrote:On Tuesday, 3 December 2019 at 17:45:27 UTC, H. S. Teoh wrote:Whoops, skimmed over the post already mentioning this.The thing is, `void` means "no return type" (or "no type" in some contexts), i.e., void == TBottom in that case.Not *quite* correct. void is not a bottom type; it's a unit type, meaning that it's a type with only 1 value (as is null, interestingly). void does not mean "no return type"; it means "there's only 1 possible value that can be returned". A function returning TBottom means that the function will never return, e.g., it loops forever, or throws an exception, etc.
Dec 03 2019