# $ interpolation into :()

**URL:** <https://discourse.julialang.org/t/interpolation-into/27806>\
**Category:** Internals & Design\
**Tags:** question\
**Created:** [August 21, 2019, 3:25pm UTC](https://discourse.julialang.org/t/interpolation-into/27806 "2019-08-21T15:25:03Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![bkamins](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bkamins/32/208538_2.png) [@bkamins](https://discourse.julialang.org/u/bkamins)\
**Post date:** [August 21, 2019, 3:25pm UTC](https://discourse.julialang.org/t/interpolation-into/27806/1 "2019-08-21T15:25:04Z")

</div>

Consider the following code:

```julia
julia> nt = (x=1, y=2)
(x = 1, y = 2)

julia> k1 = keys(nt)[1]
:x

julia> :($k1)
:x

julia> :($(keys(nt)[1]))
:x

julia> nt.:($k1)
1

julia> nt.:($(keys(nt)[1]))
ERROR: syntax: invalid syntax "nt.(keys(nt)[1])"

```

It seems to me that this behavior is inconsistent. My question is:

1. Is using of `$` to interpolate into `:()` a feature or a hack (in which case it should not be recommended to be used).
2. If it is a feature is it possible to make the case of a single identifier and an expression to be handled consistently?

Thank you!

---

<div class="post-metadata">

**Author:** ![simeonschaub](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/simeonschaub/32/216566_2.png) [@simeonschaub](https://discourse.julialang.org/u/simeonschaub)\
**Post date:** [August 21, 2019, 3:56pm UTC](https://discourse.julialang.org/t/interpolation-into/27806/2 "2019-08-21T15:56:49Z")

</div>

The problem here is that `:()` doesn’t quite work that way and `:($(keys(nt)[1]))` is equivalent to `keys(nt)[1]` after parsing. For more discussion on this behavior see also this thread:

[https://discourse.julialang.org/t/any-rational-behind-symbol-true-true/27597](https://discourse.julialang.org/t/any-rational-behind-symbol-true-true/27597)

The solution here would be to just call `getproperty` directly.

---

<div class="post-metadata">

**Author:** ![mbauman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mbauman/32/31082_2.png) [@mbauman](https://discourse.julialang.org/u/mbauman)\
**Post date:** [August 21, 2019, 5:04pm UTC](https://discourse.julialang.org/t/interpolation-into/27806/3 "2019-08-21T17:04:21Z")

</div>

For 1, yes, this is an explicit and frequently-used feature. Typical use of `:(…)` is exactly identical to `quote … end`. And splicing things into expressions like this is a key part of Julia’s metaprogramming — it is documented in that section of the manual.

For 2, this is an interaction between `.`-property access and `:` quoting. I think this may be a bug, but this is complicated because `.` is so overloaded. For example, we’re just a stone’s throw away from a broadcast:

```julia
julia> nt = (x=1,y=2)
(x = 1, y = 2)

julia> x = :y
:y

julia> nt.:(x)
1

julia> nt.:($x)
2

julia> nt.:($(x,))
ERROR: MethodError: objects of type NamedTuple{(:x, :y),Tuple{Int64,Int64}} are not callable
Stacktrace:
 [1] _broadcast_getindex_evalf at ./broadcast.jl:625 [inlined]
 [2] _broadcast_getindex at ./broadcast.jl:598 [inlined]
 [3] getindex at ./broadcast.jl:558 [inlined]
 [4] copy at ./broadcast.jl:824 [inlined]
 [5] materialize(::Base.Broadcast.Broadcasted{Base.Broadcast.DefaultArrayStyle{0},Nothing,NamedTuple{(:x, :y),Tuple{Int64,Int64}},Tuple{Base.RefValue{Symbol}}}) at ./broadcast.jl:814
 [6] top-level scope at REPL[22]:1

julia> sqrt.:($(rand(3),))
3-element Array{Float64,1}:
 0.8930844290914318
 0.3289781971083193
 0.9250148515294918

```

---

<div class="post-metadata">

**Author:** ![bkamins](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bkamins/32/208538_2.png) [@bkamins](https://discourse.julialang.org/u/bkamins)\
**Post date:** [August 21, 2019, 5:43pm UTC](https://discourse.julialang.org/t/interpolation-into/27806/4 "2019-08-21T17:43:59Z")

</div>

Thank you both for the comments. I was not aware that `:()` was equivalent to `quote`.

However, it seems that the interpolation does not happen at parse time:

```julia
julia> Meta.parse(raw":($(keys(nt)[1]))")
:($(Expr(:quote, :($(Expr(:$, :((keys(nt))[1])))))))

julia> Meta.parse(raw"quote $(keys(nt)[1]) end")
:($(Expr(:quote, quote
    #= none:1 =#
    $(Expr(:$, :((keys(nt))[1])))
end)))

```

So the substitution must happen at some later time.

---

<div class="post-metadata">

**Author:** ![bkamins](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bkamins/32/208538_2.png) [@bkamins](https://discourse.julialang.org/u/bkamins)\
**Post date:** [August 21, 2019, 8:48pm UTC](https://discourse.julialang.org/t/interpolation-into/27806/5 "2019-08-21T20:48:22Z")

</div>

Just to add, the following parses as expected:

```julia
julia> eval(Meta.parse(raw":(nt.$(keys(nt)[1]))"))
:(nt.x)

julia> eval(eval(Meta.parse(raw":(nt.$(keys(nt)[1]))")))
1

```
