Skip to content

Commit 33fd79f

Browse files
committed
RFC 0019: first pass, qt strings
1 parent 1bd67e6 commit 33fd79f

File tree

1 file changed

+174
-0
lines changed

1 file changed

+174
-0
lines changed

rfcs/rfc0019.md

Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
# A short and accurate title
2+
3+
## Preamble
4+
5+
Author: Ricardo Signes <[email protected]>
6+
Sponsor: RJBS
7+
ID: RFC 0018
8+
Status: Draft
9+
10+
## Abstract
11+
12+
This document proposes a new quote-like operator for string literals. This
13+
operator, `qt`, is meant to serve as an alternative to `qq`, with simpler rules
14+
for understanding what is interpolated and how. It takes its design from
15+
JavaScript's template literals and Ruby's string interpolation.
16+
17+
Instead of allowing a subset of variable expressions directly within a string,
18+
qt allows *any* expression to be interpolated when delimited within the string
19+
literal.
20+
21+
## Motivation
22+
23+
Existing interpolating strings are extremely convenient, but have shortcomings
24+
built into their design. Examples:
25+
26+
```perl
27+
my $what = "balloons";
28+
my $colors = [ qw( red white blue ) ];
29+
30+
my $object = Party->new({ type => "birthday", bring => $what });
31+
32+
$s = "$problems"; # "" . $problems
33+
$s = "$colors->[0]"; # "" . $colors->[0]
34+
35+
$s = "@$colors"; # join($", @$colors)
36+
$s = "$colors->@*"; # If postderef_qq on: join($", $colors->@*)
37+
# Otherwise : "" . $colors . "->@*"
38+
39+
$s = "Bring $object->{bring}"; # "Bring " . $object->{bring}
40+
$s = "Bring $object->bring"; # "Bring " . $object . "->bring}"
41+
```
42+
43+
As we look into adding new forms of dereference (for example the proposed `?->`
44+
operator), or at figuring out how to make `postderef_qq` a default behavior, we
45+
are likely to keep hitting confusing problems with the behavior of `qq`. We
46+
should add something that designs away all these problems now and for the
47+
future.
48+
49+
## Rationale
50+
51+
The proposed `qt` operator only looks for one special token in a string
52+
literal: `{`. Source content until the matching `}` is treated as a scalar
53+
expression to be interpolated into the string in place of the `{...}`
54+
construct. This is arbitrarily extensible for other existing expressions and
55+
for new ones that may be added.
56+
57+
## Specification
58+
59+
This:
60+
61+
```
62+
qt{A { TEXT } B};
63+
```
64+
65+
will be equivalent to
66+
67+
```
68+
qq{A ${ \scalar TEXT } B};
69+
```
70+
71+
To provide a heredoc version of qt, this:
72+
73+
```
74+
<<qt{END}
75+
TEXT
76+
END
77+
```
78+
79+
will apply qt-like interpolation to TEXT. This (very rarely-seen) peril will
80+
exist in qt heredocs as it does in qq heredocs:
81+
82+
```
83+
$str = <<"END";
84+
A ${
85+
END
86+
}
87+
END
88+
```
89+
90+
(The peril here is that the first `END` terminates the string, meaning that the
91+
`${` is never closed.)
92+
93+
## Backwards Compatibility
94+
95+
Existing static analysis should be able to understand `qt` as a new quote-like
96+
operator fairly easily. If the analyzer parses `${...}` within a `qq` string,
97+
parsing the `{...}` forms in a `qt` string should be possible.
98+
99+
`qt` will need to be made available by a feature guard. Use of the qt operator
100+
in source without the feature enabled would often parse as a subroutine call.
101+
102+
There is prior art on the CPAN, most specifically in
103+
[Quote::Code](https://metacpan.org/pod/Quote::Code), which provides a `qc`.
104+
The syntax provided by Quote::Code is similar to, but not identical with, that
105+
proposed here.
106+
107+
## Security Implications
108+
109+
None identified at time of writing.
110+
111+
## Examples
112+
113+
The **Motivation** section, above, provides examples of what *doesn't* work
114+
well with existing interpolation. Documentation can start with simple
115+
interpolation in both, then show how to use qt strings to allow more forms of
116+
interpolation.
117+
118+
```
119+
# No interpolation
120+
qt{Greetings};
121+
122+
# Simple scalar interpolation
123+
qt<Greetings, {$title} {$name}>;
124+
125+
# Interpolation of method calls
126+
qt"Greetings, {$user->title} {$user->name}";
127+
128+
# Interpolation of various expressions
129+
qt{It has been {$since{n}} {$since{units}} since your last login};
130+
131+
qt{...a game of {join q{$"}, $favorites->{game}->name_words->@*}};
132+
```
133+
134+
## Prototype Implementation
135+
136+
Quote::Code, mentioned above, provides something very similar.
137+
138+
## Future Scope
139+
140+
`qt` is "qq but different". If successful, it might suggest the usefulness of
141+
qt-like forms of qr, m, s, and other string-interpolating contexts. This also
142+
suggests that another possible design for qt would be a pragma to change the
143+
behavior of qq *and other interpolating quote-like operators*. This is more
144+
complex for the reader (because any given piece of code must be considered in
145+
terms of the enabled features), but eliminates the proliferation of QLOPs.
146+
147+
## Rejected Ideas
148+
149+
This proposal uses `{...}` instead of `${...}` because `${...}` expects a
150+
*reference* inside in all other contexts, which is not the case here.
151+
152+
This proposal uses `{...}` (like JavaScript) instead of `#{...}` (like Ruby)
153+
because the author didn't think the extra character was likely valuable enough
154+
for disambiguation between literal `{` and start of interpolated expression.
155+
156+
This proposal does not offer a means to interpolate a list without (say)
157+
`join`. It would require more syntax and leave the user falling back on
158+
remembering that multiple arguments to `print` are joined with one thing (`$,`,
159+
usually an empty string) but multiple list elements interpolated into a string
160+
are joined with another (`$"`, usually a space).
161+
162+
Quote::Code has `qc_to` for heredocs instead of a qc-quoted heredoc terminator.
163+
Matching "terminator quoting determines heredoc interpolation" seemed more
164+
"keep similar things similar".
165+
166+
## Open Issues
167+
168+
What, if anything, do we do now about interpolating into regex?
169+
170+
## Copyright
171+
172+
Copyright (C) 2022, Ricardo Signes.
173+
174+
This document and code and documentation within it may be used, redistributed and/or modified under the same terms as Perl itself.

0 commit comments

Comments
 (0)