-
Notifications
You must be signed in to change notification settings - Fork 0
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
Roadmap #1
Comments
This is great, thanks for getting the ball rolling! Targeting I used Megaparsec for my interpreted language HowardLang and yes it gives great errors. I've never used Alex/Happy, and I do like the idea being able to define a valid BNF grammar and just get a parser for free, but I'm down to use Parser Combinators. As a teaching tool it would be nice to use parser combinators and produce an annotated example parser for a complex language like Haskell. I would be fine with going off spec a bit so long as its behind Language Pragmas so that we are maximally compatible with existing code. It should be pretty trivial to write an interpreter for Core as well for testing purposes. |
Do we want to talk about program design yet at this point? I find Recursion Schemes to be a really fantastic tool for doing complex manipulations of trees. @TheMatten I know you did a lot of work on |
Sure 👍 Yeah, they're nice - other options to consider would be hand-rolled polymoprhic traversals (used by PureScript) and When it comes to effects, I'm sorta inclined to not go fancy and create concrete stacks for different phases - they should usually have pretty well defined scope and polymorphic return types are super inconvenient when you have bunch of local definitons without signatures that use random effects - and from my personal experience they appear a lot in this sort of code. Of course, that doesn't mean hard-coding effects into concrete monads, just wrapping concrete stacks in some As far as I was thinking a little bit about other infrastructure, and I think we could:
|
|
Hey all! I've done some thinking about this in the past, and I think it might make sense to break backward compat in a few ways that dramatically simplify the compiler implementation/make the UX a lot nicer:
On the implementation side, I think we should avoid Trees That Grow at all costs. It makes things so much more annoying to read/deal with. |
I'm open to breaking spec, we just have to be okay with losing compatibility with all of Hackage right away instead of losing most of Hackage with the possibility of regaining it via catching up with GHC (lol). |
Sounds good! We could have When it comes to |
Also if we are totally cool with going our own direction we can ask ourselves the question "is there anything we can do now--without all the baggage of GHC--to enable use to more easily add real dependent types later?" |
IIUC the subtlety starts to sneak in when you have to think about how let-generalization behaves. With that in mind, |
What if we made Core dependently typed? edit: oh wait i totally forgot about laziness. |
I guess laziness would actually be useful here - forcing type computations just to get their head would be wildly inefficient. Instead, I guess the bigger problem would be the fact that you either need to be able to plug existing interpreter into typechecker, or you have to implement a second one just to evaluate types. |
Good point - if we want to have modular AST across phases, we need to find some simple solution (I find TTG to be ugly too) |
(I'll create issue for deciding on initial set of language extensions to not clutter this one.) |
Another thing that's bugging my mind when it comes to ASTs - what about annotations like source spans? They're pretty cumbersome to work with in GHC, but at the same time it's hard to think of actually superior solution. |
I would organise things roughly as follows to get the ball rolling: Hask Frontend:
I did have the thought that we could do a pass where we target the intermediate language from the Kinds are Calling Convention paper to produce an educational backend but we can see how things go. That would include having some sort of arity analysis. It would also be interesting to see if anything can be done with linearity. |
@Boarders thanks, sounds reasonable 🙂
Yeah, there's lots of options - personally I would be interested in choosing conservative ones at first and build on top of them / replace them after a little bit of experience with the result. |
(BTW, just to be clear, I think of Core AST in sense of GHC's Core, not sligthly more explicit version of source AST - that is, I would expect it to e.g. not contain spans) |
The other question that needs to be answered is how the compiler ought to operate. A batch mode compiler is simpler, but does make writing tooling much, much harder (see the past 30 odd years of GHC related tooling). On the other hand a more incremental or query-based compiler is harder to write up front, but makes tooling and incremental compilation (duh!) easier. |
@Boarders what alternatives to System FC are you thinking of? |
@TOTBWF when it comes to the architecture, I've found this article to be interesting: https://ollef.github.io/blog/posts/query-based-compilers.html |
Is self-hosting a goal at all? It would be interesting if pulled off but understandable otherwise. |
Probably not - it would be nice to use existing libraries instead of building our own infrastructure GHC-style, but we don't even plan fundeps yet, so that would mean no access to e.g. |
I'd advocate for use of the bound library to handle naming, substitutions and dealing with bound variables in general. |
I would avoid using bound tbh. It can be super slow, and if you have a renaming pass most of the problems it solves disapear. |
I would also say to avoid bound and moreover that we should never have to perform substitution even if we want to have beta reduction in an optimizer (as you can use a semantic evaluator). |
So no Debruijn Indices? Do we just replace all binders with fresh variables?
…On Sat, Oct 24, 2020, 11:12 AM Callan McGill ***@***.***> wrote:
I would also say to avoid bound and moreover that we should never have to
perform substitution even if we want to have beta reduction in an optimizer
(as you can use a semantic evaluator).
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#1 (comment)>, or
unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAAF3ZWNR57NTMMPEO2LBQTSMMKHDANCNFSM4S4FJALQ>
.
|
Sounds reasonable to me - we can take GHC's renamer for an inspiration: https://gitlab.haskell.org/ghc/ghc/-/wikis/commentary/compiler/renamer |
One thing when it comes to renaming - I would like to learn from GHC's mistakes (and PS's successes) and support qualification of syntax everywhere where possible - so that equivalent of |
Ah, ok. So looks like we would use a fast version of the Barendregt convention described in https://www.microsoft.com/en-us/research/publication/secrets-of-the-glasgow-haskell-compiler-inliner/ |
What solution do we pick then? I'm sort of inclined to qualified modules with different versions of AST and transformations between them - it's both dumb simple and preserves exhaustivity checking without ugly tricks, and we can try to factor out common parts later where applicable. |
I'm totally fine with this solution. Lets keep things simple until we cant! |
@ssbothwell Ok 👍 I'll create draft PR soon for source AST that we can use as a "case study" to create guidelines across repo (spoiler - I want to use Haddocks for notes instead of random comments like in GHC) |
Let's put together some roadmap!
As @ssbothwell mentioned, we could start with core IR - it doesn't need any inference and should be much simpler language, while supporting all the relevant type features. I'd like to parse it, so that we can construct and test snippets easily (we could even go as far as to write quasiquoter that lets us interpolate core snippets with custom values, but that isn't really relevant right now 😄).
What about something like:
Core
Hask
after that, we would need to decide on rest of the pipeline - do we want STG and LLVM, or we want to put some intermediate stage in between, or we want to simply interpret things for now and have STG and bytecode ran by custom runtime? There's GRIN, which is literally backend for (lazy) FP languages, so maybe we could just use that one after Core, it just doesn't seem to have very extensive documentation right now, so it may need some tinkering.
Some random thoughts:
megaparsec
has support for pretty errors, operators and indentation, which could save us a lot of time (I think Idris 2 uses it?)BlockArguments
should be easy with parser combinators, andExplicitForall
literally makes us guess less? I guess we may want to take a look at "Simplify subsumption" proposal - I'm not sure if it's relevant to Rank1 in any way, but maybe it could guide us in some (future?) decisionsThe text was updated successfully, but these errors were encountered: