It would be nice to have a library like purescript-nix-builtins that provides FFI for all the different Nix builtins (like builtins.deepSeq, builtins.getEnv, builtins.mapAttrs, etc). This library should also provide FFI data types for types from Nix that are not available from PureScript by default. For instance, a Path type to represent Nix paths.
A couple other points:
-
I have a small start of what this library would look like in cabal2nixWithoutIFD: https://github.com/cdepillabout/cabal2nixWithoutIFD/blob/484515bdec2ccf9dfc02b9a442b801bc2d17b9cc/purescript-parser-combinator/src/NixBuiltins.purs
I think @thought2 may also have some parts of a Nix builtins library in https://github.com/thought2/purescript-miraculix or one of the dependencies.
-
It might make sense to split this into two packages, one that provides the FFI data types (called something like purescript-nix-types), and one that provides the Nix builtins (called purescript-nix-builtins as above). It should be possible to use purescript-nix-types without relying on purescript-nix-buitlins. This could be used by people who want to write all their own FFI. The main purescript-nix-builtins module should probably re-export everything from purescript-nix-types, so most end users never have to directly interact with purescript-nix-types.
-
It might make sense to have a Nix.Builtins module, and a Nix.Builtins.Unsafe module. Nix.Builtins would provide mostly type-safe functions, while Nix.Builtins.Unsafe would provide mostly unsafe, fully-polymorphic functions.
For instance, builtins.toString is able to take any argument type except a function or a record. It would be tough to give this a completely safe type in PureScript, but the Nix.Builtins.Unsafe module could give this a type like toString :: forall a. a -> String. The person using this function would have to take responsibility to never pass it a function or a record.
On the other hand, a function like buitins.length can be safely typed in PureScript: length :: forall a. List a -> Int. This type can always be used safely by end users.
-
One function / data type that will be necessary (but is not completely straight-forward) is to represent a Nix function that pattern matches on a record. So something like the Nix function { hello ? true, bar }: 123. I took a stab at creating this here (FunctionWithArgs and mkFunctionWithArgs):
https://github.com/cdepillabout/cabal2nixWithoutIFD/blob/484515bdec2ccf9dfc02b9a442b801bc2d17b9cc/purescript-cabal-parser/src/Main.purs#L208-L227
The FFI part:
https://github.com/cdepillabout/cabal2nixWithoutIFD/blob/484515bdec2ccf9dfc02b9a442b801bc2d17b9cc/purescript-cabal-parser/src/Main.nix#L9-L13
It would be nice to have a library like
purescript-nix-builtinsthat provides FFI for all the different Nix builtins (likebuiltins.deepSeq,builtins.getEnv,builtins.mapAttrs, etc). This library should also provide FFI data types for types from Nix that are not available from PureScript by default. For instance, aPathtype to represent Nix paths.A couple other points:
I have a small start of what this library would look like in
cabal2nixWithoutIFD: https://github.com/cdepillabout/cabal2nixWithoutIFD/blob/484515bdec2ccf9dfc02b9a442b801bc2d17b9cc/purescript-parser-combinator/src/NixBuiltins.pursI think @thought2 may also have some parts of a Nix builtins library in https://github.com/thought2/purescript-miraculix or one of the dependencies.
It might make sense to split this into two packages, one that provides the FFI data types (called something like
purescript-nix-types), and one that provides the Nix builtins (calledpurescript-nix-builtinsas above). It should be possible to usepurescript-nix-typeswithout relying onpurescript-nix-buitlins. This could be used by people who want to write all their own FFI. The mainpurescript-nix-builtinsmodule should probably re-export everything frompurescript-nix-types, so most end users never have to directly interact withpurescript-nix-types.It might make sense to have a
Nix.Builtinsmodule, and aNix.Builtins.Unsafemodule.Nix.Builtinswould provide mostly type-safe functions, whileNix.Builtins.Unsafewould provide mostly unsafe, fully-polymorphic functions.For instance,
builtins.toStringis able to take any argument type except a function or a record. It would be tough to give this a completely safe type in PureScript, but theNix.Builtins.Unsafemodule could give this a type liketoString :: forall a. a -> String. The person using this function would have to take responsibility to never pass it a function or a record.On the other hand, a function like
buitins.lengthcan be safely typed in PureScript:length :: forall a. List a -> Int. This type can always be used safely by end users.One function / data type that will be necessary (but is not completely straight-forward) is to represent a Nix function that pattern matches on a record. So something like the Nix function
{ hello ? true, bar }: 123. I took a stab at creating this here (FunctionWithArgsandmkFunctionWithArgs):https://github.com/cdepillabout/cabal2nixWithoutIFD/blob/484515bdec2ccf9dfc02b9a442b801bc2d17b9cc/purescript-cabal-parser/src/Main.purs#L208-L227
The FFI part:
https://github.com/cdepillabout/cabal2nixWithoutIFD/blob/484515bdec2ccf9dfc02b9a442b801bc2d17b9cc/purescript-cabal-parser/src/Main.nix#L9-L13