# Access to struct fields in generated function

**URL:** https://discourse.julialang.org/t/access-to-struct-fields-in-generated-function/6800
**Category:** General Usage
**Created:** [October 31, 2017, 12:12pm UTC](https://discourse.julialang.org/t/access-to-struct-fields-in-generated-function/6800 "2017-10-31T12:12:30Z")
**Posts on this page:** 5
**Page:** 1

<div class="post-metadata">

### Author: ![Philippe\_Maincon](https://avatars.discourse-cdn.com/v4/letter/p/a4c791/32.png) [@Philippe\_Maincon](https://discourse.julialang.org/u/Philippe_Maincon)
#### Post date: [October 31, 2017, 12:12pm UTC](https://discourse.julialang.org/t/access-to-struct-fields-in-generated-function/6800/1 "2017-10-31T12:12:30Z")

</div>

Hi,

I am trying to wrap my skull around metaprogramming. Feels like a stiff skull.

In my little example, I want a function that can take any composite type, and do some manipulation (here printing) of each field. Here we go

```julia
using StaticArrays
@generated function insight(f)
    print("Generating insight.\n")
    e = quote end  
    for fi in fieldnames(f) 
        blk = quote 
            print(string(fi),"::",string(typeof(f.$fi))," → ",show(f.$fi),"\n")
        end
        append!(e.args, blk.args)
    end
    return e
end

struct typo{nx}
    σ::SMatrix{nx,nx}
    b
    c
end

nx = 3

i = typo{nx}(randn(nx,nx),π,3.)
insight(i)

```

I get “undefVarError: fi not defined.”  
I know a “generated function” has access to type info, not values, at … generation time. I reckon fieldnames should be fair game. Are the fieldnames known at generation time? Is that the cause of the error anyway?

I also welcome comments on the way I append stuff. Is there simpler?

Philippe

---

<div class="post-metadata">

### Author: ![cstjean](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cstjean/32/1444_2.png) [@cstjean](https://discourse.julialang.org/u/cstjean)
#### Post date: [October 31, 2017, 12:30pm UTC](https://discourse.julialang.org/t/access-to-struct-fields-in-generated-function/6800/2 "2017-10-31T12:30:41Z")

</div>

You need to think about what computation happens when:

```julia
print(string(fi),
      "::",string(typeof(f.$fi))," → ",
      show(f.$fi),"\n")

```

The first `string(fi)` is quoted, so it will be evaluated when the (generated) function is called. `fi` is not a variable in your generated function, so it’s an error. You probably want `$(string(fi))` to evaluate it at generation-time.

The second `string` should work fine. But it will be performing the computation at runtime, since only `$fi` will be evaluated at generation time. You could use `$(string(fieldtype(f, fi)))` to do it at compile-time (though note that it’s not quite the same computation — your version shows the type of the value stored, but my version shows the type of the field)

The third `string` is fine.

---

<div class="post-metadata">

### Author: ![Philippe\_Maincon](https://avatars.discourse-cdn.com/v4/letter/p/a4c791/32.png) [@Philippe\_Maincon](https://discourse.julialang.org/u/Philippe_Maincon)
#### Post date: [October 31, 2017, 12:51pm UTC](https://discourse.julialang.org/t/access-to-struct-fields-in-generated-function/6800/3 "2017-10-31T12:51:09Z")

</div>

Thank you, that helps! One way to put it is:

```julia
@generate function foo(data)
generation time code
return quote 
    runtime code $(generation time code)
end

```

My code now works

```julia
using StaticArrays
@generated function insight(f)
    print("Generating insight.\n")
    e = quote end  
    for fi in fieldnames(f) 
        blk = quote 
            print($(string(fi))," :: ",$(string(fieldtype(f,fi)))," → ",string(f.$fi),"\n")
        end
        append!(e.args, blk.args)
    end
    return e
end

```

---

<div class="post-metadata">

### Author: ![rdeits](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rdeits/32/286_2.png) [@rdeits](https://discourse.julialang.org/u/rdeits)
#### Post date: [October 31, 2017, 3:14pm UTC](https://discourse.julialang.org/t/access-to-struct-fields-in-generated-function/6800/4 "2017-10-31T15:14:09Z")

</div>

Just a minor correction:

```julia
@generated function foo(data)
    runtime code
    return quote 
        runtime code $(generation time code)
    end
end

```

should instead be

```julia
@generated function foo(data)
    generation time code
    return quote 
        runtime code $(generation time code)
    end
end
```

---

<div class="post-metadata">

### Author: ![Philippe\_Maincon](https://avatars.discourse-cdn.com/v4/letter/p/a4c791/32.png) [@Philippe\_Maincon](https://discourse.julialang.org/u/Philippe_Maincon)
#### Post date: [November 1, 2017, 9:38am UTC](https://discourse.julialang.org/t/access-to-struct-fields-in-generated-function/6800/5 "2017-11-01T09:38:26Z")

</div>

Indeed! I corrected my post.
