Skip to content
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

Discuss how to use linear constraints with a variable amount of linear arguments #11

Open
facundominguez opened this issue Nov 2, 2019 · 1 comment

Comments

@facundominguez
Copy link
Member

facundominguez commented Nov 2, 2019

The jni package has functions like:

callObjectMethod :: JObject -> MethodID -> [JValue] -> IO JObject

data JValue
  = JInt Int32
  | JDouble Double
  | ...
  | JObject JObject

This function executes a method of a Java object, given the object on which to call the method and the arguments of the method, and it yields the result, which this particular function expects to be a reference. There is one function like this per possible return type.

The list of arguments can contain either primitive values or references to java objects (JObject). And we would like to ensure that these references are deleted when no longer needed.

The current approach in the interface based on linear types, is to have callObjectMethod destroy the references passed as arguments after the result is obtained.

callObjectMethod :: JObject ->. MethodID -> [JValue] ->. IOL (JObject, JObject)

We return both the result and a reference to the object on which the method was invoked. Only the references in the arguments of the method are destroyed.

Now, how would we cast this example with linear constraints? Unlike the current approach, here I'm aiming to keep alive all given references after the call.

-- ???
callObjectMethod
  :: (Created j, Createds js)
  =>. JObject j
  -> MethodID
  -> HList JValue js
  -> IOL (NewJObject <=. (Created j, Createds js))

data NewJObject = forall j. NewJObject (JObject j .<= Created j)

deleteLocalRef :: Created j =>. JObject j -> IOL ()

data JValue j where
  JInt :: Int32 -> JValue (NonRef j)
  JDouble :: Int32 -> JValue (NonRef j)
  ...
  JObject :: JObject j -> JValue (Ref j)

type family Createds (js :: [*]) :: * where
  Createds '[] = ()
  Createds (Ref j ': js) = (Created j, Createds js)
  Createds (NonRef j ': js) = Createds js

data HList (f :: * -> *) (xs :: [*]) where ...

Or maybe we should expand our many functions callObjectMethod, callIntMethod, callDoubleMethod, etc, to offer variants for the most common method arities:
callObjectMethodUnary, callObjectMethodBinary, callObjectMethod3, ...

@facundominguez facundominguez changed the title Discuss how to use linear constraints with variable amount of linear arguments Discuss how to use linear constraints with a variable amount of linear arguments Nov 2, 2019
@facundominguez
Copy link
Member Author

facundominguez commented Nov 4, 2019

An attempt without HList:

-- ???
callObjectMethod
  :: JValueTuple methodArguments
  => (Created j, Createds js)
  =>. JObject j
  -> MethodID
  -> methodArguments
  -> IOL (NewJObject <=. (Created j, Createds methodArguments))

data NewJObject = forall j. NewJObject (JObject j .<= Created j)

deleteLocalRef :: Created j =>. JObject j -> IOL ()

class JValueTuple t where
  type Createds t :: Contraint
  jvalues :: t -> [JValue]

class Coercible a where
  type MaybeCreated a :: Constraint
  toJValue :: JValue


instance JValueTuple () where
  type Createds () = ()
  jvalues () = []

instance Coercible a => JValueTuple a where
  type Createds a = MaybeCreated a
  jvalues a = [toJValue a]

instance (Coercible a, Coercible b) => JValueTuple (a, b) where
  type Createds (a, b) = (MaybeCreated a, MaybeCreated b)
  jvalues (a, b) = [toJValue a, toJValue b]

instance (Coercible a, ..., Coercible c) => JValueTuple (a, b, c) where ...

...

instance (Coercible a, ..., Coercible g) => JValueTuple (a, b, c, d, e, f, g) where ...

instance Coercible Int32 where ...
    type MaybeCreated Int32 = ()
    toJValue = JInt

instance Coercible Double where ...

...

instance Coercible (JObject j) where
    type MaybeCreated (JObject j) = Created j
    toJValue = JObject

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant