roger peppe
unread,Nov 20, 2009, 6:41:39 AM11/20/09Sign in to reply to author
Sign in to forward
You do not have permission to delete messages in this group
Either email addresses are anonymous for this group or you need the view member email addresses permission to view the original message
to golang-nuts
ok, i know this has a subnanoscopic chance of getting adopted,
but i thought i'd describe it anyway.
currently there are two kinds of string literal, "..." and `...`.
the former allows \ escapes and spanning lines with \; the latter allows
no escapes (not even for ` itself) and also allows multiple lines.
the case that's always been awkward with conventional quoting
syntax is when there's a substantial string that spans multiple lines,
for example a template or a subprogram in an embedded language.
a) if it spans more than a page, it's not easy to see where string
stops and program starts (particularly if the embedded syntax and
the program code syntax are similar or identical)
b) it doesn't work well with program indentation - if the block of code
containing the string is indented, then the contents of the string
gets the indentation too, which is unnecessary and possibly
error-inducing.
c) it doesn't self-embed well. for instance, currently it's not
possible to embed one `...` string inside another. multiple
embedding of \ gives exponential increase, and consequent unreadability.
here's a proposal that avoids these problems
and still fits (nicely, i think) within the go syntax:
An indented string literal starts with a " character followed
by optional whitespace characters, followed by a single non-whitespace
character, the indent character, followed by a newline.
The indent character may not be \, " or /.
This initial sequence is not part of the value of the string.
Each subsequent line must consist of optional whitespace characters,
followed by either the indent character, in which case
the rest of the line is appended to the string (including
the trailing newline), or ", in which case the string literal terminates.
Other than that, all the rules are the same as for the
other kinds of string literals.
Note that because of the strict rules on indented lines,
it's very unlikely that an accidentally unterminated string
constant will get parsed correctly as an indented string literal.
Note also, that it's potentially possible to allow whitespace
and comments inside the string literal. I haven't yet decided if that's
a good or a bad idea.
I've implemented this scheme - it adds two extra functions and about 80
lines to src/cmd/gc/lex.c
Examples:
func f() string {
return "#
#line 1
#line 2
"
}
is the same as:
func f() string {
return "line1\nline2\n";
}
// parse a template string, and return a function (closure) which
// instantiates it with respect to some environment
// variables held in env.
type Env map[string] string
func Parsetemplate(string) func(e Env) string
var render = Parsetemplate("|
|<html>
|<body>
|<h1 $header>
|$text $etc
|</body>
|</html>
")
fmt.Printf("%s", render(Env{"header": "Title", "text": "Hello,",
"etc": "world"}));