One of the strength of Haskell is the large number of packages available on Hackage. I would like to leverage this strength for MicroHs. Unfortunately, this is easier said than done. The large majority of packages on Hackage are GHC specific. So be it. I’ll have to accept that.
So what can I do? Well, I try to port what I consider important (to me) packages so that they compile with MicroHs. But this has some problems:
Some package are just too GHC specific (e.g. array), but I can make my own version.
Some package maintainers refuse to accept my pull requests (that their prerogative; it’s all a volunteer effort).
Some packages use features I will never add to MicroHs, e.g. Template Haskell.
In the case of the first two points, i will start uploading packages to hackage with names ending in -mhs, e.g., array-mhs, which will be a MicroHs version of the package. I don’t really want to do this, but I’m not sure what the alternative is. Some of the packages will be new, specific for MicroHs others will be clones of existing packages (with MicroHs patches).
When compiling with MicroCabal it will automatically detect when there is a dependency on a package with a MicroHs alternative and use that instead.
A big thanks to everyone who writes portable Haskell code. It’s a joy when I find packages that compile without changes (e.g., splitmix and granite)
Creating a separate package repository through foliage could be an option. (Maybe @Kleidukos can even help with adding it as a new package namespace to flora.pm for a nice browsing experience?)
You’ve mentioned TH, but what other things should package authors do/avoid to ensure compatibility across multiple compilers? I try to use default-language: Haskell2010 and explicit extensions on Hackage packages, but I’m not sure if there’s other folklore worth following.
Using base version bounds to proxy for GHC version restrictions seems like a bad idea now; is there a better way to indicate specific GHC compatibility when that’s necessary?
Some things to avoid: depending inghc-prim (quite common), using the MagicHash extension, using the ImplicitParameters extension. For now, avoid TypeFamilies and Generics. I’ll implement the latter two eventually. There are more, but I’m typing on my phone right now…
I’d really like to get dataframe working on microhs in some incarnation. I’ve often gotten the feedback from data scientists that try out the library that installing Haskell takes too long. Plus installing close to 5GB of stuff is prohibitive. And this is outside of random build issues like the snappy bindings not working cause of some FFI issues.
So my strategies are either to preload everything into ihaskell with a docker container or try really hard to remove all the expensive dependencies (depending on the statistics package for example almost doubled the build time).
From what I remember from your Zurihac presentation microhs would fix a lot of these issues at the cost of the speed of the final binary.
I don’t know the answer here, but I think that MicroHs is forcing this conversation is a testament to its greatness. Thank you for making it real - I am truly hoping it has legs.
In terms of practical suggestions..should PVP support ASCII parts that are not comparable? To allow for this kind of forking? It feels like either than or CPP spew (or abstraction over CPP spew which is maybe palatable).
The -mhs option pushes CPP/flag spew downstream. As an application author, I manage it. My proposals are to have it managed transparently and forever upstream. Haskell feels like a “fix it upstream” language imo.
I’m a happy user of GHC, but I think being less GHC-centric will benefit everyone. Thank you for all your work.
I tried to build one of my pet packages (it was io-region, it depends only on base and stm, which makes it a good playground). The results are two-fold. First of all, I’m impressed that green threads and STM already work (IIRC the last time I check MircoHs both where missing, and not even on a horizon)
On the other hand, the code doesn’t compile because few things are still missing, like SomeAsyncException, modifyTVar', trans: no primop “IO.getmaskingstate” etc (Should I make a PR?) I made it work by stubbing the missing parts, but it means io-region can’t be made portable at this point.
More importantly, I’m worried about how portable is the semantics. E.g. getLine seems to be blocking in MicroHs, while it’s not in GHC, at least that was my impression after playing with it for a while. I’m not even sure how portable IO-heavy code might look like. I won’t even dare trying e.g. pdf-toolbox-document. So the question: is there hope we’ll end up with common semantics shared between MicroHs and GHC?
Please, make a bug report for the missing STM API calls, etc. Those are absolutely not intentional.
The blocking getLine is a different matter. Currently all calls to C code (which getLine boils down to) are blocking. It’s a longer term effort to fix this in general. In the particular case of reading from a terminal I have a short term fix in mind. So please report that one too.
I made a ticket for the STM things. Blocking IO seems to be a deeper design issue though, and I don’t have any particular use case right now to justify creating a ticket.
Unrelated: I’d be interested in creating a http client (and potentially a server) that works with MicroHs. I don’t think porting htt-client and warp will work, so I think it has to be a separate thing. Do you think it’s realistic goal? Or is it too early for such a project?
-Does MicroHS plan to implement an alternative to template haskell?
-Why not use a package collection approach like stackage? You could make a version of stackage with your micro-hs compatible package forks replacing the mainline version
I have no plans for a TM replacement. But if I find something I like, I might implement it.
MicroCabal already uses the Stackage list of packages. So it’s really MicroStackage. I’m sure I could do something more elaborate, but this is my hobby project, so I do what I think will be the least work for me. (I didn’t really want to write MicroCabal, but Cabal uses an amazing number of LANGUAGE extensions. MicroHs cannot compile it.)
head.hackage is a hackage overlay. Cabal can accept a list of package databases, which it will query in order, and if it cannot find a package in the first, it finds it in the next. This lets forks of hackage packages be provided without hackage uploads – in the case of head.hackage this is for compatibility with unreleased versions of GHC.
I know microhs has its own microcabal – so perhaps a similar “use a list of repositories” logic can be implemented there?