www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Unexpectedly nice case of auto return type

reply Basile B. <b2.temp gmx.com> writes:
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
next sibling parent reply Basile B. <b2.temp gmx.com> writes:
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
parent reply Andrea Fontana <nospam example.com> writes:
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
parent reply Basile B. <b2.temp gmx.com> writes:
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:
     A testA()
     {
         return alwaysReturnNull(); // Tnull can be implictly 
 converted to A
     }

 still nice tho.
Why not [1]? [1] typeof(null) alwaysReturnNull() { ... } Andrea
Yeah nice, that works instead of auto. That reminds me of the discussion about TBottom.
Dec 03 2019
parent reply Basile B. <b2.temp gmx.com> writes:
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:
 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
Yeah nice, that works instead of auto. That reminds me of the discussion about TBottom.
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.
Dec 03 2019
parent reply Andrea Fontana <nospam example.com> writes:
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
parent reply mipri <mipri minimaltype.com> writes:
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:
 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);
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);
Dec 03 2019
parent reply mipri <mipri minimaltype.com> writes:
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
next sibling parent reply Adam D. Ruppe <destructionator gmail.com> writes:
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
parent reply "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
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:
 Option 4: typeof(return)
typeof(return) is super cool for like option type things too!
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.
Dec 03 2019
parent reply Adam D. Ruppe <destructionator gmail.com> writes:
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. :-D
you 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
parent reply Basile B. <b2.temp gmx.com> writes:
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:
 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
you 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
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.
Dec 04 2019
parent Basile B. <b2.temp gmx.com> writes:
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:
 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. :-D
you 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
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.
more -520 lines today.
Dec 06 2019
prev sibling parent Basile B. <b2.temp gmx.com> writes:
On Tuesday, 3 December 2019 at 23:44:59 UTC, mipri wrote:
 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); }
aha nice
Dec 04 2019
prev sibling parent reply Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
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
parent reply Basile B. <b2.temp gmx.com> writes:
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:
 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
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.
Dec 03 2019
next sibling parent reply Mike Parker <aldacron gmail.com> writes:
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
next sibling parent Mike Parker <aldacron gmail.com> writes:
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:

 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
Ah, well. I meant to post the link to the PR: https://github.com/dlang/DIPs/pull/172
Dec 03 2019
prev sibling parent reply Johannes Loher <johannes.loher fg4f.de> writes:
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:

 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
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!
Dec 06 2019
parent mipri <mipri minimaltype.com> writes:
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:
 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
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!
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.
Dec 06 2019
prev sibling next sibling parent reply Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
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:
 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
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.
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 Davis
Dec 03 2019
next sibling parent reply Basile B. <b2.temp gmx.com> writes:
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:
 [...]
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. [...]
you're right but I see two cases: - transpiling - header generation
Dec 03 2019
parent Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
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:
 On Tuesday, December 3, 2019 3:03:22 AM MST Basile B. via

 Digitalmars-d- learn 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. [...]
you're right but I see two cases: - transpiling - header generation
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 Davis
Dec 03 2019
prev sibling parent Basile B. <b2.temp gmx.com> writes:
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:
 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:
 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
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.
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 Davis
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.
Dec 04 2019
prev sibling parent reply "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
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:
[...]
 [...] 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.
Just add this line somewhere in object.d and we're good to go: alias Null = typeof(null); :-) [...]
 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
next sibling parent reply Paul Backus <snarwin gmail.com> writes:
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
parent "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
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:
 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`.
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. -- Slashdotter
Dec 03 2019
prev sibling parent reply Meta <jared771 gmail.com> writes:
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
parent Meta <jared771 gmail.com> writes:
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:
 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.
Whoops, skimmed over the post already mentioning this.
Dec 03 2019