# Cannot call @isdefined in another macro

**URL:** https://discourse.julialang.org/t/cannot-call-isdefined-in-another-macro/13350
**Category:** General Usage
**Created:** [August 13, 2018, 8:37am UTC](https://discourse.julialang.org/t/cannot-call-isdefined-in-another-macro/13350 "2018-08-13T08:37:19Z")
**Posts on this page:** 2
**Page:** 1

<div class="post-metadata">

### Author: ![cnliao](https://avatars.discourse-cdn.com/v4/letter/c/ce73a5/32.png) [@cnliao](https://discourse.julialang.org/u/cnliao)
#### Post date: [August 13, 2018, 8:37am UTC](https://discourse.julialang.org/t/cannot-call-isdefined-in-another-macro/13350/1 "2018-08-13T08:37:19Z")

</div>

In 0.6 I have a macro that evaluates an assignment if any of the left-hand-side variables is undefined. In Julia 0.7 I get a depwarn that urge me to change the call of `isdefined` to `@isdefined`. But `@isdefined` only accept a symbol rather than a variable refering to a symbol.

```julia
using MacroTools
"""@maybe a,b,c=svdfact(randn(10000,10000))"""
macro maybe(ex)
    @assert @capture(ex, ((lhs1_,lhss__)|lhs1_)=rhs_)
    lhs = [lhs1]
    lhss != nothing && append!(lhs, lhss)
    # lhs = [:v1, :v2, ...] a vector of left-hand-side symbols
    return quote
        local really = false
        for v in $lhs
            isdefined(v) || (really = true; break) # @isdefined v does not work here
        end
        really && $(esc(ex))
    end
end

```

In Julia 0.6, this macro only works in global scope. I only use this macro in repl/scripts so there is no problem. Now that `@isdefined` works for bindings in local scope, which is very nice, how should I construct the return expression of the macro?

From the implementation of `@isdefined(s)` I see that it simply translates to `Expr(:isdefined, esc(s))`. That makes `:isdefined` look like as special as `:call`, `:function` and `:ref`. I am not knowledgeable enough to understand this magic. Could you provide some pointers so that I can learn about it?

---

<div class="post-metadata">

### Author: ![cnliao](https://avatars.discourse-cdn.com/v4/letter/c/ce73a5/32.png) [@cnliao](https://discourse.julialang.org/u/cnliao)
#### Post date: [August 13, 2018, 9:34am UTC](https://discourse.julialang.org/t/cannot-call-isdefined-in-another-macro/13350/2 "2018-08-13T09:34:35Z")

</div>

For now I am hand-crafting the returning `Expr`. But there must be some better way…right?

```julia
macro maybe(ex)
    @assert @capture(ex, ((lhs1_,lhss__)|lhs1_)=rhs_)
    lhs = [lhs1]
    lhss != nothing && append!(lhs, lhss)
    local x = Expr(:&&, Expr(:isdefined, lhs[1]), true)
    local _x = x
    for i = 2:length(lhs)
        xnew = Expr(:&&, Expr(:isdefined, lhs[i]), true)
        _x.args[2] = xnew
        _x = xnew
    end
    q = Expr(:if, x, true, ex)
    return esc(q)
end

```
