Skip to content

[feature]: Isolated Scopes #1381

@johnhungerford

Description

@johnhungerford

Problem Statement

A user may want to use the Scope effect to handle resources within a generic function/class/module. The problem is that when handling Scope on a generic effect like A < (Async & Scope & S), if S includes Scope then unknown finalizers passed into generic function by the user will also unexpectedly be executed.

Proposed Solution

Provide an Isolate[Scope, Sync, Scope & Sync] (if I'm understanding Isolate correctly) that accumulates finalizers and then re-registers them. Provide a simpler API for isolating:

def genericFunction[A, S](effect: A < S): A < (Async & S) =
    Scope.isolate(effect): (isolatedEffect: A < S) =>
        Scope.run:
            // Introduces `Scope` in isolated context
            Channel.init(1024).map: channel =>
                 ??? // functionality using `isolatedEffect` goes here

val eff1 = Int < (Scope & Sync) = ???
val result: Int < (Scope & Async) = genericFunction(eff1) // keeps original finalizers

Alternative Solutions

Provide an API for creating an aliased version of Scope (e.g., CustomScope or LocalScope) that duplicates functionality while using a separate type and tag. This way, running CustomScope.run will not handle finalizer registered by Scope.

Current Workaround

Not sure there is one...

Additional Context

We may want to add the same for other effects like Abort. An ideal API would be something like:

Kyo.isolate[Abort[String] & Scope & Var[Int]](genericEffect): isolatedGenericEffect =>
    ???

I think really what I'm requesting is just a slightly more convenient API for Isolate

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions