Void being `()` or `Unit` as some other languages call it allows for some nice things. Scala in particular has erased values and whatnot that take advantage of this. Some use cases in Nim would be like so:
Nim currently has a feature where `let _ = foo` corresponds to `discard foo`. This is because `_` is a special identifier. This behaviour is arbitrary and doesn't do things you would expect, such as [this one](https://github.com/nim-lang/Nim/issues/13443) in proc definitions, and a bug that I couldn't find related to object variants (also to note, you can name an object field `_` and it works like a regular parameter but errors if you name it `_name`). There is a section in the [experimental manual](https://nim-lang.org/docs/manual_experimental.html#void-type) about the void type, and how it can be used in object fields and proc parameters to signify a parameter that doesn't exist. This implementation seems a bit verbose however, such as the following code: proc callProc[T](p: proc (x: T), x: T) = when T is void: p() else: p(x) proc intProc(x: int) = discard proc emptyProc() = discard callProc[int](intProc, 12) callProc[void](emptyProc) Run Defining `type void = tuple[]` and adding special behaviour to `tuple[]` specifically (such as `tuple[]` is a subtype of every type, and it is eluded in proc parameters) seems like it would fit Nim's philosophy of being elegant more than the existing `void`. `let _ = foo` could be replaced by `let () = foo` a la OCaml, and it would fit more of `discard`'s philosophy of "turning into a void value". Not to mention, in the above code snippet, typing `p(x)` would be equivalent to `p(())`, which seems more appropriate to translate to `p()` than it having the unique type `void`. It would also mean a standalone `discard` could just be translated to the expression `()`. This is just a personal thing, but this would look way better in case object branches in my opinion, more appropriate than `discard` or `nil` since the intended message is "there are no fields here". `distinct void`/`distinct tuple[]` types could be used in generics to fulfill the effect of special types. This would replace the current convention of just using an empty `object` type, which is unpreferable for many reasons that I don't think I need to go into in this post. This is even in the Nim standard library already, see [StaticParam[T] in typetraits](https://github.com/nim-lang/Nim/blob/14b2354b7da36041ca046e60e833b5be9a04f1e4/lib/pure/typetraits.nim#L89). While writing this post, I remembered an RFC I wrote a while ago, proposing `void converters <https://github.com/nim-lang/RFCs/issues/61>`_. The "discard overload" part of this RFC is incompatible with what I am suggesting here, since `discard` would be pretty much just syntax sugar. I also don't think void converters are good since they're hidden control flow, but that's unrelated. The point I am making is `tuple[]` will allow for solutions to more abstract problems like the ones implied in my RFC if you can do things like `distinct tuple[]`. For example, a function that normally returns void but has the possibility of setting a global `error` variable could cause problems if the code it's called in doesn't check for that `error` variable. If you give it a return type `CanError = distinct void`, the compiler will complain if you don't discard the call, thus you can be reminded to check for an error. The problem with this concept is `tuple[]` is currently treated as a value in Nim. `let x = ()` works, `echo(())` prints `()` meaning `$() == "()"`, so on. So this would be a breaking change. Not to say that anyone is actually using `tuple[]` in their code, most people probably don't even account for its existence in generics causing some potential bugs, it would just change the behaviour of the language. It's also going to harm Nim's maturity when it gets implemented, so it might be best if this was considered around Nim 2.0, but there are existing features in the language that are incomplete yet related such as `let _ = foo`, so I believe it's also fairly relevant now. Will this happen? Are there any pitfalls that I haven't considered? Does it warrant an RFC or is there already one I don't know?
