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

Made constDecDef capitalize constants in Python #3858

Merged
merged 10 commits into from
Jul 24, 2024
Merged

Made constDecDef capitalize constants in Python #3858

merged 10 commits into from
Jul 24, 2024

Conversation

B-rando1
Copy link
Collaborator

@B-rando1 B-rando1 commented Jul 18, 2024

It capitalizes them, and if the capitalized name shadows another name in the scope it throws an error.

You can see the changes to HelloWorld.py. I also did a test where I declared a second constant MYCONSTANT (capitalized in the GOOL code), and the renderer threw an error, as intended.

Closes #2179

It capitalizes them, and if the capitalized name shadows another name in
the scope it throws an error.
I added an extra boolean parameter to `staticVar` (disregarded by all
but the Python renderer) to say if the static variable is a variable or
a constant.  Then I used that to uppercase static constants in the
Python renderer.

The one thing I don't like about this is that it requires static
variables to be slightly dishonest about their contents: their name is
as given, while their contents are uppercase.
@B-rando1
Copy link
Collaborator Author

I got everything working roughly how it should. I'll just restate my couple of comments from the issue:

  • While the Python renderer does check to see if making a constant's name uppercase would conflict with any existing variable names, it does not check against variable names declared after the constant. So it's still not perfectly safe. With that said, I think we do have all the tools we need to put in more rigorous checking for name conflicts, which would enable greater safety.
  • I'm not sure how I feel about having staticVar hold the original variableName while making the Doc that it uses to render itself all uppercase. It's probably mostly harmless, but there's always a chance of things going wrong down the road when we start having parts of the program lie to other parts. Again, it might be harmless, but it can be hard to tell.

@B-rando1 B-rando1 marked this pull request as ready for review July 18, 2024 19:02
available <- varNameAvailable n
if available
then varDecDef newConst e
else error "Cannot safely capitalize constant."
Copy link
Collaborator

Choose a reason for hiding this comment

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

Do we want this to be an error? We could just warn the user and potentially just use the lowercase version of it (assuming that it is available)…

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

That's a good point. It would be better to do it that way. The only thing I'm not sure about is, how do we keep track of whether or not the renderer used the modified name? When the constant function shows up later, it needs to know whether or not to modify the variable name.

  • We could have it infer whether the modified or unmodified name was used by checking varNameAvailable (variableName v') - if the original name was used, we can probably assume that it was used for the constant in question, else we must have modified it. This would work, but it feels a little sketchy to me.
  • A better way might be to have a mapping from GOOL variable name to rendered variable name floating around in the State. Then in the constant function, we could look up the name to use, and not have to worry about any misplaced assumptions. This would be a bit of extra work to implement, though.

What are your thoughts? I'd rather not do option 2 until @JacquesCarette can take a look. Would it be better to do option 1 for now, as it should be a small change?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

As a side note, what's the best way to print a warning in Haskell? I'm not actually sure if there's anywhere else in GOOL that currently prints warnings. It seems like a shame to wrap all of GOOL in IO String just for this, is there a better way?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Honestly, I'm thinking that "error vs. warning" may be a variability we'd want to introduce at some point. Since this is likely going to be a bigger change, I would create a new issue for tracking our design decisions and working on it in a separate PR (if at all!)

No idea about your warning question 😅

AbsTol = 1.0e-10
RelTol = 1.0e-10
ABSTOL = 1.0e-10
RELTOL = 1.0e-10
Copy link
Collaborator

Choose a reason for hiding this comment

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

What I'd really expect here is ABS_TOL and REL_TOL, to preserve the separation between the two parts of the variable name. Is there a reasonably straightforward way of doing this? (If not, this is likely getting "into the weeds"; NoPCM explicitly uses underscores for its variable names, so we may just want to do that for Projectile as well, potentially enforcing variable names to be all lowercase?)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

That's a good point! It should be possible to do better. Off the top of my head, I think if we just insert a _ wherever there's a lowercase letter on the left and an uppercase letter on the right, it would match what we expect in just about every case. I'll see what functions are available, and get something working.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I made new function to do the renaming, and it handled the few examples we have well.

Now it inserts underscores at boundaries of camelCase names.  The
algorithm to do so is probably not ideal, as it heavily relies on
pattern-matching when higher-order functions might be better.  It works
(at least for now), though.
@JacquesCarette
Copy link
Owner

Some conflicts need resolved before I can merge.

@B-rando1
Copy link
Collaborator Author

Just to summarize the developments, there are a couple of things that aren't ideal with the current state of this implementation:

  • We can't currently be certain when renaming variables that the new name doesn't create a conflict. This is being discussed in Improve variable name conflict detection in GOOL #3867.
  • If we detect a conflict, currently the best we can do is throw an error. There are two reasons for this:
    • As far as I know, GOOL doesn't have the ability to do IO, so we can't issue warnings. I might be wrong here, but that's my current understanding.
    • Even if we were able to issue a warning (and pick a different name), we'd have no way of telling GOOL that we picked a different name. For this we'd want to maintain a mapping from inputted variable name to rendered variable name in the MethodState.

Based on this, what do we want to do with this PR? Is it good enough to merge in its current form, or would it be better to wait for now, and get these safety checks in place first?

@JacquesCarette
Copy link
Owner

More conflicts to resolve.

I am happy to pull this in as-is, and defer the resolution of name conflicts to a different pass (i.e. that conflicts throw a hard error for now).

@JacquesCarette JacquesCarette merged commit 07f5b17 into main Jul 24, 2024
5 checks passed
@JacquesCarette JacquesCarette deleted the PyConsts branch July 24, 2024 06:15
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.

Change constDecDef implementation in Python
3 participants