-
Notifications
You must be signed in to change notification settings - Fork 374
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
Add recommendation to Effective Gno: limit init
to only being declarable once
#1482
Comments
Furthering the conversation on this, since we are not using this in the same way as Go- rather we are using it as a constructor function to execute only a single time during its lifecycle (at deployment)- having multiple constructors could actually be problematic since those coming from other smart contract languages (eg, Solidity) are accustomed to only declaring a single constructor function within their application, despite having multiple files; in other words, there is no constructor "overloading" allowed. If we choose to continue allowing constructor "overloading," at the very least we should make it apparent in the documentation that whatever data is set within these constructors may get overwritten (especially if the same variable is mentioned) which could lead to unintended consequences or, at least, create a confusing order of operations when determining which |
Just a quick note: there will almost certainly always be ways to create "multiple constructor functions", even if we restrict init to being declarable only once. The reason is that there is a ""secret"" alternative way to express the init function: package hello
func main() {
println(x)
}
var x int
var _ = func() int {
x = 11
return 0
}() This will output Variables can be initialised to any expression without restriction per the Go spec (excluding cyclical references, whereby then initialization order could not be determined). So, while I get your point in theory, unless we also change variable initialization radically for Gno (such as, disabling it entirely, which I don't think is a good idea) there will always be ways for people to have "hidden initialisation side-effects" in other files. |
That's true, but your example isn't a widely used concept and one that is expressed within Go standard documentation (+ Effective Go); in other words, though it works, it feels more like a hack. What I am suggesting is taking what Go programmers ordinarily understand to be normal behavior (multiple |
I'm not completely opposed. It does simplify some things in many areas, and regardless of what road we undertake we should encourage having at most one That being said, we still need to consider that:
For this reason, I think it makes more sense to have |
init
to only being declarable onceinit
to only being declarable once
Yep, I hear what you are saying in terms of deviating from Go spec and I like that recommendation as a good middleground without introducing further complications. It's good we've had a discussion on this to refer back to and support what is found in Effective Gno/best practices/recommendations. |
<!-- please provide a detailed description of the changes made in this pull request. --> This PR ensures in `MemPackage.Validate` that the files that it is being passed are correctly sorted. This is called in many places, among which the VM keeper. **Context:** It was discovered that during the add package process, gno files get processed in an unpredictable order. This relates to the below related issue (#1482) regarding multiple `init` statements being allowed since these `init` statements would potentially be processed in unknown order. Related: #1482 <details><summary>Contributors' checklist...</summary> - [ ] Added new tests, or not needed, or not feasible - [ ] Provided an example (e.g. screenshot) to aid review or the PR is self-explanatory - [ ] Updated the official documentation or not needed - [ ] No breaking changes were made, or a `BREAKING CHANGE: xxx` message was included in the description - [x] Added references to related issues and PRs - [ ] Provided any useful hints for running manual tests - [ ] Added new benchmarks to [generated graphs](https://gnoland.github.io/benchmarks), if any. More info [here](https://github.com/gnolang/gno/blob/master/.benchmarks/README.md). </details> --------- Co-authored-by: Morgan Bazalgette <morgan@morganbaz.com>
Description
Similarly to Go, a
.gno
file can support multipleinit
functions within the same file. This is odd to see though, apparently, is completely valid; deploys, runs and is able to be queried.Playground example
Result:
data: ("bar" std.Address)
, meaning it operates like the LIFO (last-in; first-out) principle.Perhaps, to avoid confusion, and to further differentiate it from Go's
init
, we make the Gnoinit
behave more like themain
function in that it can only be declared once.TODO:
The text was updated successfully, but these errors were encountered: