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

proposal: Go 2: prefixed labels for backtick literals #40393

Closed
mbranch opened this issue Jul 24, 2020 · 7 comments
Closed

proposal: Go 2: prefixed labels for backtick literals #40393

mbranch opened this issue Jul 24, 2020 · 7 comments

Comments

@mbranch
Copy link

@mbranch mbranch commented Jul 24, 2020

It's common in Go source code to write code in other languages like JSON, SQL, HTML, or JavaScript.

For this, backtick literals are helpful as you can format your code as desired:

var script =`console.log('Hello world');`

var page = `
<html>
  <head>
    <title>Title</title>
  </head>
  <body>
    <p>Hello, world!</p>
  </body>
</html>
`

This proposal is a simple change to allow an optional prefixed label for backtick literals:

var script = javascript`console.log('Hello world');`

var page = html`
<html>
  <head>
    <title>Title</title>
  </head>
  <body>
    <p>Hello, world!</p>
  </body>
</html>
`

Allowing prefixed labels enables IDEs and language parsers to act on the string contents:

  • An IDE can provide linting and syntax highlighting for string contents.
  • Like gofmt, a program could format the string contents automatically by inferring the type from the label.

Like the 1.13 change which allows underscores between digits, prefixed labels are meant as a syntactic hint which has no effect on the string value itself, that is:

10000 == 10_000 // true
"contents" == foo`contents` // true
@gopherbot gopherbot added this to the Proposal milestone Jul 24, 2020
@gopherbot gopherbot added the Proposal label Jul 24, 2020
@icholy
Copy link

@icholy icholy commented Jul 24, 2020

Another approach would be a comment. This wouldn't require changing the language.

//go:syntax html
var page = `
<html>
  <head>
    <title>Title</title>
  </head>
  <body>
    <p>Hello, world!</p>
  </body>
</html>
`
@mbranch
Copy link
Author

@mbranch mbranch commented Jul 24, 2020

Another approach would be a comment. This wouldn't require changing the language.

//go:syntax html
var page = `
<html>
  <head>
    <title>Title</title>
  </head>
  <body>
    <p>Hello, world!</p>
  </body>
</html>
`

I think the benefit of formally adding to the language is that how to label a string becomes explicit. There wouldn't be special rules around how to format or place comments (before? after? either?) in order to get the benefit. With that clarity, I believe better tooling and features could be derived.

@ianlancetaylor ianlancetaylor changed the title proposal: prefixed labels for backtick literals proposal: Go 2: prefixed labels for backtick literals Jul 24, 2020
@ianlancetaylor
Copy link
Contributor

@ianlancetaylor ianlancetaylor commented Jul 24, 2020

I agree with @icholy that additional text with no semantic meaning is better handle by a comment. The go/parser package already provides a well documented mechanism for commenting variables: the same as doc comments. And in 1.15 Go documentation packages don't display comments that start with //go: (see #37974). So I don't think there will be much confusion over the formatting or placement of these comments.

@mbranch
Copy link
Author

@mbranch mbranch commented Jul 24, 2020

I do think #37974 makes using comments much more palatable.

@ianlancetaylor So I don't think there will be much confusion over the formatting or placement of these comments.

Playing with it, I came across an example where a comment approach is ambiguous:

_, err := c.exec(ctx, `
	SELECT *
	FROM orders
	WHERE state = $1 AND id = $2;
`, /*go:syntax sql*/ "pending", id)

When trying to put the comment adjacent to the backtick literal, it jumps behind or in front of nearby commas after gofmt.

Obviously, this string could be refactored out of being inline and that could just be the rule, but with a prefix labeling approach, it would just work and be clear in all cases I can think of.

Related, most IDEs won't have access to an AST—so support for a comment-based approach might have to come in the form of syntax definitions based on regular expressions. Obviously not impossible, but probably pretty rough to get right.

@icholy
Copy link

@icholy icholy commented Jul 24, 2020

A simple rule would be that //go:syntax ... affects the first string following the directive.

//go:syntax sql
_, err := c.exec(ctx, `
	SELECT *
	FROM orders
	WHERE state = $1 AND id = $2;
`, "pending", id)

That would be easy for a regex.

@martisch
Copy link
Contributor

@martisch martisch commented Jul 28, 2020

backtick literals seem to have been proposed in #32590 already.

@mbranch
Copy link
Author

@mbranch mbranch commented Jul 28, 2020

Closing in favor of #32590.

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

Successfully merging a pull request may close this issue.

None yet
5 participants
You can’t perform that action at this time.