# (on hold): If you have a function called \`main\`, you may need to tweak it

**URL:** https://discourse.julialang.org/t/on-hold-if-you-have-a-function-called-main-you-may-need-to-tweak-it/103519
**Category:** General Usage
**Created:** [September 4, 2023, 9:27pm UTC](https://discourse.julialang.org/t/on-hold-if-you-have-a-function-called-main-you-may-need-to-tweak-it/103519 "2023-09-04T21:27:52Z")
**Posts on this page:** 20
**Page:** 1

<div class="post-metadata">

### Author: ![Keno](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/keno/32/285_2.png) [@Keno](https://discourse.julialang.org/u/Keno)
#### Post date: [September 4, 2023, 9:27pm UTC](https://discourse.julialang.org/t/on-hold-if-you-have-a-function-called-main-you-may-need-to-tweak-it/103519/1 "2023-09-04T21:27:53Z")

</div>

EDIT: The change is on hold for the time being.

Yesterday I merged [https://github.com/JuliaLang/julia/pull/50974](https://github.com/JuliaLang/julia/pull/50974), which standardizes the pattern

```julia
function main()
# stuff
end
main()

```

The idea here is that by standardizing what the entry-point looks like, future iterations of (Package-,Static-,etc)Compiler will be able to automatically turns scripts with these patterns into compiled applications. However, as a result, if you are currently using this pattern, you will have to adjust it to the standardized variant.

The most common change that is required is:

1. The standard version takes `ARGS`, so you’ll have to add that to your function signature:

```julia
function main(ARGS)
# stuff
end

```

`Base.ARGS` continues to remain available, but it is recommended to switch to the passed `ARGS` instead for future compatibility (if you’re doing argument processing at all - if not you may ignore the argument, but you should still have it in your signature).

1. The main function is called automatically. If you’re living on master, that means you can simply delete the call to `main`. The `julia` driver will call it for you. If you want to support both versions, the recommended incantation is:

```julia
!isinteractive() && VERSION < v"1.11.0-DEV.403" && exit(main(ARGS))

```

I recognize that there may be some inconvenience and breakage in scripts, etc. due to this change, but hopefully it’ll be quick to fix and enable a smooth transition to fancier workflows in the near future.

---

<div class="post-metadata">

### Author: ![Krastanov](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/krastanov/32/6817_2.png) [@Krastanov](https://discourse.julialang.org/u/Krastanov)
#### Post date: [September 5, 2023, 12:41am UTC](https://discourse.julialang.org/t/on-hold-if-you-have-a-function-called-main-you-may-need-to-tweak-it/103519/2 "2023-09-05T00:41:51Z")

</div>

This is neat and useful, but is this not a breaking change that goes against the “spirit” of semantic versioning? I know this question has come up before – I have tried to read through the core developers’ comments in previous threads in order to learn the “flavor” of semver that they have adopted for julia, but this particular change still surprises me. Is there a more formal reasoning here than “by our estimate, this is sufficiently painless of a breakage with sufficiently big upside”?

To be fair, this reasoning seems good enough to me as the upside is obvious and the breakage is indeed minor (I have experienced way worse breakages in python and its ecosystem, for instance), but some more formal description of the reasoning will be helpful in building my mental model of what semver means for julia.

---

<div class="post-metadata">

### Author: ![tecosaur](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tecosaur/32/23206_2.png) [@tecosaur](https://discourse.julialang.org/u/tecosaur)
#### Post date: [September 5, 2023, 3:57am UTC](https://discourse.julialang.org/t/on-hold-if-you-have-a-function-called-main-you-may-need-to-tweak-it/103519/3 "2023-09-05T03:57:18Z")

</div>

I must admit, I don’t understand why `ARGS` can’t be optional, and reading the PR hasn’t clarified this to me.

---

<div class="post-metadata">

### Author: ![mkitti](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mkitti/32/12459_2.png) [@mkitti](https://discourse.julialang.org/u/mkitti)
#### Post date: [September 5, 2023, 4:34am UTC](https://discourse.julialang.org/t/on-hold-if-you-have-a-function-called-main-you-may-need-to-tweak-it/103519/4 "2023-09-05T04:34:59Z")

</div>

Technically any added function or behavior could be considered breaking because there might be a pre-existing function by that name somewhere.

Minor versions according to [https://semver.org/](https://semver.org/) are meant for added functionality that is backwards compatible.

@odow argues here that is actually a non-backwards compatible breaking change:

> <https://github.com/JuliaLang/julia/pull/50974#issuecomment-1705720798>
>
> Isn't the breakage an argument for \`\_\_main\_\_\`? Currently, I think this PR is a b…reaking change that shouldn't be included in a minor release.
> 
> I don't think the similarity with \`\_\_init\_\_\` is a good argument (https://github.com/JuliaLang/julia/pull/50974#issuecomment-1689242915). They could both serve well documented purposes.
> 
> I think \`main()\` is probably more common in the wild than you'd think: https://discourse.julialang.org/search?q=%22main()%22%20order%3Alatest
> 
> Here are just some of the instances in \`jump-dev\`:
> 
> \* https://github.com/jump-dev/benchmarks/blob/4c0e7e88025f7893fefe157d4540e5cb9e8c0e64/src/latency/gurobi\_lqcp.jl
> \* https://github.com/jump-dev/benchmarks/blob/4c0e7e88025f7893fefe157d4540e5cb9e8c0e64/src/latency/ipopt\_bilevel.jl#L40
> \* https://github.com/jump-dev/JuMPPaperBenchmarks/blob/b4a347938f5be2e393e1a1eac7a308d965ce034d/benchmark/facility.jl
> \* https://github.com/jump-dev/Xpress.jl/blob/4d70faf505c0ae04b355248490e9cbc72efed0fa/scripts/docs.jl#L191

Edit: My comment in summary is that I think this should be `Base.main` rather than `Main.main`.

> <https://github.com/JuliaLang/julia/pull/50974#issuecomment-1705945031>
>
> I'm not convinced that \`\_\_main\_\_\` is actually better if we still mean \`Main.\_\_ma…in\_\_\`. Technically, a user could have also defined a function with this name as well.
> 
> Bringing up \`\_\_init\_\_\` is interesting because I have regarded this as effectively main for a module:
> 
> \`\`\`
> julia -e "module Foo \_\_init\_\_() = println(\\"Hello world\\") end"
> Hello world
> \`\`\`
> 
> Because of that I'm not sure if we even need this. If we did have a \`\_\_main\_\_\` would it apply to every module? 
> 
> To make the \`main\` feature backwards compatible, I think we should choose an encapsulating namespace that is clearly not the domain of the user. Rather than \`Main.main\` this really should be \`Base.main\`. This way a user would need to explicitly opt in to use this feature. 
> 
> \`\`\`
> function Base.main(ARGS)
> # New Julia 1.11 main
> end
> \`\`\`
> 
> or
> 
> \`\`\`
> import Base: main
> 
> function main(ARGS)
> # New Julia 1.11 main
> end
> \`\`\`

That would be backwards compatible since you have to import `Base.main` to use this functionality.

---

<div class="post-metadata">

### Author: ![tecosaur](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tecosaur/32/23206_2.png) [@tecosaur](https://discourse.julialang.org/u/tecosaur)
#### Post date: [September 5, 2023, 4:50am UTC](https://discourse.julialang.org/t/on-hold-if-you-have-a-function-called-main-you-may-need-to-tweak-it/103519/5 "2023-09-05T04:50:42Z")

</div>

I see ~400 results for `function main()` here: [grep.app | code search](https://grep.app/search?q=function%20main%28%29&filter%5Blang%5D%5B0%5D=Julia)

---

<div class="post-metadata">

### Author: ![Sukera](https://avatars.discourse-cdn.com/v4/letter/s/ce7236/32.png) [@Sukera](https://discourse.julialang.org/u/Sukera)
#### Post date: [September 5, 2023, 5:17am UTC](https://discourse.julialang.org/t/on-hold-if-you-have-a-function-called-main-you-may-need-to-tweak-it/103519/6 "2023-09-05T05:17:55Z")

</div>

I think this is going to catch many more people off guard once 1.11 is released, potentially for years to come when they rerun old code (or just think of someone trying to reproduce some paper… 😬 ). It’s unfortunate that the breakage was not anticipated, but as a PkgEval would have caught this, it’s a shame that we’re now going to have broken PkgEval until this is solved one way or another.

---

<div class="post-metadata">

### Author: ![goerz](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/goerz/32/3269_2.png) [@goerz](https://discourse.julialang.org/u/goerz)
#### Post date: [September 5, 2023, 5:34am UTC](https://discourse.julialang.org/t/on-hold-if-you-have-a-function-called-main-you-may-need-to-tweak-it/103519/7 "2023-09-05T05:34:37Z")

</div>

I would absolutely consider this a breaking change, but having `Base.main` instead of `Main.main` seems like it would perfectly solve the problem, and be a really nice feature.

---

<div class="post-metadata">

### Author: ![jling](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jling/32/212909_2.png) [@jling](https://discourse.julialang.org/u/jling)
#### Post date: [September 5, 2023, 5:47am UTC](https://discourse.julialang.org/t/on-hold-if-you-have-a-function-called-main-you-may-need-to-tweak-it/103519/8 "2023-09-05T05:47:23Z")

</div>

I think PkgEval is gonna underestimate on this one because many `main()` live in scripts, not in registered packages

---

<div class="post-metadata">

### Author: ![jules](https://avatars.discourse-cdn.com/v4/letter/j/41988e/32.png) [@jules](https://discourse.julialang.org/u/jules)
#### Post date: [September 5, 2023, 5:52am UTC](https://discourse.julialang.org/t/on-hold-if-you-have-a-function-called-main-you-may-need-to-tweak-it/103519/9 "2023-09-05T05:52:19Z")

</div>

Could we throw a very informative error if the main signature doesn’t match the new format and add a command line flag for running without the new entry point? Then there would be an easy path for later to get the old behavior back when running old code. Something like `--nomain` or so.

---

<div class="post-metadata">

### Author: ![Keno](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/keno/32/285_2.png) [@Keno](https://discourse.julialang.org/u/Keno)
#### Post date: [September 5, 2023, 6:24am UTC](https://discourse.julialang.org/t/on-hold-if-you-have-a-function-called-main-you-may-need-to-tweak-it/103519/10 "2023-09-05T06:24:50Z")

</div>

> [@Krastanov](#):
>
> This is neat and useful, but is this not a breaking change that goes against the “spirit” of semantic versioning?

I replied to this on the GitHub issue to avoid bifurcating the discussion.

> [@jules](#):
>
> Could we throw a very informative error if the main signature doesn’t match the new format and add a command line flag for running without the new entry point? Then there would be an easy path for later to get the old behavior back when running old code. Something like `--nomain` or so.

Yes, this is easy to do.

---

<div class="post-metadata">

### Author: ![digital\_carver](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/digital_carver/32/33818_2.png) [@digital\_carver](https://discourse.julialang.org/u/digital_carver)
#### Post date: [September 5, 2023, 7:23am UTC](https://discourse.julialang.org/t/on-hold-if-you-have-a-function-called-main-you-may-need-to-tweak-it/103519/11 "2023-09-05T07:23:28Z")

</div>

> [@Keno](#):
>
> `isinteractive() && VERSION < v"1.11.0-DEV.403" && main(ARGS)`

The first bit is probably intended to be `!isinteractive()`.

---

<div class="post-metadata">

### Author: ![Keno](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/keno/32/285_2.png) [@Keno](https://discourse.julialang.org/u/Keno)
#### Post date: [September 5, 2023, 7:40am UTC](https://discourse.julialang.org/t/on-hold-if-you-have-a-function-called-main-you-may-need-to-tweak-it/103519/12 "2023-09-05T07:40:52Z")

</div>

> [@digital\_carver](#):
>
> The first bit is probably intended to be `!isinteractive()`.

Yes, sorry formatting issue. Will edit the OP.

---

<div class="post-metadata">

### Author: ![sijo](https://avatars.discourse-cdn.com/v4/letter/s/da6949/32.png) [@sijo](https://discourse.julialang.org/u/sijo)
#### Post date: [September 5, 2023, 7:43am UTC](https://discourse.julialang.org/t/on-hold-if-you-have-a-function-called-main-you-may-need-to-tweak-it/103519/13 "2023-09-05T07:43:19Z")

</div>

> [@goerz](#):
>
> having `Base.main` instead of `Main.main` seems like it would perfectly solve the problem

That was also my first impression but now I think it would be a confusing hack: this `main` is really about `Main`, not `Base`, and it’s not a regular method. So `Base.main` would be misleading.

Here’s what Keno wrote in the PR:

> This is not workable, because this is designed to support `Main.main` bindings that are things other than methods of a generic functions. It also breaks the `julia -e 'using MyApp'` thing, because it requires type piracy and if some other package also has a main function, suddenly you’ve broken precompile.

Also, “making compilation first class” is a huge deal and a massive win for the language, and first class means `main` rather than something “convoluted” like `Base.main`.

---

<div class="post-metadata">

### Author: ![mkitti](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mkitti/32/12459_2.png) [@mkitti](https://discourse.julialang.org/u/mkitti)
#### Post date: [September 5, 2023, 7:54am UTC](https://discourse.julialang.org/t/on-hold-if-you-have-a-function-called-main-you-may-need-to-tweak-it/103519/14 "2023-09-05T07:54:30Z")

</div>

Looking around I see that other languages are using configuration files to declare binaries and entry points.

See the `[[bin]]` section in Rust’s Cargo.toml:  
[https://doc.rust-lang.org/cargo/reference/cargo-targets.html#binaries](https://doc.rust-lang.org/cargo/reference/cargo-targets.html#binaries)

Python has even moved in this direction as well.  
[https://packaging.python.org/en/latest/specifications/declaring-project-metadata/#declaring-project-metadata](https://packaging.python.org/en/latest/specifications/declaring-project-metadata/#declaring-project-metadata)  
[https://packaging.python.org/en/latest/specifications/entry-points/](https://packaging.python.org/en/latest/specifications/entry-points/)

While not mutually exclusive, perhaps we should consider if this would be better suited to be declared in (Julia)Project.toml instead of the language?

---

<div class="post-metadata">

### Author: ![fingolfin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fingolfin/32/6033_2.png) [@fingolfin](https://discourse.julialang.org/u/fingolfin)
#### Post date: [September 5, 2023, 8:02am UTC](https://discourse.julialang.org/t/on-hold-if-you-have-a-function-called-main-you-may-need-to-tweak-it/103519/15 "2023-09-05T08:02:21Z")

</div>

There is a gigantic thread [What steps should the Julia community take to bring Julia to the next level of popularity?](https://discourse.julialang.org/t/what-steps-should-the-julia-community-take-to-bring-julia-to-the-next-level-of-popularity/101389) elsewhere.

My reply would be: Don’t casually break user code here when there are fine alternatives (such as using ` __main__ ` instead of `main`).

---

<div class="post-metadata">

### Author: ![digital\_carver](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/digital_carver/32/33818_2.png) [@digital\_carver](https://discourse.julialang.org/u/digital_carver)
#### Post date: [September 5, 2023, 8:22am UTC](https://discourse.julialang.org/t/on-hold-if-you-have-a-function-called-main-you-may-need-to-tweak-it/103519/16 "2023-09-05T08:22:52Z")

</div>

> [@Keno](#):
>
> I replied to this on the GitHub issue to avoid bifurcating the discussion.

Just so everyone is on the same page, @Keno what do you consider on topic here? IMO, Discourse is a much better place to have such (potentially) long, diverging discussions with lots of opinions, so it would be better to _discourage_ people from having this general discussion on the Github PR, and keep the PR comments to specifics about this implementation. Either this Discourse thread or a new thread split away from this would be a better place for the “is this breaking and how do we mitigate that” discussion.

---

<div class="post-metadata">

### Author: ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)
#### Post date: [September 5, 2023, 8:26am UTC](https://discourse.julialang.org/t/on-hold-if-you-have-a-function-called-main-you-may-need-to-tweak-it/103519/17 "2023-09-05T08:26:16Z")

</div>

> [@digital\_carver](#):
>
> Either this Discourse thread or a new thread split away from this would be a better place for the “is this breaking and how do we mitigate that” discussion.

I started one with a proposal.

> [@RFC: give up on SemVer](https://discourse.julialang.org/t/rfc-give-up-on-semver/103536):
>
> I am opening a new topic because I do not want to sidetrack [the one about main()](https://discourse.julialang.org/t/psa-1-11-if-you-have-a-function-called-main-you-may-need-to-tweak-it/103519). This is just the latest of “minor breaking changes” that are technically breaking, yet practically harmless and easy to deal with. [SemVer](https://semver.org/) has become a de facto standard for standardize software versioning, especially in FOSS. It is widely understood, practical, detailed. It is just perfect for packages and libraries. What I am arguing here is that it is not well-suited to a complex interactive language like Julia.…

---

<div class="post-metadata">

### Author: ![Keno](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/keno/32/285_2.png) [@Keno](https://discourse.julialang.org/u/Keno)
#### Post date: [September 5, 2023, 8:31am UTC](https://discourse.julialang.org/t/on-hold-if-you-have-a-function-called-main-you-may-need-to-tweak-it/103519/18 "2023-09-05T08:31:22Z")

</div>

> [@digital\_carver](#):
>
> Just so everyone is on the same page, @Keno what do you consider on topic here?

Well, kind of depends on where the GitHub thread is going - if the change is getting reverted, then there’s broader discussion to be had there. I guess for the moment, that means concrete technical suggestions about what to do instead go on GitHub, general griping about my cowbody attitude can remain here and personal attacks can remain in the usual social media channels 😉 . I realize that I probably set the wrong precedent for that by replying to the question about breaking changes on GitHub.

---

<div class="post-metadata">

### Author: ![Sukera](https://avatars.discourse-cdn.com/v4/letter/s/ce7236/32.png) [@Sukera](https://discourse.julialang.org/u/Sukera)
#### Post date: [September 5, 2023, 9:23am UTC](https://discourse.julialang.org/t/on-hold-if-you-have-a-function-called-main-you-may-need-to-tweak-it/103519/19 "2023-09-05T09:23:46Z")

</div>

Just to point it out here too, with a good warning message, the [compromise](https://github.com/JuliaLang/julia/pull/50974#issuecomment-1706165158) suggested by @Keno seems like a good way forward to me.

---

<div class="post-metadata">

### Author: ![gbaraldi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gbaraldi/32/22101_2.png) [@gbaraldi](https://discourse.julialang.org/u/gbaraldi)
#### Post date: [September 5, 2023, 9:41am UTC](https://discourse.julialang.org/t/on-hold-if-you-have-a-function-called-main-you-may-need-to-tweak-it/103519/20 "2023-09-05T09:41:30Z")

</div>

I disagree that ` __init__ `is like main. Using C as a comparison, it would be `__attribute(constructor)_`, while main is main. One is present in all executables while the other is a special behavior that isn’t super common.

[Next page](https://discourse.julialang.org/t/on-hold-if-you-have-a-function-called-main-you-may-need-to-tweak-it/103519.md?page=2)
