Skip to content
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 2/n #2599] [String Template Literals] #2599

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

jordwalke
Copy link
Member

@jordwalke jordwalke commented Jul 6, 2020

Reason Syntax String Template Literals


This is diff 2 in a stack of github PRs: Only examine the most recent commit in this PR to understand what this specific PR accomplishes. The whole stack is:

  1. Reason V4 [Stacked Diff 1/n Reason V4 [Stack 1/n #2605] [Allow multiple versions of Reason] #2605] [Allow multiple versions of Reason] …
  2. YOU ARE HERE --> Reason V4 [Stacked Diff 2/n Reason V4 [Stack 2/n #2599] [String Template Literals] #2599] [String Template Literals] …
  3. Reason V4 [Stacked Diff 3/n Reason V4 [Stack 3/n] [Parse Hashtags for polymorphic variants] #2614] [Parse Hashtags for polymorphic va… …
  4. Reason V4 [Stacked Diff 4/n Reason V4 [Stack 4/n #2619] [Make merlin and rtop respect latest syntax by default] #2619] [Make merlin and rtop respect late… …

This feature implements a planned v4 feature, but in a way that is totally non-breaking and incremental.

String template literals (multiline-form):
I was able to make the multiline form of string templates completely non-breaking. It would be a minor version bump, not major. This doesn't implement the final v4 single line version of string templates, which may be a breaking change.

let x = `
  Hello this is a multiline string literal and
  you can inject an expression ${like ++ this()}
`;

This does not conflict with polymorphic variants, because polymorphic variants do not have a newline break after the first backtick.

let poyVariant = `HelloThere;
let multiLineString = `
  hello!
`;

String templates automatically extract the indentation, and normalize it so that you don't have to align text to the zero column (as JS requires you do).

Bonus feature:
Non-multiline version of string templates in a non-breaking change.

Okay, this diff actually does implement single line string templates as well. It is not the final v4 form, but it currently works. It turns out that you can use any initial white space after the opening backtick and before the closing backtick - such as a space, and it will be treated the same.

let singleLine = ` Here is a template ${stringToo()}! `;

In the first breaking change (v4), the leading/final space will not be required, and I would not recommend heavily advertising the single-line version in the mean time, but it was easy to support and did not present any syntactic conflict so I included it.

vim-reasonml plugin updated with support:

@jordwalke
Copy link
Member Author

This feature allows directly embedding let expressions inside of interpolations such as:

let commentInLetSequence2 = `
  Okay, the following can accept not just an expression
  but also a "let sequence":
  ${
    let x = 200 + 49;
    string_of_int(x);
  }
  Now wasn't that cool?
`;

@jordwalke
Copy link
Member Author

Force pushed on top of the version angle braces and the feature that records a version inside of the file this PR

jordwalke added a commit that referenced this pull request Aug 6, 2020
Summary:This diff implements string template literals.

Test Plan:

Reviewers:

CC:
@jordwalke jordwalke changed the title Reason Syntax v4: String Template Literals Reason V4 [Stack 2/n #2599] [String Template Literals] Aug 6, 2020
jordwalke added a commit that referenced this pull request Aug 11, 2020
Summary:This diff implements string template literals.

Test Plan:

Reviewers:

CC:
jordwalke added a commit that referenced this pull request Aug 17, 2020
Summary:This diff implements string template literals.

Test Plan:

Reviewers:

CC:
jordwalke added a commit that referenced this pull request Aug 17, 2020
Summary:This diff implements string template literals.

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:
Summary:This diff implements string template literals.

Test Plan:

Reviewers:

CC:
@jfrolich
Copy link

jfrolich commented Aug 23, 2020

I did some more thinking. I actually think using """ is probably better in a lot of ways. First, it allows us to seamlessly support markdown in a string (which is actually used quite a bit). Secondly, it's easier when using Reason code snippets in markdown which is also used quite a lot (both within github etc., but also potentially when using the multiline string literal + a decorator to document code -- which might be a nicer way to document than the comment syntax).

I also think we should parse/format it like this:

    let multiLineString = """
      I am a multiline string
      """"
/*    ^ the string separators clearly indicate the beginning of the indentation. */

This is also exactly how multiline strings look like in Python, Swift, and Elixir, so recognizable for a lot of people.

@gaku-sei
Copy link

I'm not sure that's the proper place to ask, but is there any plan to have the template strings working with unicode characters? As per the doc file here, it seems the template strings are currently converted to "simple" strings, using the double quotes.

We could have a modifier for this maybe, to make it opt-in, and to use the parsing rules, something like:

let simple = `Created: ${string_of_int(42)}`;
// "Created: " ++ string_of_int(42)}

let unicode = u`Créée: ${string_of_int(42)}`;
// {j|Créée: |j} ++ string_of_int(42)}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants