# Naming elements in a Matrix

**URL:** <https://discourse.julialang.org/t/naming-elements-in-a-matrix/127553>\
**Category:** New to Julia\
**Created:** [March 31, 2025, 2:29pm UTC](https://discourse.julialang.org/t/naming-elements-in-a-matrix/127553 "2025-03-31T14:29:49Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![WalterMadelim](https://avatars.discourse-cdn.com/v4/letter/w/3e96dc/32.png) [@WalterMadelim](https://discourse.julialang.org/u/WalterMadelim)\
**Post date:** [March 31, 2025, 2:29pm UTC](https://discourse.julialang.org/t/naming-elements-in-a-matrix/127553/1 "2025-03-31T14:29:49Z")

</div>

I find this usage interesting (see the _second to last_ `julia>`)

```julia
julia> a = (b = 1; c = 2);

julia> a, b, c
(2, 1, 2)

julia> a = (d = 3, e = 4)
(d = 3, e = 4)

julia> @isdefined(d) || @isdefined(e)
false

julia> f = [d=3, e=4];
ERROR: syntax: misplaced assignment statement in "[d = 3, e = 4]" around REPL[5]:1
Stacktrace:
 [1] top-level scope
   @ REPL[5]:1

julia> f = [d=3; e=4];
ERROR: syntax: misplaced assignment statement in "[d = 3; e = 4]" around REPL[6]:1
Stacktrace:
 [1] top-level scope
   @ REPL[6]:1

julia> f = [d=3;
       e=4];
ERROR: syntax: misplaced assignment statement in "[d = 3; e = 4]" around REPL[7]:1
Stacktrace:
 [1] top-level scope
   @ REPL[7]:1

julia> @isdefined(f) || @isdefined(d) || @isdefined(e)
false

julia> f = [d=5 e=6;
       g=7 h=8]
2×2 Matrix{Int64}:
 5 6
 7 8

julia> d, e, g, h
(5, 6, 7, 8)

```

But why is it only allowed within a `Matrix`?

---

<div class="post-metadata">

**Author:** ![mikmoore](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mikmoore/32/31109_2.png) [@mikmoore](https://discourse.julialang.org/u/mikmoore)\
**Post date:** [March 31, 2025, 3:08pm UTC](https://discourse.julialang.org/t/naming-elements-in-a-matrix/127553/2 "2025-03-31T15:08:51Z")

</div>

This is comparing `NamedTuple` and `Array`. They are different datatypes with different design goals, so don’t support all the same syntax options. A (named) tuple is a struct-like heterogeneous object while an array is a indexable object (that usually has homogeneous elements).

However, there are many packages that have array objects that offer the ability to name the axes and/or indices of arrays (each package offers different designs and tradeoffs). Hopefully someone else can chime in with actual recommendations, but so far I’ve found (in no particular order) AxisArrays.jl, DimensionalData.jl, LabelledArrays.jl, NamedArrays.jl that all appear to provide some version of functionality like this.

---

<div class="post-metadata">

**Author:** ![GHTaarn](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ghtaarn/32/216007_2.png) [@GHTaarn](https://discourse.julialang.org/u/GHTaarn)\
**Post date:** [March 31, 2025, 4:52pm UTC](https://discourse.julialang.org/t/naming-elements-in-a-matrix/127553/3 "2025-03-31T16:52:11Z")

</div>

Are you aware that your first line is equivalent to

```julia
a = begin
    b = 1
    c = 2
end

```

which returns the value `2` and sets the variable `b` to `1` and the variable `c` to `2`.

`a = (d = 3, e = 4)` creates a `NamedTuple` and is equivalent to

```julia
a = NamedTuple{(:d, :e)}((3, 4))

```

You cannot name the elements in a `Matrix`, but the very popular DataFrames.jl package allows you to name the columns of a matrix like data type.

---

<div class="post-metadata">

**Author:** ![eldee](https://avatars.discourse-cdn.com/v4/letter/e/b5a626/32.png) [@eldee](https://discourse.julialang.org/u/eldee)\
**Post date:** [March 31, 2025, 4:56pm UTC](https://discourse.julialang.org/t/naming-elements-in-a-matrix/127553/4 "2025-03-31T16:56:04Z")

</div>

> [@WalterMadelim](#):
>
> But why is it only allowed within a `Matrix`?

I’m not sure what exactly is happening under the hood to explain the difference, but note that this is also not allowed for all matrices:

```julia-repl
julia> [5 6]
1×2 Matrix{Int64}:
 5 6

julia> [d=5 e=6]
ERROR: syntax: misplaced assignment statement in "[d = 5 e = 6]" around REPL[3]:1
Stacktrace:
 [1] top-level scope
   @ REPL[3]:1
```

---

<div class="post-metadata">

**Author:** ![sgaure](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sgaure/32/14779_2.png) [@sgaure](https://discourse.julialang.org/u/sgaure)\
**Post date:** [March 31, 2025, 6:24pm UTC](https://discourse.julialang.org/t/naming-elements-in-a-matrix/127553/5 "2025-03-31T18:24:24Z")

</div>

You’re not really naming elements in the matrix.

The ones with round parentheses are either a sequence of expressions, i.e.

```julia
a = (b = 1; c=2)

```

is the same as

```julia
a = begin
    b = 1
    c = 2
end

```

So you just assign 1 to `b`, 2 to `c`, and `a` gets the value of the compound expression, which is the value of the last expression.

Or, with a comma, `a = (b=1, c=2)`, you create a named tuple.

The array syntax does not in general allow naming of elements, but apparently there is some quirk in the parser which inadvertently allows assignments in the matrix notation so that `a = [b=1 c=2; d=3 e=4]` works, and ends up effectively as

```julia
b = 1
c = 2
d = 3
e = 4
a = [1 2; 3 4]

```

I’d guess it’s because this is parsed to some iteration which ends up as a `hvcat` call, but I’m not certain what happens.

Note that you can’t change the matrix by assigning e.g. to `e` afterwards, and `e` won’t change if you modify `a[2, 2]`. So the matrix elements have not been named. It’s merely in-place assignments, similar to constructions like `sin((x=pi/2;))`.

---

<div class="post-metadata">

**Author:** ![sgaure](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sgaure/32/14779_2.png) [@sgaure](https://discourse.julialang.org/u/sgaure)\
**Post date:** [March 31, 2025, 6:40pm UTC](https://discourse.julialang.org/t/naming-elements-in-a-matrix/127553/6 "2025-03-31T18:40:36Z")

</div>

Btw, there are other quirks in the parser as well, like

```julia
julia> for Base.exp(x) in 1:5; end
julia> exp("a")
5

```

This “works” because the for loop expands to

```julia
Base.exp(x) = 1
Base.exp(x) = 2
...
Base.exp(x) = 5

```

---

<div class="post-metadata">

**Author:** ![digital\_carver](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/digital_carver/32/33818_2.png) [@digital\_carver](https://discourse.julialang.org/u/digital_carver)\
**Post date:** [March 31, 2025, 7:24pm UTC](https://discourse.julialang.org/t/naming-elements-in-a-matrix/127553/7 "2025-03-31T19:24:10Z")

</div>

That’s… quite horrifying. Maybe someone can find a rare clever use for

```julia
julia> for Base.exp(x) in 1:5; @show exp('c'); end
exp('c') = 1
exp('c') = 2
exp('c') = 3
exp('c') = 4
exp('c') = 5

```

but the same can be accomplished in other ways, and in practice this syntax seems guaranteed to occur via typos or beginner mistakes in loops. And it makes them weirder and harder to figure out.

---

<div class="post-metadata">

**Author:** ![WalterMadelim](https://avatars.discourse-cdn.com/v4/letter/w/3e96dc/32.png) [@WalterMadelim](https://discourse.julialang.org/u/WalterMadelim)\
**Post date:** [April 1, 2025, 12:09am UTC](https://discourse.julialang.org/t/naming-elements-in-a-matrix/127553/8 "2025-04-01T00:09:59Z")

</div>

> [@mikmoore](#):
>
> A (named) tuple is a struct-like heterogeneous object while an array is a indexable object (that usually has homogeneous elements).

To be honest, I don’t find **NamedTuple** really useful in practice.  
If the size of the tuple is small, I can index by integers directly because I can remember the location.  
If it becomes complicated, I can use **Dict** instead.

> [@sgaure](#):
>
> I’d guess it’s because this is parsed to some iteration which ends up as a `hvcat` call, but I’m not certain what happens.

I like the existing behavior, I hope we can retain this property.

> [@sgaure](#):
>
> ```julia
> julia> for Base.exp(x) in 1:5; end
> julia> exp("a")
> 
> ```

I guess no one will write these 2 lines seriously in his work. It seems pointless, therefore less disquieting.

---

<div class="post-metadata">

**Author:** ![sgaure](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sgaure/32/14779_2.png) [@sgaure](https://discourse.julialang.org/u/sgaure)\
**Post date:** [April 1, 2025, 7:09am UTC](https://discourse.julialang.org/t/naming-elements-in-a-matrix/127553/9 "2025-04-01T07:09:28Z")

</div>

> [@WalterMadelim](#):
>
> To be honest, I don’t find **NamedTuple** really useful in practice.  
> If the size of the tuple is small, I can index by integers directly because I can remember the location.  
> If it becomes complicated, I can use **Dict** instead.

`NamedTuple`s are fine when one needs to return multiple values from a function and doesn’t want to create a struct only for this purpose. It’s an on the fly struct.

`Dict`s are slow to lookup, whereas lookup in a named tuple is typically compiled away. With heterogeneous types, using a `Dict` will typically lead to dynamic dispatch, which is devastating for performance.

---

<div class="post-metadata">

**Author:** ![GHTaarn](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ghtaarn/32/216007_2.png) [@GHTaarn](https://discourse.julialang.org/u/GHTaarn)\
**Post date:** [April 1, 2025, 12:11pm UTC](https://discourse.julialang.org/t/naming-elements-in-a-matrix/127553/10 "2025-04-01T12:11:56Z")

</div>

> [@WalterMadelim](#):
>
> To be honest, I don’t find **NamedTuple** really useful in practice.  
> If the size of the tuple is small, I can index by integers directly because I can remember the location.  
> If it becomes complicated, I can use **Dict** instead.

`NamedTuple`s are more restricted than `Dict`s (they are immutable and their keys must be `Symbol`s), but in cases where this is natural, I think that most experienced Julia users will prefer them over `Dict`s and `Tuple`s, consider this example:

```julia
disc = (; radius=5.5, thickness=0.8, material=:steel)
# In another part of the code
weight = disc.thickness * pi * disc.radius^2 * density[disc.material]

```

compared with

```julia
disc = (5.5, 0.8, :steel)
# In another part of the code
weight = disc[1] * pi * disc[2]^2 * density[disc[3]]

```

or

```julia
disc = Dict(:radius => 5.5, :thickness => 0.8, :material => :steel)
# In another part of the code
weight = disc[:thickness] * pi * disc[:radius]^2 * density[disc[:material]]

```

In my opinion, the `NamedTuple` version is the clearest; it is much easier to understand than the `Tuple` version and looks neater and requires less keystrokes than the `Dict` version. Also considering the performance described by @sgaure , there are many cases where it should be the chosen solution.
