# Macro challenge: Factory for creating named tuples

**URL:** https://discourse.julialang.org/t/macro-challenge-factory-for-creating-named-tuples/9748
**Category:** General Usage
**Created:** [March 15, 2018, 9:22pm UTC](https://discourse.julialang.org/t/macro-challenge-factory-for-creating-named-tuples/9748 "2018-03-15T21:22:46Z")
**Posts on this page:** 13
**Page:** 2

<div class="post-metadata">

### Author: ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)
#### Post date: [March 22, 2018, 7:27am UTC](https://discourse.julialang.org/t/macro-challenge-factory-for-creating-named-tuples/9748/21 "2018-03-22T07:27:25Z")

</div>

> [@jlperla](#):
>
> ways to teach complete novice programmers how to pass around arguments for their models when writing code

I can understand the motivation, having faced the exact same issue before, but I would have a slight preference for biting the bullet and teaching about `struct`s. I would do this because if I rely on the Julia ecosystem, students will need to interact with code that uses `struct`s anyway—it is more or less inevitable. I agree that parametric types can be confusing in the first pass. So I would omit them initially, then later demo how it speeds up calculations.

I taught R for almost a decade to econ grad students. Since S3/S4 classes are really cumbersome, the solution for organizing values that belong together was the `list(...)` (or `c(...)`) construct, basically equivalent to a `NamedTuple` when all values are named. It worked in courses, then when I was supervising thesis projects, I would observe that students continue to use it to build baroque, error-prone monstrosities.

In constrast, Julia’s structures are really lightweight, with a lot of convenience macros built around them, eg [Parameters.jl](https://github.com/mauro3/Parameters.jl) and similar, and `Base.@kwdef`. I think the trade-off boils down to making it easier to teach vs encouraging good habits that serve the subset of students who will continue to use Julia later on.

---

<div class="post-metadata">

### Author: ![rveltz](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rveltz/32/2707_2.png) [@rveltz](https://discourse.julialang.org/u/rveltz)
#### Post date: [March 22, 2018, 7:44am UTC](https://discourse.julialang.org/t/macro-challenge-factory-for-creating-named-tuples/9748/22 "2018-03-22T07:44:54Z")

</div>

Why is the struct type unstable?

---

<div class="post-metadata">

### Author: ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)
#### Post date: [March 22, 2018, 7:52am UTC](https://discourse.julialang.org/t/macro-challenge-factory-for-creating-named-tuples/9748/23 "2018-03-22T07:52:56Z")

</div>

They may be referring to [abstract field types](https://docs.julialang.org/en/stable/manual/performance-tips/#Avoid-containers-with-abstract-type-parameters-1).

---

<div class="post-metadata">

### Author: ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)
#### Post date: [March 22, 2018, 12:59pm UTC](https://discourse.julialang.org/t/macro-challenge-factory-for-creating-named-tuples/9748/24 "2018-03-22T12:59:13Z")

</div>

Thinking about this, it would be great to have a

```julia
@typed struct Foo{T} <: SuperType
   abstract1::Any
   abstract2::AbstractString
   abstract3 # unspecified
   concrete::Float64
   ... # possible inner constructor
end

```

that expands to

```julia
struct Foo{T, A1 <: Any, A2 <: AbstractString, A3} <: SuperType
   abstract1::A1
   abstract2::A2
   abstract3::A3
   concrete::Float64
   ... # possible inner constructor
end

```

which

1. works for `mutable`, too,

2. with optional supertype,

3. and generates `A1`, … not to clash with existing parameter or field names,

4. handles docstrings 😄.

sort of automagically addressing the performance hint above.

[MacroTools.jl](https://github.com/MikeInnes/MacroTools.jl) makes implementation considerably easier, but it is still a great festival of special cases 😉

---

<div class="post-metadata">

### Author: ![jlperla](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jlperla/32/34332_2.png) [@jlperla](https://discourse.julialang.org/u/jlperla)
#### Post date: [March 22, 2018, 5:21pm UTC](https://discourse.julialang.org/t/macro-challenge-factory-for-creating-named-tuples/9748/25 "2018-03-22T17:21:23Z")

</div>

First of all, I that is a great idea for a macro, and I think it belongs in `Parameters.jl` with the kw\_args built into it… I see no reason to separate it. So

```julia
@with_kw_typed struct Foo{T} <: SuperType
   abstract1::Any = 2.0
   abstract2::AbstractString = "TEST!"
   abstract3 # unspecified
   concrete::Float64
   ... # possible inner constructor
end

```

Second, I would still have intro users focus on named tuples, and use it throughout most of the code. I know I would use it. My goal is to avoid having to teach them about defining there own types (and the mechanics of abtract types) until later in the course. This is a longer discussion, but I want people to be able to have code with the aboslute minimum of syntax beyond the mathematics… and code that matlab users can say “wow, that is shorter and even more clear than matlab”.

---

<div class="post-metadata">

### Author: ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)
#### Post date: [March 22, 2018, 6:02pm UTC](https://discourse.julialang.org/t/macro-challenge-factory-for-creating-named-tuples/9748/26 "2018-03-22T18:02:28Z")

</div>

> [@jlperla](#):
>
> I want people to be able to have code with the aboslute minimum of syntax beyond the mathematics… and code that matlab users can say “wow, that is shorter and even more clear than matlab”.

I agree that this is perfectly justifiable, especially in a course where the material is mostly self-contained and you want to minimize time devoted to CS concepts (who doesn’t? 😉). I can’t wait for `v0.7` myself, named tuples will simplify a lot of code.

---

<div class="post-metadata">

### Author: ![bramtayl](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bramtayl/32/3614_2.png) [@bramtayl](https://discourse.julialang.org/u/bramtayl)
#### Post date: [March 22, 2018, 6:43pm UTC](https://discourse.julialang.org/t/macro-challenge-factory-for-creating-named-tuples/9748/27 "2018-03-22T18:43:18Z")

</div>

Huh that’s really bizarre I have no idea why that’s happening…

---

<div class="post-metadata">

### Author: ![mauro3](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mauro3/32/292_2.png) [@mauro3](https://discourse.julialang.org/u/mauro3)
#### Post date: [March 22, 2018, 6:48pm UTC](https://discourse.julialang.org/t/macro-challenge-factory-for-creating-named-tuples/9748/28 "2018-03-22T18:48:02Z")

</div>

Yes, I think Tamas’ idea is good; I had it too! To make it work with `@with_kw` something like this syntax is needed:

```julia
@with_kw struct A
       a::{<:AbstractArray}                                                                                                                                                            
       b::Int
end

```

---

<div class="post-metadata">

### Author: ![mauro3](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mauro3/32/292_2.png) [@mauro3](https://discourse.julialang.org/u/mauro3)
#### Post date: [March 22, 2018, 6:49pm UTC](https://discourse.julialang.org/t/macro-challenge-factory-for-creating-named-tuples/9748/29 "2018-03-22T18:49:10Z")

</div>

> [@jlperla](#):
>
> `@with_kw(a=1, b="test", w = w)`

I think I’d rather only allow:  
`@with_kw (a=1, b="test", w = w)`  
i.e. `@with_kw` only taking one argument.

---

<div class="post-metadata">

### Author: ![jlperla](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jlperla/32/34332_2.png) [@jlperla](https://discourse.julialang.org/u/jlperla)
#### Post date: [March 22, 2018, 6:59pm UTC](https://discourse.julialang.org/t/macro-challenge-factory-for-creating-named-tuples/9748/30 "2018-03-22T18:59:29Z")

</div>

It took me a while to mentally parse your suggestion correctly… Forgetting a space between the two would be a pretty common problem.

Could we allow multiple arguments and flatten one level to avoid that issue?

---

<div class="post-metadata">

### Author: ![mauro3](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mauro3/32/292_2.png) [@mauro3](https://discourse.julialang.org/u/mauro3)
#### Post date: [March 22, 2018, 7:03pm UTC](https://discourse.julialang.org/t/macro-challenge-factory-for-creating-named-tuples/9748/31 "2018-03-22T19:03:28Z")

</div>

How about throwing a helpful error message? I think I would prefer that.

---

<div class="post-metadata">

### Author: ![jlperla](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jlperla/32/34332_2.png) [@jlperla](https://discourse.julialang.org/u/jlperla)
#### Post date: [March 22, 2018, 7:24pm UTC](https://discourse.julialang.org/t/macro-challenge-factory-for-creating-named-tuples/9748/32 "2018-03-22T19:24:23Z")

</div>

Sure. If the error message explicitly tells people to try putting a space (as opposed to just failing to find the macro) that would be fine. Though I don’t entirely understand why we couldn’t have a forwarding version of the macro that takes that takes the variable arguments, throws them in a tuple, and calls the single argument version.

---

<div class="post-metadata">

### Author: ![jlperla](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jlperla/32/34332_2.png) [@jlperla](https://discourse.julialang.org/u/jlperla)
#### Post date: [March 22, 2018, 9:20pm UTC](https://discourse.julialang.org/t/macro-challenge-factory-for-creating-named-tuples/9748/33 "2018-03-22T21:20:16Z")

</div>

Two things on this:

- I tried this with the NamedTuples library on v0.7 master, and I couldn’t replicate the issue. Seems to be v0.62 only?
- I tried to modify your macro to use the built-in named tuples on v0.7, and couldn’t figure it out. Simply getting rid of the $`NamedTuples.@NT` did not do it, as I thought it would.

[Previous page](https://discourse.julialang.org/t/macro-challenge-factory-for-creating-named-tuples/9748.md?page=1)
