Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Matching interpolation syntax #106

Open
phipsgabler opened this issue Nov 30, 2018 · 6 comments
Open

Matching interpolation syntax #106

phipsgabler opened this issue Nov 30, 2018 · 6 comments

Comments

@phipsgabler
Copy link

Is there any way to match on expressions with a :$ head? Like, replacing

if isexpr(expr, :$)
    @assert length(expr.args) == 1
    :(shift($(esc(expr.args[1]))))
end

by

@match expr begin
    ($(e)) => :(shift($(esc(e))))
end

where expr is, for example, defined as follows:

julia> expr = :(:($(sdf))).args[1]
:($(Expr(:$, :sdf)))

julia> dump(expr)
Expr
  head: Symbol $
  args: Array{Any}((1,))
    1: Symbol sdf

I also tried interpolating the $ itself, but it didn't help:

julia> @match expr begin
           ($:$(e_)) => :(shift($(esc(e))))
       end

(obviously, since the match expression of this is a Expr(:call, :$, :e_) and not an interpolation).

@cstjean
Copy link
Collaborator

cstjean commented Nov 30, 2018

Maybe you could use MacroTools.postwalk to replace all the $(e) in expr with mozarella(e)?

@phipsgabler
Copy link
Author

That would be a nice idea if the purpose was to just work easier with it later, but it bites its own tail, since the postwalked function would itself need to match on $ internally.

But I guess the answer is then that no, such matching can't be done yet with @match or @capture?

@phipsgabler
Copy link
Author

I noticed that at least you can match on $ as an expression head, in theory:

julia> @eval @capture expr $(Symbol("x_\$"))
true

julia> x
:($(Expr(:$, :sdf)))

The problem is that you can't construct a variable called x_$ directly. So this is "just" a problem of defining a suitable surface syntax.

@MikeInnes
Copy link
Member

You can do this by interpolating a match expression that you build by hand:

@capture Expr(:$, :x) $(Expr(:$, :x_))

Unfortunately this doesn't actually give you x. So to get that you need to use a lower-level function:

julia> MacroTools.trymatch(Expr(:$, :x_), Expr(:$, :ex))
Dict{Any,Any} with 1 entry:
  :x => :ex

@phipsgabler
Copy link
Author

Interesting. I see that for the interpolation variant of @capture, the difference is that the bindings are not assigned.

Could allbindings be changed to make this work? I can't really tell what it does, and why, unfortunately.

@MikeInnes
Copy link
Member

Unfortunately not: we have to scan the expression at compile time to figure out what should be bound to local variables, but if you interpolate like that then it can vary at run time.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants