I've been learning Julia and wanted to spend some time trying it out by adding some of my favorite functional/immutable constructs to the language. Specifically: types for delayed computations and promises, like clojure's delay and promise types.
Both delays and promises are similar in principle to Ref{T}
with the caveat that (1) obj[]
may need to wait on a value or run a computation before returning when obj
is a promise or delay and (2) a delay/promise can only be set once and never read prior to being set, so is immutable (at least, its interface is that of an immutable object).
My intuition here is that both delay and promise should inherit from an abstract immutable ref type, since this part of their behavior at least is similar; however, I can't seem to do this:
abstract type ImmutableRef <: Ref end
invalid subtyping in definition of ImmutableRef
After looking through the Julia source code a bit, it seems like the Ref
type is not declared in a typical fashion and instead is declared in Julia's core C code. Is it possible to inherit from Ref in Julia? If not, what would be the idiomatic Julia way to implement/organize these kinds of ref-like types?
As noted by Lyndon, the problem was that you didn't write Ref{T}
in the type signature.
For fun, here's my implementation a promise type, though I'm sure there's a more elegant way that's makes more effort to pretend to be immutable.
struct Promise{T} <: Ref{T}
r::Ref{T}
fufilled::Ref{Bool}
end
Promise{T}() where {T} = Promise{T}(Ref{T}(), Ref(false))
Promise() where {T} = Promise{Any}(Ref{T}(), Ref(false))
function Base.getindex(p::Promise)
@assert p.fufilled[] == true
p.r[]
end
function deliver(p::Promise{T}, val::U) where {U <: T}
p.r[] = val; p.fufilled[] = true
p
end
isrealized(p) = p.fufilled[]
Now if we go the repl and, we can check how this acts:
julia> x = Promise(); # If we know we'll deliver an Int then we should do Promise{Int}()
julia> isrealized(x)
false
julia> deliver(x, 1);
julia> x[]
1
Delay should be quite similar.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With