# Clear observables created by @lift

**URL:** <https://discourse.julialang.org/t/clear-observables-created-by-lift/63127>\
**Category:** Visualization\
**Tags:** makie\
**Created:** [June 18, 2021, 7:34am UTC](https://discourse.julialang.org/t/clear-observables-created-by-lift/63127 "2021-06-18T07:34:00Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![phlavenk](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/phlavenk/32/1873_2.png) [@phlavenk](https://discourse.julialang.org/u/phlavenk)\
**Post date:** [June 18, 2021, 7:34am UTC](https://discourse.julialang.org/t/clear-observables-created-by-lift/63127/1 "2021-06-18T07:34:00Z")

</div>

What is the proper way of clearing the (perhaps wrong) @lift observable listeners?

Following example has an error

```julia
using WGLMakie
time = Node(1.5)
ξ = @lift( 1.0 < $time < 2.0 ? $time - 1.0 : 0.0*err) #error, err not defined!
xpos = 1:10
ypos = @lift( $ξ .*(1:1:10) .+ (1-$ξ).*(10:-1:1) )
fig, ax = scatter(xpos, ypos) 
f # everything is OK
time[] = 0.5 #hitting the err conditions
f

```

Now, I’ve found the error and would like to redefine

```julia
ξ = @lift( 1.0 < $time < 2.0 ? $time - 1.0 : 0.0) # correct!

```

It is correct but the old listener function (with the `0.0*err` expression) is still hanging around and causing troubles…

Any idea how to clear the old listeners (lifted variables) without restarting the julia session?

---

<div class="post-metadata">

**Author:** ![jules](https://avatars.discourse-cdn.com/v4/letter/j/41988e/32.png) [@jules](https://discourse.julialang.org/u/jules)\
**Post date:** [June 18, 2021, 7:43am UTC](https://discourse.julialang.org/t/clear-observables-created-by-lift/63127/2 "2021-06-18T07:43:45Z")

</div>

Hope this clears it up:

```julia
julia> x = Node(1)
Observable{Int64} with 0 listeners. Value:
1

julia> obsfunc = on(x) do x
           @show x
       end
(::Observables.ObserverFunction) (generic function with 0 methods)

julia> x[] = 3
x = 3
3

julia> off(obsfunc)
true

julia> x[] = 4
4

julia> y = lift(x) do x
           println("y is still there")
           3 * x
       end
y is still there
y is still there
Observable{Int64} with 0 listeners. Value:
12

julia> x[] = 5
y is still there
5

julia> y = lift(x) do x
           println("new y")
           4 * x
       end
new y
new y
Observable{Int64} with 0 listeners. Value:
20

julia> x[] = 6
y is still there
new y
6

julia> deleteat!(x.listeners, 1)
1-element Vector{Any}:
 (::Observables.OnUpdate{Observables.MapUpdater{var"#307#308", Int64}, Tuple{Observable{Int64}}}) (generic function with 1 method)

julia> x[] = 7
new y
7

julia> empty!(x.listeners)
Any[]

julia> x[] = 8
8

```

---

<div class="post-metadata">

**Author:** ![phlavenk](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/phlavenk/32/1873_2.png) [@phlavenk](https://discourse.julialang.org/u/phlavenk)\
**Post date:** [June 18, 2021, 8:13am UTC](https://discourse.julialang.org/t/clear-observables-created-by-lift/63127/3 "2021-06-18T08:13:08Z")

</div>

So, if I correctly understand, I have to manually remove the concrete function from the list of listeners of all input observables/nodes that I used during the lift call?

I’ll rephrase it once more. Do I correctly understand that if I want to remove a lifted observable, there is no function that would traverse the “parents” of my observable and deregister?

Is it feasible to write such a function? Or, would it require a bi-directional reference list (of “lifts”) as part of Observable structure, so we know on which objects to deregister?

---

<div class="post-metadata">

**Author:** ![jules](https://avatars.discourse-cdn.com/v4/letter/j/41988e/32.png) [@jules](https://discourse.julialang.org/u/jules)\
**Post date:** [June 18, 2021, 8:38am UTC](https://discourse.julialang.org/t/clear-observables-created-by-lift/63127/4 "2021-06-18T08:38:48Z")

</div>

Yeah this problem with missing links is one of my gripes with Observables. Before I added the observerfunc thing, you couldn’t even remove those with a single `off` call, you always had to keep the exact function and observable together to unlink them again.

The connections are made via closures though, so in principle it could be possible to scan those for observables and disconnect. Might be hard to implement correctly.

---

<div class="post-metadata">

**Author:** ![jules](https://avatars.discourse-cdn.com/v4/letter/j/41988e/32.png) [@jules](https://discourse.julialang.org/u/jules)\
**Post date:** [June 18, 2021, 8:46am UTC](https://discourse.julialang.org/t/clear-observables-created-by-lift/63127/5 "2021-06-18T08:46:34Z")

</div>

It appears that for the specific case of lift, a specific listener object is created where you can access the targeted observable. But there could always be side effects in the listener functions etc.

```julia
julia> x = Node(1)
Observable{Int64} with 0 listeners. Value:
1

julia> y = @lift($x * 3)
Observable{Int64} with 0 listeners. Value:
3

julia> x.listeners[1].f.observable
Observable{Int64} with 0 listeners. Value:
3

julia> x.listeners[1].f.observable === y
true

```

---

<div class="post-metadata">

**Author:** ![phlavenk](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/phlavenk/32/1873_2.png) [@phlavenk](https://discourse.julialang.org/u/phlavenk)\
**Post date:** [June 18, 2021, 10:28am UTC](https://discourse.julialang.org/t/clear-observables-created-by-lift/63127/6 "2021-06-18T10:28:06Z")

</div>

But, you still cannot start from `y` and find the appropriate `x`.  
😢

Thank you Julius for clarification

---

<div class="post-metadata">

**Author:** ![jules](https://avatars.discourse-cdn.com/v4/letter/j/41988e/32.png) [@jules](https://discourse.julialang.org/u/jules)\
**Post date:** [June 18, 2021, 11:12am UTC](https://discourse.julialang.org/t/clear-observables-created-by-lift/63127/7 "2021-06-18T11:12:09Z")

</div>

That’s similar to this problem though:

```julia
x = something

function a_function()
    do_something_with(x)
end

```

If you only have x, I have no idea how to find out it’s referenced in `a_function` in Julia. Probably need internals that traverse memory structures, something like this would be needed for garbage collection anyway.
