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

Use @main instead of top level code when initializing executable #8371

Open
wants to merge 9 commits into
base: main
Choose a base branch
from

Conversation

plemarquand
Copy link
Contributor

@plemarquand plemarquand commented Mar 14, 2025

Motivation:

Since @main is the general purpose way of marking the entry point to executables, use it over top level code when generating an executable template.

Modifications:

Update the template output when the specified --type is executable.

Result:

The template is now:

@main
struct MyProject {
  static func main() {
    print("Hello, world!")
  }
}

This patch reverts #6197 and partially reverts #6144

Copy link
Contributor

@MaxDesiatov MaxDesiatov left a comment

Choose a reason for hiding this comment

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

This was changed to use top-level code instead of @main not so long ago in #6144, what's the reason for reverting?

@dschaefer2
Copy link
Member

Yeah, this is a pretty major change and not very new user friendly. Maybe this is a separate template?

@dnadoba
Copy link
Contributor

dnadoba commented Mar 14, 2025

Top level code has various bugs that make it very easy to write code that miscompiles e.g.:

print(x)
var x: Set = ["Hello World"]

which crashes at runtime because x isn't initialized before we attempt to print it.

This isn't a great user experience. I think until this is sorted we should prefer an @main entry point.

@bitjammer
Copy link
Contributor

I generally support this change. There should ideally be only one way to define a main entry point, and it should be an explicit form. If top-level code is truly problematic, then we should remove it from the language and be done with it. It would be nice if we could put @main on a bare function, since the function within the structure is static.

I would ask that you consider naming the file/structure something that reflects the target, package, or a noun that reflects what it is, rather than just Main.

@dschaefer2
Copy link
Member

Another aspect of this template, if you are going to @main the main, then you should probably also create the module in a subdirectory of Sources.

I believe that's why the current template is like it is, this is a different use case. The original template is actually an executable package. There is no easy mechanism to add a second module, as you well know.

Which is a back to my point that this, where you're adding a module that's an executable is a different template.

Since `@main` is the general purpose way of marking the entrypoint to
executables, use it over top level code when generating an executable
template.
@shicholas
Copy link

+1 for this change! Having the @main explicit here makes it simpler because it's the same thing everywhere. It's been confusing for me to know that main.Swift runs everything top to bottom instead of the @main tag.

Copy link
Contributor

@dnadoba dnadoba left a comment

Choose a reason for hiding this comment

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

Thanks! LGTM otherwise

plemarquand and others added 2 commits March 24, 2025 13:54
To avoid users having to refactor this later as soon as they want to
introduce a second module, place templated code in `/Sources/PkgName`.

Partially reverts swiftlang#6144
@plemarquand
Copy link
Contributor Author

At @dschaefer2's suggestion I've updated the PR to place the generated Source files for executables/tools into /Sources/PkgName instead of directly in Sources. This will remove the friction of having to move your sources in to a new folder when users want to add another target.

@FranzBusch
Copy link
Member

Love this change! I think we should give the community a heads up in the forums though.

@plemarquand
Copy link
Contributor Author

Copy link
Member

@heckj heckj left a comment

Choose a reason for hiding this comment

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

minor typo

@plemarquand
Copy link
Contributor Author

@heckj Thanks!

@plemarquand
Copy link
Contributor Author

@swift-ci test

@gavineadie
Copy link
Contributor

I've updated the PR to place the generated Source files for executables/tools into /Sources/PkgName instead of directly in Sources.

Do you mean PkgName literally, or the name of the Package? If the former, I'd prefer it unabbreviated -- PackageName.

@plemarquand
Copy link
Contributor Author

@gavineadie Sorry, I was unclear, PkgName refers to the name of the package being created. So swift package init --type executable --package-path ./Foo would create the source file in ./Sources/Foo/Foo.swift.

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.

10 participants