Following up with a post describing the design of the recently announced notebook. Would appreciate comments, feedback, or experience reports.
I think this design is quite fragile. It’s not possible to reliably distinguish output of user code from separator. User’s putStrLn "--SEPARATOR--" will confuse sabela. It also rely on putStrLn being in scope. But it could be redefined, or hidden: import Prelude()
Also parser for patterns bound in the expression seems to be very primitive. And parsing full patterns amount to parsing full haskell expressions.
In the long run I think there’s no way to avoid using GHC API. Both for patterns and to separate user code from information about its execution.
For most uses cases the first issue isn’t super concerning to me.
The parser is concerning. The heuristics are extremely fragile. GHC API seems heavy handed still. I was looking into Haskell-src-exts and tree sitter as alternatives but haven’t looked into them seriously yet (started a new job yesterday).
You might also consider ghc-lib-parser instead of haskell-src-exts which is unmaintained.
It’s workable but in the long run it will cause all sort of problems with edge cases, weird bugs, features which could be implemented properly. For example interrupting cell execution will require relying on signals and could run into some race.
It’s unmaintaned and never was able to parse all of haskell in first place.