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
@mymacro a b "123" (1,2,3)
into this
@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 and this 8980 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?
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?
I came to Julia from Common Lisp, as first I was missing the equivalent of
(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.
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
@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.
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> mymacro"""
a b
"123"
(1,2,3)
"""
a
b
123
(1, 2, 3)
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.
I think you’re asking for something like 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”:
@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.
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
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
@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
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
@plot Plot begin
:points
[1,2,3]
[4,5,6]
end
Alternatively (ab)use some other space sensitive context like matrix construction: