- What is your evaluation of the proposal?
+1 on the idea of having regex literals.
+1 on #/.../#
syntax. (The re''
, #regex()
, and #()
alternatives are acceptable to me as well.)
-1 on the bare /.../
syntax. It introduces too much ambiguity (for humans) and odd special cases to Swift syntax for the sake of a feature that most people should hopefully be avoiding in favor of the regex DSL. Outright banning /
from prefix operators eliminates a lot of potentially useful syntax for libraries. It's already hard enough to come up with good operator names using only ASCII characters; removing an ASCII character from prefix/postfix use does not feel good.
- Is the problem being addressed significant enough to warrant a change to Swift?
Yes, regular expressions are a powerful tool and it's useful to have a special literal syntax for expressing them, as this makes it more obvious when they're being used and allows for editors and other tooling to provide syntax highlighting, linting, etc.
- Does this proposal fit well with the feel and direction of Swift?
I don't believe the bare /.../
syntax fits Swift well. Most of the text of the proposal documents the numerous places where Swift syntax needs to be adjusted to shoehorn this syntax into the language. A more appropriate syntax for Swift wouldn't require such wide and far-reaching changes, nor would introduce so many potentially ambiguous situations.
- If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?
I've used Perl professionally since 1997 and a majority of the Perl software I've written has used regex literals. I also use sed but its regex functionality is a subset of Perl's, with essentially the same syntax. I also use that syntax in other software such as ed/vi/vim. I've occasionally used other programming languages with similar regex literals (e.g., Ruby, Javascript) and those that use other regex literal syntax (e.g., Julia's r"..."
syntax) and those that don't have special syntax or co-opt a more general raw string syntax (e.g., Rust's r"..."
raw string syntax) for regular expressions.
I think Perl has by far the best support for regex literals but it's important to recognize that in Perl the bare /.../
syntax is actually sugar for a couple of different operations. The general syntax for a regex literal in Perl is the qr{}
operator, which can be spelled qr"..."
or qr '...'
or qr(...)
or qr[...]
or even qr A...A
(That last one is rarely a good choice.
) In some contexts /.../
is sugar for qr{...}
but in other contexts it's not. (because Perl
) In other contexts a bare /../
in Perl is sugar for the m{}
operator instead, which both creates a regex and immediately matches a string against it.
It would be nice if Swift could have similar flexibility in delimiters (but only for quote-like or bracket-like characters, not the "any non-whitespace ASCII" rule that Perl has) via something like #regex[]
but it's not absolutely necessary.
Perl examples:
$string = "foo bar baz"; # assign a string to a scalar variable
$string =~ m{o*}; # Try to match the regex /o*/ to the string
$string =~ /o*/; # shorthand for matching the regex to the string
@array = split qr{\s*}, $string; # split the string on whitespace
@array = split /\s*/, $string; #shorthand for splitting the string on whitespace
$regex = qr/foo( ba.)*/; # $regex contains a regular expression (not a string)
# The qr// operator is required above, as using bare /.../ is actually sugar for a rather non-obvious operation in this case:
$foo = /foo( ba.)*/; # shorthand for $foo = ($_ =~ m/foo( ba.)*/);
I've used Perl on a regular basis for a quarter century now and yet off the top of my head I'm not 100% sure of all the cases where /.../
is sugar for qr{...}
and where it's sugar for m{...}
The /.../
syntax in Swift would be less confusing in this regard than in Perl, as in Swift it would simply be regex literal syntax and not be sugar for a variety of different (sometimes surprising) operations. Thus the behavior of /.../
in Swift would actually be the equivalent to qr{...}
in Perl and not /.../
in Perl. So choosing /.../
to match Perl is not actually matching Perl!
The flexibility to choose a delimiter is extremely useful. The #/.../#
syntax proposed here is adequate for this and is reasonably Swifty, given the parallels to string literal syntax. A #regex(...)
syntax could conceivably allow more Perl-like flexibility in choosing delimiters but I feel that #/.../#
is a more Swifty choice. Although the #regex()
syntax would be more easily extended to include other types of literals, I can't think of any other types of string-like literals that would be nearly as useful as regular expressions, so that doesn't feel necessary to me.
Personally I'd prefer that one or more #
be required, rather than the zero or more allowed in strings. This would allow us to avoid breaking changes in Swift's syntax, reducing cognitive load on programmers by making it more clear that regular expressions are being used. If we adopt the proposed /.../
it feels like we're just making life far too easy for entrants into any future obfuscated Swift contests.
- How much effort did you put into your review? A glance, a quick reading, or an in-depth study?
I've read this proposal and the related syntax proposal SE-0355 in depth and followed the pitch threads closely. (Like several others, I participated in the pitch thread to suggest adopting only the #/.../#
syntax and not the bare /.../
syntax.)