I have a function that constructs a NamedTuple out of a vector of numbers subject to some transformation, something like

```
function vec2tuple(x)
( a = x[1], b = 1 + exp(x[2]), c = 2 + exp(x[3]), d = exp(x[4]) / (1 + exp(x[4]))
end
```

This function does 2 things. It transforms individual elements of `x`

an appropriate transformation and then assembles the results into a named tuple with keys `a`

, `b`

, `c`

, and `d`

.

`vec2tuple`

runs very fast and doesn’t allocate. But the downside is code duplication, which gets tedious as the size of the tuple increases. Also, vec2tuple is kind of hard to read b/c it doesn’t make explicit the logic that informs the choice of the transformation. Ultimately, every `xi`

in `x`

will get transformed based on a known range of values each element of the NamedTuple can take. In the example above, a can take any value on the real line, b must be in (1,Inf), c must be in (2,Inf), and d must be in (0,1).

What I really want is to specify a set of rules in a legible way and then have these transformations be constructed accordingly. Here is an example for how to express these rules, but I’m not wedded to this.

```
bounds = (a = (-Inf,Inf), b = (1,Inf), c = (2,Inf), d = (0,1) )
```

I first decided to tackle this using functional programming. I wrote a function that returns anonymous functions to perform the transformation for any kind of open interval:

```
function get_transform_function(arg)
lb, ub = arg
if lb>=ub
throw(ArgumentError("Upper bound must be strictly greater than lower bound"))
end
if lb==-Inf && ub==Inf
return x -> x
elseif lb!=Inf && ub==Inf
return x -> lb + exp(x)
elseif lb==-Inf && ub!=Inf
return x -> ub-exp(-x)
else
return x -> lb + (ub-lb)*exp(x)/(1+exp(x))
end
end
```

I then constructed rules for each of a,b, c, and d:

```
rules = map(x -> get_transform_function(x), bounds)
```

And wrote `transform`

to call instead `vec2tuple`

:

```
function transform(rules::NamedTuple{Names,<:Tuple}, vec::AbstractVector) where Names
N = length(rules)
return NamedTuple{Names}(ntuple(i -> rules[i](vec[i]), N))
end
```

Problem is, `transform`

is about 20x slower than `vec2tuple`

because it allocates a lot.

It seems like the solution should be in meta-programming. Something as performant as `vec2tuple`

should be generated once based on the information in `bounds`

before being called many times.

I tried rewriting `get_transform_function`

so that it takes an additional argument for the value to be transformed and returns expressions instead of anonymous functions, and then construct a transformation as follows. Note that I’m passing an expression as an argument to `get_transform_function`

so it gets interpolated as `x[i]`

, not any specific value.

```
names=keys(bounds)
args=[get_transform_function(:(x[$i]), v) for (i,v) in enumerate(bounds)]
tup=:($(Expr(:tuple, arguments...)))
transform=:(NamedTuple{$names}( :($(Expr(:tuple, arguments...))) ))
```

But `transform`

is an expression that needs to be evaluated for a given value of `x`

when `x`

is in scope. This sounds like it should be a macro that returns a `vec2tuple(x)`

-style function, but I can’t quite figure out how to write this.

And furthermore, what if I don’t know `bounds`

at compile-time? I can still know it before I need to call `vec2tuple`

a whole bunch of time, so I don’t mind paying a price to construction this function once during runtime, as long as it’s fast when I call it.

Sorry for the long post and a less-than-specific question, but any ideas are really welcome! Thanks.