# Is it possible to modify ast by itself?

**URL:** <https://discourse.julialang.org/t/is-it-possible-to-modify-ast-by-itself/18267>\
**Category:** General Usage\
**Created:** [December 4, 2018, 3:31am UTC](https://discourse.julialang.org/t/is-it-possible-to-modify-ast-by-itself/18267 "2018-12-04T03:31:08Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![xyyimian](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/xyyimian/32/6326_2.png) [@xyyimian](https://discourse.julialang.org/u/xyyimian)\
**Post date:** [December 4, 2018, 3:31am UTC](https://discourse.julialang.org/t/is-it-possible-to-modify-ast-by-itself/18267/1 "2018-12-04T03:31:08Z")

</div>

Hi everyone, I am trying to write a julia debugger.  
I am wondering if it is possible to modify a block’s ast by itself.

I tried like this:

```julia
julia> s = "function test1()
               println(1)
               println(2)
               println(3)
               println(4)
       end"
"function test1()\n println(1)\n println(2)\n println(3)\n println(4)\nend"

julia> ast = Meta.parse(s)
:(function test1()
      #= none:2 =#
      println(1)
      #= none:3 =#
      println(2)
      #= none:4 =#
      println(3)
      #= none:5 =#
      println(4)
  end)

julia> eval(ast)
test1 (generic function with 1 method)

julia> function helloworld()
         print("helloworld")
       end
helloworld (generic function with 1 method)

julia> function testReviseSelf(ast)
         ast.args[2].args[5] = Expr(:call, helloworld)
       end
testReviseSelf (generic function with 1 method)

julia> ast.args[2].args[3] = Expr(:call, helloworld)
:((helloworld)())

julia> ast
:(function test1()
      #= none:2 =#
      println(1)
      (helloworld)()
      println(2)
      #= none:4 =#
      println(3)
      #= none:5 =#
      println(4)
  end)

```

I want to use inter() to modify ast

```julia
julia> function inter()
         global ast
         testReviseSelf(ast)
       end
inter (generic function with 1 method)

julia> ast.args[2].args[1] = Expr(:call, inter)
:((inter)())

julia> ast
:(function test1()
      (inter)()
      println(1)
      (helloworld)()
      println(2)
      #= none:4 =#
      println(3)
      #= none:5 =#
      println(4)
  end)

```

However it seems I should run the block twice to get it changed

```julia
julia> test1()
1
helloworld2
3
4

julia> ast
:(function test1()
      (inter)()
      println(1)
      (helloworld)()
      println(2)
      (helloworld)()
      println(3)
      #= none:5 =#
      println(4)
  end)

julia> eval(ast)
test1 (generic function with 1 method)

julia> test1()
1
helloworld2
helloworld3
4

```

I am wondering if it is possible to modify the ast while eval the ast.  
Thanks!

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [December 4, 2018, 3:43am UTC](https://discourse.julialang.org/t/is-it-possible-to-modify-ast-by-itself/18267/2 "2018-12-04T03:43:05Z")

</div>

The function `test1` is in no way connected to the variable `ast` so no. Not in anyway similar to what you have.

---

<div class="post-metadata">

**Author:** ![y4lu](https://avatars.discourse-cdn.com/v4/letter/y/47e85d/32.png) [@y4lu](https://discourse.julialang.org/u/y4lu)\
**Post date:** [December 4, 2018, 5:01am UTC](https://discourse.julialang.org/t/is-it-possible-to-modify-ast-by-itself/18267/3 "2018-12-04T05:01:37Z")

</div>

It might work as a recursive `Base.invokelatest(eval(ast), "args")` if you can avoid it looping forever

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [December 4, 2018, 1:36pm UTC](https://discourse.julialang.org/t/is-it-possible-to-modify-ast-by-itself/18267/4 "2018-12-04T13:36:18Z")

</div>

Well, part of my “in anyway similar to what you have” assumes that the `test1` should not be completely rewritten. If that’s acceptable, there’s infinite many ways to change the target of a function call. Just use a callback or a non-const variable to store the function. What the OP wanted to do is never going to be type stable anyway.
