# Use multi-line arguments to macros without commas with a (new) block structure

**URL:** <https://discourse.julialang.org/t/use-multi-line-arguments-to-macros-without-commas-with-a-new-block-structure/20577>\
**Category:** General Usage\
**Tags:** question, proposal\
**Created:** [February 8, 2019, 11:28am UTC](https://discourse.julialang.org/t/use-multi-line-arguments-to-macros-without-commas-with-a-new-block-structure/20577 "2019-02-08T11:28:11Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![stakaz](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stakaz/32/4740_2.png) [@stakaz](https://discourse.julialang.org/u/stakaz)\
**Post date:** [February 8, 2019, 11:28am UTC](https://discourse.julialang.org/t/use-multi-line-arguments-to-macros-without-commas-with-a-new-block-structure/20577/1 "2019-02-08T11:28:11Z")

</div>

Hello, I just thought about the option to use multi-line statements for macro calls without the need to use comma in them.

So I am interested in being able to rewrite this

```julia
@mymacro a b "123" (1,2,3)

```

into this

```julia
@mymacro somebegin 
    a b 
    "123" 
    (1,2,3)
end

```

where `somebegin` is something which allows to do exactly this (it does **not** work with `begin` or `quote` of course).

I have seen [5622](https://discourse.julialang.org/t/multi-line-macros-for-domain-specific-language/5622) and this [8980](https://discourse.julialang.org/t/passing-multi-line-expression-to-macro-on-raspberry-pi-causes-seg-fault/8980/8) so I know that in principle this is not possible.

However, I can imagine that the step to allow it through a `somebegin` statement would be really great and would fit into julia syntax nicely, the only this is basically the newlines which have to be neglected before go to the _real_ julia call.

Could you imagine how I could manage this or even whether it would be a nice feature for the language?

Thanks.

---

<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:** [February 8, 2019, 11:53am UTC](https://discourse.julialang.org/t/use-multi-line-arguments-to-macros-without-commas-with-a-new-block-structure/20577/2 "2019-02-08T11:53:59Z")

</div>

Not sure what you are asking about. With `begin ... end`, you also get an AST you can work with. I am assuming you want to skip or customize `begin`?

> [@stakaz](#):
>
> whether it would be a nice feature for the language?

I came to Julia from Common Lisp, as first I was missing the equivalent of

```lisp
(somemacro (header arguments)
    followed by
    body)

```

but now I think that `begin` is not that much of a hassle and keeps the code readable. This is one of the trade-offs between using S-expressions (nice for macros) and and Algol-like syntax (which can be very compact with various special operators, like in Julia).

In addition to potentially being confusing to someone who did not read the docs/source for a particular macro, constructs like `somebegin` would require editor indentation macros to parse and understand macro definitions.

---

<div class="post-metadata">

**Author:** ![stakaz](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stakaz/32/4740_2.png) [@stakaz](https://discourse.julialang.org/u/stakaz)\
**Post date:** [February 8, 2019, 12:07pm UTC](https://discourse.julialang.org/t/use-multi-line-arguments-to-macros-without-commas-with-a-new-block-structure/20577/4 "2019-02-08T12:07:09Z")

</div>

Well, thanks for the answer. What I am after is a way to skip braces and commas for long lists of arguments by providing a block structure for this.

When I use a macro with this call `@mymacro a b c 1 2 3` I can access each separate argument in the argument list, work with them and then, e. g., call a function by passing this arguments. However, I cannot do the very same thing with a `begin ... end` syntax because I get an expression and not a list of arguments. O do I misunderstand something?

So I **cannot** call my macro with

```julia
@mymacro begin 
    a
    b 
    c 1 
    2 3
end

```

and deal with it in the same way I would for the single line…

The story behind this question is actually my personal plotting framework which I use for calling `PyPlot`.

I would like to simplify lines like this

```julia
@plot Plot1 :points ([1,2,3], [4,5,6]) label = "x"
@plot Plot1 :legend
@plot Plot1 :xlim 1 3

```

to

```julia
@plot begin 
    Plot1 
    :points ([1,2,3], [4,5,6]) label = "x"
    :legend
    :xlim 1 3
end

```

In this particular case it is not much shorter but I think you can see the point.

Of cause I would need to modify the definition of `@plot` by that is another story…

---

<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:** [February 8, 2019, 12:22pm UTC](https://discourse.julialang.org/t/use-multi-line-arguments-to-macros-without-commas-with-a-new-block-structure/20577/5 "2019-02-08T12:22:37Z")

</div>

You can parse both blocks and macro arguments, eg

```julia
macro foo(a, b)
    :($a + $b)
end

macro foo(block)
    @assert block.head == :block
    a, b = filter(x -> !(x isa LineNumberNode), block.args)
    :($a + $b)
end

macroexpand(Main, :(@foo 1 2))

macroexpand(Main, :(@foo begin
                    1
                    2
                    end))

```

That said, I would stick to a single syntax.

---

<div class="post-metadata">

**Author:** ![stakaz](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stakaz/32/4740_2.png) [@stakaz](https://discourse.julialang.org/u/stakaz)\
**Post date:** [February 8, 2019, 12:25pm UTC](https://discourse.julialang.org/t/use-multi-line-arguments-to-macros-without-commas-with-a-new-block-structure/20577/6 "2019-02-08T12:25:55Z")

</div>

Oh, that’s fantastic 😉 Thanks… Have not thought that is can be parse, though. Than the whole question is probably meaningless.

---

<div class="post-metadata">

**Author:** ![jandehaan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jandehaan/32/6805_2.png) [@jandehaan](https://discourse.julialang.org/u/jandehaan)\
**Post date:** [February 8, 2019, 12:41pm UTC](https://discourse.julialang.org/t/use-multi-line-arguments-to-macros-without-commas-with-a-new-block-structure/20577/7 "2019-02-08T12:41:55Z")

</div>

Would something like this be useful for you?

```julia
macro mymacro_str(s)
    Meta.parse(string("@mymacro ", replace(s, r"\r?\n" => " ")))
end

macro mymacro(args...)
    # whatever you want to do with the args of @mymacro, for example
    for arg in args
        println(arg)
    end
end

```

```julia
julia> mymacro"""
        a b 
        "123" 
        (1,2,3)
        """
a
b
123
(1, 2, 3)

```

---

<div class="post-metadata">

**Author:** ![stakaz](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stakaz/32/4740_2.png) [@stakaz](https://discourse.julialang.org/u/stakaz)\
**Post date:** [February 8, 2019, 12:43pm UTC](https://discourse.julialang.org/t/use-multi-line-arguments-to-macros-without-commas-with-a-new-block-structure/20577/8 "2019-02-08T12:43:36Z")

</div>

Regarding the complexity of the input this would end up in very unreadable text because the syntax highlighting will not work in the string context. But in principle this is also possible. Thanks.

---

<div class="post-metadata">

**Author:** ![c42f](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/c42f/32/52842_2.png) [@c42f](https://discourse.julialang.org/u/c42f)\
**Post date:** [February 8, 2019, 1:17pm UTC](https://discourse.julialang.org/t/use-multi-line-arguments-to-macros-without-commas-with-a-new-block-structure/20577/9 "2019-02-08T13:17:00Z")

</div>

I think you’re asking for something like [https://github.com/JuliaLang/julia/pull/29273](https://github.com/JuliaLang/julia/pull/29273). I don’t think that particular PR will ever be merged (too much unicode), but I still hope for something equivalent. In the meantime I use the hack of “commenting out the newline”:

```julia
@mymacro #= 
=# a b #=
=# "123" #=
=# (1,2,3)

```

Of course, if you have control over `@mymacro` you can support parsing of a block as well. However this is a fairly unusual way to pass multiple arguments to a macro and I’d say a bit unnatural in the context of the larger Julia ecosystem.

---

<div class="post-metadata">

**Author:** ![stakaz](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stakaz/32/4740_2.png) [@stakaz](https://discourse.julialang.org/u/stakaz)\
**Post date:** [February 8, 2019, 1:20pm UTC](https://discourse.julialang.org/t/use-multi-line-arguments-to-macros-without-commas-with-a-new-block-structure/20577/10 "2019-02-08T13:20:14Z")

</div>

That is a nice trick 😉 Also thanks for the link.

I agree that it is somehow not julia-ish style to leave out all the commas in the call. However, as it is a rich-macro using language I thought that a way of _changing_ the style according to your needs is also a valid way 😉

---

<div class="post-metadata">

**Author:** ![c42f](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/c42f/32/52842_2.png) [@c42f](https://discourse.julialang.org/u/c42f)\
**Post date:** [February 8, 2019, 1:30pm UTC](https://discourse.julialang.org/t/use-multi-line-arguments-to-macros-without-commas-with-a-new-block-structure/20577/11 "2019-02-08T13:30:30Z")

</div>

> [@stakaz](#):
>
> I agree that it is somehow not julia-ish style to leave out all the commas in the call

That’s not really what I mean; it’s actually much more common to leave out the commas in macro calls (at least in my experience). Personally I prefer the space separated style in macro calls which is why I wrote the linked PR.

All I mean is that having a macro which treats

```julia
@mymacro begin
a
b
end

```

the same as `@mymacro a b` is a fairly unusual style. But it’s quite workable. If it does what you need don’t let me discourage you 😉

---

<div class="post-metadata">

**Author:** ![stakaz](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stakaz/32/4740_2.png) [@stakaz](https://discourse.julialang.org/u/stakaz)\
**Post date:** [February 8, 2019, 1:33pm UTC](https://discourse.julialang.org/t/use-multi-line-arguments-to-macros-without-commas-with-a-new-block-structure/20577/12 "2019-02-08T13:33:43Z")

</div>

Yes, I think that maybe in my case something like

```julia
@plot Plot :points [1, 2, 3] [4, 5, 6]

```

and

```julia
@plot Plot begin
    :points [1, 2, 3] [4, 5, 6] 
end 

```

would be the cleanest way. Thanks for the discussion.

---

<div class="post-metadata">

**Author:** ![c42f](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/c42f/32/52842_2.png) [@c42f](https://discourse.julialang.org/u/c42f)\
**Post date:** [February 8, 2019, 10:28pm UTC](https://discourse.julialang.org/t/use-multi-line-arguments-to-macros-without-commas-with-a-new-block-structure/20577/13 "2019-02-08T22:28:13Z")

</div>

The downside there is that the parsing rules are different in a block vs a macro argument list so your second version above is invalid syntax. You’d need to write it as

```julia
@plot Plot begin
    :points
    [1,2,3]
    [4,5,6]
end

```

Alternatively (ab)use some other space sensitive context like matrix construction:

```julia
@plot Plot [
    :points [1,2,3] [4,5,6]
]

```

---

<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:** [February 9, 2019, 7:28am UTC](https://discourse.julialang.org/t/use-multi-line-arguments-to-macros-without-commas-with-a-new-block-structure/20577/14 "2019-02-09T07:28:51Z")

</div>

> [@c42f](#):
>
> use some other space sensitive context like matrix construction

That’s a great suggestion. See [`PGFPlotsX.@pgf`](https://github.com/KristofferC/PGFPlotsX.jl/blob/master/src/options.jl#L48), which uses `{ ... }` which is not used for anything else.
