[swift-evolution] URL Literals

Xiaodi Wu xiaodi.wu at gmail.com
Wed Dec 28 13:36:26 CST 2016


On Wed, Dec 28, 2016 at 2:29 PM, Micah Hainline via swift-evolution <
swift-evolution at swift.org> wrote:

> > SE-0039 says that resourceName should be a static-string-literal
>
> It compiles just fine for me in my project. My next question was going
> to be do we actually need a change in the language spec, or can we
> call fixing that a bug, I think you're answering my question for me
> before I even had to ask it!


I'd call that a bug. It doesn't run, and there's no reason why something
not allowed by the grammar shouldn't be diagnosed at compile time, IMO.

>From _The Swift Programming Language_:

GRAMMAR OF A STRING LITERAL
string-literal → static-string-literal­ | interpolated-string-literal­
static-string-literal → "­quoted-text­opt­"­
quoted-text → quoted-text-item­ quoted-text­opt­
quoted-text-item → escaped-character­
quoted-text-item → Any Unicode scalar value except "­, \­, U+000A, or U+000D
interpolated-string-literal → "­interpolated-text­opt­"­
interpolated-text → interpolated-text-item­ interpolated-text­opt­
interpolated-text-item → \(­expression­)­ | quoted-text-item­
escaped-character → \0­ | \\­ | \t­ | \n­ | \r­ | \"­ | \'­
escaped-character → \u­{­unicode-scalar-digits­}­
unicode-scalar-digits → Between one and eight hexadecimal digit



