-
Notifications
You must be signed in to change notification settings - Fork 425
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
JSX for Reason #647
JSX for Reason #647
Conversation
Wow this is amazing. Thanks for doing this! |
Update: this should be fairly simple to finish. Syntax-wise I now have support for:
Wiring everything up is also straightforward, I just need to figure out how to perform the nesting of children within the AST. |
Ready for review. |
woah this is sick! |
One thing I always wanted in JSX, was the ability to put any simple expression to the right of the let x = <Component count=10 point={x: 0, y:0} callBack=(fun x => x) /> |
I'm trying to think of ways that this could conflict with custom infix operators such as: let ( /> ) a b => a + b; If so, we'd need to provide operator swapping support for the set of operators that conflict. |
Big request while this is still in its early phase: prop punning please. |
How do we swap "createElement" with something else? Do we ever have the need? |
I personally see the primary advantage of JSX being the matching closing tags; the other syntax differences don't seem as valuable to me. So I wonder if we can find something with that benefit but without special complicated syntax rules that JSX introduces (ex: whitespace parsing, entity escaping, similar spread operator but no shorthand property support). I like that your PR here already is much more minimalist than JSX. |
@spicyj is it possible for us to eliminate the needs of jsx if we auto insert comments for "closing tags"? normalFunc prop1::value
(normalFunc2 prop2::value) // "self-closing". No comment needed here really...
// normalFunc end |
Interesting. Maybe! |
I pitched that idea when first building support for JSX in JS and for some reason people didn't get as excited about it as true JSX support. |
Yeah but times have changed and people like functions more than HTML now! (jk no idea what I'm saying). The good thing about using comments is that it provides a nice down(up?)grade path, where people who don't like matching closing tags can simply remove the comment. Also this would be editor-level rather than syntax level. But I'm sure you've heard all of these before. |
@chenglou - Punning support has been added. @jordwalke Not sure how feasible omitting |
That was actually a lot easier then I thought, replacing |
@SanderSpies Wow you're a magician. |
Spread operator is out, as it's too troublesome to add. |
|
Awesome! |
I also like to support lowercase tags, simply because writing |
Lowercase could trivially be made into function calls, but come time to format, there's no way to know which lowercase functions to render as JSX and which ones not to. You could always parse (and therefore preserve at render time), some small attribute on those function application nodes which preserve its JSX-ness. |
Remaining work:
|
# Conflicts: # src/reason_parser.messages # src/reason_parser.mly
Check again please - esp. the added support for fragments. |
@@ -510,6 +517,7 @@ rule token = parse | |||
| "-" { MINUS } | |||
| "-." { MINUSDOT } | |||
| "<>" { LESSGREATER } | |||
| "<><" { LESSGREATERLESS } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think there's no test cases for this infix operator.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried this on the master branch at the time and it didn't work. Will try again.
Okay, I've got the printing working on top of the latest master (rebased). Here's what I believe the solution is: we need lexer rules that generate tokens for the following cases:
Where you see two tokens above one of those tokens is often one of these individual tokens:
The following should parse correctly as well:
and
Constraints:In order for this to work, without ruining the natural ability for people to use
and so on. Those constraints above don't require any additional work in the parser/lexer/printer - they're just things the user must keep in mind. If this is done in the parser, then the printer that I just rebased on master should work and we can merge this PR. |
I think that this is a mistake to support this. I understand the desire to fix JSX in order to make it what you wished it was and to use Reason as a good forcing function to do so. But this is going to yet another small difference between JavaScript and Reason that's going to be in the way of people trying to read/write both languages, for no obviously good benefit than a nice to have. I'm not part of the project so feel free to disregard my opinion, but I think that there's a higher chance of it being more successful if it's seen as a "better JavaScript" than a "friendlier Ocaml". If you want to run with my theory, then you should strive to make the syntax a good subset of JavaScript and only deviate when there's a strong and clear reason to do so. This is the pattern we used for React Native where we tried as much as possible to make it a good subset of the web. Right now it seems like there's a desire to make it look like JavaScript but in practice, it's a weird mix of ocaml and js but the code doesn't look anything like actual JavaScript. Anyway, I'm happy to chat more about it and this pull request is probably not the best forum for it, sorry about it :) |
200% agree |
@vjeux It's definitely a tough balance to strike and it might take a couple of attempts to find the sweet spot. We definitely want to keep moving So maybe it's the case that having some differences in syntax is a good way to manage expectations that there will be things to learn in order to reap those benefits. It could have the same beneficial filtering effect that JSX for React had. Thoughts? But if you have some suggestions even beyond JSX, I'd love to hear them. A few people have even requested that parenthesis be mandatory around function arguments (we're also open to that suggestion as it makes named argument syntax much better - but opinions may vary). But for JSX, why not go the other direction? Why not work towards JSX supporting simple expressions to the right of the |
Oh, and one other thing @vjeux. There's actually room for a couple different "layers" here. I think with what we have for But if you're willing to give that up, there's all kinds of syntactic transforms we could do on top, even going as far as to recreate things from JS that we really believe are worse. These transforms would not be "recoverable"(you can't go back to plain Reason from them) and that would be totally okay. There's an entire spectrum we can/should explore, even if some of those solutions (that very much resemble JS) have performance drawbacks - because at the end of the day we maintain the most important thing - we have a way to write parts of our in something lower that performs better in a way that interops perfectly with all the other stuff that targets the same allocator. |
I was doing some archeology around React and you ( @jordwalke ) wrote the following in the initial diff that brought JSX to React.
So you were indeed write saying "One thing I always wanted in JSX, was the ability to put any simple expression to the right of the =." :) |
Closed due to #775 |
DO NOT MERGE
What I want to get working:
which should be translated into something like:
Although this PR is far from finished (I've only tested the feasibility in the parser) I'd like to get the discussion started.
Current limitations:
What do you guys think of adding JSX support like this?