Skip to content
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

proposal: "empty" type #28187

Closed
MOZGIII opened this issue Oct 13, 2018 · 3 comments
Closed

proposal: "empty" type #28187

MOZGIII opened this issue Oct 13, 2018 · 3 comments

Comments

@MOZGIII
Copy link

MOZGIII commented Oct 13, 2018

I stumbled upon this code recently:

go/src/context/context.go

Lines 167 to 169 in 4330866

// An emptyCtx is never canceled, has no values, and has no deadline. It is not
// struct{}, since vars of this type must have distinct addresses.
type emptyCtx int

Effectively it creates a new type that's supposed to be "empty" using int. I also noticed things like this in my own code.

It does not state the intent clearly, and the implementation is most likely suboptimal.

We could have an empty type instead. The idea is, roughly, for it to be like bool, but with just a single possible value (empty), inspead of two (true/false).

Usage example would look like this:

ch := make(chan empty)
ch <- empty

What do you think?

PS: I can already see a potnetial issue with the type name and the type value colliding with each other. If we want to move forward with this we should be able to solve it.

@gopherbot gopherbot added this to the Proposal milestone Oct 13, 2018
@MOZGIII
Copy link
Author

MOZGIII commented Oct 13, 2018

It's not clear though why that code from context package I linked as an example uses int instead of struct{}. Can anyone explain the comment, and what the author meant by mentioning the requiement to have distinct addresses? How int is different from struct{}? This may be relevant to this proposal, but don't know if it really is.

@ghost
Copy link

ghost commented Oct 13, 2018

The two scenarios you mention are unrelated. The first is due to the following in the spec:

A struct or array type has size zero if it contains no fields (or elements, respectively) that have a size greater than zero. Two distinct zero-size variables may have the same address in memory.

The second is a common way to create a "signal" channel where data is not needed.

ch := make(chan struct{})
close(ch) // Any <-ch gets unblocked

If you add a new built-in type called empty, you would need it to be a non-zero size in the first scenario, and preferably zero-sized in the second (but not required).

I think this is just adding unneeded complexity.

@MOZGIII
Copy link
Author

MOZGIII commented Oct 13, 2018

I think I'd need empty type to be zero size at all times - so that the values have the same memory address. Though, it seems struct{} already does just that.
And now I see why int is used - it's rather unobvious though. It makes perfect sense when you look at the language doc, but in this case it just didn't click for me. Thanks for making it clear, @bontibon.

So, in fact, I agree, and adding an empty type would not make sense - for the not-so-easy to grasp usecases where one actually want non-zero values just to make sure the pointer addresses will be different it's ok to use an int, and for the second case - which is much more common - to use struct{}.

I think I'll close this, please reopen if it's too early.

@MOZGIII MOZGIII closed this as completed Oct 13, 2018
@golang golang locked and limited conversation to collaborators Oct 13, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

2 participants