You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Since Klister's type system is intentionally close to Haskell's, it would be great if we could call Haskell code from Klister.
One of the easiest-to-use FFI mechanisms I've seen is Haste's ffi function, which takes string containing javascript code and trusts the programmer to make sure the javascript expression does have type a:
ffi::FFIr=>String->r
Where FFI a ensures that r has the form a -> b -> ... -> IO c, that those parameters have types which can be serialized to Javascript using some ToJS typeclass, and that the result type can be deserialized back to Haskell using some FromJS typeclass.
This nicely circumvents the difficulty that Haskell libraries aren't restricting themselves to the subset of Haskell types which Klister supports: the programmer can easily use Haskell's extra features inside the string, as long as it provides a Klister-compatible type at the boundary.
I am thinking of using the hint library (which I maintain) to evaluate a string of Haskell code, but there are some complications:
A string is not sufficient: we must also specify the modules to import, the packages in which to look for those modules, and the package database(s) in which to look for those packages. A .ghc.environment.* file provides the latter two, and hint will look for it in the current-working-directory when klister runs.
We could serialize to Strings and use the Read and Show instances, but that would be inefficient. The alternative is to use types which have Typeable instances, whose Dict would need to be provided by FromHaskell and ToHaskell typeclasses in Klister. Except, of course, Klister doesn't have typeclasses yet.
While it is obvious how to serialize Klister integers, and relatively obvious how to serialize Klister strings (Haskell String? Haskell Text? Strict or Lazy?), it is a lot less obvious how to serialize Klister algebraic datatypes. We could define Haskell datatypes with the same names as the Klister datatypes, but Klister and Haskell have different naming conventions, so those names would need to be mangled. Or we could provide them as opaque values, plus some builtin functions for e.g. obtaining the constructor name or extracting a constructor's first argument as another opaque value.
Sooner or later those strings containing Haskell code will grow too large, and the programmer will want to write helper functions and datatypes. Should we provide another function, ffi_decl : String -> IO (), for adding those definitions to some kind of environment which future ffi calls will see? How do multiple ffi calls making use of the same definitions make sure that the ffi_decl command they depend on is only run once? Perhaps the easiest would be to require the programmer to define a new package and to import their helper functions from there.
The text was updated successfully, but these errors were encountered:
Another challenge is that while a piece of Haskell code can use hint to evaluate a string to a value of any Typeable type, there will be a single piece of Haskell code which will be responsible for interpreting all the Haskell code found in all the Klister files, each of which has a different Klister type and a corresponding Haskell type.
One solution might be to use polymorphic recursion to instantiate that single piece of Haskell code at just the right type, but @david-christiansen came up with a simpler solution: define a single type, a GADT, capable of encoding a variety of Klister types: function of arbitrary arity over our few primitive types. It is less clear how to deal with datatypes.
data KlisterTypeRep a where
KlisterInteger :: KlisterTypeRep Integer
KlisterString :: KlisterTypeRep String
KlisterArrow :: KlisterTypeRep a -> KlisterTypeRep b -> KlisterTypeRep (a -> b)
Then, using more GADTs and a Parameterized.Pair, we can construct e.g. a value of that type, or a TypeRep for that type, etc.
Since Klister's type system is intentionally close to Haskell's, it would be great if we could call Haskell code from Klister.
One of the easiest-to-use FFI mechanisms I've seen is Haste's
ffi
function, which takes string containing javascript code and trusts the programmer to make sure the javascript expression does have typea
:Where
FFI a
ensures thatr
has the forma -> b -> ... -> IO c
, that those parameters have types which can be serialized to Javascript using someToJS
typeclass, and that the result type can be deserialized back to Haskell using someFromJS
typeclass.This nicely circumvents the difficulty that Haskell libraries aren't restricting themselves to the subset of Haskell types which Klister supports: the programmer can easily use Haskell's extra features inside the string, as long as it provides a Klister-compatible type at the boundary.
I am thinking of using the hint library (which I maintain) to evaluate a string of Haskell code, but there are some complications:
.ghc.environment.*
file provides the latter two, and hint will look for it in the current-working-directory when klister runs.Read
andShow
instances, but that would be inefficient. The alternative is to use types which haveTypeable
instances, whoseDict
would need to be provided byFromHaskell
andToHaskell
typeclasses in Klister. Except, of course, Klister doesn't have typeclasses yet.String
? HaskellText
? Strict or Lazy?), it is a lot less obvious how to serialize Klister algebraic datatypes. We could define Haskell datatypes with the same names as the Klister datatypes, but Klister and Haskell have different naming conventions, so those names would need to be mangled. Or we could provide them as opaque values, plus some builtin functions for e.g. obtaining the constructor name or extracting a constructor's first argument as another opaque value.ffi_decl : String -> IO ()
, for adding those definitions to some kind of environment which futureffi
calls will see? How do multipleffi
calls making use of the same definitions make sure that theffi_decl
command they depend on is only run once? Perhaps the easiest would be to require the programmer to define a new package and to import their helper functions from there.The text was updated successfully, but these errors were encountered: