Open B-rando1 opened 5 days ago
It sounds like option 1 is the 'right' choice in the sense that if we go with option 2, we wouldn't be able to generate purely executable Julia scripts. Am I understanding this correctly?
It sounds like option 1 is the 'right' choice in the sense that if we go with option 2, we wouldn't be able to generate purely executable Julia scripts. Am I understanding this correctly?
I'm not quite sure what you mean. As long as we add main()
to the bottom of the file, it would still run with the same behaviour, i.e. an outside user wouldn't be able to tell that the program is inside a function.
If you mean that scripts require a main function and won't run in the global scope, then you are correct. This might conflict with #3512, but at the same time it's no different than the C++ target. Let me know if you think this is something we should avoid.
My bigger concern with option 2 is that it doesn't help external modules that define global variables, for example here. That isn't a perfect example, as the Python version uses a class, and neither target seems to actually use the Constants
file 🤔. It gets the point across anyway, that even with option 2 we still could have cases where we need to separate the representation of global and local variables in GOOL.
The only benefit of still doing option 2, is that it would allow us to safely generate the global
declarations at the function
level rather than the level of while
, for
, function
, etc. As an example:
# Option 1
a = 1 # Needs to be global for some reason
while a < 5
global a # Need to declare at top of while loop, because there's no function to declare at
a += 1
println(a)
end
# Option 2
a = 1 # Needs to be global for some reason
function main()
global a # can safely put this at the top of the function, which might be easier to implement
while a < 5
a += 1
println(a)
end
end
main()
To be honest I'm not completely sure, but my guess is that we have more infrastructure in place to put global
declarations at the top of functions than we do for the top of while
-loops, etc.; so putting the main script inside a function might make the global
declarations easier to implement.
I hope this clears up my reasoning.
We briefly spoke about this in person, but I think I still stand with option 1. Option 1 better captures the intent of a 'unmodular, unbundled'-style program (e.g., one-shot/use-style scripts, as in #3512), unlike Option 2, which would force some amount of modularization. The issue with the comparison to C++ is that it is not a scripting language first, unlike Python and Julia. That being said, 'unmodular, unbundled'-style programs are rather unserious for large projects, so I think it's a nice feature to support for show and tell, but not necessarily something we would expect to seriously use for any non-trivial project.
Sounds good @balacij. I'm not exactly sure, but I think we'll have to add a new field for variables denoting whether they're locally or globally defined. I was hoping that we'd be able to reuse Scope
or Permanence
from ClassInterface.hs, but those are only associated with class attributes, not general variables.
Here are my current thoughts, then:
ScopeSym
to VisibilitySym
, since it has to do with public
vs private
, and the name's confusing.ScopeSym
that has to do with local vs global scope.static
vs dynamic
variable representation.I think this would be worth briefly discussing in #3815.
The conclusions in the last post above (about VisibiliySym
and ScopeSym
make sense. We do want script-like programs with global variables as well as proper programs (and libraries) that don't. So we need to know the difference.
I've been working some more on the Julia render, and I discovered that it's stricter with local scope than other languages. A minimal example is the following:
This throws an error, because the
while
loop introduces a 'soft local' scope (see here for details), and local scopes cannot refer to global variables without explicitly stating that they are. There are two ways to get the intended behaviour:1. Using
global
declaration2. Using a function to define functions in a local scope
If variables are defined in a local scope, then nested local scopes are free to access them.
Analysis
Both options have difficulties.
static
vsdynamic
to keep track of which variables are global vs local. I think that this wouldn't work for any logic occurring in the global scope, though.State
can be used to addglobal
declarations to the top of a scope, similar to how we do imports currently.