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

New explanation about template universe polymorphism #34

Merged
merged 6 commits into from
Sep 1, 2024

Conversation

lephe
Copy link
Contributor

@lephe lephe commented Jul 29, 2024

Discussed on Zulip: https://coq.zulipchat.com/#narrow/stream/437203-Coq-Platform-docs/topic/Template.20vs.2E.20proper.20universe.20polymorphism.20tutorial

The claimed scope, for now, is just an explanation of what template polymorphism does and doesn't do, with bridges around it to where the problem it solves come from (as explained with monomorphic universes) and how the limitations can be worked around (with universe polymorphism).

I think a detailed explanation of universes would be mostly independent so probably better separated. If such an explanation is written, linking to it could replace the current first section.

On the other hand, discussing other limitations of template universe polymorphism and better showing the tricks that can be used to hack around them would be, IMO, clearly in scope for this document. I could see a generalization to "more things about template polymorphism" more than to "more things about universes". The current text is still right at the limits of my understanding so I'm not really confident I can extend further.

Cc @YaZko

@lephe
Copy link
Contributor Author

lephe commented Aug 18, 2024

Gentle ping. I added the main contributors field from #36. Is there anything else I should do?

@thomas-lamiaux
Copy link
Collaborator

Hi @lephe , it is going a bit slow because of the holiday. Considering the discussions we had on the zulip, I suggest the following steps:

  1. I review it
  2. after changes, we merge it without waiting for completion with further content
  3. we create issues "intro tuto" and "complete the trade of" ?

Does that sound good to you ?

@lephe
Copy link
Contributor Author

lephe commented Aug 18, 2024

Ah, perfect, thanks for the process. This sounds good to me.

Copy link
Collaborator

@thomas-lamiaux thomas-lamiaux left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have looked at the tutorials, it is very interesting and a very good version on the subject. Thanks for the contribution.

Concerning the tutorial and the structure, I suggest to:

  • Section is unclear and most of section 2 is an introduction to universes as
    indicated by "Let's see this in action."
    Hence, I suggest moving / merging all such content with Section 1.
    Like everything which is not related to mprod and the limitations of using it.
    Then dedicate section 2 to monomorphic and limitations
  • Maybe add subsections in section 3 and 4.
    Like "Principles of (Template Poly // UnivPoly) / "advantages" / "limitations".
    I think it will make a bit easier to read and easier to improve later on,
    for a very little cost
  • It is not clear in section 2 what monomorphic means, maybe elaborate on it
  • Maybe rework the intro to say this tuto discuss the two approaches, their advantages and limitations as it is the end goal. In which case, maybe mention it is a first version or sth ?

Otherwise sounds great !

represents a universe level.

Here is the product of two types living in universe [uprod]. *)
Universe uprod.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I write Print Universes Subgraph (uprod) here, I get Set < uprod, why is that ?
You mention later that we don't care but I still find it a bit confusing.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All global universes are > Set.
Records of why this was decided are lost but AFAICT the main consequence is that they are prevented from being made = Set, which seems desired as if the user wanted a universe to be = Set they should have written Set not Type.


All of this results in the following basic rule: wherever a type in universe
[Type@{j}] is expected, you can provide a type from any universe smaller
than [j], i.e. that lives in [Type@{i}] with [i <= j].
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Say in the sentence what is the point ?


(** ** 2. Some issues with monomorphic universes *)

(** The core limitations of template universe polymorphism will be related to
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is unclear what monomorphic means

Comment on lines 111 to 116
(** Also, as we'll see later, Coq doesn't allow you to
name universes directly with a number (e.g. [Type@{42}]). So in order to
name a specific universe we have to create a variable [uprod] that
represents a universe level.

Here is the product of two types living in universe [uprod]. *)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
(** Also, as we'll see later, Coq doesn't allow you to
name universes directly with a number (e.g. [Type@{42}]). So in order to
name a specific universe we have to create a variable [uprod] that
represents a universe level.
Here is the product of two types living in universe [uprod]. *)
(** Let us create a variable [uprod] representing a universe level.
Here is the product of two types living in universe [uprod]. *)

Comment on lines 138 to 139
max of two levels (e.g. [max(uprod, uprod+1)]). Counter-intuitively, we
cannot name a specific universe by number. *)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
max of two levels (e.g. [max(uprod, uprod+1)]). Counter-intuitively, we
cannot name a specific universe by number. *)
max of two levels (e.g. [max(uprod, uprod+1)]). Counter-intuitively, we
actually cannot specify universes directly by numbers. *)

is called [Type@{Top.N}] or [Type@{JsCoq.N}] for some [N], depending on the
environment in which you're running this file). We could also instantiate
[prod] with propositions or sets and have it live in [Prop] or [Set]. *)
Check (fun (P: Prop) => P * P).
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure what is the point of this comment.
Plus Prop is complicated.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, more examples that the universe of T * T depends on the universe of T.

(** There are other constraints here but they're unrelated to the inconsistency
that we had with the monomorphic version. *)

