[RFC] Support for tagged template literals

Resurfacing from this thread. Binding to Tagged template function - #37 by zth

Tagged Template RFC

I’ve compiled this thread’s discussions into a single post here for renewed discussion. Github issue to come.

Popular JS libraries implement tagged templates (MDN) to provide some really ergonomic APIs. Rescript should make their use feel easy, whether directly supporting the syntax or compiling it into the desugared version of tagFun(expressionsArr, ...args)

Common use cases for both frontend and backend

  1. Common SQL libraries, like prisma.$rawQuery use the sql-template-tag library to form prepared statements.

    sql`select * from table where id = ${val1}` // val1 is escaped
    

    Great improvement over the typical

    sql("select * from table where id = ?", [val1]) 
    
  2. Frontend css-in-js libraries heavily use tag template literals, i.e. styled-components.

    const Button = styled.button`
      color: grey;
    `;
    
  3. graphql-tag uses tagged templates

    gql`
       {
         user(id: 5) {
         firstName
         lastName
       }
      }
     `
    

Current solutions

  1. Use raw to directly directly inline the tagged template. referenced post.

    %%raw("require('gql')` your query `")
    
  2. Create bindings that map to the desugared form (terrible, and I’ve yet to do this myself). referenced post

    @val @variadic
    external gql:  array<string>  => array<'a> => int = "gql"
    
    let result = max([5, -2, 6, 1])
    

Prior art - what’s been done so far

@kevinbarabash 's done alot of exploration and have submitted PRs 1 and 2 to have Rescript compile Rescript tagged templates into the js desugared form (see post).

The main blocker to this possible solution is to have the rescript syntax understand when a tagged template function is called. See @Maxim 's response.

Where to go from here? Can we add native support into rescript?

The team and community should determine the best solution and outline a proper implementation plan with dev costs.

3 Likes

My desire for this feature is relatively moderate as it’d let me use our prisma and sql in a team-appetizing, but not enough for me to dive into the compiler just yet. :slight_smile:

There’s alot of work done already, but no consensus on what’s actually acceptable.

We can all probably agree that this is a desired feature. It will however most likely need substantial amounts of work still, even with the exploration done. Let’s see if someone can pick this up at some point.