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

vernac/declaremods: make object collection tail-recursive #13731

Merged
merged 1 commit into from
Feb 4, 2021

Conversation

gasche
Copy link
Contributor

@gasche gasche commented Jan 9, 2021

This patch is trying to upstream a jsCoq patch that was written to
solve Stack Overflow issues:

https://github.com/jscoq/jscoq/blob/v8.12/etc/patches/cps.patch

It turns List.fold_right in vernac/declaremods into List.fold_left
followed by List.rev (the output of the fold is a list which is now
constructed in reverse order).

My naive understanding of the code is that the order in which the
collection is performed should not be observable,
only the order of elements in the output, so that the switch from
List.fold_right to List.fold_left should be correct. In particular,
notice that some slight effects (calling Lib.make_oname) were called
from right to left in the collect_* functions, and then from left to
right in the open_* functions.

Of course, reality differs: this modification appears to change
parameter resolution in an obscure use of a pow_N function in
Ncring_tac.v. The existing code would break, and I now have to pass
the (previously implicit) parameters explicitly.

I am not sure whether it means that the current change should be
thrown in the garbage bin (it breaks code), or that there is a bug
somewhere else (sounds somewhat likely to me).

Kind: performance (stack space usage).

(I cannot tell if this change would require an entry in the changelog.)

@gasche gasche requested review from a team as code owners January 9, 2021 16:02
@SkySkimmer
Copy link
Contributor

In particular, notice that some slight effects (calling Lib.make_oname)

That's just a record builder, no effects there

@SkySkimmer
Copy link
Contributor

It turns List.fold_right in vernac/declaremods into List.fold_left
followed by List.rev (the output of the fold is a list which is now
constructed in reverse order).

Why not do the rev first? IIUC it would be closer to what we do currently.

vernac/declaremods.ml Outdated Show resolved Hide resolved
@SkySkimmer SkySkimmer requested a review from a team January 9, 2021 18:01
@gasche
Copy link
Contributor Author

gasche commented Jan 9, 2021

That's just a record builder, no effects there

Ah, I assumed that there was some "fresh name" effect in KerName.make but I checked and indeed you are correct. Thanks!

Why not do the rev first? IIUC it would be closer to what we do currently.

First, I find reverse-after more natural (it's the standard approach for tail-recursive processing of lists). Second, it is more efficient if the number of exported objects is noticeably smaller than the number of processed objects, which sounds likely to me (but then I don't actually understand that code and how it is used). Third, reverse-before makes it harder to work with items that themselves generate lists, as in collect_module_objects (I have to reverse those lists as well, etc.).

This being said, "less natural and vaguely less efficient and less readable" is better than "unexplained failure", so I may try that if the other change you suggested (thanks!) does not fix the issue.

@gasche
Copy link
Contributor Author

gasche commented Jan 9, 2021

I pushed a commit implementing the reverse-first approach, and it seems that the breakage in Ncring_tac.v is gone. I would have a small preference for knowing why it breaks, but I can't investigate myself, and avoiding a stack overflow is better than not.

@gasche
Copy link
Contributor Author

gasche commented Jan 10, 2021

Note: I pushed the previous approach (reverse at the end, breaks one line of code in the stdlib) to a dedicated branch export-tail-recursive-broken, the commit is gasche@852b8c3 . This is in case anyone is curious to investigate why this looking-ok change breaks things. But I realize that you may all have more urgent bugs to hunt that a maybe-not-a-bug in a version of the code that was easily replaced by a fully-correct alternative in this PR.

@ejgallego ejgallego self-assigned this Jan 11, 2021
@SkySkimmer SkySkimmer removed the request for review from a team January 28, 2021 14:37
Copy link
Contributor

@SkySkimmer SkySkimmer left a comment

Choose a reason for hiding this comment

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

@gasche please rebase for fresh CI (elpi failure looks spurious)

@ejgallego I'm taking the assignment considering nothing happened since you assigned.

@SkySkimmer SkySkimmer assigned SkySkimmer and unassigned ejgallego Jan 28, 2021
@SkySkimmer SkySkimmer added kind: anomaly An uncaught exception has been raised. kind: fix This fixes a bug or incorrect documentation. labels Jan 28, 2021
@SkySkimmer SkySkimmer added this to the 8.14+beta1 milestone Jan 28, 2021
@SkySkimmer SkySkimmer added the kind: performance Improvements to performance and efficiency. label Jan 28, 2021
This patch is trying to upstream a jsCoq patch that was written to
solve Stack Overflow issues:

  https://github.com/jscoq/jscoq/blob/v8.12/etc/patches/cps.patch

It turns List.fold_right in vernac/declaremods into List.fold_left
on a reversed lit.
@gasche
Copy link
Contributor Author

gasche commented Jan 28, 2021

Thanks, I just rebased the PR.

@ejgallego
Copy link
Member

@ejgallego I'm taking the assignment considering nothing happened since you assigned.

Thanks for the help, I wanted to investigate the problems with the first approach and get to investigate this code, but didn't get to it in time.

@SkySkimmer
Copy link
Contributor

@coqbot: merge now

@coqbot-app coqbot-app bot merged commit 9485db5 into coq:master Feb 4, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind: anomaly An uncaught exception has been raised. kind: fix This fixes a bug or incorrect documentation. kind: performance Improvements to performance and efficiency.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants