You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Main entrypoint take 3 - revenge of the macro (#51435)
As they say, if at first you don't succeed, try again, then try again,
add an extra layer of indirection and take a little bit of spice from
every other idea and you've got yourself a wedding cake. Or something
like that, I don't know - at times it felt like this cake was getting a
bit burnt.
Where was I?
Ah yes.
This is the third edition of the main saga (#50974, #51417). In this
version, the spelling that we'd expect for the main use case is:
```
function (@main)(ARGS)
println("Hello World")
end
```
This syntax was originally proposed by `@vtjnash`. However, the
semantics here are slightly different. `@main` simply expands to `main`,
so the above is equivalent to:
```
function main(ARGS)
println("Hello World")
end
@main
```
So `@main` is simply a marker that the `main` binding has special
behavior. This way, all the niceceties of import/export, etc. can still
be used as in the original `Main.main` proposal, but there is an
explicit opt-in and feature detect macro to avoid executing this when
people do not expect.
Additionally, there is a smooth upgrade path if we decide to
automatically enable `Main.main` in Julia 2.0.
See also [Scripting](@ref man-scripting) for more information on writing Julia scripts.
41
41
42
+
## The `Main.main` entry point
43
+
44
+
As of Julia, 1.11, Base export a special macro `@main`. This macro simply expands to the symbol `main`,
45
+
but at the conclusion of executing a script or expression, `julia` will attempt to execute the function
46
+
`Main.main(ARGS)` if such a function has been defined and this behavior was opted into
47
+
using the `@main macro`. This feature is intended to aid in the unification
48
+
of compiled and interactive workflows. In compiled workflows, loading the code that defines the `main`
49
+
function may be spatially and temporally separated from the invocation. However, for interactive workflows,
50
+
the behavior is equivalent to explicitly calling `exit(main(ARGS))` at the end of the evaluated script or
51
+
expression.
52
+
53
+
!!! compat "Julia 1.11"
54
+
The special entry point `Main.main` was added in Julia 1.11. For compatibility with prior julia versions,
55
+
add an explicit `@isdefined(var"@main") ? (@main) : exit(main(ARGS))` at the end of your scripts.
56
+
57
+
To see this feature in action, consider the following definition, which will execute the print function despite there being no explicit call to `main`:
58
+
59
+
```
60
+
$ julia -e '(@main)(ARGS) = println("Hello World!")'
61
+
Hello World!
62
+
$
63
+
```
64
+
65
+
Only the `main` binding in the `Main`, module has this special behavior and only if
66
+
the macro `@main` was used within the defining module.
67
+
68
+
For example, using `hello` instead of `main` will result not result in the `hello` function executing:
69
+
70
+
```
71
+
$ julia -e 'hello(ARGS) = println("Hello World!")'
72
+
$
73
+
```
74
+
75
+
and neither will a plain definition of `main`:
76
+
```
77
+
$ julia -e 'main(ARGS) = println("Hello World!")'
78
+
$
79
+
```
80
+
81
+
However, the opt-in need not occur at definition time:
82
+
$ julia -e 'main(ARGS) = println("Hello World!"); @main'
83
+
Hello World!
84
+
$
85
+
86
+
The `main` binding may be imported from a package. A hello package defined as
87
+
88
+
```
89
+
module Hello
90
+
91
+
export main
92
+
(@main)(ARGS) = println("Hello from the package!")
93
+
94
+
end
95
+
```
96
+
97
+
may be used as:
98
+
99
+
```
100
+
$ julia -e 'using Hello'
101
+
Hello from the package!
102
+
$ julia -e 'import Hello' # N.B.: Execution depends on the binding not whether the package is loaded
103
+
$
104
+
```
105
+
106
+
However, note that the current best practice recommendation is to not mix application and reusable library
107
+
code in the same package. Helper applications may be distributed as separate pacakges or as scripts with
108
+
separate `main` entry points in a package's `bin` folder.
0 commit comments