In the past few years, GHC has been moving to remove the `fail` method
from the definition of `Monad`, a longtime wart, and requiring monads
that fail due to an incomplete pattern match to implement `MonadFail`.
You can read about it[here](https://wiki.haskell.org/MonadFail_Proposal).
Though this move is still in progress, we can opt into it by turning
on the `-XMonadFailDesugaring` extension.
The matching and rewriting systems will both benefit from this, as the
incomplete pattern match in following rewrite rule will crash without
`-XMonadFailDesugaring`, even though the sensible and correct thing
for the rule to do is call out to its `MonadFail` instance:
```haskell
-- crashes the program without -XMonadFailDesugaring
getReceiver :: Rule a (Ruby.Send term) term
getReceiver = do
(Ruby.Send (Just rec) _ _ _) <- target
pure rec
```
In addition, turning on `MonadFailDesugaring` will warn you if you put
an incomplete pattern match in a monad that doesn't implement `MonadFail`.
This setting will become implicit in GHC 8.6, so this is a good chance
to make sure that we don't introduce any incomplete patterns going forward.
The bumped version of tree-sitter-ruby did not make it into #2223 due
to an error on my part. This halves the time it takes to parse the
pathological lexer.rb file.
As per https://github.com/tree-sitter/haskell-tree-sitter/pull/67, we
weren't using the right tree-sitter APIs to copy node children into a
Haskell-compatible data structure. This bumps tree-sitter-haskell and
adjusts the change in signature of ts_node_copy_child_nodes.
This was the longest (in terms of line count) file in the project.
Splitting it up will save on compile time, as it did for TypeScript.
I observe a ~20sec speedup from `stack clean semantic && stack build semantic:lib`
Right now, Semantic.Version is recompiled on every invocation of
`stack build`, since we marked it as `-fforce-recomp` to ensure that
all deployments are tagged appropriately for haystack. However, this
entails a good deal of wasted time during development. With some
liberal application of `CPP`, we can make this recompilation only
happen on CI, thanks to the `release` flag and passing in a compiler
flag.
To test:
* apply the patch
* `stack build semantic`, then `stack exec semantic -- -v`. It should
print `semantic version 0.4.0 (<development>)`.
* `stack clean semantic && stack build --ghc-options=-DCOMPUTE_GIT_SHA`.
`stack exec semantic -- -v` should then print out the correct SHA.
Though it's probably not strictly necessary, I've marked the
`semantic` and `semanticd` executables to compile with
-DCOMPUTE_GIT_SHA, just in case.
Because we're getting serious about benchmarking in the run-up to
Windrose, it's time to bring in the `deepseq` package to ensure that
benchmarks can fully evaluate the result of a test case.
The `deepseq` package provides an `NFData` typeclass:
```
class NFData a where
rnf :: a -> ()
```
Instances use the `seq` combinator to ensure that the argument to
`rnf` is fully evaluated, returning (). If there is a `Generic`
instance for `a`, the implementation can be omitted. This patch adds
NFData for every syntax node, graph vertex, environment data
structures, and exceptions. It is long, but the work is very
straightforward, so don't panick.
The benchmark suite (`stack bench`) now produces more accurate
results. The benchmarks previously mimicked `rnf` by calling `show` on
the result of an evaluation or graph construction; now that we have
actual `NFData` instances we can use the `nfIO` combinator from
criterion. This has sped up the evaluation benchmarks and reduced
their memory consumption, while it has slowed down the call graph
benchmarks, as those benchmarks weren't evaluating the whole of the
graph.
Unfortunately, this patch increases compile times, as we have to
derive a few more Generic instances. I wish this weren't the case, but
there's little we can do about it now. In the future I have some plans
for how to reduce compile time, and I bet that those gains will at
least nullify the speed hit from this patch.
Now that we have NFData instances for every data type, we can start
benchmarking assignments, in preparation for fixing #2205.
This patch also pulls in updates to `effects` and `fastsum` that add
appropriate NFData instances for the data they vend.