(** So, problem solved, right? Nope! Because this only works with inductive
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds like you had a lot of issues with it 😆

src/Explanation_Template_Polymorphism.v Show resolved Hide resolved
Definition pstate_lazy {S T: Type} (t: T) :=
pstate_pure (S := S) (lazy_pure t).

(** Problem solved! ... well, assuming you are ready and able to re-define your
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It sounds a bit bitter

Fail Definition state_lazy {S T: Type} (t: T) :=
state_pure (S := S) (lazy_pure t).

(** Tricks to bypass the limitations of template universe polymorphism generally
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should there be examples ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not really familiar with these, I just know they exist.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suggest creating a subsection as you mentioned and leave it for further contributions

@lephe
Copy link
Contributor Author

lephe commented Aug 18, 2024

Thanks, I'll go through that!

One point on which I need an expert's opinion is the status of template to full universe polymorphism. The latter is more expressive on paper, and I thought it was seen as superseding template polymorphism. I'd heard in particular of attempts to write a universe polymorphic standard library, suggesting that this was desirable.

I indeed had issues with it. ^^" At some point in my last project I debugged universes for 20-30 hours, with some problems arising from the project itself, the others from template polymorphism in the standard library. Having to untangle these and sometimes purge standard types from sections was very painful (hence the slightly bad vibe, sorry—will fix). As of now this project still reimplements the product type btw, so I was truly writing under the assumption that template polymorphism was insufficient.

Can anyone more involved with this stuff comment on how the relationship between these two types of polymorphism should be presented? Is template polymorphism really considered to be superseded by full universe polymorphism (either now or in the future)? Are there contexts in which it is specifically desirable to use one type of polymorphism over the other? Maybe some context about what the project's direction is?

@thomas-lamiaux
Copy link
Collaborator

@lephe
Copy link
Contributor Author

lephe commented Aug 19, 2024

Pushed things. I've addressed all comments so far except for:

Maybe rework the intro to say this tuto discuss the two approaches, their advantages and limitations as it is the end goal. In which case, maybe mention it is a first version or sth ?

Hoping for more background, the post linked above goes into useful technical details but I'm still not sure whether template polymorphism is supposed to be superseded and used for legacy reasons + cases where univ poly blows up or whether these are really two parallel systems that are designed to exist concurrently.

Explain somewhere that whenever Type is used, then a new variable is created or sth and the universe constrains. Maybe add a Print Universes Subgraph (lazyT.u0 lazyT.u1).

I'll have to look up what happens exactly as I don't know directly.

Should there be examples [of tricks to bypass limitations of template universe polymorphism] ?

I also don't know these very well. I just personally inline stuff. Gaëtan recently demonstrated how eta-expansion helps but it seems like the trick should be an entire section by itself. Which would be on topic, IMO.

(** ** 2. Some issues with monomorphic universes *)

(** The core limitations of template universe polymorphism are related to when
it _isn't_ polymorphic, so we can first demonstrate these issues on
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is it ?

index and avoid the bump, but it's not the case in general (e.g., the freer
monad or functor laws). *)

(** We can see this in a universe constraint if we bring them both in a single
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be good here to explain a bit much how each constrains appear because it easy to get lost in the direction of the inequalities

Copy link
Collaborator

@thomas-lamiaux thomas-lamiaux left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

structure looks better

Definition lazy_pure {A: Type} (a: A): lazyT A := lazy (fun _ => a).
Print Universes Subgraph (lazy_pure.u0 lazyT.u0 lazyT.u1).

(** The core of the problem now shows up if we now happen to want products in
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is an example of how the issue arises, but it is not a very general comment.
Would you have a more general explanation for when this issues arise to add in complement just before ?

(** Template universe polymorphism is a middle-ground between monomorphic
universes and proper polymorphic universes that allow for some degree of
flexibility. We can see it in action in the type of [prod] from the standard
library. *)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

About prod is printed but there are no explanations, they come further.
I suggest adding a line or two to discuss the change here.

Definition state (S: Type) := fun (T: Type) => S -> (S * T).
About state.

(** [state.{u0,u1}] correspond to the old [uprod]: the type of [T] is
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you develop here, I have some trouble understanding what is the issue as the type of state is

prod : Type@{prod.u0} -> Type@{prod.u1} -> Type@{max(prod.u0,prod.u1)}
state : Type@{state.u0} -> Type@{state.u1} -> Type@{max(state.u0,state.u1)}

which to me looks like the same as prod and not mprod

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 difference is not in the type, it's in the annotation "X is template universe polymorphic" shown by About. This status affects the way instances of the definition are treated, and that's what makes the difference. I clarified.

@thomas-lamiaux
Copy link
Collaborator

Moving further, I suggest fixing the last tiny issues, then merge it.
It does not matter if it not perfect

@thomas-lamiaux
Copy link
Collaborator

@lephe Have you had time to progress ? I would like to merge it soon

@lephe
Copy link
Contributor Author

lephe commented Aug 31, 2024

I can do the next (supposedly last) pass tomorrow.

@thomas-lamiaux
Copy link
Collaborator

Ok sounds good to me. I'll merge it and then create issues to improve it

@lephe
Copy link
Contributor Author

lephe commented Sep 1, 2024

@thomas-lamiaux Ready to merge if nothing major remains.

@thomas-lamiaux thomas-lamiaux merged commit 8cd5d40 into coq:main Sep 1, 2024
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Development

Successfully merging this pull request may close these issues.

3 participants