# Get a Symbol vector of all variable names in an Expr?

**URL:** <https://discourse.julialang.org/t/get-a-symbol-vector-of-all-variable-names-in-an-expr/39391>\
**Category:** General Usage\
**Created:** [May 13, 2020, 11:09am UTC](https://discourse.julialang.org/t/get-a-symbol-vector-of-all-variable-names-in-an-expr/39391 "2020-05-13T11:09:48Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![robsmith11](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/robsmith11/32/29641_2.png) [@robsmith11](https://discourse.julialang.org/u/robsmith11)\
**Post date:** [May 13, 2020, 11:09am UTC](https://discourse.julialang.org/t/get-a-symbol-vector-of-all-variable-names-in-an-expr/39391/1 "2020-05-13T11:09:48Z")

</div>

Is there a simple and type stable way to do this?

```julia
julia> f(:(x^2+sum(x,y-3,z)))

4-element Array{Symbol,1}:
 :x
 :x
 :y
 :z

```

---

<div class="post-metadata">

**Author:** ![mcabbott](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mcabbott/32/6603_2.png) [@mcabbott](https://discourse.julialang.org/u/mcabbott)\
**Post date:** [May 13, 2020, 11:20am UTC](https://discourse.julialang.org/t/get-a-symbol-vector-of-all-variable-names-in-an-expr/39391/2 "2020-05-13T11:20:40Z")

</div>

It’s pretty easy to walk expression trees, typing `:(x^2+1) |> dump` etc. will let you see how they are structured. Here’s a rough solution, but there are expressions which will trip this up:

```julia
julia> walk!(list) = ex -> begin
       ex isa Symbol && push!(list, ex)
       ex isa Expr && ex.head == :call && map(walk!(list), ex.args[2:end])
       list
       end
walk! (generic function with 1 method)

julia> :(x^2+sum(x,y-3,z)) |> walk!([])
4-element Array{Any,1}:
 :x
 :x
 :y
 :z

```

---

<div class="post-metadata">

**Author:** ![FireCrumb](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/firecrumb/32/35370_2.png) [@FireCrumb](https://discourse.julialang.org/u/FireCrumb)\
**Post date:** [May 18, 2022, 1:38pm UTC](https://discourse.julialang.org/t/get-a-symbol-vector-of-all-variable-names-in-an-expr/39391/3 "2022-05-18T13:38:38Z")

</div>

[MacroTools.jl Expression Walking](https://fluxml.ai/MacroTools.jl/stable/pattern-matching/#Expression-Walking-1) can iterate expressions.

1. How to get just `x, y, z` (from both `ex1` and `ex2`) and not `+,-,^,sum`?
2. How to return the list directly from postwalk instead of pushing to external list?

```julia
import MacroTools: postwalk

function get_ex_symbols1(ex)
    list = []
    postwalk(x -> x isa Symbol ? (push!(list, x); x) : x, ex)
    return Set{Symbol}(list)
end

function get_ex_symbols2(ex)
    list = []
    walk!(list) = ex -> begin
       ex isa Symbol && push!(list, ex)
       ex isa Expr && ex.head == :call && map(walk!(list), ex.args[2:end])
       list
    end
    Set{Symbol}(walk!([])(ex))
end

ex1 = :(x^2+sum(x,y-3,z))
ex2 = :(function f(x,y); x=x+1; y=y^2; z=sum(x,y) end);

```

```julia
julia> get_ex_symbols1(ex1)
Set{Symbol} with 7 elements:
  :+
  :^
  :y
  :-
  :z
  :sum
  :x

julia> get_ex_symbols1(ex2)
Set{Symbol} with 7 elements:
  :+
  :z
  :f
  :^
  :y
  :sum
  :x

julia> get_ex_symbols2(ex1)
Set{Symbol} with 3 elements:
  :y
  :z
  :x

julia> get_ex_symbols2(ex2)
Set{Symbol}()

```
