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

Feature request: Alternative{T,U} #17073

Closed
eschnett opened this issue Jun 23, 2016 · 5 comments · Fixed by #22441
Closed

Feature request: Alternative{T,U} #17073

eschnett opened this issue Jun 23, 2016 · 5 comments · Fixed by #22441

Comments

@eschnett
Copy link
Contributor

An efficient implementation of a type Alternative{T,U} in the sense of a discriminated union requires support from the compiler, hence I'm opening a feature request here for feedback.

I imagine a type Alternative{T,U,...} that holds a value of any of the types T, U, etc., and remembers which alternative is valid. This is an extension of both enums and Nullable: Enums correspond to an Alternative where all types are Void, and Nullable{T} is identical to Alternative{T,Void}. Similar to the way in which Nullable{Void} still remembers whether it holds Void element or not, Alternative{T,T} still remembers which of the two alternatives is valid, different from Union{T,T}.

Alternative could be implemented as

immutable Alternative{T,U}
    which::UInt8
    value::Union{T,U}
end

but obviously a more efficient representation would be valuable so that bitstypes don't require boxing.

If there is future work on the compiler to make Nullable more efficient, then maybe this work can keep efficiency for Alternative in mind.

@johnmyleswhite
Copy link
Member

I'd love to see something like this.

I would have assumed the representation would be more like the following:

immutable Alternative{T,U}
    which::UInt8
    value_T::T
    value_U::U
end

Why store a Union inline? Is that a way of getting at the request for just enough bits to store the larger of T and U?

@eschnett
Copy link
Contributor Author

Yes; similar to a C union, I would hope that storage is optimized this way.

@carnaval
Copy link
Contributor

We could inline unions this way but it will still require an inline tag so that doing obj.value is still well defined. It's too bad that in a lot of cases the discriminating value tag is redundant (when the types are all different).

I guess you could do something like (assuming we do inline unions)

immutable TaggedUnionElt{Tag,T}
value::T
end
immutable Alternative{T,U}
value :: Union{TaggedUnionElt{0,T},TaggedUnionElt{1,U}}
end

not sure how much of a good idea that is though.

@carnaval
Copy link
Contributor

(it does require a pointer which is larger than a byte but the ABI will probably have you pad it this way anyway)

@StefanKarpinski
Copy link
Sponsor Member

We could inline unions this way but it will still require an inline tag so that doing obj.value is still well defined. It's too bad that in a lot of cases the discriminating value tag is redundant (when the types are all different).

This reminds me of the "lazy tag" idea: instead of storing object references as pointers to tagged values, keep the tag to the reference.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants