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

[library] Allow require to load libraries from memory. #17393

Open
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

ejgallego
Copy link
Member

This is one more step in our quest to avoid saving / loading .vo files to disk when not needed.

Most changes are straightforward except for the extension of the command type to include an internalization function.

This is IMHO a good start to the goal of having the vernacular layer access all file-system by a parameterized structure to interpretation, so document managers can properly handle file-system access.

For example, a typical use case in jsCoq is to download a .vo file on Require, but there are many more possibilities.

@ejgallego ejgallego requested review from a team as code owners March 17, 2023 00:38
@coqbot-app coqbot-app bot added the needs: full CI The latest GitLab pipeline that ran was a light CI. Say "@coqbot run full ci" to get a full CI. label Mar 17, 2023
@ejgallego ejgallego added kind: enhancement Enhancement to an existing user-facing feature, tactic, etc. kind: internal API, ML documentation... part: vernac High level command interpretation. labels Mar 17, 2023
@ejgallego
Copy link
Member Author

@coqbot run full CI

@coqbot-app coqbot-app bot removed the needs: full CI The latest GitLab pipeline that ran was a light CI. Say "@coqbot run full ci" to get a full CI. label Mar 17, 2023
@ppedrot ppedrot added the needs: overlay This is breaking external developments we track in CI. label Mar 17, 2023
vernac/library.ml Outdated Show resolved Hide resolved
@@ -254,7 +255,7 @@ let mk_intern_library sum lib digest_lib univs digest_univs proofs =
| Some (_,false) ->
mk_library sum lib (Dvo_or_vi digest_lib) Univ.ContextSet.empty

let intern_from_file lib_resolver dir =
let intern_from_file ~lib_resolver dir =
let f = lib_resolver dir in
Feedback.feedback(Feedback.FileDependency (Some f, DirPath.to_string dir));
Copy link
Contributor

Choose a reason for hiding this comment

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

Considering how lib_resolver and dir are used I think it would make sense to have intern_file : string -> library_t
Then some upper layer would define

let intern_from_file dir =
  let f = Loadpath.try_locate_absolute_library dir in
  Feedback.feedback(Feedback.FileDependency (Some f, DirPath.to_string dir));
  let lib = Library.intern_file f in
  Feedback.feedback (Feedback.FileLoaded(DirPath.to_string dir, f));
  lib

(DirPath.equal dir lsd.md_name check left to intern_library as per my other comment)
(this would be done somewhere where we don't need to abstract over lib_resolver, I guess sysinit since stm depends on sysinit and sysinit needs this API)

Copy link
Member Author

Choose a reason for hiding this comment

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

It makes sense; we could just get rid of the Feedback.File stuff altogether (it was nice for jsCoq), as now users can just provide their own intern function, which should be usable for this.

This PR is usable for my purposes, however the Loadpath API is not.

@SkySkimmer SkySkimmer self-assigned this Mar 17, 2023
@SkySkimmer
Copy link
Contributor

@ejgallego ping

@github-actions github-actions bot added the needs: rebase Should be rebased on the latest master to solve conflicts or have a newer CI run. label Apr 7, 2023
@gares
Copy link
Member

gares commented Apr 13, 2023

The entire patch makes it possible to change the ~intern value at run time.

I don't see a use case, and we fix it once and for all at system initialization time, then this patch becomes much simpler, e.g. no need to changes to vernacextend.

Is there any use case for not having the intern function be given only once?

Copy link
Member

@gares gares left a comment

Choose a reason for hiding this comment

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

simplify the patch making the intern argument part of the system configuration

@coqbot-app
Copy link
Contributor

coqbot-app bot commented May 8, 2023

The "needs: rebase" label was set more than 30 days ago. If the PR is not rebased in 30 days, it will be automatically closed.

@coqbot-app coqbot-app bot added the stale This PR will be closed unless it is rebased. label May 8, 2023
@coqbot-app
Copy link
Contributor

coqbot-app bot commented Jun 7, 2023

This PR was not rebased after 30 days despite the warning, it is now closed.

@coqbot-app coqbot-app bot closed this Jun 7, 2023
@ejgallego ejgallego reopened this Jun 8, 2023
@coqbot-app coqbot-app bot added needs: full CI The latest GitLab pipeline that ran was a light CI. Say "@coqbot run full ci" to get a full CI. and removed needs: rebase Should be rebased on the latest master to solve conflicts or have a newer CI run. stale This PR will be closed unless it is rebased. labels Jun 8, 2023
@ejgallego ejgallego marked this pull request as draft June 8, 2023 13:43
@ejgallego
Copy link
Member Author

The entire patch makes it possible to change the ~intern value at run time.

I don't see a use case, and we fix it once and for all at system initialization time, then this patch becomes much simpler, e.g. no need to changes to vernacextend.

Is there any use case for not having the intern function be given only once?

The main use case here is not so much to dynamically update the .vo intern function, but to follow a methodology where effects are reflected in the types of the commands. In this case, I'd like to have all the commands that require access to the env FS to reflect so in the type so the incremental engine can properly track these dependencies without having to analyze the internals.

@github-actions github-actions bot added the needs: rebase Should be rebased on the latest master to solve conflicts or have a newer CI run. label Sep 6, 2023
@coqbot-app
Copy link
Contributor

coqbot-app bot commented Oct 6, 2023

The "needs: rebase" label was set more than 30 days ago. If the PR is not rebased in 30 days, it will be automatically closed.

Copy link
Contributor

coqbot-app bot commented Mar 8, 2024

The "needs: rebase" label was set more than 30 days ago. If the PR is not rebased in 30 days, it will be automatically closed.

@coqbot-app coqbot-app bot added the stale This PR will be closed unless it is rebased. label Mar 8, 2024
@SkySkimmer
Copy link
Contributor

@gares at the coq call we could not figure out the need for your request for changes.
Please explain more, or alternatively we can merge as is (after rebase of course).

@gares
Copy link
Member

gares commented Mar 20, 2024

It Is a matter of convenience and self documentation. Something set up at coq initialization time is supposed not to change, something you explicitly pass around may change but you pay the price of verbosity.

My last message was asking for use cases where the loader would change at run time. We're these provided in the call?

@ejgallego
Copy link
Member Author

It Is a matter of convenience and self documentation.

How is it setting a global reference more convenient or better documented that declaring the effects a function perform in the type?

Something set up at coq initialization time is supposed not to change, something you explicitly pass around may change but you pay the price of verbosity.

My last message was asking for use cases where the loader would change at run time. We're these provided in the call?

There are use cases where the loader could change, but that's not the point of the current design, as I already explained above a few times.

Reading a .vo file is a side effect that needs to be tracked by the upper layers. It is good methodology to force commands accessing the filesystem to declare this access, so random commands cannot start reading .vo files for example without the upper layers being aware of it.

In this case the "price of verbosity" is pretty small, as compared to the gain of having a more principled API.

@gares
Copy link
Member

gares commented Mar 20, 2024

So there are no concrete use cases you can cite.

@ejgallego
Copy link
Member Author

So there are no concrete use cases you can cite.

My main use case is detecting which vernacular functions do read .vo files.

@gares
Copy link
Member

gares commented Mar 20, 2024

This is not a use case.

@ejgallego
Copy link
Member Author

This is not a use case.

Ok, if you don't want to call it "use case" is fine to me; but this is still an important need.

@SkySkimmer
Copy link
Contributor

This argument about changing the value at runtime is nonsense, both a global ref and a passed parameter can do it.

@gares
Copy link
Member

gares commented Mar 20, 2024

A global ref you set once at initialization time (the sysinit component) is not really a thing meant to be changed at runtime, even if ocaml let's you do it.

My impression from this discussion is that there is no need to pass the parameter, since it does not change while coq runs. If there was a usecase, I would prefer the explicit parameter.

Does it still sound like nonsense?

@ejgallego
Copy link
Member Author

Does it still sound like nonsense?

You seem to focus on some criteria about refs vs parameter for things that change vs not. That's not the point of this PR.

The point of the technical solution chosen is to track which commands are going to access .vo reading, so that if a command needs to read a .vo, it has to declare it in the type.

This is an important need.

@SkySkimmer
Copy link
Contributor

My impression from this discussion is that there is no need to pass the parameter, since it does not change while coq runs. If there was a usecase, I would prefer the explicit parameter.

I don't really understand the preference TBH.

Also I feel like this discussion should have been handled as "make suggestion for change -> Emilio rejects it because he really wants the parameter -> have it your way" instead of blocking the PR.

Copy link
Contributor

coqbot-app bot commented Apr 8, 2024

This PR was not rebased after 30 days despite the warning, it is now closed.

@coqbot-app coqbot-app bot closed this Apr 8, 2024
@mattam82 mattam82 reopened this Apr 9, 2024
Copy link
Member

@gares gares left a comment

Choose a reason for hiding this comment

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

We can move on.

@andres-erbsen
Copy link
Contributor

andres-erbsen commented Apr 9, 2024

@gares FYI my understanding of what Emilio is trying accomplish using parameter-passing here is similar to visibility restrictions that have been broadly successful in simplifying code review. Whether the specific technical approach here is good or not, I don't know, but the overall concept has been quite valuable for me as a developer.

@ejgallego
Copy link
Member Author

ejgallego commented Apr 9, 2024

@andres-erbsen thanks for the reference. Indeed I do remain puzzled because the methodology we are using (isolation of state) is pretty standard in large systems.

Actually the origin of us making Coq command interpretation like this was motivated to write a modern document manager, project we started to study in 2016. We observed some key points:

  • the vernac API is the main entry point for the document manager, and must be descriptive enough as to understand how commands affect state
  • the most important feature for a document manager is incrementality
  • the experience of Makarious Wenzel on turning Isabelle from a CLI tool to a modern UI showed that a functional model was required in order to make the implementation manageable
  • our own experience with the number of bugs associated to Coq due to global state or wrong static analysis (very high)
  • for UI development, incrementality is the most important feature
  • incremental computing is pretty hard in the non-pure setting (see for example R. Leiven keynote on youtube)

Thus we aim to expose a vernac API that can reflect the effects the upper layers care about (in this case access to .vo files) in the types.

ejgallego and others added 2 commits April 9, 2024 20:10
This is one more step in our quest to avoid saving / loading .vo
files to disk when not needed.

Most changes are straightforward except for the extension of the
command type to include an internalization function.

For example, a typical use case in jsCoq is to download a .vo file on
Require, but there are many more possibilities.
Co-authored-by: Gaëtan Gilbert <gaetan.gilbert@skyskimmer.net>
@coqbot-app coqbot-app bot removed needs: rebase Should be rebased on the latest master to solve conflicts or have a newer CI run. stale This PR will be closed unless it is rebased. labels Apr 9, 2024
let save_library dir : library_t =
let sd, md, vmlib, _ast = save_library_struct ~output_native_objects:false dir in
let digest = Safe_typing.Dvo_or_vi (Digest.string "") in
mk_library sd md digest Univ.ContextSet.empty (Vmlibrary.inject vmlib)
Copy link
Member Author

Choose a reason for hiding this comment

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

@ppedrot can you confirm this is correct w.r.t. the new Vmlibrary stuff?

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 so. Unrelatedly the dummy digest part is slightly more concerning to me, we should have an option there or something to signal that the data didn't come from a vo file.

Copy link
Member

Choose a reason for hiding this comment

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

(Also as-is this will never work with native, which is another reason why we should have a distinct library type.)

Copy link
Member Author

Choose a reason for hiding this comment

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

Let me indeed fix the digest stuff before this is merged.

Actually native could be made work with this in the same way: have the kernel relay a .cmxs request to the document manager / whoever is coordinating the filesystem layout.

Indeed it seems to me that a few parts of Coq could benefit from exposing a caching layer (that's the way I see the .vo files, as a cache), for example in #17674 ; I wanted to discuss this in the call actually.

@SkySkimmer SkySkimmer added the needs: progress Work in progress: awaiting action from the author. label Apr 17, 2024
@github-actions github-actions bot added the needs: rebase Should be rebased on the latest master to solve conflicts or have a newer CI run. label Apr 17, 2024
@ppedrot
Copy link
Member

ppedrot commented Apr 19, 2024

Can we try to get this merged quickly before another flamewar roars up?

@ejgallego
Copy link
Member Author

@ppedrot unfortunately it's gonna take me a while to rebase and test given my current workload; feel free to take over with the rebase + fixes due to upstream changes; I can do the testing myself.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind: enhancement Enhancement to an existing user-facing feature, tactic, etc. kind: internal API, ML documentation... needs: full CI The latest GitLab pipeline that ran was a light CI. Say "@coqbot run full ci" to get a full CI. needs: overlay This is breaking external developments we track in CI. needs: progress Work in progress: awaiting action from the author. needs: rebase Should be rebased on the latest master to solve conflicts or have a newer CI run. part: vernac High level command interpretation.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants