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

feat(#1602): default empty versions near to the root object #2501

Draft
wants to merge 19 commits into
base: master
Choose a base branch
from

Conversation

maxonfjvipon
Copy link
Member

@maxonfjvipon maxonfjvipon commented Sep 19, 2023

Ref: #2503

What's done:

  • added flag versioned to Syntax, ParsingTrain, XeListener and few more classes
  • depends on the flag XeListener adds empty ver attribute to ALL objects
  • this empty ver will be replaced with default hash in the next PR
  • depends on the flag ParsingTrain applies move-versions-down.xsl transformation
  • added move-versions-down.xsl transformation that moves ver attribute from the top object to the root (.org). When this sequence of objects will be traspiled to java (smth like Phi.Ф.attr("org").get().attr("eolang").get()...) it will check if there is a "ver" attribute and paste hash right after Phi.Ф so it would be Phi.Ф.attr("hash-here").get().attr("org").get()...

PR-Codex overview

This PR focuses on enabling object versioning in the code.

Detailed summary

  • Added a new boolean flag versioned to the Syntax class constructor.
  • Modified the Syntax class constructor to accept the versioned flag.
  • Added a new method oprop to the Objects interface.
  • Added a new XSL file for applying changes to XML after processing all shifts.
  • Updated the ParsingTrain class to use the new XSL file for versioning.

The following files were skipped due to too many changes: eo-parser/src/main/java/org/eolang/parser/ParsingTrain.java, eo-parser/src/main/java/org/eolang/parser/XeListener.java, eo-parser/src/main/resources/org/eolang/parser/move-versions-deeper.xsl

✨ Ask PR-Codex anything about this PR by commenting with /codex {your question}

@maxonfjvipon
Copy link
Member Author

@volodya-lombrozo please review this one

Copy link
Member

@volodya-lombrozo volodya-lombrozo left a comment

Choose a reason for hiding this comment

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

@maxonfjvipon I've tried to understand the reason behind that changes and I failed. Could you please attach that pr to a particular issue or add more human-readable message, please?

Copy link
Member

@volodya-lombrozo volodya-lombrozo left a comment

Choose a reason for hiding this comment

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

@maxonfjvipon Maybe I have some misunderstanding here, but there are my questions:

  1. Why do you mix adding boolean versioned and move-versions-down.xsl in the same PR?
  2. Which part of the issue will be solved by that PR?

* @param condition Condition
* @param key Key
*/
void oprop(boolean condition, String key);
Copy link
Member

Choose a reason for hiding this comment

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

@maxonfjvipon Could you please rename this method? It is hard to understand what you mean by this abbreviation. I don't think you meant this.

Copy link
Member Author

Choose a reason for hiding this comment

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

@volodya-lombrozo first "o" stands for "optional". Property that will be added depends on giving condition

Copy link
Member

Choose a reason for hiding this comment

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

@maxonfjvipon Why do we need such a method, if in case of condition==false we can just avoid calling this method?

Copy link
Member Author

Choose a reason for hiding this comment

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

@volodya-lombrozo this method is used 8 times in XeListener. We either call oprop 8 times or replace these calls with if (this.versioned) { this.objects.prop(key); } at 8 places

Copy link
Member

Choose a reason for hiding this comment

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

@maxonfjvipon I don't know how it happened that we have xprop method, but both of them xprop and oprop:

  1. Hard readable.
  2. Might produce some issues.

Copy link
Member Author

Choose a reason for hiding this comment

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

@volodya-lombrozo there's nothing about overloading

  1. prop - just adds property, uses attr from Xemlby
  2. xprop - changes property by given xpath, uses xattr from Xembly. It was added here: feat(#2399): new syntax ebnf #2474
  3. oprop - addes property if given condition is TRUE. Actually is a temporary method. When object versioning is implemented it will be removed and all its occurrences will be replaced with prop

@maxonfjvipon
Copy link
Member Author

maxonfjvipon commented Sep 20, 2023

@volodya-lombrozo

  1. Why do you mix adding boolean versioned and move-versions-down.xsl in the same PR?

It just happened that way. I agree that these changes may be in separated PRs

  1. Which part of the issue will be solved by that PR?

It's a preparation step for part 3 of the ticket. Version is moved to the "org" object. So when this xmir will be transpiled to java, to-java.xsl will check if "ver" attribute exists there. If so - to-java.xsl will add extra attr("hash").get() java code

@maxonfjvipon
Copy link
Member Author

@volodya-lombrozo please have a look one more time

* @param condition Condition
* @param key Key
*/
void oprop(boolean condition, String key);
Copy link
Member

Choose a reason for hiding this comment

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

@maxonfjvipon I don't know how it happened that we have xprop method, but both of them xprop and oprop:

  1. Hard readable.
  2. Might produce some issues.

@maxonfjvipon
Copy link
Member Author

@volodya-lombrozo please have a look one more time

Copy link
Member

@volodya-lombrozo volodya-lombrozo left a comment

Choose a reason for hiding this comment

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

@maxonfjvipon Could you please link that pr with the corresponding issue (#2503 I guess?)

@@ -347,8 +360,10 @@ public void enterApplicable(final ProgramParser.ApplicableContext ctx) {
if (ctx.STAR() != null) {
base = "tuple";
this.objects.prop("data", "tuple");
this.objects.oprop(this.versioned, "ver");
Copy link
Member

Choose a reason for hiding this comment

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

@maxonfjvipon If we add ver attribute for all objects without checking versioned, will it break something?

Copy link
Member Author

Choose a reason for hiding this comment

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

@volodya-lombrozo I guess so. For example in DiscoverMojo we have the next code:

private Collection<String> names(final XML xml, final String tojo) {
        return new SetOf<>(
            new Mapped<>(
                (String name) -> this.versioned(name, tojo).toString(),
                new Filtered<>(
                    name -> !name.isEmpty(),
                    xml.xpath(
                        String.join(
                            "",
                            "//o[",
                            "not(starts-with(@base,'.'))",
                            " and @base != 'Q'",
                            " and @base != '^'",
                            " and @base != '$'",
                            " and @base != '&'",
                            " and not(@ref)",
                            "]/string-join((@base,@ver),'",
                            OnReplaced.DELIMITER,
                            "')"
                        )
                    )
                )
            )
        );
    }

It does not check withVersions flag and joins base and ver. If there will be many empty ver attributes, I believe there will be troubles. So versioned field in XeListener is safer

Copy link
Member

Choose a reason for hiding this comment

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

@maxonfjvipon Ok, I've checked it myself. I put versioned=true everywhere (including Syntax constructor), then made 3 changes in XMIR.xsd, add-probes.xsl and OnReplaced.java and some more tests:

7 files changed, 14 insertions(+), 6 deletions(-)

Then I run the tests and got the next result:

[INFO] eo ................................................. SUCCESS [  4.958 s]
[INFO] eo-parser .......................................... SUCCESS [ 12.196 s]
[INFO] eo-maven-plugin .................................... SUCCESS [02:31 min]
[INFO] eo-runtime ......................................... SUCCESS [02:11 min]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  05:00 min
[INFO] Finished at: 2023-09-21T15:11:22+03:00
[INFO] ------------------------------------------------------------------------

It means we can use ver for all objects and everything will work fine. What is the most important - we don't need all this changes related to versioned field in many classes, including the notorious oprop method.

Copy link
Member Author

Choose a reason for hiding this comment

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

@volodya-lombrozo so you suggest replace one set of changes, which:

  • is safer
  • is more controllable (because it's just a boolean variable)
  • lets us do not have extra attributes where they are not needed

with other set of changes, that works for now, but uncontrollable and will lead to the cases, where we will have eo code without any hint to the versions, but there will be some confusing emtpy "ver" attributes in xmir.
The boolean variable is less evil here, I believe

Copy link
Member Author

Choose a reason for hiding this comment

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

@volodya-lombrozo if you personally don't like oprop method, I can remove it and replace its occurrences with its content in XeListener

Copy link
Member

Choose a reason for hiding this comment

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

@maxonfjvipon

  1. Which type of 'safety' are you referring to? I run the tests and showed that everything works fine.
  2. Why do we need the control here? Moreover, as I already mentioned, the solution with boolean values creates even more problems (like that and OCP violation).
  3. The current implementation of XeListener in that PR does exactly what you mentioned: it adds empty "ver" attributes.

@maxonfjvipon
Copy link
Member Author

@volodya-lombrozo please have a look one more time

@@ -347,8 +360,10 @@ public void enterApplicable(final ProgramParser.ApplicableContext ctx) {
if (ctx.STAR() != null) {
base = "tuple";
this.objects.prop("data", "tuple");
this.objects.oprop(this.versioned, "ver");
Copy link
Member

Choose a reason for hiding this comment

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

@maxonfjvipon Ok, I've checked it myself. I put versioned=true everywhere (including Syntax constructor), then made 3 changes in XMIR.xsd, add-probes.xsl and OnReplaced.java and some more tests:

7 files changed, 14 insertions(+), 6 deletions(-)

Then I run the tests and got the next result:

[INFO] eo ................................................. SUCCESS [  4.958 s]
[INFO] eo-parser .......................................... SUCCESS [ 12.196 s]
[INFO] eo-maven-plugin .................................... SUCCESS [02:31 min]
[INFO] eo-runtime ......................................... SUCCESS [02:11 min]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  05:00 min
[INFO] Finished at: 2023-09-21T15:11:22+03:00
[INFO] ------------------------------------------------------------------------

It means we can use ver for all objects and everything will work fine. What is the most important - we don't need all this changes related to versioned field in many classes, including the notorious oprop method.

<!--
Here we move "ver" attribute from the top object deeper to pre-last one (before <o base="Q"/>)

1. The reason of transformation - move version to pre-last object ("org"). Then on "transpile"
Copy link
Member

Choose a reason for hiding this comment

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

@maxonfjvipon It seems that you are tying to apply this transformation in order to solve hypothetical algorithm in the future (that nobody knows, except you). What do you think if we start implement that algorithm first? Then, the first implementation of the algorithm will reveal the need for that transformation (or not). Moreover by doing this it will be more than clear "why we need that transformation".

Copy link
Member Author

Choose a reason for hiding this comment

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

@volodya-lombrozo I believe it would be harder and slower to implement, because we will have to manipulate what is not yet in any form, even if not quite right.
When you don't know for sure how this whole feature should work, you can't just come and say "we need this here, this there, and this out there". You need to start with something small, maybe not quite elegant, just to have something in front of you so you can work with it

Copy link
Member

Choose a reason for hiding this comment

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

@maxonfjvipon Exactly:

You need to start with something small, maybe not quite elegant, just to have something in front of you so you can work with it

But you don't start your work with something random. The first thing you usually do is answer the question, "what do I want to achieve?" and then draw a skeleton. After that, you start adding "meat" to that skeleton. When we have a skeleton and an endpoint, we don't ask questions like "why do we need that change?" because it's obvious.
Otherwise, you'll find yourself in the situation we're currently facing: no clear reason for the change and no understanding of the final goal we aim to achieve. The next day, any developer could easily remove those changes, and they'd be justified in doing so.

Suddenly, I didn't find a good article how to do so, but may be this blog post might explain the idea a bit:

Let’s keep all these unknowns in mind as we try to solve the problem on the highest level of abstraction. Of course, we start with a test

<!--
Here we move "ver" attribute from the top object deeper to pre-last one (before <o base="Q"/>)

1. The reason of transformation - move version to pre-last object ("org"). Then on "transpile"
Copy link
Member

Choose a reason for hiding this comment

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

@maxonfjvipon Exactly:

You need to start with something small, maybe not quite elegant, just to have something in front of you so you can work with it

But you don't start your work with something random. The first thing you usually do is answer the question, "what do I want to achieve?" and then draw a skeleton. After that, you start adding "meat" to that skeleton. When we have a skeleton and an endpoint, we don't ask questions like "why do we need that change?" because it's obvious.
Otherwise, you'll find yourself in the situation we're currently facing: no clear reason for the change and no understanding of the final goal we aim to achieve. The next day, any developer could easily remove those changes, and they'd be justified in doing so.

Suddenly, I didn't find a good article how to do so, but may be this blog post might explain the idea a bit:

Let’s keep all these unknowns in mind as we try to solve the problem on the highest level of abstraction. Of course, we start with a test

@@ -347,8 +360,10 @@ public void enterApplicable(final ProgramParser.ApplicableContext ctx) {
if (ctx.STAR() != null) {
base = "tuple";
this.objects.prop("data", "tuple");
this.objects.oprop(this.versioned, "ver");
Copy link
Member

Choose a reason for hiding this comment

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

@maxonfjvipon

  1. Which type of 'safety' are you referring to? I run the tests and showed that everything works fine.
  2. Why do we need the control here? Moreover, as I already mentioned, the solution with boolean values creates even more problems (like that and OCP violation).
  3. The current implementation of XeListener in that PR does exactly what you mentioned: it adds empty "ver" attributes.

@maxonfjvipon maxonfjvipon marked this pull request as draft September 25, 2023 18:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants