-
Notifications
You must be signed in to change notification settings - Fork 15
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Introduce type-level regions #73
Comments
FTR, by typed regions @facundominguez means tagging each So instead of cc @aspiwack - eventually all three uses could be replaced with linear types + borrowing? |
I can see how linear types could help with (1), but not with (2) and (3). |
Another problem that perhaps regions could help solving: The current approach is to have the Haskell GC delete the global references. Unfortunately, the Haskell GC has no pressure to delete the global references when the Java heap is full. Moreover, the GC runs finalizers in unbound threads, which requires sending the computation to some bound thread or thread pool to delete the references. Linear types might help with this too. |
I don't understand what 2. is about. But 3 can at least be partially addressed with linear types: in general, So it could seem to solve 3, but in fact, I think that it's desirable to have linear I'm not sure what should be done about 4, either with regions or linear types. We could have them be linear so that we have to call a |
I see global references as serving two purposes: Solving AWith regions, local references can be cloned and given to another thread vial global references. Inspired by Rust, imagine this primitive: forkOSWithRefs :: [JObject r0] -> (forall r. [JObject r] -> IOR r ()) -> IOR r0 ThreadId
forkOSWithRefs xs f = do
xs' <- mapM newGlobalRef xs
liftIOR $ forkOS $
xs '' <- mapM newLocalRef xs'
mapM_ deleteGlobalRef xs'
-- Or we might find a way to pass the global refs directly here
-- and destroy them at the end of the region.
runIOR (f xs'') Solving BIn this case, a global reference is like a local reference that lives in a longer scoped region than a native call. I don't see immediately what the impediment would be to assign it to an appropriate region and delete it there. |
I think I need an example of how linear Async works, and how it would interact with references to make sense of it. |
Like problem (2), a fifth problem that would be solved with a reader monad is: |
Currently we write: createList :: IO (J ('Class "java.util.List"))
createList = do
jIntegerArray <- reflect ([1..10] :: Int32)
callStaticObject "java.utils.Arrays" "asList" [coerce jIntegerArray] with linear types we need some monad with a linear bind I guess. Otherwise, we could not enforce the returned reference to be released eventually. createList :: LIO (J ('Class "java.util.List"))
createList = do
jIntegerArray <- reflect ([1..10] :: Int32)
callStaticObject "java.utils.Arrays" "asList" [coerce jIntegerArray]
(>>=) :: LIO a -o (a -o LIO b) -o LIO b
runLIO :: LIO a -o IO a -- ? Perhaps borrowing could be implemented with:
|
There are three problems that could be addressed by the introduction of type-level regions:
There are alternative ways to address each of these issues but using regions might yield a simpler and still effective design.
The text was updated successfully, but these errors were encountered: