Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is `System.Void` different from `unit` type?

F# Types Docs said that:

Unit Type: Describes the unit type, a type that has one value and that is indicated by (); equivalent to void in C# and Nothing in Visual Basic.

It said they're equal, but why does the following comparison return false?

typedefof<System.Void> = typedefof<unit>;;
val it : bool = false
like image 458
MiP Avatar asked Dec 14 '22 18:12

MiP


1 Answers

Well, they're not really equivalent. The quote you posted is a bit misleading.

The F# type unit is equivalent to C# keyword void (not the type System.Void!) in that both the type and the keyword are used to declare functions that don't return anything:

// F#
let f (x:int) : unit = ...

// C#
void f( int x ) { ... }

This is what your quote is talking about, but the equivalence stops there.

In C# void is not really a type. It's a keyword that is used to declare return-less methods, but you can't use it in type positions - e.g. you can't have void variables, parameters, type parameters, etc. That's why we have a separate delegate Action instead of just using Func<void>.

The type System.Void is a different animal altogether: it exist only to support reflection, but it's not the same as void, the way System.Int32 is the same as int.

In F#, on the other hand, the type unit is mostly just a regular type, like any other. It even has a definition in the standard library. Yes, the compiler does give it some special treatment in certain special cases, but that's only for optimization and interop, invisible at the language level. Consequently, unit can be used in any type position - parameters, variables, whatever. This means that F#, for example, doesn't need a special function type for functions that don't return anything, it can just use int -> unit.

like image 149
Fyodor Soikin Avatar answered Jan 04 '23 11:01

Fyodor Soikin