... | ... | @@ -100,7 +100,138 @@ Possibly, we remove the pattern synonyms to avoid a layer of indirection and get |
|
|
|
|
|
We work on refactoring, by then redundant, bits and pieces of TH by either just removing them (like the HsSyn-TH translator) or reusing the ones in the compiler.
|
|
|
|
|
|
### Experiment
|
|
|
## Experiment 2
|
|
|
|
|
|
|
|
|
\@simonpj wrote
|
|
|
|
|
|
>
|
|
|
> I was talking to Ben, Simon et al about your big patch [ https://phabricator.haskell.org/D3935](https://phabricator.haskell.org/D3935), which \> is Step 1 of [ https://ghc.haskell.org/trac/ghc/wiki/ImplementingTreesThatGrow](https://ghc.haskell.org/trac/ghc/wiki/ImplementingTreesThatGrow).
|
|
|
>
|
|
|
>
|
|
|
> To us it seems that separating out Step 3 is a pretty big detour:
|
|
|
>
|
|
|
> - It involves defining a massive collection of pattern synonyms that we will then discard.
|
|
|
>
|
|
|
> - It defines a massive file AST.hs that defines all the HsSyn data types, all moved from HsPat, HsType etc – but those declarations will all move back again in Step 3.
|
|
|
> - Each synonym has the comments from the original data constructor carefully transferred to it; then in Step 3 we will transfer them back to the data constructor.
|
|
|
>
|
|
|
> - There is some faff associated with record-field-name clashes that we can revert in step 3.
|
|
|
>
|
|
|
>
|
|
|
> So could we just do Step 1 and Step 3 at once?
|
|
|
>
|
|
|
>
|
|
|
> Of course, that means that all pattern matches must be dealt with. But many of them use field names anyway, and so will be minimally changed. And it’s totally straightforward what to do.
|
|
|
>
|
|
|
>
|
|
|
> If you prefer, you could do it one data type at a time. We already have the right type parameters.
|
|
|
|
|
|
|
|
|
This experiment is taking place at [ https://github.com/ghc/ghc/tree/wip/ttg-2017-10-13](https://github.com/ghc/ghc/tree/wip/ttg-2017-10-13)
|
|
|
|
|
|
#### Rough notes based on starting the work (AZ)
|
|
|
|
|
|
1. The design is inherently layered, so information has to appear in at least two places.
|
|
|
|
|
|
|
|
|
Pieces
|
|
|
|
|
|
- The actual data structure containing the extension points
|
|
|
|
|
|
```
|
|
|
dataPat x
|
|
|
=WildPat(XWildPat x)...
|
|
|
```
|
|
|
|
|
|
- The type family definition per extension point
|
|
|
|
|
|
```
|
|
|
typefamilyXWildPat x
|
|
|
```
|
|
|
|
|
|
- A convenience constraint naming all extension points for a given data type
|
|
|
|
|
|
```
|
|
|
typeForallXPat c x =...
|
|
|
```
|
|
|
|
|
|
- The type instance definition, giving a concrete type for a given type tag
|
|
|
|
|
|
```
|
|
|
typeinstanceXWildPat(GHC pass)=PostTc pass Type
|
|
|
```
|
|
|
|
|
|
1. In current implementation
|
|
|
|
|
|
```
|
|
|
typePat pass =AST.Pat(GHC pass)
|
|
|
```
|
|
|
|
|
|
|
|
|
effectively forces all extension points to be in the GHC "namespace"
|
|
|
|
|
|
1. Argument for patterns
|
|
|
|
|
|
```
|
|
|
dataHsValBindsLR idL idR
|
|
|
=-- | Value Bindings In---- Before renaming RHS; idR is always RdrName-- Not dependency analysed-- Recursive by defaultValBindsIn(XValBinds idL idR)(LHsBindsLR idL idR)[LSig idR]-- | Value Bindings Out---- After renaming RHS; idR can be Name or Id Dependency analysed,-- later bindings in the list may depend on earlier ones.|NewValBindsLR(XNewValBindsLR idL idR)-- | ValBindsOut-- [(RecFlag, LHsBinds idL)]-- [LSig GhcRn] -- AZ: how to do this?
|
|
|
```
|
|
|
|
|
|
1. We need to define a way of combining extensions
|
|
|
|
|
|
```
|
|
|
plusHsValBinds ::HsValBinds a ->HsValBinds a ->HsValBinds a
|
|
|
plusHsValBinds (ValBindsIn x1 ds1 sigs1)(ValBindsIn x2 ds2 sigs2)=ValBindsIn(x1 `mappend` x2)(ds1 `unionBags` ds2)(sigs1 ++ sigs2)
|
|
|
```
|
|
|
|
|
|
>
|
|
|
> Is `mappend` the right thing to use?
|
|
|
|
|
|
1. Current implementation defines
|
|
|
|
|
|
```
|
|
|
pattern
|
|
|
ValBindsIn a b
|
|
|
=AST.ValBindsNoFieldExt a b
|
|
|
```
|
|
|
|
|
|
>
|
|
|
> which means that any tag using the extension will break in GHC code.
|
|
|
|
|
|
1. what are we trying to achieve with TTG?
|
|
|
|
|
|
- Pass arbitrary AST through GHC and have it processed?
|
|
|
What minimal constraints?
|
|
|
- GHC processes AST, but other tools can then post-process?
|
|
|
- What about alternate GhcPs representation, one for IDE usage?
|
|
|
- Who owns the extensions?
|
|
|
|
|
|
- alternate representations for e.g. GhcPs IDE vs non-IDE
|
|
|
- phase specific changes e.g. ValBindsOut
|
|
|
- Other uses, non-GHC
|
|
|
|
|
|
Basic question is when should a GHC dev make a modifcation to
|
|
|
the core data type, and when use an extension point?
|
|
|
|
|
|
1. A pattern locks in a particular use of an extension point.
|
|
|
|
|
|
```
|
|
|
pattern
|
|
|
ValBindsOut a b
|
|
|
=NewValBindsLR(NValBindsOut a b)
|
|
|
```
|
|
|
|
|
|
>
|
|
|
> it is not possible to pattern match on the type params on the LHS
|
|
|
> so the following does not parse
|
|
|
|
|
|
```
|
|
|
pattern
|
|
|
ValBindsOut(GhcPass a)(GhcPass b)=NewValBindsLR(NValBindsOut(GhcPass a)(GhcPass b))
|
|
|
```
|
|
|
|
|
|
### Experiment 1
|
|
|
|
|
|
|
|
|
There is an experimental implementation at [ https://github.com/alanz/ghc/tree/wip/new-tree-one-param](https://github.com/alanz/ghc/tree/wip/new-tree-one-param).
|
... | ... | |