# Is \`macro\` "a compressed part of code"?

**URL:** <https://discourse.julialang.org/t/is-macro-a-compressed-part-of-code/47360>\
**Category:** New to Julia\
**Tags:** question, macros\
**Created:** [September 27, 2020, 12:08pm UTC](https://discourse.julialang.org/t/is-macro-a-compressed-part-of-code/47360 "2020-09-27T12:08:01Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![iHany](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ihany/32/18151_2.png) [@iHany](https://discourse.julialang.org/u/iHany)\
**Post date:** [September 27, 2020, 12:08pm UTC](https://discourse.julialang.org/t/is-macro-a-compressed-part-of-code/47360/1 "2020-09-27T12:08:01Z")

</div>

According to [this](https://discourse.julialang.org/t/generate-a-mutable-struct-which-inherits-others/47347/5), I’m trying to use `macro` for inheritance as @xiaodai suggested.

However, I’ve not figured out how exactly macro works ☹

What I’m trying to do is basically “refering a struct’s fields from others”.  
For this, here’s my example code:

```julia
abstract type AbstractABC end

mutable struct BaseABC <: AbstractABC
    a
end

mutable struct MyABC <: AbstractABC
    _abc
    b
end

macro inherit(ABC)
    ex = quote
        function Base.getproperty(abc::ABC, prop::Symbol)
            if prop in fieldnames(BaseABC) && !(prop in fieldnames(ABC))
                return getfield(abc._abc, prop)
            else
                return getfield(abc, prop)
            end
        end
    end
    return ex
end

@inherit(MyABC)

function test_all()
    baseabc = BaseABC(1)
    myabc = MyABC(baseabc, 2)
    println(myabc.a) # should be "1"
end
test_all()

```

But it raises an error: `UndefVarError: ABC not defined` (at line 14).

Questions:

1. Is `macro` a “compressed code”? I mean, macro probably runs at compile time as described [here](https://www.reddit.com/r/Julia/comments/78zhid/functions_vs_macros/), then it seems “a function for automatic generation of codes” to me.
2. If so, what should I correct to fulfill my purpose at the above code?

---

<div class="post-metadata">

**Author:** ![xiaodai](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/xiaodai/32/15937_2.png) [@xiaodai](https://discourse.julialang.org/u/xiaodai)\
**Post date:** [September 27, 2020, 12:12pm UTC](https://discourse.julialang.org/t/is-macro-a-compressed-part-of-code/47360/2 "2020-09-27T12:12:13Z")

</div>

> [@iHany](#):
>
> ```julia
> mutable struct MyABC <: AbstractABC
> _abc
> b
> end
> 
> ```

What I mean is something like this

```julia
@inherit mutable struct MyABC <: AbstractABC
   @embed _abc::BaseABC
    .... # other stuff
end

```

and it will generate the get property function as well.

> [@iHany](#):
>
> `(ABC)`

u didn’t define a type called `ABC` do you mean `MyABC`?

---

<div class="post-metadata">

**Author:** ![iHany](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ihany/32/18151_2.png) [@iHany](https://discourse.julialang.org/u/iHany)\
**Post date:** [September 27, 2020, 12:14pm UTC](https://discourse.julialang.org/t/is-macro-a-compressed-part-of-code/47360/4 "2020-09-27T12:14:28Z")

</div>

I intended to use the `@inherit` for any structs, which is a subtype of `AbstractABC`.

I may wrongly be implementing macros (quite difficult to me 😓 ).

---

<div class="post-metadata">

**Author:** ![iHany](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ihany/32/18151_2.png) [@iHany](https://discourse.julialang.org/u/iHany)\
**Post date:** [September 27, 2020, 12:20pm UTC](https://discourse.julialang.org/t/is-macro-a-compressed-part-of-code/47360/5 "2020-09-27T12:20:53Z")

</div>

Sorry for being bothering but can you give me an example code if u don’t mind?

---

<div class="post-metadata">

**Author:** ![xiaodai](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/xiaodai/32/15937_2.png) [@xiaodai](https://discourse.julialang.org/u/xiaodai)\
**Post date:** [September 27, 2020, 12:27pm UTC](https://discourse.julialang.org/t/is-macro-a-compressed-part-of-code/47360/6 "2020-09-27T12:27:01Z")

</div>

I don’t understand what u r trying to do. Maybe u need to describe what u want. U only need macro if want the convenience

---

<div class="post-metadata">

**Author:** ![iHany](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ihany/32/18151_2.png) [@iHany](https://discourse.julialang.org/u/iHany)\
**Post date:** [September 27, 2020, 12:33pm UTC](https://discourse.julialang.org/t/is-macro-a-compressed-part-of-code/47360/7 "2020-09-27T12:33:04Z")

</div>

I did! I missed `$`.

What I was trying to do is to make a macro `@inherit` for any struct `ABC` (`ABC <: AbstractABC` such that `@inherit ABC` will make the struct `ABC` can refer any fields of `BaseABC` (`BaseABC <: AbstractABC`).

I would appreciate if you know a more convenient and Julian approach 🙂

The corrected code:

```julia
abstract type AbstractABC end

mutable struct BaseABC <: AbstractABC
    a
end

mutable struct MyABC <: AbstractABC
    _abc
    b
end

macro inherit(ABC)
    ex = quote
        function Base.getproperty(abc::$ABC, prop::Symbol)
            if prop in fieldnames(BaseABC) && !(prop in fieldnames($ABC))
                return getfield(abc._abc, prop)
            else
                return getfield(abc, prop)
            end
        end
    end
    return ex
end

@inherit(MyABC)

function test_all()
    baseabc = BaseABC(1)
    myabc = MyABC(baseabc, 2)
    println(myabc.a) # = 1
end
test_all()

```

---

<div class="post-metadata">

**Author:** ![tomerarnon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomerarnon/32/3170_2.png) [@tomerarnon](https://discourse.julialang.org/u/tomerarnon)\
**Post date:** [September 27, 2020, 12:41pm UTC](https://discourse.julialang.org/t/is-macro-a-compressed-part-of-code/47360/8 "2020-09-27T12:41:56Z")

</div>

> [@iHany](#):
>
> I would appreciate if you know a more convenient and Julian approach 🙂

The more julian approach is to simply not do this… generally, you will only define a small handful of types as subtypes of an abstract type. In that case you should just write out all of the fields explicitly (which also should be a small handful). If you have dozens of types or dozens of fields, that is code that needs refactoring.

```julia
abstract type AbstactX end

# an interface function to grab the :x field.
f(x::AbstractX) = x.x

struct X <: AbstractX
    x::Int
end

struct Y <: AbstractX
    x::Int
    y::Float64
end

struct Z <: AbstractX
    x::Int
    z::Float64
end

# etc.

```

---

<div class="post-metadata">

**Author:** ![iHany](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ihany/32/18151_2.png) [@iHany](https://discourse.julialang.org/u/iHany)\
**Post date:** [September 27, 2020, 12:45pm UTC](https://discourse.julialang.org/t/is-macro-a-compressed-part-of-code/47360/9 "2020-09-27T12:45:00Z")

</div>

Actually, I’m importing my Python codes into Julia codes as a first step 😓

Probably this would be a reason why I’m struggling with such non-Julian ways.

Unfortunately, although I’m doing my best to do that without Pythonic ways, I cannot find an alternative way to replace my codes in a whole Julian way ☹

Anyhow, thank you all 🙂

---

<div class="post-metadata">

**Author:** ![tomerarnon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomerarnon/32/3170_2.png) [@tomerarnon](https://discourse.julialang.org/u/tomerarnon)\
**Post date:** [September 27, 2020, 12:54pm UTC](https://discourse.julialang.org/t/is-macro-a-compressed-part-of-code/47360/10 "2020-09-27T12:54:21Z")

</div>

Yes, a 1-to-1 port from another language is hard. It is easier to think about the big picture of what the code is trying to accomplish and reimagine how to get to that goal from first principles. Usually you will find your result is clearer, faster, shorter, and simply better. For large code bases though, this process is hard and sometimes not worth it in the short term. If you want to DM me a link to your python code, maybe I can offer some directed advice.

---

<div class="post-metadata">

**Author:** ![iHany](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ihany/32/18151_2.png) [@iHany](https://discourse.julialang.org/u/iHany)\
**Post date:** [September 27, 2020, 3:25pm UTC](https://discourse.julialang.org/t/is-macro-a-compressed-part-of-code/47360/11 "2020-09-27T15:25:18Z")

</div>

@tomerarnon  
I realised that such inheritance of structs would be unnecessary for my task (it was in my Python codes though).

So I tried to change it without inheritance, and it finally becomes much better to use in Julia.

Thanks 🙂
