Skip to content

Instantly share code, notes, and snippets.

@andreypopp
Created October 15, 2022 13:59
Show Gist options
  • Save andreypopp/56ee76f110006d3cc143fa80ef7706f5 to your computer and use it in GitHub Desktop.
Save andreypopp/56ee76f110006d3cc143fa80ef7706f5 to your computer and use it in GitHub Desktop.
module Ink
mutable struct Thunk
f::Function
result::Any
sub::Vector{Thunk}
sup::Vector{Thunk}
clean::Bool
end
thunk(f) = Thunk(f, nothing, [], [], false)
function add_edge(sup::Thunk, sub::Thunk)
push!(sup.sub, sub)
push!(sub.sup, sup)
end
function del_edge(sup::Thunk, sub::Thunk)
filter!(sub₁ -> sub₁ != sub, sup.sub)
filter!(sup₁ -> sup₁ != sup, sub.sup)
end
function compute!(t::Thunk)
if t.clean
t.result
else
for s in t.sub
del_edge(s, t)
end
t.clean = true
t.result = t.f(t)
compute!(t)
end
end
function dirty!(t::Thunk)
if t.clean
t.clean = false
for s in t.sup
dirty!(s)
end
end
end
ref(v) = Thunk(compute!, v, [], [], true)
function set!(t::Thunk, v::Any)
t.result = v
dirty!(t)
end
macro read(t)
self = esc(:self)
t = esc(t)
quote
add_edge($self, $t)
compute!($t)
end
end
macro thunk(body)
self = esc(:self)
body = esc(body)
quote
thunk(($self) -> $body)
end
end
export @thunk, @read, ref, set!, compute!
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment