-
Notifications
You must be signed in to change notification settings - Fork 1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Usage of System.Void as a subtype for every single type #1146
Comments
you can write
to create readonly empty list (not sure what will be the use case). you can also create empty enumerable which is useful some times (when you want to pass empty but non null sequence)
|
@MkazemAkhgary Then it wouldn't be possible to write Use cases? There would be only one value typed as empty list. That value could be assigned to every other list. Something like that is not currently expressible in the language I think. |
What you're asking for is called the bottom type and there is already a proposal for that: #538. But it wouldn't let you use List<void> empty = new List<void>();
List<object> l = empty;
l.Add(new object());
Console.WriteLine(empty[0]); This has to fail somehow, and I think the only reasonable solution is to not allow the conversion from |
Thank you for your answer. Bottom type is exactly what I am looking for and I really hope that this will make it into language. It would be nice that bottom type to be System.Void. In fact |
@svick I have found out that I thing that it wouldn't be much work to make this just work. The bottom type is almost prepared and it is void. I have nothing against Never type etc. but I thing that it would be very similar to void. |
@drozdekl By current rules? No, it wouldn't. Generic interface covariance only works on reference types. |
In fact I think that void fits into the whole concept of bottom type:
Then object would be Union of absolutely all types and void would be intersection of all types. Sadly I can't describe well how much I thing that all of that fits into whole concept. It would also imply that there exists type |
Bottom/Never means something very different from |
now imagine you have |
@MkazemAkhgary default(T) should be compile time error just like it is currently compile time error to use default(System.Void). Bottom type should behave just like the current type System.Void but also should be subtype of every existing type. In fact I do think that every other possibility than System.Void would be strange because otherwise the bottom type should be also subtype of System.Void which does not make much sense. Methods operating on T would behave just like now because bottom type can't have instance thus you can't really call a method on it. |
I am interested in mathematics and especially in Set theory. I also like thinking about types in C# like classes in set theories. System.Void behaves just like an empty set and the same thing wenexpect of a bottom type. Also sets are due to extensionality considered equal iff they contain the same members and that is why I so like thinking about void as bottom type. Also an empty set is fhe only set which is subset of every possible set. That is thing we expect of bottom type. |
@drozdekl from a purely practical point of view, I think it is more useful to consider the |
I have other question. I am asking it here because I think that it is related to special type System.Void. I searched a bit and found these citations which probably are true:
I am asking whether it would be potentially possible to give name to the type of null. Something like "nulltype" which could be used only in a returning value of function. So function Why I do think this may be not a bad idea? Because it would be possible to bring into language non-returnable functions. It would simple be function with return value of the type edit: It is probable not possible :( Otherwise there would already be functions which can't return null (otherwise would be thrown an exception) which would simple mean that there is guranteed non-nullability in C# which clearly is not possible. So it is not possible to generate condition |
Sorry, do you mean in general? Or for very specific cases. default(T) definitely has to be allowed for generic type parameters (that's why it was actually added to the language in the first place :)). |
So do I (this is what i studied for my masters along with type theory :)). However, i don't want to do things in C# just for the sake of mathematical fun. Doing this sort of thing shoudl be done when it provides significant and substantial improvements to the user across a wide gamut of programming scenarios. It's unclear to me that this proposal accomplishes that. It seems extremely niche, and doesn't really address any sort of core pain point that users tend to commonly run into. Just, it's mathematically nifty, but that's not something that is honestly that beneficial to our users. |
@CyrusNajmabadi It is currently compile time error for System.Void. And it does make sense because there can't exist an instance of type void. edit: By non returnable functions I meant something like function where is an infinite loop but now I also think that it does not make much sense. |
Why would i ever need this? How is that any better than just having a 'void' method. If i can only return 'null', how is that any better than not being able to return anything at all?
We have non-returnable functions. that's what a 'void' method is. You can't return any values from it. |
@jdegoes shown me the way I want to do programming in C#. Than he shown good(best?) approach to do it in hybrid language like Scala[2]. At least in server environment. During my life I had fun doing In Scala there is using System;
using System.IO;
public struct Unit{}
public interface IO<in TEnvironment, out TError, out TUnit>{}
public class Nothing // : null // inherits all objects including sealed, but cannot be created
{
private Nothing(){}
public static implicit operator IOException(Nothing a) => default;
public static implicit operator int(Nothing a) => default;
public static implicit operator string(Nothing a) => default;
public static implicit operator bool(Nothing a) => default;
// should be casted from any type
//public static implicit operator T<T>(Nothing a) => default;
}
public class C
{
public static void Do()
{
IO<object, Exception, Unit> a = null;
IO<String, Exception, Unit> b = null;
b = a;
IO<object, IOException, int> c = null;
IO<object, Nothing, int> d = null;
c = d; // error CS0266: Cannot implicitly convert type 'IO<object, Nothing, int>' to 'IO<object, System.IO.IOException, int>'. An explicit conversion exists (are you missing a cast?)
}
} Next items may help to implement |
Hi. There is a predefined struct
System.Void
which is treated specially by C# language. The only thing you can currently do with that struct is to applytypeof
operator which is possible only via built in aliasvoid
. (var x = typeof(System.Void);
is not permitted butvar y = typeof(void);
is completely legal.)I would like to suggest removal of that restriction so
var x = typeof(System.Void)
would be valid C# code. Then it would be much clearer that there existsSystem.Void
structure which is special for many reasons. For example you can't make instance of that type which is a property that would be nice to use in some way. Next paragraph summarize the one special property I think thatvoid
structure should have to make it useful.Firstly I would allow
System.Void
structure in generic arguments. Then you could write something likeList<System.Void> empty = new List<System.Void>()
which list would stay empty forever because you can't build instance of special structSystem.Void
! Then there is only one step to makevoid
structure useful. I suggestSystem.Void
structure to be treated as subtype of every single type. That property sounds weird but I think it would be useful. You could for example writeList<int> = empty
and alsoList<List<string>> = empty
, etc. I miss in C# something like haskell's[]
list which is considered to be list convertible to every other list. The only thing that would be necessary is to modify behaviour of only one single type which is treated very specially even now. I've found also other use cases but this one is the clearest.(I had tried to search before I wrote this text and haven't found anything similar to my proposal. It is possible that I only can't search well so if this one is duplicate I will immediately close the issue)
The text was updated successfully, but these errors were encountered: