Are there any plans for Julia to adopt an effects system?

I might be missing something crucial, but I think we can already do this today with ScopedValues. For example, taking the error-handling example from the blog post @mnemnion linked, we can write this in Julia as

using ScopedValues
function getName(user)
    name = user.name
    if name === nothing
        name = perform("ask_name")
    end
    return name
end

function makeFriends(user1, user2)
    push!(user1.friendNames, getName(user2))
    push!(user2.friendNames, getName(user1))
end
   
const arya = (; name=nothing, friendNames=[])
const gendry = (; name="Gendry", friendNames=[])

const HANDLER = ScopedValue{Union{Nothing, Function}}(nothing)

function perform(effect)
    handler = HANDLER[]
    isnothing(handler) && error("Could not perform effect $effect; no handler")
    return handler(effect)
end

with(HANDLER => function(effect)
    if effect === "ask_name"
        return "Arya Stark"
    end
    error("No handler for effect $effect")
end) do

    makeFriends(arya, gendry)
end

@show arya.friendNames gendry.friendNames;

which results in

arya.friendNames = Any["Gendry"]
gendry.friendNames = Any["Arya Stark"]

(ScopedValues are in Base in v1.11 due to this PR, and available in earlier versions via https://github.com/vchuravy/ScopedValues.jl.)

edit: I see Conditions.jl uses ScopedValues, so I guess their relevance here is old news :slight_smile:

10 Likes