# Why the parenthesis around \`(@main)\`?

**URL:** https://discourse.julialang.org/t/why-the-parenthesis-around-main/123017
**Category:** New to Julia
**Tags:** question
**Created:** [November 24, 2024, 3:28pm UTC](https://discourse.julialang.org/t/why-the-parenthesis-around-main/123017 "2024-11-24T15:28:29Z")
**Posts on this page:** 18
**Page:** 1

<div class="post-metadata">

### Author: ![world-peace](https://avatars.discourse-cdn.com/v4/letter/w/9f8e36/32.png) [@world-peace](https://discourse.julialang.org/u/world-peace)
#### Post date: [November 24, 2024, 3:28pm UTC](https://discourse.julialang.org/t/why-the-parenthesis-around-main/123017/1 "2024-11-24T15:28:29Z")

</div>

Since Julia’s most recent release (1.11) it seems the de-facto way to write a `main` (entrypoint function) is

```julia
function (@main)(args)
    println("hello world")
end

```

Why the parenthesis around `@main`?

Not that it matters, I’m just curious.

---

<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: [November 24, 2024, 3:33pm UTC](https://discourse.julialang.org/t/why-the-parenthesis-around-main/123017/2 "2024-11-24T15:33:16Z")

</div>

Because `@main` is not supposed to be applied to `args`, it just returns the `main` symbol as if you had written `function main` plus some behind the scenes bookkeeping

---

<div class="post-metadata">

### Author: ![savq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/savq/32/22063_2.png) [@savq](https://discourse.julialang.org/u/savq)
#### Post date: [November 26, 2024, 4:20am UTC](https://discourse.julialang.org/t/why-the-parenthesis-around-main/123017/3 "2024-11-26T04:20:58Z")

</div>

You could also call `@main` as a function-like macro

```julia
function @main()(args)
    println("hello world")
end

```

which makes Jules’ point clearer, but looks kinda weird.

---

<div class="post-metadata">

### Author: ![world-peace](https://avatars.discourse-cdn.com/v4/letter/w/9f8e36/32.png) [@world-peace](https://discourse.julialang.org/u/world-peace)
#### Post date: [November 26, 2024, 10:26am UTC](https://discourse.julialang.org/t/why-the-parenthesis-around-main/123017/4 "2024-11-26T10:26:29Z")

</div>

In this context, what does the macro do?

Does it just expand to the word `main`?

---

<div class="post-metadata">

### Author: ![sgaure](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sgaure/32/14779_2.png) [@sgaure](https://discourse.julialang.org/u/sgaure)
#### Post date: [November 26, 2024, 11:22am UTC](https://discourse.julialang.org/t/why-the-parenthesis-around-main/123017/5 "2024-11-26T11:22:30Z")

</div>

Here’s the definition (see it with `julia> @less @main`)

```julia
macro main(args...)
    if !isempty(args)
        error("USAGE: `@main` is expected to be used as `(@main)` without macro arguments.")
    end
    if isdefined( __module__ , :main)
        if Base.binding_module( __module__ , :main) !== __module__
            error("USAGE: Symbol `main` is already a resolved import in module $( __module__ ). `@main` must be used in the defining module.")
        end
    end
    Core.eval( __module__ , quote
        # Force the binding to resolve to this module
        global main
        global var"# __main_is_entrypoint__ #"::Bool = true
    end)
    esc(:main)
end

```

---

<div class="post-metadata">

### Author: ![world-peace](https://avatars.discourse-cdn.com/v4/letter/w/9f8e36/32.png) [@world-peace](https://discourse.julialang.org/u/world-peace)
#### Post date: [November 26, 2024, 11:30am UTC](https://discourse.julialang.org/t/why-the-parenthesis-around-main/123017/6 "2024-11-26T11:30:25Z")

</div>

That’s odd. Should I be able to do this?

```julia
function (@main)(args)
    println("first main")
end

function (@main)(args)
    println("second main")
end

```

```julia
$ julia main.jl
second main

```

---

<div class="post-metadata">

### Author: ![sgaure](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sgaure/32/14779_2.png) [@sgaure](https://discourse.julialang.org/u/sgaure)
#### Post date: [November 26, 2024, 11:34am UTC](https://discourse.julialang.org/t/why-the-parenthesis-around-main/123017/7 "2024-11-26T11:34:25Z")

</div>

> [@world-peace](#):
>
> That’s odd. Should I be able to do this?
> 
> ```julia
> function (@main)(args)
> println("first main")
> end
> 
> function (@main)(args)
> println("second main")
> end
> 
> ```

Just like with every method. However, you’ll get a warning if you start julia with `--warn-overwrite=yes`.

---

<div class="post-metadata">

### Author: ![world-peace](https://avatars.discourse-cdn.com/v4/letter/w/9f8e36/32.png) [@world-peace](https://discourse.julialang.org/u/world-peace)
#### Post date: [November 26, 2024, 11:39am UTC](https://discourse.julialang.org/t/why-the-parenthesis-around-main/123017/8 "2024-11-26T11:39:34Z")

</div>

I can’t read macros very well yet.

What is this doing?

```julia
    if isdefined( __module__ , :main)
        if Base.binding_module( __module__ , :main) !== __module__
            error("USAGE: Symbol `main` is already a resolved import in module $( __module__ ). `@main` must be used in the defining module.")
        end
    end

```

---

<div class="post-metadata">

### Author: ![sgaure](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sgaure/32/14779_2.png) [@sgaure](https://discourse.julialang.org/u/sgaure)
#### Post date: [November 26, 2024, 11:43am UTC](https://discourse.julialang.org/t/why-the-parenthesis-around-main/123017/9 "2024-11-26T11:43:12Z")

</div>

It checks if `main` is already defined and bound in the current module. If it’s bound in another module, it throws an error. I.e. if you have done something like `import OtherModule: main`.

---

<div class="post-metadata">

### Author: ![world-peace](https://avatars.discourse-cdn.com/v4/letter/w/9f8e36/32.png) [@world-peace](https://discourse.julialang.org/u/world-peace)
#### Post date: [November 26, 2024, 11:45am UTC](https://discourse.julialang.org/t/why-the-parenthesis-around-main/123017/10 "2024-11-26T11:45:54Z")

</div>

Ok thank you.

Finally, what does this bit do?

```julia
esc(:main)

```

I looked at the documentation for `esc`.

---

<div class="post-metadata">

### Author: ![sgaure](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sgaure/32/14779_2.png) [@sgaure](https://discourse.julialang.org/u/sgaure)
#### Post date: [November 26, 2024, 11:50am UTC](https://discourse.julialang.org/t/why-the-parenthesis-around-main/123017/11 "2024-11-26T11:50:12Z")

</div>

That’s what the macro returns, just the symbol `:main`. Without `esc` the macro system will “sanitize” the return value. E.g. making variables local etc. so they don’t interfere with the caller’s context. This sanitation can be avoided with `esc`. I don’t think it’s strictly needed in this case. A symbol is a symbol.

---

<div class="post-metadata">

### Author: ![sgaure](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sgaure/32/14779_2.png) [@sgaure](https://discourse.julialang.org/u/sgaure)
#### Post date: [November 26, 2024, 11:54am UTC](https://discourse.julialang.org/t/why-the-parenthesis-around-main/123017/12 "2024-11-26T11:54:54Z")

</div>

Consider the following macro which just returns its input:

```julia
julia> module Foo
       macro bar(s)
           s
       end
       macro baz(s)
           esc(s)
       end
       end
Main.Foo
julia> @macroexpand Foo.@bar(:foo)
:(:foo)

julia> @macroexpand Foo.@bar(a)
:(Main.Foo.a)

julia> @macroexpand Foo.@baz(a)
:a

```

---

<div class="post-metadata">

### Author: ![world-peace](https://avatars.discourse-cdn.com/v4/letter/w/9f8e36/32.png) [@world-peace](https://discourse.julialang.org/u/world-peace)
#### Post date: [November 26, 2024, 12:00pm UTC](https://discourse.julialang.org/t/why-the-parenthesis-around-main/123017/13 "2024-11-26T12:00:23Z")

</div>

Ah, ok, so sanitization means to do something which prevents a macro from interacting with variables which are in the same scope as where a macro is used?

For example, in your second example `@macroexpand Foo.@bar(a)`, `a` here is some local variable (it doesn’t actually exist, but the fact you used the symbol a as an argument implies that it could exist as a local variable?) but because of sanitization, when `bar` returns `s`, `a` has become sanitized so that it is no longer the local `Main.a` but `Main.Foo.a`?

Not sure if I’m quite following the logic correctly.

---

<div class="post-metadata">

### Author: ![GunnarFarneback](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gunnarfarneback/32/1827_2.png) [@GunnarFarneback](https://discourse.julialang.org/u/GunnarFarneback)
#### Post date: [November 26, 2024, 12:01pm UTC](https://discourse.julialang.org/t/why-the-parenthesis-around-main/123017/14 "2024-11-26T12:01:49Z")

</div>

> [@sgaure](#):
>
> A symbol is a symbol.

I thought that’s what it isn’t?

```julia
julia> module Foo
       macro escaped() esc(:main) end
       macro unescaped() :main end
       end
Main.Foo

julia> @macroexpand Foo.@escaped
:main

julia> @macroexpand Foo.@unescaped
:(Main.Foo.main)

```

---

<div class="post-metadata">

### Author: ![sgaure](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sgaure/32/14779_2.png) [@sgaure](https://discourse.julialang.org/u/sgaure)
#### Post date: [November 26, 2024, 12:10pm UTC](https://discourse.julialang.org/t/why-the-parenthesis-around-main/123017/15 "2024-11-26T12:10:08Z")

</div>

> [@GunnarFarneback](#):
>
> I thought that’s what it isn’t?

Ah, right, the `esc` is necessary. My example `bar(:foo)` is more like:

```julia
julia> macro unescaped() :(:foo) end
@unescaped (macro with 1 method)

julia> @unescaped
:foo

```

---

<div class="post-metadata">

### Author: ![sgaure](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sgaure/32/14779_2.png) [@sgaure](https://discourse.julialang.org/u/sgaure)
#### Post date: [November 26, 2024, 12:24pm UTC](https://discourse.julialang.org/t/why-the-parenthesis-around-main/123017/16 "2024-11-26T12:24:40Z")

</div>

> [@world-peace](#):
>
> For example, in your second example `@macroexpand Foo.@bar(a)`, `a` here is some local variable (it doesn’t actually exist, but the fact you used the symbol a as an argument implies that it could exist as a local variable?) but because of sanitization, when `bar` returns `s`, `a` has become sanitized so that it is no longer the local `Main.a` but `Main.Foo.a`?

Yes, the idea is that the macro may return a piece of code which assigns its own variables, they will be rewritten. Or they may use global variables in the module where the macro was defined. To use the caller’s variables/expressions, the sanitation must be switched off.

```julia
julia> module Foo
       const S = 42
       macro myadd(a, b)
           quote
               q = $(esc(a)) + $(esc(b))
               if q < $(esc(a))
                   s = q + S
               else
                   s = q - S
               end
               s
           end
       end

       end
Main.Foo

julia> using .Foo: @myadd

julia> @macroexpand @myadd(x, y)
quote
    var"#3#q" = x + y
    if var"#3#q" < x
        var"#4#s" = var"#3#q" + Main.Foo.S
    else
        var"#4#s" = var"#3#q" - Main.Foo.S
    end
    var"#4#s"
end

```

The effect of this is that, semantically, a macro has its own scope, inside the module in which it was defined. Interaction with the caller’s scope is explicit by switching the sanitation off with `esc`.

---

<div class="post-metadata">

### Author: ![CameronBieganek](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cameronbieganek/32/6915_2.png) [@CameronBieganek](https://discourse.julialang.org/u/CameronBieganek)
#### Post date: [November 26, 2024, 1:21pm UTC](https://discourse.julialang.org/t/why-the-parenthesis-around-main/123017/17 "2024-11-26T13:21:33Z")

</div>

This thread contains low-level answers to the question “why?”, but not a high-level answer. The reason this syntax was adopted as the standard entry-point for Julia programs is because it is backwards-compatible. There are already many scripts in the wild with a `main` function. I haven’t really followed the development, but I believe the `(@main)` entry point has semantics that are somewhat different from a regular old script with a `main` function.

---

<div class="post-metadata">

### Author: ![technocrat](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/technocrat/32/220947_2.png) [@technocrat](https://discourse.julialang.org/u/technocrat)
#### Post date: [December 8, 2024, 1:43am UTC](https://discourse.julialang.org/t/why-the-parenthesis-around-main/123017/18 "2024-12-08T01:43:28Z")

</div>

Thank you for parting the mists.
