Zulip Chat Archive
Stream: mathlib4
Topic: linting for unclosed sections?
Kim Morrison (Jul 02 2024 at 04:53):
Does anyone have an idea about linting for unclosed sections? They are quite common in Mathlib, and they are tedious to encounter when doing minimizations.
Damiano Testa (Jul 02 2024 at 06:09):
Oh, that's a challenge!
Damiano Testa (Jul 02 2024 at 06:10):
Should they be closed at the end of file?
Johan Commelin (Jul 02 2024 at 06:13):
They should be closed before the scope that contains them is closed. This containing scope could be a file/namespace/section.
Damiano Testa (Jul 02 2024 at 06:13):
Ok, I meant to say "they should be closed at the latest point where it is legal to do so"?
Damiano Testa (Jul 02 2024 at 06:14):
An alternative being "the earliest place where the file still builds".
Johan Commelin (Jul 02 2024 at 06:17):
Well, I think you are going one step beyond, and thinking already about a refactor tool.
As a first step it would of course already be useful to have the warning.
Damiano Testa (Jul 02 2024 at 06:19):
Ok, I'll think about this. I've been indeed also thinking of producing the refactor tool with every linter, but not actively writing one for every linter.
Damiano Testa (Jul 02 2024 at 06:19):
I'll have to see how/if sections leave traces in Scope
(or elsewhere).
Damiano Testa (Jul 02 2024 at 06:50):
"Anonymous" sections (as in section
) leave very little trace, while "named" sections (as in section Easy_lemmas
) do modify the "header". What do you think of linting against anonymous section
s and then catching missing end section
?
Johan Commelin (Jul 02 2024 at 06:57):
How many anonymous sections are there in mathlib?
Just to be sure: you are proposing that they all become named, right?
Damiano Testa (Jul 02 2024 at 06:58):
I have not checked how many unnamed sections there are and yes, the linter would ask to name them.
Damiano Testa (Jul 02 2024 at 06:58):
Technically, this is not needed, as I can simply begin linting for the named ones and then think about the unnamed ones.
Damiano Testa (Jul 02 2024 at 06:59):
However, unnamed sections are a little weird anyway...
Kim Morrison (Jul 02 2024 at 06:59):
Please let's not do anything disruptive like forbidding anonymous sections!
Kim Morrison (Jul 02 2024 at 06:59):
I just want to warn on unclosed sections (named or not) at EOF.
Kim Morrison (Jul 02 2024 at 07:00):
The problem is that when minimising, we copy one file into another and unclosed sections need to be repaired.
Damiano Testa (Jul 02 2024 at 07:02):
Ok, grepping suggests that there are close to 2k unnamed sections. I will think of how to handle them without flagging them.
Michael Rothgang (Jul 02 2024 at 08:12):
You can probably write a simple-minded text-based linter for this, right? As in, ignore multi-line comments and keep a stack of all open sections and namespace, which you update as you encounter them. (No time until end of this week, but I could also try writing the latter.)
Damiano Testa (Jul 02 2024 at 08:54):
Yes, I am trying exactly this at the moment.
Damiano Testa (Jul 02 2024 at 08:56):
Oh, actually it seems that the only way to have open namespaces/sections is if they accumulate at the end of a file. So the only thing to do is check that the last command of each file closes everything!
Eric Wieser (Jul 02 2024 at 09:13):
Kim Morrison said:
I just want to warn on unclosed sections (named or not) at EOF.
Could this warning be built into lean core?
Eric Wieser (Jul 02 2024 at 09:14):
It seems like the existing section elaborator would know if there are unclosed sections (it surely did in lean 3), and so it could emit the lint warning itself rather than in a dedicated linter
Eric Wieser (Jul 02 2024 at 09:16):
Kim Morrison said:
The problem is that when minimising, we copy one file into another and unclosed sections need to be repaired.
An alternative solution would be to allow
section outer
section unclosed
end outer
which means you can assemble your mwe by adding section my_file
around the entire file contents. This feels like something you might already want to do today to insulate variable
s and set_option
s
Kim Morrison (Jul 02 2024 at 09:18):
I'd prefer not to touch any core behaviour here. This would add work for me rather than save it. I know Mario has expressed a desire for the opposite convention in Batteries (leave out all unnecessary end
at EOF).
Damiano Testa (Jul 02 2024 at 11:43):
#14352 -- let's see if it works!
Damiano Testa (Jul 02 2024 at 12:12):
It looks like there might be ~1k files with missing end
: should I add the ending end
s?
Kim Morrison (Jul 02 2024 at 12:16):
Ouch. I would like this, but maybe we should get some +1s before proceeding.
Kevin Buzzard (Jul 02 2024 at 12:29):
I thought "you don't have to end sections now" was a feature not a bug, and IIRC this was the sort of change from Lean 3 that the devs were loving. Are we saying that this is no longer considered good style in mathlib?
Kim Morrison (Jul 02 2024 at 12:31):
My understanding is that Mathlib has for the most part been closing sections, but that it has not been consistent.
Kim Morrison (Jul 02 2024 at 12:31):
I think Damiano's number says that roughly 80% of files close their sections.
Mario Carneiro (Jul 02 2024 at 12:31):
keep in mind that 80% of files are from lean 3 which required sections to be closed
Mario Carneiro (Jul 02 2024 at 12:32):
noncomputable section
is not a section that should need to be closed
Damiano Testa (Jul 02 2024 at 12:32):
It was easy enough to add the first layer of end
: 936 files.
Kim Morrison (Jul 02 2024 at 12:32):
Admittedly copilot usually manages to write the end
statements for me when I am minimizing and this causes an error.
Mario Carneiro (Jul 02 2024 at 12:33):
surely copilot doesn't have enough context length to get end
right?
Kim Morrison (Jul 02 2024 at 12:33):
It reads the error message
Kim Morrison (Jul 02 2024 at 12:33):
(I think???)
Mario Carneiro (Jul 02 2024 at 12:33):
ok we should clearly make autocomplete better there
Damiano Testa (Jul 02 2024 at 12:34):
(also, my script is actually closing noncomputable section
s, I think.)
Mario Carneiro (Jul 02 2024 at 12:34):
and we could definitely have a code action at global scope to close the last section/namespace
Damiano Testa (Jul 02 2024 at 12:37):
(Btw, I am not particularly invested in this: I went for a quick hack to get missing end
s and I do not have a strong opinion on whether I am happy or not with the change!)
Damiano Testa (Jul 02 2024 at 15:32):
In case anyone is curious, the linter is happy with #14352
Kim Morrison (Jul 03 2024 at 01:12):
@Damiano Testa how does this linter handle noncomputable section
? Mario asked that that be allowed with a corresponding end
, and this seems quite reasonable to me.
Damiano Testa (Jul 03 2024 at 03:42):
The linter treats noncomputable section
like any other section
and asks to close it.
Damiano Testa (Jul 03 2024 at 03:44):
What should it do with
section
noncomputable section
end
end
?
Are both final ends optional? Or should only an "outermost" noncomputable section
be allowed to not end
?
Damiano Testa (Jul 03 2024 at 05:27):
I adapted the linter. The behaviour now should be that the linter asks to close all dangling section
s/namespace
s, with the exception of the "outermost" noncomputable section
, regardless of whether or not it is named.
Damiano Testa (Jul 03 2024 at 05:28):
I imagine that it is never the case that there is a noncomputable section
nested inside a noncomputable section
, but I am not sure and the linter does not check this.
Damiano Testa (Jul 03 2024 at 07:56):
I am trying out the "new" linter that allows dangling noncomputable section
to be left open in #14378.
There are only 200 files in Mathlib/*
that need an end
to please the "noncomputable
-admitting linter", as opposed to the ~900 files that the stricter linter flagged.
Damiano Testa (Jul 03 2024 at 07:57):
TIL: did you know that
section A.B
end B
end A
is valid?
Damiano Testa (Jul 03 2024 at 08:58):
#14378 added end
s to 212 files and passed CI. No outmost open noncomputable section
has been closed.
Yaël Dillies (Jul 03 2024 at 09:17):
I did! I think I used this behaviour exactly once so far, though :sweat_smile:
Kim Morrison (Jul 03 2024 at 09:19):
Damiano Testa said:
TIL: did you know that
section A.B end B end A
is valid?
It works the other way around as well, I think. You can probably even section a.b; section c.d.e; end a.b.c; end d.e
if you are feeling antisocial!
Mario Carneiro (Jul 03 2024 at 09:57):
an even more amusing variant of this:
section
section Foo
end «».Foo
Damiano Testa (Jul 03 2024 at 13:44):
Btw, the linter is no longer going to allow this feature:
section
end section
Damiano Testa (Jul 03 2024 at 13:45):
(Mathlib has this twice.)
Kevin Buzzard (Jul 03 2024 at 17:15):
Given that this is silly and should be removed, I think it's great that we can lint for it!
Damiano Testa (Jul 03 2024 at 18:08):
Is the consensus that the "strict" linter that also wants to close noncomputable section
s is not desired?
If this is the case, I will close that PR (#14352) and leave just the one with the "permissive" linter (#14378) and the discussion can continue about that one.
Johan Commelin (Jul 04 2024 at 07:38):
I for one wouldn't mind requiring noncomputable section
to be closed. But I don't have a strong opinion about it.
Damiano Testa (Jul 04 2024 at 08:20):
The way the linter is set up, to not allow dangling noncomputable section
s it suffices to remove this line (and then deal with adding end
s wherever the linter tells you to).
As allowing dangling noncomputable
s is probably less controversial than not allowing them, I have closed the other PR anyway. I can always re-open it later, or simply remove the line, re-run the linter and the autocorrection and prepare a fresh one!
Damiano Testa (Jul 06 2024 at 15:39):
Are there any more thoughts on #14378?
It is a bit insidious to maintain, since splitting a file need not trigger a merge conflict, but might make the linter unhappy with merging master.
Johan Commelin (Jul 06 2024 at 16:35):
@Michael Rothgang @Jon Eugster could one of you maybe review this please?
Michael Rothgang (Jul 06 2024 at 21:52):
Sure - I'll try to review this by Wednesday. (Might happen sooner, but no promises: I'm decompressing from having my thesis submitted, so am taking things slightly slower.)
Jon Eugster (Jul 08 2024 at 07:06):
I'm on vacation until the 18th, sorry. I'd take a look if it still remains open by then
David Renshaw (Jul 13 2024 at 01:42):
How do I disable this linter? I tried putting ⟨
linter.endOf, false⟩ in
leanOptions` in my lakefile.lean, but that yielded
invalid -D parameter, unknown configuration option 'linter.endOf'
Michael Rothgang (Jul 13 2024 at 01:51):
David Renshaw said:
How do I disable this linter? I tried putting
⟨
linter.endOf, false⟩in
leanOptions` in my lakefile.lean, but that yieldedinvalid -D parameter, unknown configuration option 'linter.endOf'
You're in a project depending on mathlib, right? Short answer, as far as I know is "lobby the lint author to restrict the lint to mathlib".
David Renshaw (Jul 13 2024 at 01:52):
yes, for a project that depends on mathlib
Michael Rothgang (Jul 13 2024 at 01:53):
Longer answer: AFAIK, only built-in linters can be disabled in the lakefile (that's lean4#3403, feel free to upvote if you care about this). The endOf linter is defined in mathlib, hence is not built in.
Michael Rothgang (Jul 13 2024 at 02:30):
#14696 deactivates the linter outside of mathlib - for discussion.
That said: is simply complying by the linter onerous for you? #14378 has a shell script to automatically fix all errors.
David Renshaw (Jul 13 2024 at 02:51):
I ran that script and it added a bunch of spurious sorries
David Renshaw (Jul 13 2024 at 02:52):
in any file that had a sorry, it added its own sorry, causing an error
David Renshaw (Jul 13 2024 at 02:53):
This is in Compfiles, where every file has a single namespace (so unclosed namespaces pose no danger to refactoring), and I want to avoid extra clutter
Damiano Testa (Jul 13 2024 at 02:57):
The script was written assuming that the build would only report warnings from the linter. I can adapt it to be more robust, if that is desirable, or, if you prefer to use refactor
, a better solution would be using that.
Damiano Testa (Jul 13 2024 at 02:58):
(The issue is that refactor
is still a PR.)
Damiano Testa (Jul 13 2024 at 03:24):
The script below should be more robust:
eval "$(
lake build |
sed -z 's=\n\nend=\\n\\nend=g; s='"'"'\n=\\n&=g' |
awk -F: '/^warning.*unclosed sections or namespaces; expected:/ {
line=$0
gsub(/^.*unclosed sections or namespaces; expected: /, "", line)
printf("printf %s >> %s\n", line, $2)
}'
)"
David Renshaw (Jul 13 2024 at 10:52):
Thanks. That works, though I would still prefer to be able to disable the linter.
Damiano Testa (Jul 13 2024 at 12:13):
I agree that it would be useful to set global options in projects: the issue about this is lean4#3403.
Michael Rothgang (Jul 14 2024 at 11:49):
Thinking about this again, I'm still not very happy with the name endOf
: what do you think about renaming it to unclosedScope
? (Yes, the word "scope" is jargon, but I find the new name less cryptic that endOf
.)
Damiano Testa (Jul 14 2024 at 13:19):
I'm happy to change name, other options: missingEnd
or openSection
(even though a namespace
might also be open)?
Michael Rothgang (Jul 14 2024 at 13:52):
Namespaces can also be open. openSectionOrNamespace
feel a bit clunky for me.
Kim Morrison (Jul 14 2024 at 14:39):
I like missingEnd
.
Michael Rothgang (Jul 15 2024 at 12:37):
Filed #14758 doing the rename.
Last updated: May 02 2025 at 03:31 UTC