* Upstream changes into Cabal to make your new compiler a first-class
     citizen. This is what GHCJS did.

Just a word of caution, please don't do this. It leads to non-negligible maintainence burden on your and on the cabal side. Rather try as hard as you can to make your compiler behave like a ghc wrt to cabal. Or add generic support for more powerful compilers to cabal. Adding special handling for one additional compiler will just result in bitrot, odd quirks that only happen with that one compiler, and just a maintenance nightmare for everyone involved.

We will be ripping out GHCJS custom logic from cabal. And I've also advised the Asterius author not to go down that route.

My suggesting--if I may--is to try and build a c-like toolchain around your compiler. That has some notion of compiler, archiver, linker, and those could you empty shell wrappers, or no-ops, depending on your target.

Cheers,
 Moritz

On Tue, Mar 30, 2021 at 11:08 AM Ben Gamari <ben@well-typed.com> wrote:
Clinton Mead <clintonmead@gmail.com> writes:

> Thanks again for the detailed reply Ben.
>
> I guess the other dream of mine is to give GHC a .NET backend. For my
> problem it would be the ideal solution, but it looks like other attempts in
> this regard (e.g. Eta, GHCJS etc) seem to have difficulty keeping up with
> updates to GHC. So I'm sure it's not trivial.
>
> It would be quite lovely though if I could generate .NET + Java + even
> Python bytecode from GHC.
>
> Whilst not solving my immediate problem, perhaps my efforts are best spent
> in giving GHC a plugin architecture for backends (or if one already
> exists?) trying to make a .NET backend.
>
This is an interesting (albeit ambitious, for the reasons others have
mentioned) idea. In particular, I think the CLR has a slightly advantage
over the JVM as a Haskell target in that it has native tail-call
support [1]. This avoids a fair amount of complexity (and performance
overhead) that Eta had to employ to work around this lack in the JVM.

I suspect that writing an STG -> CLR IR wouldn't itself be difficult.
The hard part is dealing with the primops, RTS, and core libraries.

[1] https://docs.microsoft.com/en-us/previous-versions/windows/silverlight/dotnet-windows-silverlight/56c08k0k(v=vs.95)?redirectedfrom=MSDN

> I believe "Csaba Hruska" is working in this space with GRIN, yes?

Csaba is indeed using GHC's front-end and Core pipeline to feed his own
compilation pipeline. However, I believe his approach is currently quite
decoupled from GHC. This may or may not complicate the ability to
integrate with the rest of the ecosystem (e.g. Cabal; Csaba, perhaps you could
comment here?)


>
> I read SPJs paper on Implementing Lazy Functional Languages on Stock
> Hardware: The Spineless Tagless G-machine
> <https://www.microsoft.com/en-us/research/publication/implementing-lazy-functional-languages-on-stock-hardware-the-spineless-tagless-g-machine/>
> which
> implemented STG in C and whilst it wasn't trivial, it didn't seem
> stupendously complex (even I managed to roughly follow it). I thought to
> myself also, implementing this in .NET would be even easier because I can
> hand off garbage collection to the .NET runtime so there's one less thing
> to worry about. I also, initially, don't care _too_ much about performance.
>
Indeed, STG itself is reasonably straightforward. Implementing tagged
unions in the CLR doesn't even look that hard (F# does it, afterall).
However, there are plenty of tricky bits:

 * You still need to implement a fair amount of RTS support for a full
   implementation (e.g. light-weight threads and STM)

 * You need to shim-out or reimplement the event manager in `base`

 * What do you do about the many `foreign import`s used by, e.g.,
   `text`?

 * How do you deal with `foreign import`s elsewhere?

> Of course, there's probably a whole bunch of nuance. One actually needs to,
> for example, represent all the complexities of GADTs into object orientated
> classes, maybe converting sum types to inheritance hierarchies with Visitor
> Patterns. And also you'd actually have to make sure to do one's best to
> ensure exposed Haskell functions look like something sensible.
>
> So I guess, given I have a bit of an interest here, what would be the best
> approach if I wanted to help GHC develop more backends and into an
> architecture where people can add backends without forking GHC? Where could
> I start helping that effort? Should I contact "Csaba Hruska" and get
> involved in GRIN? Or is there something that I can start working on in GHC
> proper?
>
At the moment we rather lack a good model for how new backends should
work. There are quite a few axes to consider here:

 * How do core libraries (e.g. `text`) work? Various choices are:

   * Disregard the core libraries (along with most of Hackage) and just
     take the Haskell language

   * Reimplement many of the core libraries in the target language (e.g.
     as done by GHCJS)

 * How does the compiler interact with the Haskell build toolchain (e.g.
   Cabal)? Choices are:

   * Disregard the Haskell build toolchain. My (possibly incorrect)
     understanding is this is what GRIN does.

   * Implement something that looks enough like GHC to fool Cabal.

   * Upstream changes into Cabal to make your new compiler a first-class
     citizen. This is what GHCJS did.

 * How does the backend interact with GHC? Choices:

   * The GRIN model: Run the GHC pipeline and serialise the resulting IR
     (in the case of GRIN, STG) to a file to be slurped up by another process

   * The Clash/GHCJS model: Implement the new compiler as an executable
     linking against the GHC API.

   * The frontend plugin model: For many years now GHC has had support
     for "front-end plugins". This mechanism allows a plugin to
     fundamentally redefine what the GHC executable does (e.g.
     essentially adding a new "mode" to GHC, a la --interactive or
     --make). It's not impossible that one could use this to implement a
     new backend.

   * A hypothetical "backend plugin" mechanism: Currently GHC has no
     means of introducing plugins after the Core pipeline. Perhaps this
     should change? This would need a fair amount of design as aspects
     of the backend currently tend to leak into GHC's frontend. John
     Ericson has been keen on cleaning this up.

Anyways, lots to think about.

> Considering that I've been playing around with Haskell since 2002, and I'd
> like to actually get paid to write it at some point in my career, and I
> have an interest in this area, perhaps this is a good place to start, and
> actually helping to develop a pluggable backend architecture for GHC may be
> more useful for more people over the long term than trying to hack up an
> existing GHC to support 32 bit Windows XP, a battle I suspect will have to
> be refought every time a new GHC version is released given the current
> structure of GHC.
>
Yes, 32-bit Windows support sounds like something of a futile exercise.
If the problem were *merely* GHC, then perhaps it would be possible.
However, the entirety of the open-source compiler community struggles
with Windows. For instance, binutils struggles to support even 64-bit
Windows without regressions (e.g. see
https://gitlab.haskell.org/ghc/ghc/-/issues/16780#note_342715).

Cheers,

- Ben

_______________________________________________
ghc-devs mailing list
ghc-devs@haskell.org
http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs