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

GHC Plugin in GHCJS? #796

Open
konn opened this issue Sep 25, 2020 · 10 comments
Open

GHC Plugin in GHCJS? #796

konn opened this issue Sep 25, 2020 · 10 comments

Comments

@konn
Copy link

konn commented Sep 25, 2020

Currently, I'm trying to use some Compiler Plugins such as ghc-typelits-presburger and overloaded with GHCjs 8.6.
But it seems that they failed to find the modules related to GHC API: TyCoRep, Type, etc.
It seems that README suggests depending on ghc-api-ghcjs instead of ghc; but changing to dependency to it.
See my fork of ghc-tcplugins-extra for my (failed) attepmt.

Is there any way to use Compiler Plugins with GHCJS, or even access to GHC API itself?

@ddssff
Copy link
Contributor

ddssff commented Sep 27, 2020

I'm interested in what all this means and what you can do with this capability.

@konn
Copy link
Author

konn commented Sep 27, 2020

GHC's Compiler Plugin mechanism provides a various ways to enhance the way the compiler compiles the Haskell program via GHC API.
There are several kinds of plugins, such as Source Plugins (can modify the parsed AST), Type Checker plugins, Core-to-Core plugins (can manipulate core representation after desugaring).

Users of plugins can simply add a such plugin package to the usual build-depends in Cabal file, and invoke them by simply adding the following pragma at the top of the module where the plugin should be enabled:

{-# OPTIONS_GHC -fplugin Module.That.Provides.APlugin #-}

I usually use them to augment the treatment of GHC's type-level natural numbers and type level literals.
For example, current GHC alone cannot see n + m ~ m + n by itself, but if we use ghc-typelits-natnormalise (by clash team) or ghc-typelits-presburger (advertisement: my package!) knows how to solve such constraints and generates needed instance dictionary/evidence to automatically convince GHC.
There is also ghc-typelits-knownnat plugin, which derives KnownNat instances for, e.g. n + m or n * m, from KnownNat n and KnownNat m and so on.

These belong to the "Type Checker Plugin" category.
Since current native type-checker of GHC can barely solve non-trivial relations on type naturals, such plugins will eventually become necessary when one treats type-level naturals deeply.

Another wonderful example, which belongs to Source Plugin, is overloaded plugin.
It enables overloading mechanisms which are impossible in the plain GHC.
For example, it can use list literals like [1, True, Nothing, "Hello"] for heterogeneous list HList '[Int, Bool, Maybe Char, String] type-safely.
It can be even used for type-safe ordinal literals: if a type Fin n stands for a type of integers >= 0 and < n, it can refuse 4 :: Fin 2 at the compile time!
These are impossible with current -XOverloaded* or -XRebindableSyntax extensions; they assume somewhat monomorphic and unconstrained types for such rebinding so we need the mechanism of Source Plugins to achieve this.

@Ericson2314
Copy link
Member

Follow what @hsyl20 is doing and see at least the long term outlook is very bright :).

@konn
Copy link
Author

konn commented Sep 27, 2020

Great! So, both GHC API and Compiler Plugins will eventually be avilable also in ghcjs? Is there any dedicated branch/fork for this topic?

@konn
Copy link
Author

konn commented Sep 27, 2020

Aha, I've just found this article by @hsyl20. Thanks!

@konn
Copy link
Author

konn commented Sep 27, 2020

Oh, and it states that GHCjs supports Plugins somehow!
Since that code seems existing in 8.6 branch, at least with the latest binary, one can invoke plugins, right?
If so, the question becomes: how to write Compiler plugins that works with GHCjs? Is there such working example?

@hsyl20
Copy link

hsyl20 commented Sep 28, 2020

As far as I know, you need to compile a fake my-plugin-package with ghcjs which contents doesn't matter as it won't be used at all. You can't compile the normal plugin code because it needs GHC API which isn't available.

Then you also need to compile my-plugin-package with the compiler for ghcjs's host (e.g. using the ghc used to build ghcjs itself) and to install it somewhere ghcjs can find it. ghcjs should substitute the former package for the latter.

More details in the note:

Compiler plugins for GHCJS

@konn
Copy link
Author

konn commented Sep 28, 2020

@hsyl20 Thanks for the clarification! So, if I maintain a project using ghcjs by Nix and want to use compiler plugins in them, then I must devise some additional scripts to maintain such duplicated situation.
Anyway, thank you again for the detailed article on the current situation and future of cross-compilation in GHC. I'm really looking forward to seeing all the work mentioned your article become reality!

@hpacheco
Copy link

hpacheco commented Feb 5, 2021

I am also trying to use plugins in the 8.6 branch. So far, i was able to compile ghc-tcplugins-extra and the cmptype plugin itself with ghc-api-ghcjs. Trying to compile a program that uses the plugin with ghcjs yields an error The value plugin did not have the type Plugin as required.
From the attached log it seems like ghcjs is actually loading the plugin from the host GHC database. Any clues?
log.txt

@otto-dev
Copy link

otto-dev commented Aug 28, 2022

Same problem as @hpacheco, on 8.8

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

6 participants