# How to use string substitution in variable names

**URL:** https://discourse.julialang.org/t/how-to-use-string-substitution-in-variable-names/55192
**Category:** New to Julia
**Tags:** strings
**Created:** [February 13, 2021, 5:57am UTC](https://discourse.julialang.org/t/how-to-use-string-substitution-in-variable-names/55192 "2021-02-13T05:57:30Z")
**Posts on this page:** 16
**Page:** 1

<div class="post-metadata">

### Author: ![samerb](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/samerb/32/9242_2.png) [@samerb](https://discourse.julialang.org/u/samerb)
#### Post date: [February 13, 2021, 5:57am UTC](https://discourse.julialang.org/t/how-to-use-string-substitution-in-variable-names/55192/1 "2021-02-13T05:57:30Z")

</div>

I would like to do something like the following but that doesn’t work. How can I do this? Maybe use `$` somehow? Edit: To be clear, I am trying to create the first 7 unit vectors. Thanks

```julia
for i in 1:7
    e_i = zeros(7)
    e_i[i] = 1
end

```

---

<div class="post-metadata">

### Author: ![Oscar\_Smith](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oscar_smith/32/25343_2.png) [@Oscar\_Smith](https://discourse.julialang.org/u/Oscar_Smith)
#### Post date: [February 13, 2021, 7:35am UTC](https://discourse.julialang.org/t/how-to-use-string-substitution-in-variable-names/55192/2 "2021-02-13T07:35:51Z")

</div>

What result do you want to get? Did you want the following?

```julia
e_i = zeros(7)
for i in 1:7
    e_i[i] = 1
end

```

---

<div class="post-metadata">

### Author: ![pbayer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pbayer/32/11675_2.png) [@pbayer](https://discourse.julialang.org/u/pbayer)
#### Post date: [February 13, 2021, 8:25am UTC](https://discourse.julialang.org/t/how-to-use-string-substitution-in-variable-names/55192/3 "2021-02-13T08:25:32Z")

</div>

very clumsy, but I guess you look for something like:

```julia
julia> for i in 1:7
           eval(Meta.parse("e_$i = zeros(7)"))
           eval(Meta.parse("e_$i[$i] = 1"))
       end

julia> show(e_5)
[0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0]

```

---

<div class="post-metadata">

### Author: ![samerb](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/samerb/32/9242_2.png) [@samerb](https://discourse.julialang.org/u/samerb)
#### Post date: [February 13, 2021, 3:45pm UTC](https://discourse.julialang.org/t/how-to-use-string-substitution-in-variable-names/55192/4 "2021-02-13T15:45:46Z")

</div>

I was trying to create unit vectors.

---

<div class="post-metadata">

### Author: ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)
#### Post date: [February 13, 2021, 4:08pm UTC](https://discourse.julialang.org/t/how-to-use-string-substitution-in-variable-names/55192/5 "2021-02-13T16:08:58Z")

</div>

> [@samerb](#):
>
> I would like to do something like the following but that doesn’t work. How can I do this? Maybe use `$` somehow? Edit: To be clear, I am trying to create the first 7 unit vectors. Thanks

Don’t use metaprogramming or generated variable names. Use a data structure. For example, an array `e` of the 7 unit vectors in ℝ⁷ can be constructed with:

```julia
e = [let v = zeros(7); v[i] = 1; v; end for i in 1:7 ]

```

This way, you can refer to `e[i]` programmatically rather than (as you seem to want) having 7 separate variables `e_1`, `e_2`, …, `e_7`. For example:

```julia
julia> e[3]
7-element Array{Float64,1}:
 0.0
 0.0
 1.0
 0.0
 0.0
 0.0
 0.0

```

See also this thread: [How to warn new users away from metaprogramming](https://discourse.julialang.org/t/how-to-warn-new-users-away-from-metaprogramming/35022)

---

<div class="post-metadata">

### Author: ![samerb](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/samerb/32/9242_2.png) [@samerb](https://discourse.julialang.org/u/samerb)
#### Post date: [February 13, 2021, 4:32pm UTC](https://discourse.julialang.org/t/how-to-use-string-substitution-in-variable-names/55192/6 "2021-02-13T16:32:00Z")

</div>

It’s not fully transparent to me what is going in on in

`e = [let v = zeros(7); v[i] = 1; v; end for i in 1:7 ]`.

I looked up `let` so have a little feel for that, but I don’t understand how to think about the `v;` part. I notice that if I take it out, I just get a single vector of all ones instead of an array of 7 unit vectors/arrays.

---

<div class="post-metadata">

### Author: ![pdeffebach](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pdeffebach/32/10320_2.png) [@pdeffebach](https://discourse.julialang.org/u/pdeffebach)
#### Post date: [February 13, 2021, 4:35pm UTC](https://discourse.julialang.org/t/how-to-use-string-substitution-in-variable-names/55192/7 "2021-02-13T16:35:01Z")

</div>

Here is a more transparent, but less performant, way of constructing the same object.

```julia
e = Vector{Float64}[]
for i in 1:7
    v = zeros(7)
    v[i] = 1
    push!(e, v)
end

```

---

<div class="post-metadata">

### Author: ![samerb](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/samerb/32/9242_2.png) [@samerb](https://discourse.julialang.org/u/samerb)
#### Post date: [February 13, 2021, 4:39pm UTC](https://discourse.julialang.org/t/how-to-use-string-substitution-in-variable-names/55192/8 "2021-02-13T16:39:04Z")

</div>

I assume you meant `v[i] =1` not `v[1] =1` but I understand that thanks everyone.

---

<div class="post-metadata">

### Author: ![pdeffebach](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pdeffebach/32/10320_2.png) [@pdeffebach](https://discourse.julialang.org/u/pdeffebach)
#### Post date: [February 13, 2021, 4:44pm UTC](https://discourse.julialang.org/t/how-to-use-string-substitution-in-variable-names/55192/9 "2021-02-13T16:44:07Z")

</div>

Thank you. Fixed.

---

<div class="post-metadata">

### Author: ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)
#### Post date: [February 13, 2021, 4:45pm UTC](https://discourse.julialang.org/t/how-to-use-string-substitution-in-variable-names/55192/10 "2021-02-13T16:45:15Z")

</div>

> [@samerb](#):
>
> I don’t understand how to think about the `v;` part. I notice that if I take it out, I just get a single vector of all ones instead of an array of 7 unit vectors/arrays.

The `let` block needs to return the value that you want to store in the array formed by the comprehension. Since the return value of a `let` block is the value of the _last statement_, you have to put `v` as the last statement to store the vector `v` in the result array.

In contrast, if the last statement in the `let` block is `v[i] = 1`, the value of this statement is `1` (e.g. `x = v[i] = 1` assigns `1` to both `x` and `v[i]`), so the comprehension returns an array of `1`’s.

---

<div class="post-metadata">

### Author: ![Mason](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mason/32/2423_2.png) [@Mason](https://discourse.julialang.org/u/Mason)
#### Post date: [February 13, 2021, 7:32pm UTC](https://discourse.julialang.org/t/how-to-use-string-substitution-in-variable-names/55192/11 "2021-02-13T19:32:20Z")

</div>

While I agree that this is perhaps not an appropriate place for using meta-programming, I beleive it’s still useful to also answer the question that was asked. Since the only answer here that attempts to address the actual question asked uses `eval`, I want to note that something like this can be done very cleanly without `eval`, and is actually an important part of julia’s Cartesian indexing implementation.

The way to do this when the number of unit vectors needed is known at macroexpansion time is to write a macro. Here’s one possible way:

```julia
julia> macro define_basis_vecs(sym::Symbol, n::Integer)
           Expr(:block, __source__ , map(i -> :($(esc(Symbol(sym, i))) = $( [j==i for j in 1:n] )), 1:n)...)
       end
@define_basis_vecs (macro with 1 method)

```

We can macroexpand it to make sure it generates the right code:

```julia
julia> @macroexpand @define_basis_vecs e_ 5
quote
    #= REPL[15]:1 =#
    e_1 = Bool[1, 0, 0, 0, 0]
    e_2 = Bool[0, 1, 0, 0, 0]
    e_3 = Bool[0, 0, 1, 0, 0]
    e_4 = Bool[0, 0, 0, 1, 0]
    e_5 = Bool[0, 0, 0, 0, 1]
end

```

Unlike solutions with `eval`, this will work in the local scope.

```julia
julia> let 
           @define_basis_vecs e_ 7
           e_1 * e_7'
       end
7×7 BitMatrix:
 0 0 0 0 0 0 1
 0 0 0 0 0 0 0
 0 0 0 0 0 0 0
 0 0 0 0 0 0 0
 0 0 0 0 0 0 0
 0 0 0 0 0 0 0
 0 0 0 0 0 0 0

```

and won’t leak any variables out of that scope:

```julia
julia> e_1
ERROR: UndefVarError: e_1 not defined

```

But again, as was pointed out earlier, this is a usecase that is usually better satisfied in much more ‘boring’ ways without any metaprogramming.

If you’ve spoken to your doctor and you think that Metaprogramming may be right for you, I’d recommend reading this section of the manual thoroughly: [Metaprogramming · The Julia Language](https://docs.julialang.org/en/v1/manual/metaprogramming/)

---

<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: [February 14, 2021, 10:28am UTC](https://discourse.julialang.org/t/how-to-use-string-substitution-in-variable-names/55192/12 "2021-02-14T10:28:14Z")

</div>

> [@Mason](#):
>
> If you’ve spoken to your doctor and you think that Metaprogramming may be right for you

In the context of this problem, I would suggest finding another doctor.

---

<div class="post-metadata">

### Author: ![rafael.guerra](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rafael.guerra/32/216610_2.png) [@rafael.guerra](https://discourse.julialang.org/u/rafael.guerra)
#### Post date: [May 2, 2021, 7:06pm UTC](https://discourse.julialang.org/t/how-to-use-string-substitution-in-variable-names/55192/13 "2021-05-02T19:06:39Z")

</div>

@stevengj, assuming LinearAlgebra is being used, one could also write the 7 unit vectors in ℝ⁷ compactly with:

```julia
e = [diagm(ones(7))[i,:] for i in 1:7]

```

---

<div class="post-metadata">

### Author: ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)
#### Post date: [May 2, 2021, 8:11pm UTC](https://discourse.julialang.org/t/how-to-use-string-substitution-in-variable-names/55192/14 "2021-05-02T20:11:54Z")

</div>

Faster an shorter:

```julia
collect(eachcol(diagm(ones(7))))

```

---

<div class="post-metadata">

### Author: ![rafael.guerra](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rafael.guerra/32/216610_2.png) [@rafael.guerra](https://discourse.julialang.org/u/rafael.guerra)
#### Post date: [May 2, 2021, 8:27pm UTC](https://discourse.julialang.org/t/how-to-use-string-substitution-in-variable-names/55192/15 "2021-05-02T20:27:17Z")

</div>

@DNF, [quoting you in this other post](https://discourse.julialang.org/t/function-for-finding-additiion-decompositions-of-an-integer/60295/7) _" Why are you using `collect` ? 😬 Never use `collect` (If I ever get a tattoo, it will say that)"_  
Cheers 🙂

_ **NB:** one could also use splatting:_

```julia
e = [eachcol(diagm(ones(7)))...]

```

---

<div class="post-metadata">

### Author: ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)
#### Post date: [May 2, 2021, 8:35pm UTC](https://discourse.julialang.org/t/how-to-use-string-substitution-in-variable-names/55192/16 "2021-05-02T20:35:33Z")

</div>

I am _so_ aware 😉 But I wouldn’t do it if I were to iterate over them.
