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

Consistent use of singleton types in manual. #36591

Merged
merged 8 commits into from
Jul 21, 2020

Conversation

tpapp
Copy link
Contributor

@tpapp tpapp commented Jul 9, 2020

Fixes #7135, see discussion there.

Changes

  • 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) 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?

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)
@tkf
Copy link
Member

tkf commented Jul 9, 2020

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 Fix1(Vector, undef) is Fix1{Type{Vector},UndefInitializer} rather than Fix1{DataType,UndefInitializer}. This is required for the field type to be inferable. So, I think it'd be better to avoid stressing that Type{T} is only for dispatch. "Type{T} types" section in this PR seems to be fine as-is, though.

Comment on lines 1063 to 1064
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]
Copy link
Member

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.

Copy link
Contributor Author

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.

@tkf
Copy link
Member

tkf commented Jul 9, 2020

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"?

Yeah, calling Type{T} a singleton sounds a bit confusing since you can write something like Type{<:Integer}. For the new name, "type selectors" sound reasonable to me.

should I expunge the remaining use of 'singleton' for Type{T} from Conversion and Promotion?

👍 from me :)

@tpapp
Copy link
Contributor Author

tpapp commented Jul 9, 2020

@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 Type{Type{T}} etc constructs and other misunderstandings. Type is mysterious to a newcomer as is, and each common use case should serve as an example. So I would rather just include them if feasible.

@tkf
Copy link
Member

tkf commented Jul 9, 2020

Yeah, including example is a good idea. I think a minimal example is Some:

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"
@tpapp
Copy link
Contributor Author

tpapp commented Jul 9, 2020

Thanks @tkf, I simplified the example somewhat as I did not want to deal with @code_warntype in a jldoctest. I also did the other changes above.

@tpapp
Copy link
Contributor Author

tpapp commented Jul 14, 2020

Friendly bump — if this needs to be improved, I am happy to implement any further suggested changes.

@StefanKarpinski StefanKarpinski added the status:merge me PR is reviewed. Merge when all tests are passing label Jul 14, 2020
@StefanKarpinski
Copy link
Sponsor Member

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
Copy link
Member

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 Show resolved Hide resolved
doc/src/manual/types.md Outdated Show resolved Hide resolved
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),
Copy link
Member

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.

doc/src/manual/types.md Outdated Show resolved Hide resolved
tpapp and others added 4 commits July 16, 2020 12:52
Co-authored-by: Rafael Fourquet <[email protected]>
Co-authored-by: Rafael Fourquet <[email protected]>
Co-authored-by: Rafael Fourquet <[email protected]>
@tpapp
Copy link
Contributor Author

tpapp commented Jul 16, 2020

@rfourquet, thanks for the thorough reading and the detailed suggestions, I applied all of them.

@StefanKarpinski
Copy link
Sponsor Member

Great clarification. Thank you! This looks ready to merge once CI passes.

doc/src/manual/types.md Outdated Show resolved Hide resolved
Copy link
Member

@rfourquet rfourquet left a 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
Copy link
Member

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.

Copy link
Contributor Author

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.

Copy link
Contributor Author

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.

doc/src/manual/types.md Outdated Show resolved Hide resolved
Co-authored-by: Rafael Fourquet <[email protected]>
@tpapp
Copy link
Contributor Author

tpapp commented Jul 21, 2020

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.

@tkf tkf merged commit c6955d7 into JuliaLang:master Jul 21, 2020
@tkf
Copy link
Member

tkf commented Jul 21, 2020

It has two approvals and the merge me label. I think it's more than enough :)

simeonschaub pushed a commit to simeonschaub/julia that referenced this pull request Aug 11, 2020
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]>
@DilumAluthge DilumAluthge removed the status:merge me PR is reviewed. Merge when all tests are passing label Jan 11, 2021
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 this pull request may close these issues.

Manual could be clearer about parametric singleton types
6 participants