#4323 discusses two recently discovered bugs. Both bugs involve @language directives, but fixing them involves entirely different design questions. This post discusses only bug 2.
A subtle problem
Bug 2 arises when an @<file> node (call it node A) contains no @language directive. Imo, this is bad Leonine style because what Leo writes might depend on @language directives in the node's ancestors! And because of clones, there might even be several different @languages in effect for node A!
Let us say that node A is self-contained if Leo can read and write node A without examining any of node A's ancestors.
The workaround is clear. Good style dictates that all @<file> nodes should contain exactly one @language directive, thereby making them self-contained.
A complication
Leo's read code works without using (or knowing) what node A contains! I only recently realized this surprising fact. The read code gets the file's comment delimiters from the @+leo sentinel line.
In contrast, Leo's write code depends on the @language that is in effect for node A.
The tough choice
We have seen that good Leonine style dictates that all @<file> nodes should contain exactly one @language directive. The question is, what (if anything) should Leo do if that's not true?
Changing the rules for how Leo writes @<file> nodes would constitute a breaking change to Leo. Potentially, existing Leo outlines might write existing external files differently! Leo's code could change, provided that the effect of the code remains exactly the same.
Otoh, forgetting to add an @language directive to an @<file> node puts a time bomb into the outline. Moving node A might change the @language directive in effect for node A. As a result, Leo may mysteriously fail to write the external file correctly! In short, bug 2 may be rare, but it's far from harmless.
A possible solution
PR #4324 provides a fallback policy. The PR uses the language implied by the external file's extension to set the language (comment delimiters) to be used when writing the external file. This policy makes @<file> nodes self-contained.
Alas, this policy might cause existing Leo outlines to write existing external files differently. This could happen if the @language directive in effect for node A did not match the language computed by the file's extension. This actually happened in several of Leo's unit tests, but the PR easily corrected that problem.
Warnings and checks
On startup, Leo could warn if an @<file> node contained no (or more than one) @language directive. Such warnings are always annoying, but perhaps they would be wise.
Summary
PR #4324 changes both Leo's read and write code. However, Leo's read code does not depend on the questions raised here, so Leo's read code should work exactly as before.
Otoh, PR #4324 does implement a new policy for writing @<file> nodes. When writing an external file, the PR uses the file's extension to determine the language in effect, thereby making all @<file> nodes self-contained.
In rare cases, this new policy might change the effect of existing Leo outlines. What do you think? Is this policy reasonable? Is it worth the risk of changing the meaning of outlines?
All of your questions, comments, and suggestions are welcome.
Edward
P.S. The fix for the other bug (bug 1) will likely involve more complex code changes, but the design issues should be non-controversial.
EKR
#4323 discusses two recently discovered bugs. Both bugs involve @language directives, but fixing them involves entirely different design questions. This post discusses only bug 2.
[snip]
The tough choice
We have seen that good Leonine style dictates that all @<file> nodes should contain exactly one @language directive. The question is, what (if anything) should Leo do if that's not true?
Changing the rules for how Leo writes @<file> nodes would constitute a breaking change to Leo. Potentially, existing Leo outlines might write existing external files differently! Leo's code could change, provided that the effect of the code remains exactly the same.
Otoh, forgetting to add an @language directive to an @<file> node puts a time bomb into the outline. Moving node A might change the @language directive in effect for node A. As a result, Leo may mysteriously fail to write the external file correctly! In short, bug 2 may be rare, but it's far from harmless.
A possible solution
PR #4324 provides a fallback policy. The PR uses the language implied by the external file's extension to set the language (comment delimiters) to be used when writing the external file. This policy makes @<file> nodes self-contained.
Alas, this policy might cause existing Leo outlines to write existing external files differently. This could happen if the @language directive in effect for node A did not match the language computed by the file's extension. This actually happened in several of Leo's unit tests, but the PR easily corrected that problem.
PR #4324 provides a fallback policy. The PR uses the language implied by the external file's extension to set the language (comment delimiters) to be used when writing the external file. This policy makes @<file> nodes self-contained.
If a new policy is going to be applied, I think a new leo version sentinel should be applied.
#4323 discusses two recently discovered bugs. Both bugs involve @language directives, but fixing them involves entirely different design questions. This post discusses only bug 2.
...
Bug 2 arises when an @<file> node (call it node A) contains no @language directive. Imo, this is bad Leonine style because what Leo writes might depend on @language directives in the node's ancestors! And because of clones, there might even be several different @languages in effect for node A!