> On Wed, Dec 28, 2016 at 1:20 PM, Xiaodi Wu <xiaodi.wu at gmail.com> wrote:
> > On Wed, Dec 28, 2016 at 2:08 PM, Micah Hainline via swift-evolution
> > <swift-evolution at swift.org> wrote:
> >>
> >> As an aide to learning I've been playing around with implementation of
> >> some of these concepts in the compiler and a few things popped up that
> >> I'm not happy with.
> >>
> >> First, regarding the way #fileLiteral works, it necessitates the
> >> addition of URL.init(fileReferenceLiteralResourceName:) which takes a
> >> string but does not return an optional value. Fine, except that I
> >> don't have to call #fileLiteral in my code to use that constructor, I
> >> can also use it directly. While I could get compile-time checking on
> >> the #fileLiteral, I can't on the direct constructor. Additionally, I
> >> could use the direct constructor with any String, not just literals.
> >> Internally that will call ```self = Bundle.main.url(forResource: name,
> >> withExtension: nil)!``` and crash at runtime if it's not found.
> >> Clearly we do not intend that init to be called directly, but that
> >> isn't clear to new Swift user Jude Doe, who discovers the API as xe
> >> autocompletes from Xcode.
> >
> >
> > That could be fixed with documentation. This API design was reviewed and
> > approved as part of SE-0039:
> > https://github.com/apple/swift-evolution/blob/master/proposals/0039-
> playgroundliterals.md
> >
> >>
> >> The second problem comes from String Interpolation. It's a basic
> >> problem I think with anything that extends the concept of the
> >> string_literal with additional requirements that need to be checked at
> >> compile-time. Right now I can put in something like
> >> ```#fileLiteral(resourceName: "\(myString)")```.
> >
> >
> > Can you? SE-0039 says that resourceName should be a
> static-string-literal,
> > which (unless I'm mistaken) should forbid interpolation.
> >
> >>
> >> While at one level it
> >> might seem nice to be able to construct this sort of thing, it's not
> >> at all nice from a validation perspective.
> >>
> >> I think this has to be solved at a higher level, in the Lexer, making
> >> a url literal a concept at that level, and fundamentally NOT a string
> >> literal underneath, even if they shared some similar constructs.
> >>
> >> The Lexer would be able to see #url("https://\(host)") and say
> >> "Invalid escape sequence in literal, \( is not understood as a url".
> >> In fact, the URL literal should probably not need ANY escape sequences
> >> or even the concept of escape sequences, since a double-quote is not a
> >> legal character in a URL.
> >>
> >> I definitely think we should take this opportunity to identify that we
> >> do NOT want to use string literal as it currently stands as a base
> >> construct for other literal types. Quite possibly there's another,
> >> more restricted concept that we can draw out of string literal that
> >> would make a good base construct, but certainly not a string literal
> >> with interpolation.
> >>
> >>
> >>
> >>
> >> On Wed, Dec 28, 2016 at 8:01 AM, Jonathan Hull via swift-evolution
> >> <swift-evolution at swift.org> wrote:
> >> >
> >> > On Dec 27, 2016, at 11:46 AM, David Sweeris <davesweeris at mac.com>
> wrote:
> >> >
> >> >
> >> > On Dec 22, 2016, at 11:39 PM, Jonathan Hull <jhull at gbis.com> wrote:
> >> >
> >> >
> >> > On Dec 20, 2016, at 12:29 PM, David Sweeris <davesweeris at mac.com>
> wrote:
> >> >
> >> >
> >> > On Dec 20, 2016, at 2:11 AM, Jonathan Hull via swift-evolution
> >> > <swift-evolution at swift.org> wrote:
> >> >
> >> > Yes, I agree.  I am excited to see what happens in phase 2.
> >> >
> >> > What I am suggesting here is slightly different. Basically being able
> to
> >> > use
> >> > RegEx (with capture groups) as a shorthand for a type composed of base
> >> > literals. For example: (StringLiteral, [IntegerLiteral]). Named
> capture
> >> > groups could even map to a dictionary literal.  I am using “RegEx goes
> >> > Here”
> >> > to represent RegEx in the examples below, but hopefully it will get
> it’s
> >> > own
> >> > literal type in Xcode (Imagine that replacing it here).
> >> >
> >> > func foo( _ param: “RegExGoesHere”) {…} //Definition uses a RegEx
> where
> >> > the
> >> > type would normally be
> >> > foo(“my parseable string") //Calling with a string literal
> >> >
> >> > In this case, ‘param’ takes a string literal when called but the
> >> > compiler
> >> > converts it to a tuple of literals based on the regEx supplied and
> >> > passes
> >> > that tuple the function. The type/structure of the tuple is defined by
> >> > the
> >> > capture groups in the RegEx
> >> >
> >> > The parameter above would only allow string literals to be passed in,
> >> > and
> >> > would give a compiler error if you tried to pass a variable or if the
> >> > string
> >> > didn’t conform to the supplied RegEx.  To allow passing String
> variables
> >> > you
> >> > would have to add either ‘?’ or ‘!’ after the RegEx definition to
> handle
> >> > the
> >> > case where the value doesn’t conform.
> >> >
> >> > func foo( _ param: “RegExGoesHere”?) {…} //‘param' is nil if RegEx
> fails
> >> > foo(myStringVar) //Calling
> >> >
> >> > func bar( _ param: “RegExGoesHere”!) {…} //fatal error if RegEx fails
> >> >
> >> > When a variable is passed, the RegEx is performed at runtime instead
> of
> >> > compile time.
> >> >
> >> > Once you have this, the syntax to add new literal types/initializers
> >> > falls
> >> > out virtually for free.
> >> >
> >> >
> >> > Is “RegExGoesHere” where the regex pattern goes, or where the string
> >> > you’re
> >> > trying to match goes? If it’s the latter, where does the pattern go?
> If
> >> > it’s
> >> > the former, where does the string you’re trying to match go?
> >> >
> >> >
> >> > “RegExGoesHere” is where the pattern goes (instead of the type).  The
> >> > string
> >> > you are trying to match gets passed in as the parameter (e.g. “my
> >> > parseable
> >> > string”).
> >> >
> >> > Ah, ok, I think I understand what you’re saying now... You’re
> suggesting
> >> > that instead of defining a custom type that conforms to “RegExLiteral”
> >> > (or
> >> > some other mechanism) and using that as the parameter’s type, you put
> >> > your
> >> > regex pattern as the type directly?
> >> >
> >> >
> >> > Yes.  It is admittedly an advanced feature, but I think it would be a
> >> > useful
> >> > one.
> >> >
> >> > Thanks,
> >> > Jon
> >> >
> >> >
> >> >
> >> > _______________________________________________
> >> > swift-evolution mailing list
> >> > swift-evolution at swift.org
> >> > https://lists.swift.org/mailman/listinfo/swift-evolution
> >> >
> >> _______________________________________________
> >> swift-evolution mailing list
> >> swift-evolution at swift.org
> >> https://lists.swift.org/mailman/listinfo/swift-evolution
> >
> >
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20161228/7bbd8add/attachment.html>


More information about the swift-evolution mailing list