-
Notifications
You must be signed in to change notification settings - Fork 428
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
Reason V4 [Stack 1/n #2605] [Allow multiple versions of Reason] #2605
base: master
Are you sure you want to change the base?
Conversation
b04dc41
to
d718736
Compare
e6c54e1
to
8047d1d
Compare
That could also be integrated in dune so that you don't need to write the header later, maybe |
I think this is quite nifty, but how many times do we expect the syntax to have a breaking change. My concerns are:
Wouldn't it be better to come up with a good syntax proposal that might take a bit more time, and then have a proper migration script? Then it's also possible to simplify the compiler perhaps incorporating some of the code of the Bucklescript syntax that helps to have better errors and faster parsing/printing. This partly of comes from my experience with Would it be a possibility to ship multiple versions of the compiler, and not facilitate everything in the same code base (or is that actually the idea) |
Yes, an env var is the easiest way to plumb it through all the tooling, and dune should already support environment variables for build. An build env var could also be set in an esy package.json. |
@jfrolich Do you have an example in mind? I've been trying to fix all the ones I've come across so if you have a common one in mind I can take a look at it. |
That's definitely a valid concern, but either way, we will still want to be able to support two different syntaxes so that we can continually upgrade people without breaking the ecosystem. In the worst case if it gets too burdensome, we could literally just freeze the old parser/printer implementation, fork new ones, and switch depending on a prepassed lex. One thing that we can do to make the implementation of the parser much cleaner despite supporting two separate syntaxes, is to create different tokens depending on what is lexed early on. For example, after we see a version attribute (or a dune env var etc), we lex the token |
This actually resembles what dune does. I can specify any dune language version which is |
Docker is doing the same thing btw, see "Overriding default frontends" in https://docs.docker.com/develop/develop-images/build_enhancements/, special comment at the start of dockerfile can change the syntax flavour being used:
|
With writing the ppx I often take snapshots of AST and use Refmt to make readable snapshots. I often need to edit them to make them work (like adding some braces in some places). I'll try to post some bug reports. |
@jfrolich Yes, please do report those as issues especially if those same ASTs that format into invalid syntax could be constructed manually in a |
Yeah I am not entirely sure if the AST is possible to construct using plain re. It shouldn't be related to OCaml printer as I just use refmt to parse to binary and then to a AST transform and then print it back. Any idea how to best report this, not sure if a binary AST is very informative. |
I see the tests are now huge bash scripts. Is there any appetite to convert them to rely with snapshot testing? I wrote pretty fast concurrent tests using simple |
Couple of other thoughts I had:
@reason.version.3.8;
/**
* My regular doc comment
* @reason.version.3.8
*/; To encourage people to use floating doc comments more we could parse the triple star comments as floating doc comments. /***
* This is a floating doc comment
* @reason.version.3.8
*/ |
I like the floating doc comment because it entices people to write proper module documentation. I also like the triple star for floating comments! The only thing is that it might be easier to parse (for humans and compilers) if the reason version is always on the first line of the comment. (maybe it can even be at the top line after the three dots) |
Summary:This allows multiple versions of Reason in a single project by inferring and recording the version of syntax used into the file in an attribute. The attribute allows us to switch the parser and lexer on the fly. This attribute is not the only way we can infer the version, and we can allow project level configuration, but this is the approach that is guaranteed to work with any build system or tooling. Test Plan: Reviewers: CC:
8047d1d
to
dab3565
Compare
Summary:This allows multiple versions of Reason in a single project by inferring and recording the version of syntax used into the file in an attribute. The attribute allows us to switch the parser and lexer on the fly. This attribute is not the only way we can infer the version, and we can allow project level configuration, but this is the approach that is guaranteed to work with any build system or tooling. Test Plan: Reviewers: CC:
Summary:This allows multiple versions of Reason in a single project by inferring and recording the version of syntax used into the file in an attribute. The attribute allows us to switch the parser and lexer on the fly. This attribute is not the only way we can infer the version, and we can allow project level configuration, but this is the approach that is guaranteed to work with any build system or tooling. Test Plan: Reviewers: CC:
dab3565
to
688057d
Compare
Summary:This allows multiple versions of Reason in a single project by inferring and recording the version of syntax used into the file in an attribute. The attribute allows us to switch the parser and lexer on the fly. This attribute is not the only way we can infer the version, and we can allow project level configuration, but this is the approach that is guaranteed to work with any build system or tooling. Test Plan: Reviewers: CC:
688057d
to
7f5fe7e
Compare
Summary:This allows multiple versions of Reason in a single project by inferring and recording the version of syntax used into the file in an attribute. The attribute allows us to switch the parser and lexer on the fly. This attribute is not the only way we can infer the version, and we can allow project level configuration, but this is the approach that is guaranteed to work with any build system or tooling. Test Plan: Reviewers: CC:
7f5fe7e
to
b9d5ed4
Compare
Summary:This allows multiple versions of Reason in a single project by inferring and recording the version of syntax used into the file in an attribute. The attribute allows us to switch the parser and lexer on the fly. This attribute is not the only way we can infer the version, and we can allow project level configuration, but this is the approach that is guaranteed to work with any build system or tooling. Test Plan: Reviewers: CC:
b9d5ed4
to
37aa34f
Compare
Summary:This allows multiple versions of Reason in a single project by inferring and recording the version of syntax used into the file in an attribute. The attribute allows us to switch the parser and lexer on the fly. This attribute is not the only way we can infer the version, and we can allow project level configuration, but this is the approach that is guaranteed to work with any build system or tooling. Test Plan: Reviewers: CC:
37aa34f
to
4ecd629
Compare
Summary:This allows multiple versions of Reason in a single project by inferring and recording the version of syntax used into the file in an attribute. The attribute allows us to switch the parser and lexer on the fly. This attribute is not the only way we can infer the version, and we can allow project level configuration, but this is the approach that is guaranteed to work with any build system or tooling. Test Plan: Reviewers: CC:
4ecd629
to
70705a3
Compare
Allow multiple versions of Reason Syntax inside of
refmt
This is an approach to the Reason parser that lets us start incorporating Reason v4 changes that would otherwise be breaking, without needing breaking versions. This is important for allowing packages that depend on old versions to build alongside dependencies that depend on the new version of Reason. Without a feature like this, we risk breaking the ecosystem. But with this feature, all packages can depend on the specific version of Reason that they individually choose without worrying about if it will conflict with dependencies or dependers.
The approach in this diff is that each file will automatically record the version of Reason that it uses inside an attribute. This is not the only approach or the best/final one. It's just one that will work right now and with any build/editor tooling out there. While it records versions inside of individual files, and can allow each individual file to choose its version of Reason - it is not the goal. The goal is strictly to avoid breaking packages. Eventually we can build a configuration in some
.refmt
config that configures the specific version for all files in the project. For now, here's how this works. You have a file in a package that uses Reason v3.7.0
.Then you upgrade your Reason package from
3.7.0
to3.8.0
. Nothing breaks - it's a minor version and minor versions can only introduce new features but cannot break older features. But inside your editor, next time you reformat, it knows that you were programming in Reason3.7.0
previously and it records that fact into a version attribute. It was automatic. You didn't need to do anything.That attribute tells readers and tooling what version of Reason to use when parsing/printing.
But you upgraded to
3.8
, so how do you use the new features? Change the version attribute to[@reason.version 3.8]
and now you can use the new syntax features released in3.8
such as angle bracket types.If you want to upgrade your whole project, then the same upgrade scripts we always use will work.
This version attribute is not the only way we can infer the version - we can allow project level configuration for example, but this is the approach that is guaranteed to work with any build system or tooling.
Future Feature: Auto-upgrade in editor
Supposed that a hypothetical version
3.9
is released where type variables may be upper cased identifiers instead of'a
. You bump yourpackage.json
version ofreason
to3.9.0
, and then inside of your file change the attribute to[@reason.upgradeFrom 3.8]
. Then next time you reformat in your editor it will automatically upgrade from 3.8 to the current version of Reason in your project.