We are seeking feedback on a proposed change to the corefn JSON format. Specifically, we are considering changing the moduleExports
property in the corefn JSON format from [Ident]
to [(Maybe ModuleName, Ident)]
in order to handle re-exports better.
If this change is accepted, we would like to include it in v0.14.0 (which should hopefully be released Soon™).
Details
At the moment, the corefn module format is defined like this:
In particular, the module exports are just a list of Ident
. This means that in corefn, modules can only export local declarations. In order to sensibly include re-exports in generated code (without being forced to generate a bunch of extra local declarations), we need to provide a way of expressing “this module re-exports foo from module Bar”. The module exports would become a list of (Maybe ModuleName, Ident)
, where a Just
indicates that the export is a re-export from the given module, and a Nothing
indicates a normal export.
In terms of the actual JSON, consider the following module:
module Main (foo, module X) where
import Control.Category (identity) as X
foo :: Int
foo = 0
Right now, its corefn output looks like this:
{
"moduleName": [
"Main"
],
"exports": [
"foo"
],
...
}
After this change, it would look like this:
{
"moduleName": [
"Main"
],
"exports": [
[null, "foo"],
[["Control", "Category"], "identity"]
],
...
}
Each export would be an array of two elements, the first being either a list of strings for the module name for a re-export, or null
for a normal export, and the second being the name of the thing being exported. This is, of course, a breaking change.
Motivation
See https://github.com/purescript/purescript/issues/1888
This change will make the JavaScript output (or indeed any output, regardless of the backend in use) more useful, as right now, you can only import values from the modules they were originally defined in if you’re writing in the target language. In addition, it is the first step towards cut-off in incremental builds, allowing us to skip more work and finish compilation faster (see https://github.com/purescript/purescript/issues/3724).
An alternative option would be to generate local declarations for re-exports, in which case we could do this without breaking the format. However, that is more complicated (as it could involve lots of name mangling) and more expensive from a performance perspective. It also increases the size of the compiler output, which can be a big drawback in the case of JavaScript running in a browser.