FluxML / MacroTools.jl

MacroTools provides a library of tools for working with Julia code and expressions.
https://fluxml.ai/MacroTools.jl/stable/
Other
310 stars 79 forks source link

@capture(:(a.(b,c)),x_.y_) is false #191

Closed PhilippeMaincon closed 1 year ago

PhilippeMaincon commented 1 year ago

First things first: MacroTools is very useful, thank you.

I execute @capture(:(a.(b,c)),x_.y_) and expect to get a=:x and y=:(b,c). Instead @capture is false.

A Julia quirk (as far as I can see) is that a.b parses to Expr(:. , :a, QuoteNode(:b), but a.(b,c) parses without a QuoteNode. I imagine this is what upsets the cart. Arguably, a.(b,c) is not sound Julia syntax. On the other hand, one classic use of macros is to create new syntaxes.

cstjean commented 1 year ago

a.(b,c) is broadcasting syntax (i.e. sin.([1,2,3])), whereas a.b is getproperty syntax. The two are parsed differently because they correspond to different concepts, so I would say that MacroTools is correct.

If you want to capture .(), you need that in your pattern too. Eg.

julia> @capture(:(sin.(x)), f_.(args__))
true
PhilippeMaincon commented 1 year ago

Aha! that explains this behaviour which I called quirky. I think my troubles come from me wanting my macro to create a new syntax in which the dots get a Julia-incompatible meaning, and so I get at odds with the parser. I will explore another solution: in my syntax, replace the dot with a multiplication operator, we'll see.

Closed, merci.

cstjean commented 1 year ago

De rien!

Julia has a long list list of binary operators which can be fun to mine for extra macro quirkiness. With \ they are simple to write in most editors.