-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
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
Consistent use of singleton types in manual. #36591
Conversation
Fixes JuliaLang#7135, see discussion there. - separate discussion of singleton types (as in `Base.issingletontype`) and `Type{T}` - move discussion about singleton types to a later section so that parametric singleton types can be discussed - add example and discussion about parametric singleton types - add usage hint about `Type` outside dispatch (TL;DR: don't)
A usage (workaround) outside dispatch is to get a sharp field type. For example, the type of |
doc/src/manual/types.md
Outdated
Immutable composite types with no fields are called *singletons*. Formally, if | ||
`a isa T && b isa T` implies `a === b`, then `T` is a singleton type. [^2] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the spirit of this formalism is great, but if I have
julia> abstract type A end
julia> struct B <: A end
and I don't define any other subtype of A
, would it imply that A
is also a singleton type?
Maybe making this perfect requires isconcretetype(T)
? Although if you say "for any a
and b
" I guess it could mean "for any a
and b
of any implementable type."
should I mention that abstract types can't be singleton types, or is it obvious from the context?
So yes, I think this helps to make this definition clearer.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I think we should stress that only concrete types can to be singletons.
Yeah, calling
👍 from me :) |
@tkf: thanks for the review. Yes, sharp field types are another use case --- if you have a small, self-contained example, I would be happy to add it to the PR if that's OK with you. I included the usage hint because I have seen users on Discourse trying to work with |
Yeah, including example is a good idea. I think a minimal example is struct SomeBad{T}
value::T
end
struct SomeGood{T}
value::T
end
SomeGood(::Type{T}) where {T} = SomeGood{Type{T}}(T)
sbad = SomeBad(Symbol)
sgood = SomeGood(Symbol)
@assert sbad isa SomeBad{DataType}
@assert sgood isa SomeGood{Type{Symbol}}
getvalue(x) = x.value
@code_warntype getvalue(sbad) # => Body::DataType
@code_warntype getvalue(sgood) # => Body::Type{Symbol} |
- remove incorrect reference to "singleton types" from the conversion chapter - emphasize that singleton types need to be concrete types, specifically mention abstract types - include a type sharpening example for `Type{T}` (thanks @tkf) - introduce the term "type selector"
Thanks @tkf, I simplified the example somewhat as I did not want to deal with |
Friendly bump — if this needs to be improved, I am happy to implement any further suggested changes. |
I've requested review by @JeffBezanson. I'll merge one way or another this week. |
@@ -168,13 +168,12 @@ Such a definition might look like this: | |||
convert(::Type{MyType}, x) = MyType(x) | |||
``` | |||
|
|||
The type of the first argument of this method is a [singleton type](@ref man-singleton-types), | |||
The type of the first argument of this method is a [`Type{T}`](@ref man-typet-type), | |||
`Type{MyType}`, the only instance of which is `MyType`. Thus, this method is only invoked |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not put directly Type{MyType}
within the []
brackets, where Type{T}
is currently?
doc/src/manual/types.md
Outdated
In other words, [`isa(A,Type{B})`](@ref) is true if and only if `A` and `B` are the same object | ||
and that object is a type. | ||
|
||
In particular, since parametric types are [invariant](@ref man-parametric-composite-types), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds like the sentence is missing a "connection" word, e.g. I would expect "we have:" or something like that at the end, before the example.
Co-authored-by: Rafael Fourquet <[email protected]>
Co-authored-by: Rafael Fourquet <[email protected]>
Co-authored-by: Rafael Fourquet <[email protected]>
@rfourquet, thanks for the thorough reading and the detailed suggestions, I applied all of them. |
Great clarification. Thank you! This looks ready to merge once CI passes. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes nice change! Just one more possible change ("ie" -> "i.e.") if you also update this branch for something else.
1. `T` is an immutable composite type (ie defined with `struct`), | ||
1. `a isa T && b isa T` implies `a === b`, | ||
|
||
then `T` is a singleton type.[^2] [`Base.issingletontype`](@ref) can be used to check if a |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there an official convention on whether the footnote sign should go before or after the period? I saw both in the manual.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The Chicago Manual of Style suggests that it goes after the period.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Incidentally, since these questions are in general important for high-quality documentation, I started some discussion about referring a style guide in #36723.
Co-authored-by: Rafael Fourquet <[email protected]>
Another friendly bump: I think I addressed all comments. I am happy to wait for more feedback if necessary, just don't want this PR to be forgotten. |
It has two approvals and the |
Fixes JuliaLang#7135, see discussion there. * separate discussion of singleton types (as in `Base.issingletontype`) and `Type{T}` * move discussion about singleton types to a later section so that parametric singleton types can be discussed * add example and discussion about parametric singleton types * add usage hint about `Type` outside dispatch Co-authored-by: Rafael Fourquet <[email protected]> Co-authored-by: Daniel Karrasch <[email protected]>
Fixes #7135, see discussion there.
Changes
separate discussion of singleton types (as in
Base.issingletontype
) andType{T}
move discussion about singleton types to a later section so that parametric singleton types can be discussed
add example and discussion about parametric singleton types
add usage hint about
Type
outside dispatch(TL;DR: don't)example: type sharpening (thanks @tkf)Open questions:
is there a terminology for
Type{T}
now that we don't confuse it with singleton types? If not, do we want to introduce one, eg call it "type selectors"?should I mention that abstract types can't be singleton types, or is it obvious from the context?
should I expunge the remaining use of 'singleton' for
Type{T}
from Conversion and Promotion?