URL Literals

I think that's all doable. I'm not sure what delimiters would be the
best though, which is why I hadn't moved away from url yet. I've been
thinking hard about the regex, which seems like an even stronger case
to make into a literal, and /abc/ works well for those, but even those
have some problems, as an empty regex (valid according to
NSRegularExpression) of // would parse also as a comment. For < and >
it could start getting confusing with overloaded operators. I think it
would work, but could be a little trickier than it seems like on first
blush.

It would be easier to lex if it were expressed like
#url<https://example.com>, but ease of lexing probably doesn't weigh
that heavily. If we wanted to do more than string, url, and regex we'd
start running out of delimiters fast though...

Another idea (taking from ruby a little) would be to have something
like %url{https://example.com} and %regex{my/regex}

In ruby, their %r{} structure can take things other than {} as long as
they don't appear in the string (for instance %r@my/regex@ works too),
we could do something like that and have a pretty robust structure for
whatever literals we wanted going forward, and it should work for url
and regex, which are in the more immediate future. Of course, % could
just as easily be #.

···

On Thu, Dec 29, 2016 at 12:37 PM, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

Micah,

I think I'm coming round to your line of thinking re URL literals. It'd be
nice to have them supported first-class, not like image literals (the design
for which is really geared towards playgrounds and is rather hacky, IMO),
but like strings. In that scenario, Foundation URL would conform to
ExpressibleByURLLiteral. URL could even be the default URLLiteralType once
Foundation is imported (just like String is the default StringLiteralType).

What'd be _really_ nice, though, is to solidify the first-class status of
URL literals by their spelling: not `#urlLiteral(resourceName: "blahblah")`
or even `#url("blahblah")`, but just as you write `let str = "this is a
string"` (and I'm sure we'll have `let regex = /foo/`), we should have `let
url = <https://google.com/&gt;\`\. The compiler would ensure that what's between
the delimiters is a valid relative or absolute URL, and `init(urlLiteral:)`
will get a parsed tuple just as the official standard outlines, with scheme,
username, password, host, port, cannot-be-a-base-URL flag, path, query,
fragment all ready to go. Looking through the lexer, it seems like this
_should_ be possible and not inordinate amounts of work. Any thoughts about
this idea, since you're actively studying the lexer?

Xiaodi

On Wed, Dec 28, 2016 at 5:18 PM, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

PR #6503. Turned out to be trivial.

On Wed, Dec 28, 2016 at 4:38 PM, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

Not yet, still building locally. My computer's slow. There's one problem
that's apparent though. Here's an existing test in the repo:

LiteralsTestSuite.test("image") {
  let image = #imageLiteral(resourceName: NSImageNameComputer)
  expectTrue(image.isValid)
}

Unfortunately, although `NSImageNameComputer` is a constant, it's of type
`String`. And tweaking global Obj-C bridging rules so that `NSString *
const` comes through as `StaticString` is just not gonna happen, because of
all the things you'd break. We'll lose this (kinda useful) use of
#imageLiteral unless someone goes ahead and manually bridges the
NSImageName* constants, which is acceptable, I suppose. That someone would
have to be the Foundation team, because Foundation APIs aren't really
subject to Evolution.

On Wed, Dec 28, 2016 at 4:29 PM, Micah Hainline >>> <micah.hainline@gmail.com> wrote:

Do you have it checked in somewhere I can see it?

On Wed, Dec 28, 2016 at 2:51 PM, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:
> I may be wrong, but I think I've fixed it. Will test and make sure.
>
> On Wed, Dec 28, 2016 at 3:22 PM, Xiaodi Wu <xiaodi.wu@gmail.com> >>>> > wrote:
>>
>> Well, let's stop that :)
>>
>>
>> On Wed, Dec 28, 2016 at 3:21 PM, Micah Hainline >>>> >> <micah.hainline@gmail.com> >>>> >> wrote:
>>>
>>> Yep, compiles, runs, no warnings or errors and the program displays
>>> the expected results.
>>>
>>> On Wed, Dec 28, 2016 at 2:12 PM, Micah Hainline >>>> >>> <micah.hainline@gmail.com> wrote:
>>> > Good question. It certainly compiles, but I've stuck it in an
>>> > out-of-the-way spot, I'll need to create a test project to know
>>> > the
>>> > answer to that. Just FYI: [SR-3504] #fileLiteral and #imageLiteral allow non-static strings · Issue #46092 · apple/swift · GitHub
>>> >
>>> >
>>> > On Wed, Dec 28, 2016 at 2:11 PM, Xiaodi Wu <xiaodi.wu@gmail.com> >>>> >>> > wrote:
>>> >> Does it run?
>>> >>
>>> >> On Wed, Dec 28, 2016 at 3:10 PM, Micah Hainline >>>> >>> >> <micah.hainline@gmail.com> >>>> >>> >> wrote:
>>> >>>
>>> >>> I'm doing it in a normal project rather than a playground.
>>> >>>
>>> >>> On Wed, Dec 28, 2016 at 1:50 PM, Xiaodi Wu <xiaodi.wu@gmail.com> >>>> >>> >>> wrote:
>>> >>> > Offlist--
>>> >>> >
>>> >>> > In a playground, I get a runtime error when I move the string
>>> >>> > into
>>> >>> > a
>>> >>> > variable and write `#fileLiteral(resourceName: "\(myVar)")`.
>>> >>> > Could
>>> >>> > be
>>> >>> > doing
>>> >>> > it wrong though.
>>> >>> >
>>> >>> > I'll submit a PR to document that users should not use the
>>> >>> > technically
>>> >>> > public APIs for literals.
>>> >>> >
>>> >>> >
>>> >>> > On Wed, Dec 28, 2016 at 2:44 PM, Micah Hainline via >>>> >>> >>> > swift-evolution >>>> >>> >>> > <swift-evolution@swift.org> wrote:
>>> >>> >>
>>> >>> >> I think the way it's set up it probably WOULD run, but it
>>> >>> >> should
>>> >>> >> still
>>> >>> >> probably be a compile error. I like that we have the concept
>>> >>> >> of
>>> >>> >> static-string-literal in the language definition, but I'm
>>> >>> >> having a
>>> >>> >> bit
>>> >>> >> of a hard time tracking it through the compiler. Of course,
>>> >>> >> these
>>> >>> >> are
>>> >>> >> problems probably not right for this list, so I'll take them
>>> >>> >> into
>>> >>> >> a
>>> >>> >> bug instead.
>>> >>> >>
>>> >>> >> On Wed, Dec 28, 2016 at 1:36 PM, Xiaodi Wu >>>> >>> >>> >> <xiaodi.wu@gmail.com> >>>> >>>> >>> >>> >> wrote:
>>> >>> >> > On Wed, Dec 28, 2016 at 2:29 PM, Micah Hainline via >>>> >>> >>> >> > swift-evolution >>>> >>> >>> >> > <swift-evolution@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@gmail.com> >>>> >>> >>> >> >> wrote:
>>> >>> >> >> > On Wed, Dec 28, 2016 at 2:08 PM, Micah Hainline via >>>> >>> >>> >> >> > swift-evolution >>>> >>> >>> >> >> > <swift-evolution@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@swift.org> wrote:
>>> >>> >> >> >> >
>>> >>> >> >> >> > On Dec 27, 2016, at 11:46 AM, David Sweeris >>>> >>> >>> >> >> >> > <davesweeris@mac.com> >>>> >>> >>> >> >> >> > wrote:
>>> >>> >> >> >> >
>>> >>> >> >> >> >
>>> >>> >> >> >> > On Dec 22, 2016, at 11:39 PM, Jonathan Hull >>>> >>> >>> >> >> >> > <jhull@gbis.com> >>>> >>> >>> >> >> >> > wrote:
>>> >>> >> >> >> >
>>> >>> >> >> >> >
>>> >>> >> >> >> > On Dec 20, 2016, at 12:29 PM, David Sweeris >>>> >>> >>> >> >> >> > <davesweeris@mac.com> >>>> >>> >>> >> >> >> > wrote:
>>> >>> >> >> >> >
>>> >>> >> >> >> >
>>> >>> >> >> >> > On Dec 20, 2016, at 2:11 AM, Jonathan Hull via >>>> >>> >>> >> >> >> > swift-evolution >>>> >>> >>> >> >> >> > <swift-evolution@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@swift.org
>>> >>> >> >> >> >
>>> >>> >> >> >> > https://lists.swift.org/mailman/listinfo/swift-evolution
>>> >>> >> >> >> >
>>> >>> >> >> >> _______________________________________________
>>> >>> >> >> >> swift-evolution mailing list
>>> >>> >> >> >> swift-evolution@swift.org
>>> >>> >> >> >>
>>> >>> >> >> >> https://lists.swift.org/mailman/listinfo/swift-evolution
>>> >>> >> >> >
>>> >>> >> >> >
>>> >>> >> >> _______________________________________________
>>> >>> >> >> swift-evolution mailing list
>>> >>> >> >> swift-evolution@swift.org
>>> >>> >> >> https://lists.swift.org/mailman/listinfo/swift-evolution
>>> >>> >> >
>>> >>> >> >
>>> >>> >> _______________________________________________
>>> >>> >> swift-evolution mailing list
>>> >>> >> swift-evolution@swift.org
>>> >>> >> https://lists.swift.org/mailman/listinfo/swift-evolution
>>> >>> >
>>> >>> >
>>> >>
>>> >>
>>
>>
>

I'd prefer to see a literal URL than a Foundation URL that is string-initializable. I don't see a URL literal as being in any way necessarily tightly coupled with a Foundation URL type. The point of a literal is that it is inherently typeless and checked at compile time. A color literal depending on context can be a UIColor or NSColor but that's not specified outside of the use context. The code is portable and cross platform.

-- E

···

On Dec 17, 2016, at 10:18 PM, Xiaodi Wu via swift-evolution <swift-evolution@swift.org> wrote:

With respect to URL specifically, that it's a Foundation type may change the timeline as well. Various improvements to the Foundation API (and URL in particular) have been proposed here, but if I remember correctly, the stated goal was first to have a complete Swift version of Foundation, preserving the existing API as exactly as possible with no additions or subtractions, and only then to consider Swifty evolution of the APIs. I don't think the first step is complete yet.

On Sat, Dec 17, 2016 at 21:46 Step C via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
Probably worth pointing out that this topic seems entirely additive. Which means it would be at least a phase 2 proposal, if not later.

> On Dec 17, 2016, at 4:44 PM, Micah Hainline via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>
> Yes, everyone who has what they feel like is a solid workable solution should write it up for URL and we can compare and pick holes in them all until we get something really solid.
>
>> On Dec 17, 2016, at 3:27 PM, David Sweeris <davesweeris@mac.com <mailto:davesweeris@mac.com>> wrote:
>>
>>
>>
>> Sent from my iPhone
>>
>>> On Dec 17, 2016, at 13:20, David Sweeris <davesweeris@mac.com <mailto:davesweeris@mac.com>> wrote:
>>>
>>>
>>>
>>> Sent from my iPhone
>>>
>>>> On Dec 17, 2016, at 13:12, Micah Hainline via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>>>>
>>>> I'd love a fleshed out elegant example for URL that shows what a complete implementation of that special init method would look like.
>>>
>>> I can't do it now, but I'll try post one before tomorrow that shows how I'd envision it working.
>>
>> Oh, and to be clear, I'm not trying to "claim" this or anything... if anyone else has ideas, please post them! The more the merrier.

URLs are unlikely to be something that can be validated by regex. See, for
instance, this discussion: <
https://webkit.org/blog/7086/url-parsing-in-webkit/&gt;\. The full spec is
here: <https://url.spec.whatwg.org>. If Swift were to implement parsing of
URLs at the level of the compiler or core library, I'd expect it to be the
full spec, as we do with Unicode.

···

On Mon, Dec 19, 2016 at 2:26 AM, Benjamin Spratling via swift-evolution < swift-evolution@swift.org> wrote:

Howdy,
Yes, I was also intrigued by the “Regex” validation mentioned in another
post. It could offer a convenient way to get some literals support in
without the headaches associated with the constexpr C++ approach.
I’m curious, though, how many types can we image in can be validated by
this method? If it really is just URL’s, then I’d actually lean towards
making this a compiler magic feature.

Someone else mentioned fetching the URL’s for a preview. Given that we
might be coding “deletes” in URL’s (yes, I recently met a backend developer
who coded a delete as a GET), I really highly suggest we not ping people’s
API’s artificially. At least we shouldn’t for non-file-scheme URLs. IMHO,
verifying that a service is active isn’t really the Swift compiler’s job.
It might happen as part of coordinated run-time tests, which sometimes have
to be balanced to keep test data correct, something the IDE wouldn’t know
how to enforce correctly.
-Ben

On Dec 19, 2016, at 1:41 AM, David Sweeris via swift-evolution < > swift-evolution@swift.org> wrote:

On Dec 17, 2016, at 1:12 PM, Micah Hainline via swift-evolution < > swift-evolution@swift.org> wrote:

I'd love a fleshed out elegant example for URL that shows what a complete
implementation of that special init method would look like.

Sorry this took so long… the weekend kinda got away from me.

Anyway, I was thinking something like this (which has been very simplified
on account of my regexing being sub-sketchy, and me not knowing exactly
what’s valid in an URL anyway):

#literalpatterns += (name: “URLLiteralType”, components: (name: url,
type: StringLiteralType, pattern: “(http|https)://(www.)?[a-z|A-Z|0-9]+
.(com|org|net)(/[a-z|A-Z|0-9]+)*(/[a-z|A-Z|0-9]+.[a-z|A-Z|0-9]+)?”),
protocol: ExpressibleByURLLiteral)

This would let the compiler know pretty much everything it needs to know…
that the “new” type is called “URLLiteralType", that it starts out life as
young StringLiteralType with a bright future in the computer industry, that
in order to succeed it has to match a given pattern, and what protocol a
type has to conform to in order to use an URLLiteral. In practice, the
compiler would synthesize a struct containing the specified members and
validate the literal with the specified pattern before making an “instance”
of it (since we’re talking about literals and compile-time code here, I’m
pretty sure that “instance" the wrong terminology… pardon my ignorance)

struct URLLiteralType: {
    let url: StringLiteralType
}

A tuple would be better, IMHO, but according to the playground,
single-element tuples can’t have element labels. As for the
implementation of the init function:

init(urlLiteral value: URLLiteralType) {
    let urlString = value.url
    //Do whatever URL is doing now, except there’s no need to check for
errors since the compiler pre-validated it for us
}

If it’d be more useful, the pattern could be split into multiple pieces:

#literalpatterns += (name: “URLLiteralType”,
                     components: ((name: “`protocol`", type:
StringLiteralType, pattern: “(http|https)”),
                                  (name: _, type:
StringLiteralType, pattern: “://”),
                                  (name: “domain", type:
StringLiteralType, pattern: “(www.)?[a-z|A-Z|0-9]+.(com|org|net)”),
                                  (name: “path”, type:
StringLiteralType, pattern: "(/[a-z|A-Z|0-9]+)*(/[a-z|A-Z|0-9]+.
[a-z|A-Z|0-9]+)?”))
                     protocol: ExpressibleByURLLiteral)

This would result in URLLiteralType looking like this:

struct URLLiteralType: {
    let `protocol`: StringLiteralType
    let domain: StringLiteralType
    let path: StringLiteralType
}

And in the init would start out like this:

init(urlLiteral value: URLLiteralType) {
    let protocolType = value.protocol
    let domain = value.domain
    let path = value.path
    //Do whatever with the components
}

The “base” types of literals like Int or String that don’t refine
pre-existing literal types would still need a bit of compiler magic (or at
least a different mechanism for becoming actual types), but as long as a
type doesn’t take advantage of reference semantics in its stored properties
or something, I *think* pretty much any data type could become
“literalizeable” with something like this. Oh, and there’s nothing
particularly magical about regular expressions as far as this idea is
concerned; they’re just usually the first thing that comes to mind when I
think of pattern matching in a string.

I know this looks like a lot of code, but the scary-looking parts with the
regex stuff only has to be written once for each “type” of literal… types
that want to be expressible by such a literal just have to write an init
function.

While I was writing this up, it occurred to me that another solution would
be to have a set of "ExpressibleByValidated*Literal” protocols, where the
init is failable and has to be @pure/@constexpr/@
whateverthecompilerneedstorunitatcompiletime. That way the literal can be
validated simply by calling the init and checking if it returns nil. Make
`URL` conform to `ExpressibleByValidatedStringLiteral`, and you'll get
the complie-time validation functionality just by copying whatever’s in the
current `URL.init?(string: String)` function.

- Dave Sweeris
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

I think that's all doable. I'm not sure what delimiters would be the
best though, which is why I hadn't moved away from url yet. I've been
thinking hard about the regex, which seems like an even stronger case
to make into a literal, and /abc/ works well for those, but even those
have some problems, as an empty regex (valid according to
NSRegularExpression) of // would parse also as a comment.

True, but I doubt that's a common use case. JavaScript supports `/regex/`
and I haven't heard of complaints re not supporting `//`.

For < and >
it could start getting confusing with overloaded operators. I think it
would work, but could be a little trickier than it seems like on first
blush.

Besides being a natural way of writing it, < and > have the advantage that
resolving their different uses is already heavily tested (because generics
use <>, and because the lexer understands merging artifacts like <<<<<< and

).

It would be easier to lex if it were expressed like
#url<https://example.com>, but ease of lexing probably doesn't weigh
that heavily. If we wanted to do more than string, url, and regex we'd
start running out of delimiters fast though...

To me, that's a feature, not a bug. I'd argue that the language should
provide first-class support for only a few, very important literals (like
strings). Compile time validation for arbitrary types, as I've said before,
should probably be solved in other, more holistic ways (such as some sort
of constexpr-like feature).

Another idea (taking from ruby a little) would be to have something

like %url{https://example.com} and %regex{my/regex}

In ruby, their %r{} structure can take things other than {} as long as
they don't appear in the string (for instance %r@my/regex@ works too),
we could do something like that and have a pretty robust structure for
whatever literals we wanted going forward, and it should work for url
and regex, which are in the more immediate future. Of course, % could
just as easily be #.

We had that before, essentially. Object literals (file, image, color) were
spelled like this: [#Color(...)#]. They were removed with SE-0039.

···

On Thu, Dec 29, 2016 at 3:18 PM, Micah Hainline <micah.hainline@gmail.com> wrote:

On Thu, Dec 29, 2016 at 12:37 PM, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

> Micah,
>
> I think I'm coming round to your line of thinking re URL literals. It'd
be
> nice to have them supported first-class, not like image literals (the
design
> for which is really geared towards playgrounds and is rather hacky, IMO),
> but like strings. In that scenario, Foundation URL would conform to
> ExpressibleByURLLiteral. URL could even be the default URLLiteralType
once
> Foundation is imported (just like String is the default
StringLiteralType).
>
> What'd be _really_ nice, though, is to solidify the first-class status of
> URL literals by their spelling: not `#urlLiteral(resourceName:
"blahblah")`
> or even `#url("blahblah")`, but just as you write `let str = "this is a
> string"` (and I'm sure we'll have `let regex = /foo/`), we should have
`let
> url = <https://google.com/&gt;\`\. The compiler would ensure that what's
between
> the delimiters is a valid relative or absolute URL, and
`init(urlLiteral:)`
> will get a parsed tuple just as the official standard outlines, with
scheme,
> username, password, host, port, cannot-be-a-base-URL flag, path, query,
> fragment all ready to go. Looking through the lexer, it seems like this
> _should_ be possible and not inordinate amounts of work. Any thoughts
about
> this idea, since you're actively studying the lexer?
>
> Xiaodi
>
>
> On Wed, Dec 28, 2016 at 5:18 PM, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:
>>
>> PR #6503. Turned out to be trivial.
>>
>> On Wed, Dec 28, 2016 at 4:38 PM, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:
>>>
>>> Not yet, still building locally. My computer's slow. There's one
problem
>>> that's apparent though. Here's an existing test in the repo:
>>>
>>> ```
>>> LiteralsTestSuite.test("image") {
>>> let image = #imageLiteral(resourceName: NSImageNameComputer)
>>> expectTrue(image.isValid)
>>> }
>>> ```
>>>
>>> Unfortunately, although `NSImageNameComputer` is a constant, it's of
type
>>> `String`. And tweaking global Obj-C bridging rules so that `NSString *
>>> const` comes through as `StaticString` is just not gonna happen,
because of
>>> all the things you'd break. We'll lose this (kinda useful) use of
>>> #imageLiteral unless someone goes ahead and manually bridges the
>>> NSImageName* constants, which is acceptable, I suppose. That someone
would
>>> have to be the Foundation team, because Foundation APIs aren't really
>>> subject to Evolution.
>>>
>>>
>>> On Wed, Dec 28, 2016 at 4:29 PM, Micah Hainline > >>> <micah.hainline@gmail.com> wrote:
>>>>
>>>> Do you have it checked in somewhere I can see it?
>>>>
>>>> On Wed, Dec 28, 2016 at 2:51 PM, Xiaodi Wu <xiaodi.wu@gmail.com> > wrote:
>>>> > I may be wrong, but I think I've fixed it. Will test and make sure.
>>>> >
>>>> > On Wed, Dec 28, 2016 at 3:22 PM, Xiaodi Wu <xiaodi.wu@gmail.com> > >>>> > wrote:
>>>> >>
>>>> >> Well, let's stop that :)
>>>> >>
>>>> >>
>>>> >> On Wed, Dec 28, 2016 at 3:21 PM, Micah Hainline > >>>> >> <micah.hainline@gmail.com> > >>>> >> wrote:
>>>> >>>
>>>> >>> Yep, compiles, runs, no warnings or errors and the program
displays
>>>> >>> the expected results.
>>>> >>>
>>>> >>> On Wed, Dec 28, 2016 at 2:12 PM, Micah Hainline > >>>> >>> <micah.hainline@gmail.com> wrote:
>>>> >>> > Good question. It certainly compiles, but I've stuck it in an
>>>> >>> > out-of-the-way spot, I'll need to create a test project to know
>>>> >>> > the
>>>> >>> > answer to that. Just FYI: [SR-3504] #fileLiteral and #imageLiteral allow non-static strings · Issue #46092 · apple/swift · GitHub
>>>> >>> >
>>>> >>> >
>>>> >>> > On Wed, Dec 28, 2016 at 2:11 PM, Xiaodi Wu <xiaodi.wu@gmail.com > > > >>>> >>> > wrote:
>>>> >>> >> Does it run?
>>>> >>> >>
>>>> >>> >> On Wed, Dec 28, 2016 at 3:10 PM, Micah Hainline > >>>> >>> >> <micah.hainline@gmail.com> > >>>> >>> >> wrote:
>>>> >>> >>>
>>>> >>> >>> I'm doing it in a normal project rather than a playground.
>>>> >>> >>>
>>>> >>> >>> On Wed, Dec 28, 2016 at 1:50 PM, Xiaodi Wu < > xiaodi.wu@gmail.com> > >>>> >>> >>> wrote:
>>>> >>> >>> > Offlist--
>>>> >>> >>> >
>>>> >>> >>> > In a playground, I get a runtime error when I move the
string
>>>> >>> >>> > into
>>>> >>> >>> > a
>>>> >>> >>> > variable and write `#fileLiteral(resourceName: "\(myVar)")`.
>>>> >>> >>> > Could
>>>> >>> >>> > be
>>>> >>> >>> > doing
>>>> >>> >>> > it wrong though.
>>>> >>> >>> >
>>>> >>> >>> > I'll submit a PR to document that users should not use the
>>>> >>> >>> > technically
>>>> >>> >>> > public APIs for literals.
>>>> >>> >>> >
>>>> >>> >>> >
>>>> >>> >>> > On Wed, Dec 28, 2016 at 2:44 PM, Micah Hainline via > >>>> >>> >>> > swift-evolution > >>>> >>> >>> > <swift-evolution@swift.org> wrote:
>>>> >>> >>> >>
>>>> >>> >>> >> I think the way it's set up it probably WOULD run, but it
>>>> >>> >>> >> should
>>>> >>> >>> >> still
>>>> >>> >>> >> probably be a compile error. I like that we have the
concept
>>>> >>> >>> >> of
>>>> >>> >>> >> static-string-literal in the language definition, but I'm
>>>> >>> >>> >> having a
>>>> >>> >>> >> bit
>>>> >>> >>> >> of a hard time tracking it through the compiler. Of course,
>>>> >>> >>> >> these
>>>> >>> >>> >> are
>>>> >>> >>> >> problems probably not right for this list, so I'll take
them
>>>> >>> >>> >> into
>>>> >>> >>> >> a
>>>> >>> >>> >> bug instead.
>>>> >>> >>> >>
>>>> >>> >>> >> On Wed, Dec 28, 2016 at 1:36 PM, Xiaodi Wu > >>>> >>> >>> >> <xiaodi.wu@gmail.com> > >>>> > >>>> >>> >>> >> wrote:
>>>> >>> >>> >> > On Wed, Dec 28, 2016 at 2:29 PM, Micah Hainline via > >>>> >>> >>> >> > swift-evolution > >>>> >>> >>> >> > <swift-evolution@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@gmail.com> > >>>> >>> >>> >> >> wrote:
>>>> >>> >>> >> >> > On Wed, Dec 28, 2016 at 2:08 PM, Micah Hainline via > >>>> >>> >>> >> >> > swift-evolution > >>>> >>> >>> >> >> > <swift-evolution@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(fileReferenceLiteralResourceNa
me:)
>>>> >>> >>> >> >> >> 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:
>>>> >>> >>> >> >> >
>>>> >>> >>> >> >> >
>>>> >>> >>> >> >> >
>>>> >>> >>> >> >> >
>>>> >>> >>> >> >> >
>>>> >>> >>> >> >> > GitHub - apple/swift-evolution: This maintains proposals for changes and user-visible enhancements to the Swift Programming Language.
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@swift.org> wrote:
>>>> >>> >>> >> >> >> >
>>>> >>> >>> >> >> >> > On Dec 27, 2016, at 11:46 AM, David Sweeris > >>>> >>> >>> >> >> >> > <davesweeris@mac.com> > >>>> >>> >>> >> >> >> > wrote:
>>>> >>> >>> >> >> >> >
>>>> >>> >>> >> >> >> >
>>>> >>> >>> >> >> >> > On Dec 22, 2016, at 11:39 PM, Jonathan Hull > >>>> >>> >>> >> >> >> > <jhull@gbis.com> > >>>> >>> >>> >> >> >> > wrote:
>>>> >>> >>> >> >> >> >
>>>> >>> >>> >> >> >> >
>>>> >>> >>> >> >> >> > On Dec 20, 2016, at 12:29 PM, David Sweeris > >>>> >>> >>> >> >> >> > <davesweeris@mac.com> > >>>> >>> >>> >> >> >> > wrote:
>>>> >>> >>> >> >> >> >
>>>> >>> >>> >> >> >> >
>>>> >>> >>> >> >> >> > On Dec 20, 2016, at 2:11 AM, Jonathan Hull via > >>>> >>> >>> >> >> >> > swift-evolution > >>>> >>> >>> >> >> >> > <swift-evolution@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@swift.org
>>>> >>> >>> >> >> >> >
>>>> >>> >>> >> >> >> > https://lists.swift.org/mailman/listinfo/swift-
evolution
>>>> >>> >>> >> >> >> >
>>>> >>> >>> >> >> >> _______________________________________________
>>>> >>> >>> >> >> >> swift-evolution mailing list
>>>> >>> >>> >> >> >> swift-evolution@swift.org
>>>> >>> >>> >> >> >>
>>>> >>> >>> >> >> >> https://lists.swift.org/mailman/listinfo/swift-
evolution
>>>> >>> >>> >> >> >
>>>> >>> >>> >> >> >
>>>> >>> >>> >> >> _______________________________________________
>>>> >>> >>> >> >> swift-evolution mailing list
>>>> >>> >>> >> >> swift-evolution@swift.org
>>>> >>> >>> >> >> https://lists.swift.org/mailman/listinfo/swift-
evolution
>>>> >>> >>> >> >
>>>> >>> >>> >> >
>>>> >>> >>> >> _______________________________________________
>>>> >>> >>> >> swift-evolution mailing list
>>>> >>> >>> >> swift-evolution@swift.org
>>>> >>> >>> >> https://lists.swift.org/mailman/listinfo/swift-evolution
>>>> >>> >>> >
>>>> >>> >>> >
>>>> >>> >>
>>>> >>> >>
>>>> >>
>>>> >>
>>>> >
>>>
>>>
>>
>

1 Like

That's a fair point. I suppose we could have, in the same way as file
literals,

#urlLiteral(resourceName: "http://example.com")

which in an IDE would be automatically generated when someone drops a link
and might be rendered as a hyperlink, blue underline and all.

···

On Sun, Dec 18, 2016 at 16:17 Erica Sadun <erica@ericasadun.com> wrote:

I'd prefer to see a literal URL than a Foundation URL that is
string-initializable. I don't see a URL literal as being in any way
necessarily tightly coupled with a Foundation URL type. The point of a
literal is that it is inherently typeless and checked at compile time. A
color literal depending on context can be a UIColor or NSColor but that's
not specified outside of the use context. The code is portable and cross
platform.

-- E

On Dec 17, 2016, at 10:18 PM, Xiaodi Wu via swift-evolution < > swift-evolution@swift.org> wrote:

With respect to URL specifically, that it's a Foundation type may change
the timeline as well. Various improvements to the Foundation API (and URL
in particular) have been proposed here, but if I remember correctly, the
stated goal was first to have a complete Swift version of Foundation,
preserving the existing API as exactly as possible with no additions or
subtractions, and only then to consider Swifty evolution of the APIs. I
don't think the first step is complete yet.

On Sat, Dec 17, 2016 at 21:46 Step C via swift-evolution < > swift-evolution@swift.org> wrote:

Probably worth pointing out that this topic seems entirely additive. Which
means it would be at least a phase 2 proposal, if not later.

> On Dec 17, 2016, at 4:44 PM, Micah Hainline via swift-evolution < > swift-evolution@swift.org> wrote:

>

> Yes, everyone who has what they feel like is a solid workable solution
should write it up for URL and we can compare and pick holes in them all
until we get something really solid.

>

>> On Dec 17, 2016, at 3:27 PM, David Sweeris <davesweeris@mac.com> wrote:

>>

>>

>>

>> Sent from my iPhone

>>

>>> On Dec 17, 2016, at 13:20, David Sweeris <davesweeris@mac.com> wrote:

>>>

>>>

>>>

>>> Sent from my iPhone

>>>

>>>> On Dec 17, 2016, at 13:12, Micah Hainline via swift-evolution < > swift-evolution@swift.org> wrote:

>>>>

>>>> I'd love a fleshed out elegant example for URL that shows what a
complete implementation of that special init method would look like.

>>>

>>> I can't do it now, but I'll try post one before tomorrow that shows
how I'd envision it working.

>>

>> Oh, and to be clear, I'm not trying to "claim" this or anything... if
anyone else has ideas, please post them! The more the merrier.

It doesn’t have to be regex per se… instead of
#literalpatterns += (name: “URLLiteralType”, components: (name: url, type: StringLiteralType, pattern: “(http|https)://(www.)?[a-z|A-Z|0-9]+.(com|org|net)(/[a-z|A-Z|0-9]+)*(/[a-z|A-Z|0-9]+.[a-z|A-Z|0-9]+)?”), protocol: ExpressibleByURLLiteral)
I probably should’ve written something more like:
#literalpatterns += (name: “URLLiteralType”, components: (name: url, type: StringLiteralType, matching: Regex(“(http|https)://(www.)?[a-z|A-Z|0-9]+.(com|org|net)(/[a-z|A-Z|0-9]+)*(/[a-z|A-Z|0-9]+.[a-z|A-Z|0-9]+)?”)), protocol: ExpressibleByURLLiteral)
where the `matching` argument can be anything that can (“@purely”-ly) use some specified mechanism (I’d vote for the ~= operator) with a literal to test whether it matches. Also, there is no existing `Regex` struct/class/mechanism in Swift, unless you count `NSRegularExpression`. I didn’t want to use that for a couple reasons… 1) I don’t think it’s part of the stdlib, and 2) it doesn’t have a non-failable init that just takes a string, so using it unmodified would kinda put us in a “it’s turtles all the way down” kind of situation. What I’d started doing was to look for the existing mechanism for specifying literals in the compiler so I could use the existing name for it (somehow I doubt there’s a actually an array of patterns called “literalpatterns" in the compiler) and copy the existing methods for specifying a valid literal. After being unsuccessful for some amount of time, I decided I was getting too tired and made up what I sent last night.

The more I think about it, the more I’m starting to be of the opinion that we really ought to have two mechanisms here… One for specifying what constitutes a “base” literal (like `43`, `[“foo”, “bar”]`, or `true`), and one for types that merely need to perform some sort of validation on existing “base” literals. The first mechanism probably should be fairly arcane and involved, because you’d essentially be able to create new syntaxes, which should be kinda scary and hard to understand because it’s most certainly not an area beginners should be in. The second mechanism — something like that `ExpressibleByValidatedStringLiteral` idea — isn’t nearly as complicated. In the case of URLs, I’d vote the second approach. We only really need two extra features to implement it (“@constexpr” and the compiler being able to use the REPL to evaluate @costexpr statements), and both of them have more uses other than just getting a few more compile-time checks or allowing for more inits to be non-failable. With both of those in place, getting an url “literal” becomes just this:
protocol ExpressibleByValidatedStringLiteral {
    init?(stringLiteral value: StringLiteralType)
}
struct URL : ExpressibleByValidatedStringLiteral {
    //Stuff
    //...
    init?(stringLiteral value: StringLiteralType) {
        //Perform validation here; return nil if it fails
    }
    //...
    //Things
}
var lru: URL = "foo" //Compiler throws this to the init? function, it returns nil, the compiler raises a syntax error
var url: URL = "http://www.some.valid.url.com" //Compiler throws this to the init? function, it returns an optional URL, the compiler unwraps it and does the assignment

I still very much want a way to define custom literals (precisely because it’d let me make new syntaxes), but I’m starting to think that something like the second, disappointingly easy idea, is probably the way to go in this case.

- Dave Sweeris

···

On Dec 19, 2016, at 1:26 AM, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

URLs are unlikely to be something that can be validated by regex. See, for instance, this discussion: <https://webkit.org/blog/7086/url-parsing-in-webkit/&gt;\. The full spec is here: <https://url.spec.whatwg.org <https://url.spec.whatwg.org/&gt;&gt;\. If Swift were to implement parsing of URLs at the level of the compiler or core library, I'd expect it to be the full spec, as we do with Unicode.

On Mon, Dec 19, 2016 at 2:26 AM, Benjamin Spratling via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
Howdy,
  Yes, I was also intrigued by the “Regex” validation mentioned in another post. It could offer a convenient way to get some literals support in without the headaches associated with the constexpr C++ approach.
  I’m curious, though, how many types can we image in can be validated by this method? If it really is just URL’s, then I’d actually lean towards making this a compiler magic feature.

  Someone else mentioned fetching the URL’s for a preview. Given that we might be coding “deletes” in URL’s (yes, I recently met a backend developer who coded a delete as a GET), I really highly suggest we not ping people’s API’s artificially. At least we shouldn’t for non-file-scheme URLs. IMHO, verifying that a service is active isn’t really the Swift compiler’s job. It might happen as part of coordinated run-time tests, which sometimes have to be balanced to keep test data correct, something the IDE wouldn’t know how to enforce correctly.
-Ben

On Dec 19, 2016, at 1:41 AM, David Sweeris via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

On Dec 17, 2016, at 1:12 PM, Micah Hainline via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

I'd love a fleshed out elegant example for URL that shows what a complete implementation of that special init method would look like.

Sorry this took so long… the weekend kinda got away from me.

Anyway, I was thinking something like this (which has been very simplified on account of my regexing being sub-sketchy, and me not knowing exactly what’s valid in an URL anyway):
#literalpatterns += (name: “URLLiteralType”, components: (name: url, type: StringLiteralType, pattern: “(http|https)://(www.)?[a-z|A-Z|0-9]+.(com|org|net)(/[a-z|A-Z|0-9]+)*(/[a-z|A-Z|0-9]+.[a-z|A-Z|0-9]+)?”), protocol: ExpressibleByURLLiteral)
This would let the compiler know pretty much everything it needs to know… that the “new” type is called “URLLiteralType", that it starts out life as young StringLiteralType with a bright future in the computer industry, that in order to succeed it has to match a given pattern, and what protocol a type has to conform to in order to use an URLLiteral. In practice, the compiler would synthesize a struct containing the specified members and validate the literal with the specified pattern before making an “instance” of it (since we’re talking about literals and compile-time code here, I’m pretty sure that “instance" the wrong terminology… pardon my ignorance)
struct URLLiteralType: {
    let url: StringLiteralType
}
A tuple would be better, IMHO, but according to the playground, single-element tuples can’t have element labels. As for the implementation of the init function:
init(urlLiteral value: URLLiteralType) {
    let urlString = value.url
    //Do whatever URL is doing now, except there’s no need to check for errors since the compiler pre-validated it for us
}

If it’d be more useful, the pattern could be split into multiple pieces:
#literalpatterns += (name: “URLLiteralType”,
                     components: ((name: “`protocol`", type: StringLiteralType, pattern: “(http|https)”),
                                  (name: _, type: StringLiteralType, pattern: “://”),
                                  (name: “domain", type: StringLiteralType, pattern: “(www.)?[a-z|A-Z|0-9]+.(com|org|net)”),
                                  (name: “path”, type: StringLiteralType, pattern: "(/[a-z|A-Z|0-9]+)*(/[a-z|A-Z|0-9]+.[a-z|A-Z|0-9]+)?”))
                     protocol: ExpressibleByURLLiteral)
This would result in URLLiteralType looking like this:
struct URLLiteralType: {
    let `protocol`: StringLiteralType
    let domain: StringLiteralType
    let path: StringLiteralType
}
And in the init would start out like this:
init(urlLiteral value: URLLiteralType) {
    let protocolType = value.protocol
    let domain = value.domain
    let path = value.path
    //Do whatever with the components
}

The “base” types of literals like Int or String that don’t refine pre-existing literal types would still need a bit of compiler magic (or at least a different mechanism for becoming actual types), but as long as a type doesn’t take advantage of reference semantics in its stored properties or something, I *think* pretty much any data type could become “literalizeable” with something like this. Oh, and there’s nothing particularly magical about regular expressions as far as this idea is concerned; they’re just usually the first thing that comes to mind when I think of pattern matching in a string.

I know this looks like a lot of code, but the scary-looking parts with the regex stuff only has to be written once for each “type” of literal… types that want to be expressible by such a literal just have to write an init function.

+1 to Erica’s literal extensions (and Xiaodi’s idea of showing Favicons in Xcode where possible)

Perhaps the easiest way to allow arbitrary literal extensions beyond those would be, in phase 2 when we add RegEx to the language, to take a RegEx defining the custom literal and have the compiler output a tuple of other literal types (including array literals for ‘*’, etc...) to the init method as a result of parsing it.

It would actually be interesting to have the parsing via RegEx into literals as a general feature for parameters, and then the init syntax would fall out basically for free...

Thanks,
Jon

···

On Dec 18, 2016, at 2:17 PM, Erica Sadun via swift-evolution <swift-evolution@swift.org> wrote:

I'd prefer to see a literal URL than a Foundation URL that is string-initializable. I don't see a URL literal as being in any way necessarily tightly coupled with a Foundation URL type. The point of a literal is that it is inherently typeless and checked at compile time. A color literal depending on context can be a UIColor or NSColor but that's not specified outside of the use context. The code is portable and cross platform.

-- E

On Dec 17, 2016, at 10:18 PM, Xiaodi Wu via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

With respect to URL specifically, that it's a Foundation type may change the timeline as well. Various improvements to the Foundation API (and URL in particular) have been proposed here, but if I remember correctly, the stated goal was first to have a complete Swift version of Foundation, preserving the existing API as exactly as possible with no additions or subtractions, and only then to consider Swifty evolution of the APIs. I don't think the first step is complete yet.

On Sat, Dec 17, 2016 at 21:46 Step C via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
Probably worth pointing out that this topic seems entirely additive. Which means it would be at least a phase 2 proposal, if not later.

> On Dec 17, 2016, at 4:44 PM, Micah Hainline via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>
> Yes, everyone who has what they feel like is a solid workable solution should write it up for URL and we can compare and pick holes in them all until we get something really solid.
>
>> On Dec 17, 2016, at 3:27 PM, David Sweeris <davesweeris@mac.com <mailto:davesweeris@mac.com>> wrote:
>>
>>
>>
>> Sent from my iPhone
>>
>>> On Dec 17, 2016, at 13:20, David Sweeris <davesweeris@mac.com <mailto:davesweeris@mac.com>> wrote:
>>>
>>>
>>>
>>> Sent from my iPhone
>>>
>>>> On Dec 17, 2016, at 13:12, Micah Hainline via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>>>>
>>>> I'd love a fleshed out elegant example for URL that shows what a complete implementation of that special init method would look like.
>>>
>>> I can't do it now, but I'll try post one before tomorrow that shows how I'd envision it working.
>>
>> Oh, and to be clear, I'm not trying to "claim" this or anything... if anyone else has ideas, please post them! The more the merrier.

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

I think for me, the big difference between a color literal and URL literal,
which swayed me in the end was this:

As noted in SE-0039, `[#Color(...)#]` (now `#colorLiteral(...)`) isn't
itself a literal; it's a spelling that allows you to _get_ a literal, which
is a swatch of color. On reflection, whether these things ought to be
termed "literals" exactly like strings is something maybe worth revisiting.
They certainly have benefits (_seeing_ a color is nice), but still,
consider how they differ from string literals, etc:

To me at least, `"foo"` _is_ literally a string and `0` is literally an
integer, both of no particular type until it's assigned to a variable,
which is what literals make possible. By the same token, almost any power
user of computers can recognize that `<http://google.com/&gt;\` _is_ literally
a URL and `/regex/` _is_ literally a regular expression. I'll call these
"true literals" for the moment. There are, naturally, a limited number of
true literals in the world, and that upper bound is not an artificial limit
of any programming language. For that reason, I think we ought not be
concerned about "running out" of delimiters.

Even as I continue to believe that a constexpr-like facility might be the
best holistic solution for those who need compile-time validation of custom
types, I can now see that there are grounds to regard a URL as something
special, a true literal for which there is a rational basis for first-class
support from the compiler.

···

On Thu, Dec 29, 2016 at 3:49 PM, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

On Thu, Dec 29, 2016 at 3:18 PM, Micah Hainline <micah.hainline@gmail.com> > wrote:

I think that's all doable. I'm not sure what delimiters would be the
best though, which is why I hadn't moved away from url yet. I've been
thinking hard about the regex, which seems like an even stronger case
to make into a literal, and /abc/ works well for those, but even those
have some problems, as an empty regex (valid according to
NSRegularExpression) of // would parse also as a comment.

True, but I doubt that's a common use case. JavaScript supports `/regex/`
and I haven't heard of complaints re not supporting `//`.

For < and >
it could start getting confusing with overloaded operators. I think it
would work, but could be a little trickier than it seems like on first
blush.

Besides being a natural way of writing it, < and > have the advantage that
resolving their different uses is already heavily tested (because generics
use <>, and because the lexer understands merging artifacts like <<<<<< and
>>>>>>).

It would be easier to lex if it were expressed like
#url<https://example.com>, but ease of lexing probably doesn't weigh
that heavily. If we wanted to do more than string, url, and regex we'd
start running out of delimiters fast though...

To me, that's a feature, not a bug. I'd argue that the language should
provide first-class support for only a few, very important literals (like
strings). Compile time validation for arbitrary types, as I've said before,
should probably be solved in other, more holistic ways (such as some sort
of constexpr-like feature).

Another idea (taking from ruby a little) would be to have something

like %url{https://example.com} and %regex{my/regex}

In ruby, their %r{} structure can take things other than {} as long as
they don't appear in the string (for instance %r@my/regex@ works too),
we could do something like that and have a pretty robust structure for
whatever literals we wanted going forward, and it should work for url
and regex, which are in the more immediate future. Of course, % could
just as easily be #.

We had that before, essentially. Object literals (file, image, color) were
spelled like this: [#Color(...)#]. They were removed with SE-0039.

On Thu, Dec 29, 2016 at 12:37 PM, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

> Micah,
>
> I think I'm coming round to your line of thinking re URL literals. It'd
be
> nice to have them supported first-class, not like image literals (the
design
> for which is really geared towards playgrounds and is rather hacky,
IMO),
> but like strings. In that scenario, Foundation URL would conform to
> ExpressibleByURLLiteral. URL could even be the default URLLiteralType
once
> Foundation is imported (just like String is the default
StringLiteralType).
>
> What'd be _really_ nice, though, is to solidify the first-class status
of
> URL literals by their spelling: not `#urlLiteral(resourceName:
"blahblah")`
> or even `#url("blahblah")`, but just as you write `let str = "this is a
> string"` (and I'm sure we'll have `let regex = /foo/`), we should have
`let
> url = <https://google.com/&gt;\`\. The compiler would ensure that what's
between
> the delimiters is a valid relative or absolute URL, and
`init(urlLiteral:)`
> will get a parsed tuple just as the official standard outlines, with
scheme,
> username, password, host, port, cannot-be-a-base-URL flag, path, query,
> fragment all ready to go. Looking through the lexer, it seems like this
> _should_ be possible and not inordinate amounts of work. Any thoughts
about
> this idea, since you're actively studying the lexer?
>
> Xiaodi
>
>
> On Wed, Dec 28, 2016 at 5:18 PM, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:
>>
>> PR #6503. Turned out to be trivial.
>>
>> On Wed, Dec 28, 2016 at 4:38 PM, Xiaodi Wu <xiaodi.wu@gmail.com> >> wrote:
>>>
>>> Not yet, still building locally. My computer's slow. There's one
problem
>>> that's apparent though. Here's an existing test in the repo:
>>>
>>> ```
>>> LiteralsTestSuite.test("image") {
>>> let image = #imageLiteral(resourceName: NSImageNameComputer)
>>> expectTrue(image.isValid)
>>> }
>>> ```
>>>
>>> Unfortunately, although `NSImageNameComputer` is a constant, it's of
type
>>> `String`. And tweaking global Obj-C bridging rules so that `NSString *
>>> const` comes through as `StaticString` is just not gonna happen,
because of
>>> all the things you'd break. We'll lose this (kinda useful) use of
>>> #imageLiteral unless someone goes ahead and manually bridges the
>>> NSImageName* constants, which is acceptable, I suppose. That someone
would
>>> have to be the Foundation team, because Foundation APIs aren't really
>>> subject to Evolution.
>>>
>>>
>>> On Wed, Dec 28, 2016 at 4:29 PM, Micah Hainline >> >>> <micah.hainline@gmail.com> wrote:
>>>>
>>>> Do you have it checked in somewhere I can see it?
>>>>
>>>> On Wed, Dec 28, 2016 at 2:51 PM, Xiaodi Wu <xiaodi.wu@gmail.com> >> wrote:
>>>> > I may be wrong, but I think I've fixed it. Will test and make sure.
>>>> >
>>>> > On Wed, Dec 28, 2016 at 3:22 PM, Xiaodi Wu <xiaodi.wu@gmail.com> >> >>>> > wrote:
>>>> >>
>>>> >> Well, let's stop that :)
>>>> >>
>>>> >>
>>>> >> On Wed, Dec 28, 2016 at 3:21 PM, Micah Hainline >> >>>> >> <micah.hainline@gmail.com> >> >>>> >> wrote:
>>>> >>>
>>>> >>> Yep, compiles, runs, no warnings or errors and the program
displays
>>>> >>> the expected results.
>>>> >>>
>>>> >>> On Wed, Dec 28, 2016 at 2:12 PM, Micah Hainline >> >>>> >>> <micah.hainline@gmail.com> wrote:
>>>> >>> > Good question. It certainly compiles, but I've stuck it in an
>>>> >>> > out-of-the-way spot, I'll need to create a test project to know
>>>> >>> > the
>>>> >>> > answer to that. Just FYI: Issues · apple/swift-issues · GitHub
SR-3504
>>>> >>> >
>>>> >>> >
>>>> >>> > On Wed, Dec 28, 2016 at 2:11 PM, Xiaodi Wu < >> xiaodi.wu@gmail.com> >> >>>> >>> > wrote:
>>>> >>> >> Does it run?
>>>> >>> >>
>>>> >>> >> On Wed, Dec 28, 2016 at 3:10 PM, Micah Hainline >> >>>> >>> >> <micah.hainline@gmail.com> >> >>>> >>> >> wrote:
>>>> >>> >>>
>>>> >>> >>> I'm doing it in a normal project rather than a playground.
>>>> >>> >>>
>>>> >>> >>> On Wed, Dec 28, 2016 at 1:50 PM, Xiaodi Wu < >> xiaodi.wu@gmail.com> >> >>>> >>> >>> wrote:
>>>> >>> >>> > Offlist--
>>>> >>> >>> >
>>>> >>> >>> > In a playground, I get a runtime error when I move the
string
>>>> >>> >>> > into
>>>> >>> >>> > a
>>>> >>> >>> > variable and write `#fileLiteral(resourceName:
"\(myVar)")`.
>>>> >>> >>> > Could
>>>> >>> >>> > be
>>>> >>> >>> > doing
>>>> >>> >>> > it wrong though.
>>>> >>> >>> >
>>>> >>> >>> > I'll submit a PR to document that users should not use the
>>>> >>> >>> > technically
>>>> >>> >>> > public APIs for literals.
>>>> >>> >>> >
>>>> >>> >>> >
>>>> >>> >>> > On Wed, Dec 28, 2016 at 2:44 PM, Micah Hainline via >> >>>> >>> >>> > swift-evolution >> >>>> >>> >>> > <swift-evolution@swift.org> wrote:
>>>> >>> >>> >>
>>>> >>> >>> >> I think the way it's set up it probably WOULD run, but it
>>>> >>> >>> >> should
>>>> >>> >>> >> still
>>>> >>> >>> >> probably be a compile error. I like that we have the
concept
>>>> >>> >>> >> of
>>>> >>> >>> >> static-string-literal in the language definition, but I'm
>>>> >>> >>> >> having a
>>>> >>> >>> >> bit
>>>> >>> >>> >> of a hard time tracking it through the compiler. Of
course,
>>>> >>> >>> >> these
>>>> >>> >>> >> are
>>>> >>> >>> >> problems probably not right for this list, so I'll take
them
>>>> >>> >>> >> into
>>>> >>> >>> >> a
>>>> >>> >>> >> bug instead.
>>>> >>> >>> >>
>>>> >>> >>> >> On Wed, Dec 28, 2016 at 1:36 PM, Xiaodi Wu >> >>>> >>> >>> >> <xiaodi.wu@gmail.com> >> >>>> >> >>>> >>> >>> >> wrote:
>>>> >>> >>> >> > On Wed, Dec 28, 2016 at 2:29 PM, Micah Hainline via >> >>>> >>> >>> >> > swift-evolution >> >>>> >>> >>> >> > <swift-evolution@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@gmail.com> >> >>>> >>> >>> >> >> wrote:
>>>> >>> >>> >> >> > On Wed, Dec 28, 2016 at 2:08 PM, Micah Hainline via >> >>>> >>> >>> >> >> > swift-evolution >> >>>> >>> >>> >> >> > <swift-evolution@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(fileReferenceLiteralR
esourceName:)
>>>> >>> >>> >> >> >> 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:
>>>> >>> >>> >> >> >
>>>> >>> >>> >> >> >
>>>> >>> >>> >> >> >
>>>> >>> >>> >> >> >
>>>> >>> >>> >> >> >
>>>> >>> >>> >> >> > GitHub - apple/swift: The Swift Programming Language
-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@swift.org> wrote:
>>>> >>> >>> >> >> >> >
>>>> >>> >>> >> >> >> > On Dec 27, 2016, at 11:46 AM, David Sweeris >> >>>> >>> >>> >> >> >> > <davesweeris@mac.com> >> >>>> >>> >>> >> >> >> > wrote:
>>>> >>> >>> >> >> >> >
>>>> >>> >>> >> >> >> >
>>>> >>> >>> >> >> >> > On Dec 22, 2016, at 11:39 PM, Jonathan Hull >> >>>> >>> >>> >> >> >> > <jhull@gbis.com> >> >>>> >>> >>> >> >> >> > wrote:
>>>> >>> >>> >> >> >> >
>>>> >>> >>> >> >> >> >
>>>> >>> >>> >> >> >> > On Dec 20, 2016, at 12:29 PM, David Sweeris >> >>>> >>> >>> >> >> >> > <davesweeris@mac.com> >> >>>> >>> >>> >> >> >> > wrote:
>>>> >>> >>> >> >> >> >
>>>> >>> >>> >> >> >> >
>>>> >>> >>> >> >> >> > On Dec 20, 2016, at 2:11 AM, Jonathan Hull via >> >>>> >>> >>> >> >> >> > swift-evolution >> >>>> >>> >>> >> >> >> > <swift-evolution@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@swift.org
>>>> >>> >>> >> >> >> >
>>>> >>> >>> >> >> >> > https://lists.swift.org/mailma
n/listinfo/swift-evolution
>>>> >>> >>> >> >> >> >
>>>> >>> >>> >> >> >> _______________________________________________
>>>> >>> >>> >> >> >> swift-evolution mailing list
>>>> >>> >>> >> >> >> swift-evolution@swift.org
>>>> >>> >>> >> >> >>
>>>> >>> >>> >> >> >> https://lists.swift.org/mailma
n/listinfo/swift-evolution
>>>> >>> >>> >> >> >
>>>> >>> >>> >> >> >
>>>> >>> >>> >> >> _______________________________________________
>>>> >>> >>> >> >> swift-evolution mailing list
>>>> >>> >>> >> >> swift-evolution@swift.org
>>>> >>> >>> >> >> https://lists.swift.org/mailma
n/listinfo/swift-evolution
>>>> >>> >>> >> >
>>>> >>> >>> >> >
>>>> >>> >>> >> _______________________________________________
>>>> >>> >>> >> swift-evolution mailing list
>>>> >>> >>> >> swift-evolution@swift.org
>>>> >>> >>> >> https://lists.swift.org/mailman/listinfo/swift-evolution
>>>> >>> >>> >
>>>> >>> >>> >
>>>> >>> >>
>>>> >>> >>
>>>> >>
>>>> >>
>>>> >
>>>
>>>
>>
>

Earlier in this thread, I pasted in a draft I discussed on-list (from July 10) about extending literals to include other "universal" typeless concepts including fonts, dates, points, etc but I should have spent a moment discussing why I had dropped that link.

-- E
p.s. For those that missed it:

* earlier discussion: [swift-evolution] [Pitch] Extending Swift Literals
* draft work: literals.md · GitHub

···

On Dec 18, 2016, at 3:52 PM, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

That's a fair point. I suppose we could have, in the same way as file literals,

#urlLiteral(resourceName: "http://example.com <http://example.com/>")

which in an IDE would be automatically generated when someone drops a link and might be rendered as a hyperlink, blue underline and all.

On Sun, Dec 18, 2016 at 16:17 Erica Sadun <erica@ericasadun.com <mailto:erica@ericasadun.com>> wrote:
I'd prefer to see a literal URL than a Foundation URL that is string-initializable. I don't see a URL literal as being in any way necessarily tightly coupled with a Foundation URL type. The point of a literal is that it is inherently typeless and checked at compile time. A color literal depending on context can be a UIColor or NSColor but that's not specified outside of the use context. The code is portable and cross platform.

-- E

On Dec 17, 2016, at 10:18 PM, Xiaodi Wu via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

With respect to URL specifically, that it's a Foundation type may change the timeline as well. Various improvements to the Foundation API (and URL in particular) have been proposed here, but if I remember correctly, the stated goal was first to have a complete Swift version of Foundation, preserving the existing API as exactly as possible with no additions or subtractions, and only then to consider Swifty evolution of the APIs. I don't think the first step is complete yet.

On Sat, Dec 17, 2016 at 21:46 Step C via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
Probably worth pointing out that this topic seems entirely additive. Which means it would be at least a phase 2 proposal, if not later.

> On Dec 17, 2016, at 4:44 PM, Micah Hainline via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

>

> Yes, everyone who has what they feel like is a solid workable solution should write it up for URL and we can compare and pick holes in them all until we get something really solid.

>

>> On Dec 17, 2016, at 3:27 PM, David Sweeris <davesweeris@mac.com <mailto:davesweeris@mac.com>> wrote:

>>

>>

>>

>> Sent from my iPhone

>>

>>> On Dec 17, 2016, at 13:20, David Sweeris <davesweeris@mac.com <mailto:davesweeris@mac.com>> wrote:

>>>

>>>

>>>

>>> Sent from my iPhone

>>>

>>>> On Dec 17, 2016, at 13:12, Micah Hainline via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

>>>>

>>>> I'd love a fleshed out elegant example for URL that shows what a complete implementation of that special init method would look like.

>>>

>>> I can't do it now, but I'll try post one before tomorrow that shows how I'd envision it working.

>>

>> Oh, and to be clear, I'm not trying to "claim" this or anything... if anyone else has ideas, please post them! The more the merrier.

+1 to the sentiment in your last paragraph.

In general, I'm not a very big fan of the #foo(...) syntax for literals and
I think using that as the starting point for discussion biases us towards
those when more general and powerful alternatives could exist. That syntax
exists for Playground support and I'd hate to see it proliferate into
non-playground sources. Furthermore, if the user could write a
compile-time-validating initializer for `URL("http://foo.com/bar&quot;\)` (or
`let url: URL = "http://foo.com/bar&quot;\`\), then that expression becomes just
as much a "literal" as something like `#url("http://foo.com/bar&quot;\)`. There's
no functional difference between the two: both are sequences of tokens that
the compiler can evaluate statically. The benefit is that the end user
doesn't have to worry about the distinction; the compiler picks the
appropriate evaluation automatically depending on whether the initializer
argument is statically known or not.

Taking this a step further, if we can get constexpr-like validation for
initializers like this, then I wonder if the #foo literal syntax needs to
exist at all, and I'd propose that we abandon it and just let the
playground UI and other IDEs transform things like `UIColor(red: 0.5,
green: 0.5, blue: 0.5)` into a swatch when it sees them if they can be
evaluated at compile-time. What you lose is, as Erica mentioned earlier,
the fact that `#colorLiteral(...)` is untyped and can be turned into
multiple color types, but the value already has to be assigned to a
concrete type eventually anyway.

Am I missing any use cases for things like #colorLiteral that doing this
would make difficult or impossible?

···

On Mon, Dec 19, 2016 at 10:53 AM David Sweeris via swift-evolution < swift-evolution@swift.org> wrote:

On Dec 19, 2016, at 1:26 AM, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

URLs are unlikely to be something that can be validated by regex. See, for
instance, this discussion: <
https://webkit.org/blog/7086/url-parsing-in-webkit/&gt;\. The full spec is
here: <https://url.spec.whatwg.org>. If Swift were to implement parsing
of URLs at the level of the compiler or core library, I'd expect it to be
the full spec, as we do with Unicode.

On Mon, Dec 19, 2016 at 2:26 AM, Benjamin Spratling via swift-evolution < > swift-evolution@swift.org> wrote:

Howdy,
Yes, I was also intrigued by the “Regex” validation mentioned in another
post. It could offer a convenient way to get some literals support in
without the headaches associated with the constexpr C++ approach.
I’m curious, though, how many types can we image in can be validated by
this method? If it really is just URL’s, then I’d actually lean towards
making this a compiler magic feature.

Someone else mentioned fetching the URL’s for a preview. Given that we
might be coding “deletes” in URL’s (yes, I recently met a backend developer
who coded a delete as a GET), I really highly suggest we not ping people’s
API’s artificially. At least we shouldn’t for non-file-scheme URLs. IMHO,
verifying that a service is active isn’t really the Swift compiler’s job.
It might happen as part of coordinated run-time tests, which sometimes have
to be balanced to keep test data correct, something the IDE wouldn’t know
how to enforce correctly.
-Ben

On Dec 19, 2016, at 1:41 AM, David Sweeris via swift-evolution < > swift-evolution@swift.org> wrote:

On Dec 17, 2016, at 1:12 PM, Micah Hainline via swift-evolution < > swift-evolution@swift.org> wrote:

I'd love a fleshed out elegant example for URL that shows what a complete
implementation of that special init method would look like.

Sorry this took so long… the weekend kinda got away from me.

Anyway, I was thinking something like this (which has been very simplified
on account of my regexing being sub-sketchy, and me not knowing exactly
what’s valid in an URL anyway):

#literalpatterns += (name: “URLLiteralType”, components: (name: url,
type: StringLiteralType, pattern: “(http|https)://(www.)?[a-z|A-Z|0-9]+
.(com|org|net)(/[a-z|A-Z|0-9]+)*(/[a-z|A-Z|0-9]+.[a-z|A-Z|0-9]+)?”),
protocol: ExpressibleByURLLiteral)

This would let the compiler know pretty much everything it needs to know…
that the “new” type is called “URLLiteralType", that it starts out life as
young StringLiteralType with a bright future in the computer industry, that
in order to succeed it has to match a given pattern, and what protocol a
type has to conform to in order to use an URLLiteral. In practice, the
compiler would synthesize a struct containing the specified members and
validate the literal with the specified pattern before making an “instance”
of it (since we’re talking about literals and compile-time code here, I’m
pretty sure that “instance" the wrong terminology… pardon my ignorance)

struct URLLiteralType: {
    let url: StringLiteralType
}

A tuple would be better, IMHO, but according to the playground,
single-element tuples can’t have element labels. As for the
implementation of the init function:

init(urlLiteral value: URLLiteralType) {
    let urlString = value.url
    //Do whatever URL is doing now, except there’s no need to check for
errors since the compiler pre-validated it for us
}

If it’d be more useful, the pattern could be split into multiple pieces:

#literalpatterns += (name: “URLLiteralType”,
                     components: ((name: “`protocol`", type:
StringLiteralType, pattern: “(http|https)”),
                                  (name: _, type:
StringLiteralType, pattern: “://”),
                                  (name: “domain", type:
StringLiteralType, pattern: “(www.)?[a-z|A-Z|0-9]+.(com|org|net)”),
                                  (name: “path”, type:
StringLiteralType, pattern: "(/[a-z|A-Z|0-9]+)*(/[a-z|A-Z|0-9]+.
[a-z|A-Z|0-9]+)?”))
                     protocol: ExpressibleByURLLiteral)

This would result in URLLiteralType looking like this:

struct URLLiteralType: {
    let `protocol`: StringLiteralType
    let domain: StringLiteralType
    let path: StringLiteralType
}

And in the init would start out like this:

init(urlLiteral value: URLLiteralType) {
    let protocolType = value.protocol
    let domain = value.domain
    let path = value.path
    //Do whatever with the components
}

The “base” types of literals like Int or String that don’t refine
pre-existing literal types would still need a bit of compiler magic (or at
least a different mechanism for becoming actual types), but as long as a
type doesn’t take advantage of reference semantics in its stored properties
or something, I *think* pretty much any data type could become
“literalizeable” with something like this. Oh, and there’s nothing
particularly magical about regular expressions as far as this idea is
concerned; they’re just usually the first thing that comes to mind when I
think of pattern matching in a string.

I know this looks like a lot of code, but the scary-looking parts with the
regex stuff only has to be written once for each “type” of literal… types
that want to be expressible by such a literal just have to write an init
function.

It doesn’t have to be regex per se… instead of
#literalpatterns += (name: “URLLiteralType”, components: (name: url,
type: StringLiteralType, pattern: “(http|https)://(www.)?[a-z|A-Z|0-9]+
.(com|org|net)(/[a-z|A-Z|0-9]+)*(/[a-z|A-Z|0-9]+.[a-z|A-Z|0-9]+)?”),
protocol: ExpressibleByURLLiteral)
I probably should’ve written something more like:
#literalpatterns += (name: “URLLiteralType”, components: (name: url,
type: StringLiteralType, matching: Regex(“(http|https)://
(www.)?[a-z|A-Z|0-9]+.(com|org|net)(/[a-z|A-Z|0-9]+)*(/[a-z|A-Z|0-9]+.
[a-z|A-Z|0-9]+)?”)), protocol: ExpressibleByURLLiteral)
where the `matching` argument can be anything that can (“@purely”-ly) use
some specified mechanism (I’d vote for the ~= operator) with a literal to
test whether it matches. Also, there is no existing `Regex`
struct/class/mechanism in Swift, unless you count `NSRegularExpression`. I
didn’t want to use that for a couple reasons… 1) I don’t think it’s part of
the stdlib, and 2) it doesn’t have a non-failable init that just takes a
string, so using it unmodified would kinda put us in a “it’s turtles all
the way down” kind of situation. What I’d started doing was to look for the
existing mechanism for specifying literals in the compiler so I could use
the existing name for it (somehow I doubt there’s a actually an array of
patterns called “literalpatterns" in the compiler) and copy the existing
methods for specifying a valid literal. After being unsuccessful for some
amount of time, I decided I was getting too tired and made up what I sent
last night.

The more I think about it, the more I’m starting to be of the opinion that
we really ought to have two mechanisms here… One for specifying what
constitutes a “base” literal (like `43`, `[“foo”, “bar”]`, or `true`), and
one for types that merely need to perform some sort of validation on
existing “base” literals. The first mechanism probably should be fairly
arcane and involved, because you’d essentially be able to create new
syntaxes, which *should* be kinda scary and hard to understand because
it’s most certainly not an area beginners should be in. The second
mechanism — something like that `ExpressibleByValidatedStringLiteral`
idea — isn’t nearly as complicated. In the case of URLs, I’d vote the
second approach. We only really need two extra features to implement it
(“@constexpr” and the compiler being able to use the REPL to evaluate
@costexpr statements), and both of them have more uses other than just
getting a few more compile-time checks or allowing for more inits to be
non-failable. With both of those in place, getting an url “literal” becomes
just this:
protocol ExpressibleByValidatedStringLiteral {
    init?(stringLiteral value: StringLiteralType)
}
struct URL : ExpressibleByValidatedStringLiteral {
    //Stuff
    //...
    init?(stringLiteral value: StringLiteralType) {
        //Perform validation here; return nil if it fails
    }
    //...
    //Things
}
var lru: URL = "foo" //Compiler throws this to the init? function, it
returns nil, the compiler raises a syntax error
var url: URL = "http://www.some.valid.url.com" //Compiler throws this to
the init? function, it returns an optional URL, the compiler unwraps it and
does the assignment

I still very much want a way to define custom literals (precisely because
it’d let me make new syntaxes), but I’m starting to think that something
like the second, disappointingly easy idea, is probably the way to go in
this case.

- Dave Sweeris
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Regex is another thing that appears on many platforms and has a standard way to express it.

-- E

···

On Dec 19, 2016, at 5:51 PM, Jonathan Hull <jhull@gbis.com> wrote:

+1 to Erica’s literal extensions (and Xiaodi’s idea of showing Favicons in Xcode where possible)

Perhaps the easiest way to allow arbitrary literal extensions beyond those would be, in phase 2 when we add RegEx to the language, to take a RegEx defining the custom literal and have the compiler output a tuple of other literal types (including array literals for ‘*’, etc...) to the init method as a result of parsing it.

It would actually be interesting to have the parsing via RegEx into literals as a general feature for parameters, and then the init syntax would fall out basically for free...

Thanks,
Jon

On Dec 18, 2016, at 2:17 PM, Erica Sadun via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

I'd prefer to see a literal URL than a Foundation URL that is string-initializable. I don't see a URL literal as being in any way necessarily tightly coupled with a Foundation URL type. The point of a literal is that it is inherently typeless and checked at compile time. A color literal depending on context can be a UIColor or NSColor but that's not specified outside of the use context. The code is portable and cross platform.

-- E

On Dec 17, 2016, at 10:18 PM, Xiaodi Wu via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

With respect to URL specifically, that it's a Foundation type may change the timeline as well. Various improvements to the Foundation API (and URL in particular) have been proposed here, but if I remember correctly, the stated goal was first to have a complete Swift version of Foundation, preserving the existing API as exactly as possible with no additions or subtractions, and only then to consider Swifty evolution of the APIs. I don't think the first step is complete yet.

On Sat, Dec 17, 2016 at 21:46 Step C via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
Probably worth pointing out that this topic seems entirely additive. Which means it would be at least a phase 2 proposal, if not later.

> On Dec 17, 2016, at 4:44 PM, Micah Hainline via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>
> Yes, everyone who has what they feel like is a solid workable solution should write it up for URL and we can compare and pick holes in them all until we get something really solid.
>
>> On Dec 17, 2016, at 3:27 PM, David Sweeris <davesweeris@mac.com <mailto:davesweeris@mac.com>> wrote:
>>
>>
>>
>> Sent from my iPhone
>>
>>> On Dec 17, 2016, at 13:20, David Sweeris <davesweeris@mac.com <mailto:davesweeris@mac.com>> wrote:
>>>
>>>
>>>
>>> Sent from my iPhone
>>>
>>>> On Dec 17, 2016, at 13:12, Micah Hainline via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>>>>
>>>> I'd love a fleshed out elegant example for URL that shows what a complete implementation of that special init method would look like.
>>>
>>> I can't do it now, but I'll try post one before tomorrow that shows how I'd envision it working.
>>
>> Oh, and to be clear, I'm not trying to "claim" this or anything... if anyone else has ideas, please post them! The more the merrier.

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

I was thinking about a possibility to extend the language itself with
custom literals. It should cover quite some stuff including URL, Regex, etc.

Just add an extended operator-ish syntax. Can be done with regular
expressions or similar.

//RegexLiteralDefinition
literal /(.*)/(.*)/ (regex:String, flags:String) -> RegexLiteralProtocol {
//code of construction here
}

//Use
let regex = /myregex/g/

//URLLiteralDefinition
literal u"(.*)" (url:String) -> URLLiteralProtocol {
//code of construction here
}

//use
let url = u"http://swift.org/&quot;

This way we can add more literals later without compiler modifications.

If this gets any support I can create a draft of the spec for the feature.

···

On Tue, 20 Dec 2016 at 6:21 Jonathan Hull via swift-evolution < swift-evolution@swift.org> wrote:

+1 to Erica’s literal extensions (and Xiaodi’s idea of showing Favicons in
Xcode where possible)

Perhaps the easiest way to allow arbitrary literal extensions beyond those
would be, in phase 2 when we add RegEx to the language, to take a RegEx
defining the custom literal and have the compiler output a tuple of other
literal types (including array literals for ‘*’, etc...) to the init method
as a result of parsing it.

It would actually be interesting to have the parsing via RegEx into
literals as a general feature for parameters, and then the init syntax
would fall out basically for free...

Thanks,
Jon

On Dec 18, 2016, at 2:17 PM, Erica Sadun via swift-evolution < > swift-evolution@swift.org> wrote:

I'd prefer to see a literal URL than a Foundation URL that is
string-initializable. I don't see a URL literal as being in any way
necessarily tightly coupled with a Foundation URL type. The point of a
literal is that it is inherently typeless and checked at compile time. A
color literal depending on context can be a UIColor or NSColor but that's
not specified outside of the use context. The code is portable and cross
platform.

-- E

On Dec 17, 2016, at 10:18 PM, Xiaodi Wu via swift-evolution < > swift-evolution@swift.org> wrote:

With respect to URL specifically, that it's a Foundation type may change
the timeline as well. Various improvements to the Foundation API (and URL
in particular) have been proposed here, but if I remember correctly, the
stated goal was first to have a complete Swift version of Foundation,
preserving the existing API as exactly as possible with no additions or
subtractions, and only then to consider Swifty evolution of the APIs. I
don't think the first step is complete yet.

On Sat, Dec 17, 2016 at 21:46 Step C via swift-evolution < > swift-evolution@swift.org> wrote:

Probably worth pointing out that this topic seems entirely additive. Which
means it would be at least a phase 2 proposal, if not later.

> On Dec 17, 2016, at 4:44 PM, Micah Hainline via swift-evolution < > swift-evolution@swift.org> wrote:

>

> Yes, everyone who has what they feel like is a solid workable solution
should write it up for URL and we can compare and pick holes in them all
until we get something really solid.

>

>> On Dec 17, 2016, at 3:27 PM, David Sweeris <davesweeris@mac.com> wrote:

>>

>>

>>

>> Sent from my iPhone

>>

>>> On Dec 17, 2016, at 13:20, David Sweeris <davesweeris@mac.com> wrote:

>>>

>>>

>>>

>>> Sent from my iPhone

>>>

>>>> On Dec 17, 2016, at 13:12, Micah Hainline via swift-evolution < > swift-evolution@swift.org> wrote:

>>>>

>>>> I'd love a fleshed out elegant example for URL that shows what a
complete implementation of that special init method would look like.

>>>

>>> I can't do it now, but I'll try post one before tomorrow that shows
how I'd envision it working.

>>

>> Oh, and to be clear, I'm not trying to "claim" this or anything... if
anyone else has ideas, please post them! The more the merrier.

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________

swift-evolution mailing list

swift-evolution@swift.org

https://lists.swift.org/mailman/listinfo/swift-evolution

With the passage of time, I continue to believe that literals in Swift are
fundamentally valuable because they can, er, literally (or
immediately/WYSIWYG-ly?) show in code something that must otherwise be
interpreted by the human reader and then visualized in the mind's eye, and
they allow users to input these things in a more natural way than text.
(For instance, a color swatch as opposed to RGB numerals, a picture as
opposed to a file path.)

There is no limiting principle to your proposal about 'universal typeless
concepts'; essentially all of Foundation is widely useful (foundational, if
you like, or universal), and since each of these useful classes might be
implemented by another library in a different way, one might wish for all
of these classes to be initializable with a 'typeless' literal. Taken to
its logical conclusion we circle back to a way of evaluating initialization
of any arbitrary class in Foundation or any competing library at compile
time. In fact, for many of the literals you propose, with some minor
changes in syntax the result would be indistinguishable from the
'constexpr' proposal discussed above, and I think the latter would be the
more holistic treatment that permits end users to use the feature for their
own types as well.

What I think you've convinced me of is that--regardless of other
compile-time error-checking facilities--URLs would benefit from the same
treatment as files. Indeed, one thing an IDE could do with a URL literal is
to show the favicon, for instance, for a web page. This would immediately
show a hint to the writer or reader of the code something more than whether
or not their URL is malformed, but also whether at the time of writing it
points to the intended endpoint.

But that's quite enough from me for now--I'll be quiet and let others chime
in on the subject.

···

On Sun, Dec 18, 2016 at 17:59 Erica Sadun <erica@ericasadun.com> wrote:

Earlier in this thread, I pasted in a draft I discussed on-list (from July
10) about extending literals to include other "universal" typeless concepts
including fonts, dates, points, etc but I should have spent a moment
discussing why I had dropped that link.

-- E
p.s. For those that missed it:

* earlier discussion:
[swift-evolution] [Pitch] Extending Swift Literals
* draft work:
literals.md · GitHub

On Dec 18, 2016, at 3:52 PM, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

That's a fair point. I suppose we could have, in the same way as file
literals,

#urlLiteral(resourceName: "http://example.com")

which in an IDE would be automatically generated when someone drops a link
and might be rendered as a hyperlink, blue underline and all.

On Sun, Dec 18, 2016 at 16:17 Erica Sadun <erica@ericasadun.com> wrote:

I'd prefer to see a literal URL than a Foundation URL that is
string-initializable. I don't see a URL literal as being in any way
necessarily tightly coupled with a Foundation URL type. The point of a
literal is that it is inherently typeless and checked at compile time. A
color literal depending on context can be a UIColor or NSColor but that's
not specified outside of the use context. The code is portable and cross
platform.

-- E

On Dec 17, 2016, at 10:18 PM, Xiaodi Wu via swift-evolution < > swift-evolution@swift.org> wrote:

With respect to URL specifically, that it's a Foundation type may change
the timeline as well. Various improvements to the Foundation API (and URL
in particular) have been proposed here, but if I remember correctly, the
stated goal was first to have a complete Swift version of Foundation,
preserving the existing API as exactly as possible with no additions or
subtractions, and only then to consider Swifty evolution of the APIs. I
don't think the first step is complete yet.

On Sat, Dec 17, 2016 at 21:46 Step C via swift-evolution < > swift-evolution@swift.org> wrote:

Probably worth pointing out that this topic seems entirely additive. Which
means it would be at least a phase 2 proposal, if not later.

> On Dec 17, 2016, at 4:44 PM, Micah Hainline via swift-evolution < > swift-evolution@swift.org> wrote:

>

> Yes, everyone who has what they feel like is a solid workable solution
should write it up for URL and we can compare and pick holes in them all
until we get something really solid.

>

>> On Dec 17, 2016, at 3:27 PM, David Sweeris <davesweeris@mac.com> wrote:

>>

>>

>>

>> Sent from my iPhone

>>

>>> On Dec 17, 2016, at 13:20, David Sweeris <davesweeris@mac.com> wrote:

>>>

>>>

>>>

>>> Sent from my iPhone

>>>

>>>> On Dec 17, 2016, at 13:12, Micah Hainline via swift-evolution < > swift-evolution@swift.org> wrote:

>>>>

>>>> I'd love a fleshed out elegant example for URL that shows what a
complete implementation of that special init method would look like.

>>>

>>> I can't do it now, but I'll try post one before tomorrow that shows
how I'd envision it working.

>>

>> Oh, and to be clear, I'm not trying to "claim" this or anything... if
anyone else has ideas, please post them! The more the merrier.

+1 to the sentiment in your last paragraph.

In general, I'm not a very big fan of the #foo(...) syntax for literals and I think using that as the starting point for discussion biases us towards those when more general and powerful alternatives could exist. That syntax exists for Playground support and I'd hate to see it proliferate into non-playground sources.

I like the syntax. I'd like to see more of the syntax. Problem is they stand out in their current definition.

I'm not sure where these platform-independent concepts should go but I don't believe it should be in the standard library or Foundation.

Taking this a step further, if we can get constexpr-like validation for initializers like this, then I wonder if the #foo literal syntax needs to exist at all, and I'd propose that we abandon it and just let the playground UI and other IDEs transform things like `UIColor(red: 0.5, green: 0.5, blue: 0.5)` into a swatch when it sees them if they can be evaluated at compile-time. What you lose is, as Erica mentioned earlier, the fact that `#colorLiteral(...)` is untyped and can be turned into multiple color types, but the value already has to be assigned to a concrete type eventually anyway.

If you don't provide an inferable type, it errors with "Could not infer type of color literal".

Am I missing any use cases for things like #colorLiteral that doing this would make difficult or impossible?

There are issues with wide color vs device color for example. I've assumed that device is presumed. You can create

#colorLiteral(red: 5.1764705926, green: 0.01176470611, blue: -0.5607843399, alpha: 1000)

and this produces with Cocoa and tvOS UIKit:

NSCustomColorSpace sRGB IEC61966-2.1 colorspace 5.17647 0.0117647 -0.560784 1000
UIExtendedSRGBColorSpace 5.17647 0.0117647 -0.560784 1

-- E

···

On Dec 19, 2016, at 12:18 PM, Tony Allevato via swift-evolution <swift-evolution@swift.org> wrote:

On Mon, Dec 19, 2016 at 10:53 AM David Sweeris via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

On Dec 19, 2016, at 1:26 AM, Xiaodi Wu <xiaodi.wu@gmail.com <mailto:xiaodi.wu@gmail.com>> wrote:

URLs are unlikely to be something that can be validated by regex. See, for instance, this discussion: <https://webkit.org/blog/7086/url-parsing-in-webkit/&gt;\. The full spec is here: <https://url.spec.whatwg.org <https://url.spec.whatwg.org/&gt;&gt;\. If Swift were to implement parsing of URLs at the level of the compiler or core library, I'd expect it to be the full spec, as we do with Unicode.

On Mon, Dec 19, 2016 at 2:26 AM, Benjamin Spratling via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
Howdy,
  Yes, I was also intrigued by the “Regex” validation mentioned in another post. It could offer a convenient way to get some literals support in without the headaches associated with the constexpr C++ approach.
  I’m curious, though, how many types can we image in can be validated by this method? If it really is just URL’s, then I’d actually lean towards making this a compiler magic feature.

  Someone else mentioned fetching the URL’s for a preview. Given that we might be coding “deletes” in URL’s (yes, I recently met a backend developer who coded a delete as a GET), I really highly suggest we not ping people’s API’s artificially. At least we shouldn’t for non-file-scheme URLs. IMHO, verifying that a service is active isn’t really the Swift compiler’s job. It might happen as part of coordinated run-time tests, which sometimes have to be balanced to keep test data correct, something the IDE wouldn’t know how to enforce correctly.
-Ben

On Dec 19, 2016, at 1:41 AM, David Sweeris via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

On Dec 17, 2016, at 1:12 PM, Micah Hainline via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

I'd love a fleshed out elegant example for URL that shows what a complete implementation of that special init method would look like.

Sorry this took so long… the weekend kinda got away from me.

Anyway, I was thinking something like this (which has been very simplified on account of my regexing being sub-sketchy, and me not knowing exactly what’s valid in an URL anyway):
#literalpatterns += (name: “URLLiteralType”, components: (name: url, type: StringLiteralType, pattern: “(http|https)://(www.)?[a-z|A-Z|0-9]+.(com|org|net)(/[a-z|A-Z|0-9]+)*(/[a-z|A-Z|0-9]+.[a-z|A-Z|0-9]+)?”), protocol: ExpressibleByURLLiteral)
This would let the compiler know pretty much everything it needs to know… that the “new” type is called “URLLiteralType", that it starts out life as young StringLiteralType with a bright future in the computer industry, that in order to succeed it has to match a given pattern, and what protocol a type has to conform to in order to use an URLLiteral. In practice, the compiler would synthesize a struct containing the specified members and validate the literal with the specified pattern before making an “instance” of it (since we’re talking about literals and compile-time code here, I’m pretty sure that “instance" the wrong terminology… pardon my ignorance)
struct URLLiteralType: {
    let url: StringLiteralType
}
A tuple would be better, IMHO, but according to the playground, single-element tuples can’t have element labels. As for the implementation of the init function:
init(urlLiteral value: URLLiteralType) {
    let urlString = value.url
    //Do whatever URL is doing now, except there’s no need to check for errors since the compiler pre-validated it for us
}

If it’d be more useful, the pattern could be split into multiple pieces:
#literalpatterns += (name: “URLLiteralType”,
                     components: ((name: “`protocol`", type: StringLiteralType, pattern: “(http|https)”),
                                  (name: _, type: StringLiteralType, pattern: “://”),
                                  (name: “domain", type: StringLiteralType, pattern: “(www.)?[a-z|A-Z|0-9]+.(com|org|net)”),
                                  (name: “path”, type: StringLiteralType, pattern: "(/[a-z|A-Z|0-9]+)*(/[a-z|A-Z|0-9]+.[a-z|A-Z|0-9]+)?”))
                     protocol: ExpressibleByURLLiteral)
This would result in URLLiteralType looking like this:
struct URLLiteralType: {
    let `protocol`: StringLiteralType
    let domain: StringLiteralType
    let path: StringLiteralType
}
And in the init would start out like this:
init(urlLiteral value: URLLiteralType) {
    let protocolType = value.protocol
    let domain = value.domain
    let path = value.path
    //Do whatever with the components
}

The “base” types of literals like Int or String that don’t refine pre-existing literal types would still need a bit of compiler magic (or at least a different mechanism for becoming actual types), but as long as a type doesn’t take advantage of reference semantics in its stored properties or something, I *think* pretty much any data type could become “literalizeable” with something like this. Oh, and there’s nothing particularly magical about regular expressions as far as this idea is concerned; they’re just usually the first thing that comes to mind when I think of pattern matching in a string.

I know this looks like a lot of code, but the scary-looking parts with the regex stuff only has to be written once for each “type” of literal… types that want to be expressible by such a literal just have to write an init function.

It doesn’t have to be regex per se… instead of
#literalpatterns += (name: “URLLiteralType”, components: (name: url, type: StringLiteralType, pattern: “(http|https)://(www.)?[a-z|A-Z|0-9]+.(com|org|net)(/[a-z|A-Z|0-9]+)*(/[a-z|A-Z|0-9]+.[a-z|A-Z|0-9]+)?”), protocol: ExpressibleByURLLiteral)
I probably should’ve written something more like:
#literalpatterns += (name: “URLLiteralType”, components: (name: url, type: StringLiteralType, matching: Regex(“(http|https)://(www.)?[a-z|A-Z|0-9]+.(com|org|net)(/[a-z|A-Z|0-9]+)*(/[a-z|A-Z|0-9]+.[a-z|A-Z|0-9]+)?”)), protocol: ExpressibleByURLLiteral)
where the `matching` argument can be anything that can (“@purely”-ly) use some specified mechanism (I’d vote for the ~= operator) with a literal to test whether it matches. Also, there is no existing `Regex` struct/class/mechanism in Swift, unless you count `NSRegularExpression`. I didn’t want to use that for a couple reasons… 1) I don’t think it’s part of the stdlib, and 2) it doesn’t have a non-failable init that just takes a string, so using it unmodified would kinda put us in a “it’s turtles all the way down” kind of situation. What I’d started doing was to look for the existing mechanism for specifying literals in the compiler so I could use the existing name for it (somehow I doubt there’s a actually an array of patterns called “literalpatterns" in the compiler) and copy the existing methods for specifying a valid literal. After being unsuccessful for some amount of time, I decided I was getting too tired and made up what I sent last night.

The more I think about it, the more I’m starting to be of the opinion that we really ought to have two mechanisms here… One for specifying what constitutes a “base” literal (like `43`, `[“foo”, “bar”]`, or `true`), and one for types that merely need to perform some sort of validation on existing “base” literals. The first mechanism probably should be fairly arcane and involved, because you’d essentially be able to create new syntaxes, which should be kinda scary and hard to understand because it’s most certainly not an area beginners should be in. The second mechanism — something like that `ExpressibleByValidatedStringLiteral` idea — isn’t nearly as complicated. In the case of URLs, I’d vote the second approach. We only really need two extra features to implement it (“@constexpr” and the compiler being able to use the REPL to evaluate @costexpr statements), and both of them have more uses other than just getting a few more compile-time checks or allowing for more inits to be non-failable. With both of those in place, getting an url “literal” becomes just this:
protocol ExpressibleByValidatedStringLiteral {
    init?(stringLiteral value: StringLiteralType)
}
struct URL : ExpressibleByValidatedStringLiteral {
    //Stuff
    //...
    init?(stringLiteral value: StringLiteralType) {
        //Perform validation here; return nil if it fails
    }
    //...
    //Things
}
var lru: URL = "foo" //Compiler throws this to the init? function, it returns nil, the compiler raises a syntax error
var url: URL = "http://www.some.valid.url.com <http://www.some.valid.url.com/&gt;&quot; //Compiler throws this to the init? function, it returns an optional URL, the compiler unwraps it and does the assignment

I still very much want a way to define custom literals (precisely because it’d let me make new syntaxes), but I’m starting to think that something like the second, disappointingly easy idea, is probably the way to go in this case.

- Dave Sweeris
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

+1 to the sentiment in your last paragraph.

In general, I'm not a very big fan of the #foo(...) syntax for literals
and I think using that as the starting point for discussion biases us
towards those when more general and powerful alternatives could exist. That
syntax exists for Playground support and I'd hate to see it proliferate
into non-playground sources. Furthermore, if the user could write a
compile-time-validating initializer for `URL("http://foo.com/bar&quot;\)` (or
`let url: URL = "http://foo.com/bar&quot;\`\), then that expression becomes just
as much a "literal" as something like `#url("http://foo.com/bar&quot;\)`.
There's no functional difference between the two: both are sequences of
tokens that the compiler can evaluate statically. The benefit is that the
end user doesn't have to worry about the distinction; the compiler picks
the appropriate evaluation automatically depending on whether the
initializer argument is statically known or not.

+1 to this. If we could mark an initializer for URL as a constexpr that
takes a string literal, then conformance to ExpressibleByStringLiteral
would make `let foo = URL("http://example.com")` work exactly as desired at
compile time, and this is IMO the most elegant solution.

Taking this a step further, if we can get constexpr-like validation for

···

On Mon, Dec 19, 2016 at 1:18 PM, Tony Allevato <allevato@google.com> wrote:

initializers like this, then I wonder if the #foo literal syntax needs to
exist at all, and I'd propose that we abandon it and just let the
playground UI and other IDEs transform things like `UIColor(red: 0.5,
green: 0.5, blue: 0.5)` into a swatch when it sees them if they can be
evaluated at compile-time. What you lose is, as Erica mentioned earlier,
the fact that `#colorLiteral(...)` is untyped and can be turned into
multiple color types, but the value already has to be assigned to a
concrete type eventually anyway.

Am I missing any use cases for things like #colorLiteral that doing this
would make difficult or impossible?

On Mon, Dec 19, 2016 at 10:53 AM David Sweeris via swift-evolution < > swift-evolution@swift.org> wrote:

On Dec 19, 2016, at 1:26 AM, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

URLs are unlikely to be something that can be validated by regex. See,
for instance, this discussion: <URL Parsing in WebKit | WebKit
url-parsing-in-webkit/>. The full spec is here: <
https://url.spec.whatwg.org>. If Swift were to implement parsing of URLs
at the level of the compiler or core library, I'd expect it to be the full
spec, as we do with Unicode.

On Mon, Dec 19, 2016 at 2:26 AM, Benjamin Spratling via swift-evolution < >> swift-evolution@swift.org> wrote:

Howdy,
Yes, I was also intrigued by the “Regex” validation mentioned in another
post. It could offer a convenient way to get some literals support in
without the headaches associated with the constexpr C++ approach.
I’m curious, though, how many types can we image in can be validated by
this method? If it really is just URL’s, then I’d actually lean towards
making this a compiler magic feature.

Someone else mentioned fetching the URL’s for a preview. Given that we
might be coding “deletes” in URL’s (yes, I recently met a backend developer
who coded a delete as a GET), I really highly suggest we not ping people’s
API’s artificially. At least we shouldn’t for non-file-scheme URLs. IMHO,
verifying that a service is active isn’t really the Swift compiler’s job.
It might happen as part of coordinated run-time tests, which sometimes have
to be balanced to keep test data correct, something the IDE wouldn’t know
how to enforce correctly.
-Ben

On Dec 19, 2016, at 1:41 AM, David Sweeris via swift-evolution < >> swift-evolution@swift.org> wrote:

On Dec 17, 2016, at 1:12 PM, Micah Hainline via swift-evolution < >> swift-evolution@swift.org> wrote:

I'd love a fleshed out elegant example for URL that shows what a complete
implementation of that special init method would look like.

Sorry this took so long… the weekend kinda got away from me.

Anyway, I was thinking something like this (which has been very
simplified on account of my regexing being sub-sketchy, and me not knowing
exactly what’s valid in an URL anyway):

#literalpatterns += (name: “URLLiteralType”, components: (name: url,
type: StringLiteralType, pattern: “(http|https)://(www.)?[a-z|A-Z|0-9]+
.(com|org|net)(/[a-z|A-Z|0-9]+)*(/[a-z|A-Z|0-9]+.[a-z|A-Z|0-9]+)?”),
protocol: ExpressibleByURLLiteral)

This would let the compiler know pretty much everything it needs to know…
that the “new” type is called “URLLiteralType", that it starts out life as
young StringLiteralType with a bright future in the computer industry, that
in order to succeed it has to match a given pattern, and what protocol a
type has to conform to in order to use an URLLiteral. In practice, the
compiler would synthesize a struct containing the specified members and
validate the literal with the specified pattern before making an “instance”
of it (since we’re talking about literals and compile-time code here, I’m
pretty sure that “instance" the wrong terminology… pardon my ignorance)

struct URLLiteralType: {
    let url: StringLiteralType
}

A tuple would be better, IMHO, but according to the playground,
single-element tuples can’t have element labels. As for the
implementation of the init function:

init(urlLiteral value: URLLiteralType) {
    let urlString = value.url
    //Do whatever URL is doing now, except there’s no need to check for
errors since the compiler pre-validated it for us
}

If it’d be more useful, the pattern could be split into multiple pieces:

#literalpatterns += (name: “URLLiteralType”,
                     components: ((name: “`protocol`", type:
StringLiteralType, pattern: “(http|https)”),
                                  (name: _, type:
StringLiteralType, pattern: “://”),
                                  (name: “domain", type:
StringLiteralType, pattern: “(www.)?[a-z|A-Z|0-9]+.(com|org|net)”),
                                  (name: “path”, type:
StringLiteralType, pattern: "(/[a-z|A-Z|0-9]+)*(/[a-z|A-Z|0-9]+.
[a-z|A-Z|0-9]+)?”))
                     protocol: ExpressibleByURLLiteral)

This would result in URLLiteralType looking like this:

struct URLLiteralType: {
    let `protocol`: StringLiteralType
    let domain: StringLiteralType
    let path: StringLiteralType
}

And in the init would start out like this:

init(urlLiteral value: URLLiteralType) {
    let protocolType = value.protocol
    let domain = value.domain
    let path = value.path
    //Do whatever with the components
}

The “base” types of literals like Int or String that don’t refine
pre-existing literal types would still need a bit of compiler magic (or at
least a different mechanism for becoming actual types), but as long as a
type doesn’t take advantage of reference semantics in its stored properties
or something, I *think* pretty much any data type could become
“literalizeable” with something like this. Oh, and there’s nothing
particularly magical about regular expressions as far as this idea is
concerned; they’re just usually the first thing that comes to mind when I
think of pattern matching in a string.

I know this looks like a lot of code, but the scary-looking parts with
the regex stuff only has to be written once for each “type” of literal…
types that want to be expressible by such a literal just have to write an
init function.

It doesn’t have to be regex per se… instead of
#literalpatterns += (name: “URLLiteralType”, components: (name: url,
type: StringLiteralType, pattern: “(http|https)://(www.)?[a-z|A-Z|0-9]+
.(com|org|net)(/[a-z|A-Z|0-9]+)*(/[a-z|A-Z|0-9]+.[a-z|A-Z|0-9]+)?”),
protocol: ExpressibleByURLLiteral)
I probably should’ve written something more like:
#literalpatterns += (name: “URLLiteralType”, components: (name: url,
type: StringLiteralType, matching: Regex(“(http|https)://(
www.)?[a-z|A-Z|0-9]+.(com|org|net)(/[a-z|A-Z|0-9]+)*(/[a-z|A-Z|0-9]+.
[a-z|A-Z|0-9]+)?”)), protocol: ExpressibleByURLLiteral)
where the `matching` argument can be anything that can (“@purely”-ly) use
some specified mechanism (I’d vote for the ~= operator) with a literal to
test whether it matches. Also, there is no existing `Regex`
struct/class/mechanism in Swift, unless you count `NSRegularExpression`. I
didn’t want to use that for a couple reasons… 1) I don’t think it’s part of
the stdlib, and 2) it doesn’t have a non-failable init that just takes a
string, so using it unmodified would kinda put us in a “it’s turtles all
the way down” kind of situation. What I’d started doing was to look for the
existing mechanism for specifying literals in the compiler so I could use
the existing name for it (somehow I doubt there’s a actually an array of
patterns called “literalpatterns" in the compiler) and copy the existing
methods for specifying a valid literal. After being unsuccessful for some
amount of time, I decided I was getting too tired and made up what I sent
last night.

The more I think about it, the more I’m starting to be of the opinion
that we really ought to have two mechanisms here… One for specifying what
constitutes a “base” literal (like `43`, `[“foo”, “bar”]`, or `true`), and
one for types that merely need to perform some sort of validation on
existing “base” literals. The first mechanism probably should be fairly
arcane and involved, because you’d essentially be able to create new
syntaxes, which *should* be kinda scary and hard to understand because
it’s most certainly not an area beginners should be in. The second
mechanism — something like that `ExpressibleByValidatedStringLiteral`
idea — isn’t nearly as complicated. In the case of URLs, I’d vote the
second approach. We only really need two extra features to implement it
(“@constexpr” and the compiler being able to use the REPL to evaluate
@costexpr statements), and both of them have more uses other than just
getting a few more compile-time checks or allowing for more inits to be
non-failable. With both of those in place, getting an url “literal” becomes
just this:
protocol ExpressibleByValidatedStringLiteral {
    init?(stringLiteral value: StringLiteralType)
}
struct URL : ExpressibleByValidatedStringLiteral {
    //Stuff
    //...
    init?(stringLiteral value: StringLiteralType) {
        //Perform validation here; return nil if it fails
    }
    //...
    //Things
}
var lru: URL = "foo" //Compiler throws this to the init? function, it
returns nil, the compiler raises a syntax error
var url: URL = "http://www.some.valid.url.com" //Compiler throws this to
the init? function, it returns an optional URL, the compiler unwraps it and
does the assignment

I still very much want a way to define custom literals (precisely because
it’d let me make new syntaxes), but I’m starting to think that something
like the second, disappointingly easy idea, is probably the way to go in
this case.

- Dave Sweeris
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

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.

Thanks,
Jon

···

On Dec 19, 2016, at 8:02 PM, Erica Sadun <erica@ericasadun.com> wrote:

Regex is another thing that appears on many platforms and has a standard way to express it.

-- E

On Dec 19, 2016, at 5:51 PM, Jonathan Hull <jhull@gbis.com <mailto:jhull@gbis.com>> wrote:

+1 to Erica’s literal extensions (and Xiaodi’s idea of showing Favicons in Xcode where possible)

Perhaps the easiest way to allow arbitrary literal extensions beyond those would be, in phase 2 when we add RegEx to the language, to take a RegEx defining the custom literal and have the compiler output a tuple of other literal types (including array literals for ‘*’, etc...) to the init method as a result of parsing it.

It would actually be interesting to have the parsing via RegEx into literals as a general feature for parameters, and then the init syntax would fall out basically for free...

Thanks,
Jon

On Dec 18, 2016, at 2:17 PM, Erica Sadun via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

I'd prefer to see a literal URL than a Foundation URL that is string-initializable. I don't see a URL literal as being in any way necessarily tightly coupled with a Foundation URL type. The point of a literal is that it is inherently typeless and checked at compile time. A color literal depending on context can be a UIColor or NSColor but that's not specified outside of the use context. The code is portable and cross platform.

-- E

On Dec 17, 2016, at 10:18 PM, Xiaodi Wu via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

With respect to URL specifically, that it's a Foundation type may change the timeline as well. Various improvements to the Foundation API (and URL in particular) have been proposed here, but if I remember correctly, the stated goal was first to have a complete Swift version of Foundation, preserving the existing API as exactly as possible with no additions or subtractions, and only then to consider Swifty evolution of the APIs. I don't think the first step is complete yet.

On Sat, Dec 17, 2016 at 21:46 Step C via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
Probably worth pointing out that this topic seems entirely additive. Which means it would be at least a phase 2 proposal, if not later.

> On Dec 17, 2016, at 4:44 PM, Micah Hainline via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>
> Yes, everyone who has what they feel like is a solid workable solution should write it up for URL and we can compare and pick holes in them all until we get something really solid.
>
>> On Dec 17, 2016, at 3:27 PM, David Sweeris <davesweeris@mac.com <mailto:davesweeris@mac.com>> wrote:
>>
>>
>>
>> Sent from my iPhone
>>
>>> On Dec 17, 2016, at 13:20, David Sweeris <davesweeris@mac.com <mailto:davesweeris@mac.com>> wrote:
>>>
>>>
>>>
>>> Sent from my iPhone
>>>
>>>> On Dec 17, 2016, at 13:12, Micah Hainline via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>>>>
>>>> I'd love a fleshed out elegant example for URL that shows what a complete implementation of that special init method would look like.
>>>
>>> I can't do it now, but I'll try post one before tomorrow that shows how I'd envision it working.
>>
>> Oh, and to be clear, I'm not trying to "claim" this or anything... if anyone else has ideas, please post them! The more the merrier.

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

I believe regex was one of the topics that the core team proposed was a
possibility for phase 2. I too am eager to hear what they have in mind.

···

On Mon, Dec 19, 2016 at 23:02 Erica Sadun <erica@ericasadun.com> wrote:

Regex is another thing that appears on many platforms and has a standard
way to express it.

-- E

On Dec 19, 2016, at 5:51 PM, Jonathan Hull <jhull@gbis.com> wrote:

+1 to Erica’s literal extensions (and Xiaodi’s idea of showing Favicons in
Xcode where possible)

Perhaps the easiest way to allow arbitrary literal extensions beyond those
would be, in phase 2 when we add RegEx to the language, to take a RegEx
defining the custom literal and have the compiler output a tuple of other
literal types (including array literals for ‘*’, etc...) to the init method
as a result of parsing it.

It would actually be interesting to have the parsing via RegEx into
literals as a general feature for parameters, and then the init syntax
would fall out basically for free...

Thanks,
Jon

On Dec 18, 2016, at 2:17 PM, Erica Sadun via swift-evolution < > swift-evolution@swift.org> wrote:

I'd prefer to see a literal URL than a Foundation URL that is
string-initializable. I don't see a URL literal as being in any way
necessarily tightly coupled with a Foundation URL type. The point of a
literal is that it is inherently typeless and checked at compile time. A
color literal depending on context can be a UIColor or NSColor but that's
not specified outside of the use context. The code is portable and cross
platform.

-- E

On Dec 17, 2016, at 10:18 PM, Xiaodi Wu via swift-evolution < > swift-evolution@swift.org> wrote:

With respect to URL specifically, that it's a Foundation type may change
the timeline as well. Various improvements to the Foundation API (and URL
in particular) have been proposed here, but if I remember correctly, the
stated goal was first to have a complete Swift version of Foundation,
preserving the existing API as exactly as possible with no additions or
subtractions, and only then to consider Swifty evolution of the APIs. I
don't think the first step is complete yet.

On Sat, Dec 17, 2016 at 21:46 Step C via swift-evolution < > swift-evolution@swift.org> wrote:

Probably worth pointing out that this topic seems entirely additive. Which
means it would be at least a phase 2 proposal, if not later.

> On Dec 17, 2016, at 4:44 PM, Micah Hainline via swift-evolution < > swift-evolution@swift.org> wrote:
>
> Yes, everyone who has what they feel like is a solid workable solution
should write it up for URL and we can compare and pick holes in them all
until we get something really solid.
>
>> On Dec 17, 2016, at 3:27 PM, David Sweeris <davesweeris@mac.com> wrote:
>>
>>
>>
>> Sent from my iPhone
>>
>>> On Dec 17, 2016, at 13:20, David Sweeris <davesweeris@mac.com> wrote:
>>>
>>>
>>>
>>> Sent from my iPhone
>>>
>>>> On Dec 17, 2016, at 13:12, Micah Hainline via swift-evolution < > swift-evolution@swift.org> wrote:
>>>>
>>>> I'd love a fleshed out elegant example for URL that shows what a
complete implementation of that special init method would look like.
>>>
>>> I can't do it now, but I'll try post one before tomorrow that shows
how I'd envision it working.
>>
>> Oh, and to be clear, I'm not trying to "claim" this or anything... if
anyone else has ideas, please post them! The more the merrier.

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Mixfix operators were a possibility sketched out in a recent proposal draft
on operators by Jonathan Shapiro. That would enable custom syntax like you
show here. Not sure if a revision of that draft is still in the works.

···

On Mon, Dec 19, 2016 at 22:37 Daniel Leping via swift-evolution < swift-evolution@swift.org> wrote:

I was thinking about a possibility to extend the language itself with
custom literals. It should cover quite some stuff including URL, Regex, etc.

Just add an extended operator-ish syntax. Can be done with regular
expressions or similar.

//RegexLiteralDefinition
literal /(.*)/(.*)/ (regex:String, flags:String) -> RegexLiteralProtocol {
//code of construction here
}

//Use
let regex = /myregex/g/

//URLLiteralDefinition
literal u"(.*)" (url:String) -> URLLiteralProtocol {
//code of construction here
}

//use
let url = u"http://swift.org/&quot;

This way we can add more literals later without compiler modifications.

If this gets any support I can create a draft of the spec for the feature.

On Tue, 20 Dec 2016 at 6:21 Jonathan Hull via swift-evolution < > swift-evolution@swift.org> wrote:

+1 to Erica’s literal extensions (and Xiaodi’s idea of showing Favicons in
Xcode where possible)

Perhaps the easiest way to allow arbitrary literal extensions beyond those
would be, in phase 2 when we add RegEx to the language, to take a RegEx
defining the custom literal and have the compiler output a tuple of other
literal types (including array literals for ‘*’, etc...) to the init method
as a result of parsing it.

It would actually be interesting to have the parsing via RegEx into
literals as a general feature for parameters, and then the init syntax
would fall out basically for free...

Thanks,
Jon

On Dec 18, 2016, at 2:17 PM, Erica Sadun via swift-evolution < > swift-evolution@swift.org> wrote:

I'd prefer to see a literal URL than a Foundation URL that is
string-initializable. I don't see a URL literal as being in any way
necessarily tightly coupled with a Foundation URL type. The point of a
literal is that it is inherently typeless and checked at compile time. A
color literal depending on context can be a UIColor or NSColor but that's
not specified outside of the use context. The code is portable and cross
platform.

-- E

On Dec 17, 2016, at 10:18 PM, Xiaodi Wu via swift-evolution < > swift-evolution@swift.org> wrote:

With respect to URL specifically, that it's a Foundation type may change
the timeline as well. Various improvements to the Foundation API (and URL
in particular) have been proposed here, but if I remember correctly, the
stated goal was first to have a complete Swift version of Foundation,
preserving the existing API as exactly as possible with no additions or
subtractions, and only then to consider Swifty evolution of the APIs. I
don't think the first step is complete yet.

On Sat, Dec 17, 2016 at 21:46 Step C via swift-evolution < > swift-evolution@swift.org> wrote:

Probably worth pointing out that this topic seems entirely additive. Which
means it would be at least a phase 2 proposal, if not later.

> On Dec 17, 2016, at 4:44 PM, Micah Hainline via swift-evolution < > swift-evolution@swift.org> wrote:

>

> Yes, everyone who has what they feel like is a solid workable solution
should write it up for URL and we can compare and pick holes in them all
until we get something really solid.

>

>> On Dec 17, 2016, at 3:27 PM, David Sweeris <davesweeris@mac.com> wrote:

>>

>>

>>

>> Sent from my iPhone

>>

>>> On Dec 17, 2016, at 13:20, David Sweeris <davesweeris@mac.com> wrote:

>>>

>>>

>>>

>>> Sent from my iPhone

>>>

>>>> On Dec 17, 2016, at 13:12, Micah Hainline via swift-evolution < > swift-evolution@swift.org> wrote:

>>>>

>>>> I'd love a fleshed out elegant example for URL that shows what a
complete implementation of that special init method would look like.

>>>

>>> I can't do it now, but I'll try post one before tomorrow that shows
how I'd envision it working.

>>

>> Oh, and to be clear, I'm not trying to "claim" this or anything... if
anyone else has ideas, please post them! The more the merrier.

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________

swift-evolution mailing list

swift-evolution@swift.org

https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________

swift-evolution mailing list

swift-evolution@swift.org

https://lists.swift.org/mailman/listinfo/swift-evolution

I personally would like something that lived outside the standard library and outside the immediate compiler. I don't think the color, file, and image literals that exist really should be part of core Swift. But I also don't think they should be Foundation either. I also would prefer something extensible (like customizable attributes) but that had a bar of community support to be added (CoreLiteral). :)

-- E

···

On Dec 18, 2016, at 6:56 PM, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

With the passage of time, I continue to believe that literals in Swift are fundamentally valuable because they can, er, literally (or immediately/WYSIWYG-ly?) show in code something that must otherwise be interpreted by the human reader and then visualized in the mind's eye, and they allow users to input these things in a more natural way than text. (For instance, a color swatch as opposed to RGB numerals, a picture as opposed to a file path.)

There is no limiting principle to your proposal about 'universal typeless concepts'; essentially all of Foundation is widely useful (foundational, if you like, or universal), and since each of these useful classes might be implemented by another library in a different way, one might wish for all of these classes to be initializable with a 'typeless' literal. Taken to its logical conclusion we circle back to a way of evaluating initialization of any arbitrary class in Foundation or any competing library at compile time. In fact, for many of the literals you propose, with some minor changes in syntax the result would be indistinguishable from the 'constexpr' proposal discussed above, and I think the latter would be the more holistic treatment that permits end users to use the feature for their own types as well.

What I think you've convinced me of is that--regardless of other compile-time error-checking facilities--URLs would benefit from the same treatment as files. Indeed, one thing an IDE could do with a URL literal is to show the favicon, for instance, for a web page. This would immediately show a hint to the writer or reader of the code something more than whether or not their URL is malformed, but also whether at the time of writing it points to the intended endpoint.

But that's quite enough from me for now--I'll be quiet and let others chime in on the subject.

On Sun, Dec 18, 2016 at 17:59 Erica Sadun <erica@ericasadun.com <mailto:erica@ericasadun.com>> wrote:
Earlier in this thread, I pasted in a draft I discussed on-list (from July 10) about extending literals to include other "universal" typeless concepts including fonts, dates, points, etc but I should have spent a moment discussing why I had dropped that link.

-- E
p.s. For those that missed it:

* earlier discussion: [swift-evolution] [Pitch] Extending Swift Literals
* draft work: literals.md · GitHub

On Dec 18, 2016, at 3:52 PM, Xiaodi Wu <xiaodi.wu@gmail.com <mailto:xiaodi.wu@gmail.com>> wrote:

That's a fair point. I suppose we could have, in the same way as file literals,

#urlLiteral(resourceName: "http://example.com <http://example.com/>")

which in an IDE would be automatically generated when someone drops a link and might be rendered as a hyperlink, blue underline and all.

On Sun, Dec 18, 2016 at 16:17 Erica Sadun <erica@ericasadun.com <mailto:erica@ericasadun.com>> wrote:
I'd prefer to see a literal URL than a Foundation URL that is string-initializable. I don't see a URL literal as being in any way necessarily tightly coupled with a Foundation URL type. The point of a literal is that it is inherently typeless and checked at compile time. A color literal depending on context can be a UIColor or NSColor but that's not specified outside of the use context. The code is portable and cross platform.

-- E

On Dec 17, 2016, at 10:18 PM, Xiaodi Wu via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

With respect to URL specifically, that it's a Foundation type may change the timeline as well. Various improvements to the Foundation API (and URL in particular) have been proposed here, but if I remember correctly, the stated goal was first to have a complete Swift version of Foundation, preserving the existing API as exactly as possible with no additions or subtractions, and only then to consider Swifty evolution of the APIs. I don't think the first step is complete yet.

On Sat, Dec 17, 2016 at 21:46 Step C via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
Probably worth pointing out that this topic seems entirely additive. Which means it would be at least a phase 2 proposal, if not later.

> On Dec 17, 2016, at 4:44 PM, Micah Hainline via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

>

> Yes, everyone who has what they feel like is a solid workable solution should write it up for URL and we can compare and pick holes in them all until we get something really solid.

>

>> On Dec 17, 2016, at 3:27 PM, David Sweeris <davesweeris@mac.com <mailto:davesweeris@mac.com>> wrote:

>>

>>

>>

>> Sent from my iPhone

>>

>>> On Dec 17, 2016, at 13:20, David Sweeris <davesweeris@mac.com <mailto:davesweeris@mac.com>> wrote:

>>>

>>>

>>>

>>> Sent from my iPhone

>>>

>>>> On Dec 17, 2016, at 13:12, Micah Hainline via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

>>>>

>>>> I'd love a fleshed out elegant example for URL that shows what a complete implementation of that special init method would look like.

>>>

>>> I can't do it now, but I'll try post one before tomorrow that shows how I'd envision it working.

>>

>> Oh, and to be clear, I'm not trying to "claim" this or anything... if anyone else has ideas, please post them! The more the merrier.

+1 to the sentiment in your last paragraph.

In general, I'm not a very big fan of the #foo(...) syntax for literals
and I think using that as the starting point for discussion biases us
towards those when more general and powerful alternatives could exist. That
syntax exists for Playground support and I'd hate to see it proliferate
into non-playground sources. Furthermore, if the user could write a
compile-time-validating initializer for `URL("http://foo.com/bar&quot;\)` (or
`let url: URL = "http://foo.com/bar&quot;\`\), then that expression becomes
just as much a "literal" as something like `#url("http://foo.com/bar&quot;\)`.
There's no functional difference between the two: both are sequences of
tokens that the compiler can evaluate statically. The benefit is that the
end user doesn't have to worry about the distinction; the compiler picks
the appropriate evaluation automatically depending on whether the
initializer argument is statically known or not.

+1 to this. If we could mark an initializer for URL as a constexpr that
takes a string literal, then conformance to ExpressibleByStringLiteral
would make `let foo = URL("http://example.com")`

Rather, I meant `let foo: URL = "http://example.com"`.

···

On Mon, Dec 19, 2016 at 1:40 PM, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

On Mon, Dec 19, 2016 at 1:18 PM, Tony Allevato <allevato@google.com> > wrote:

work exactly as desired at compile time, and this is IMO the most elegant
solution.

Taking this a step further, if we can get constexpr-like validation for

initializers like this, then I wonder if the #foo literal syntax needs to
exist at all, and I'd propose that we abandon it and just let the
playground UI and other IDEs transform things like `UIColor(red: 0.5,
green: 0.5, blue: 0.5)` into a swatch when it sees them if they can be
evaluated at compile-time. What you lose is, as Erica mentioned earlier,
the fact that `#colorLiteral(...)` is untyped and can be turned into
multiple color types, but the value already has to be assigned to a
concrete type eventually anyway.

Am I missing any use cases for things like #colorLiteral that doing this
would make difficult or impossible?

On Mon, Dec 19, 2016 at 10:53 AM David Sweeris via swift-evolution < >> swift-evolution@swift.org> wrote:

On Dec 19, 2016, at 1:26 AM, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

URLs are unlikely to be something that can be validated by regex. See,
for instance, this discussion: <URL Parsing in WebKit | WebKit
url-parsing-in-webkit/>. The full spec is here: <
https://url.spec.whatwg.org>. If Swift were to implement parsing of
URLs at the level of the compiler or core library, I'd expect it to be the
full spec, as we do with Unicode.

On Mon, Dec 19, 2016 at 2:26 AM, Benjamin Spratling via swift-evolution >>> <swift-evolution@swift.org> wrote:

Howdy,
Yes, I was also intrigued by the “Regex” validation mentioned in another
post. It could offer a convenient way to get some literals support in
without the headaches associated with the constexpr C++ approach.
I’m curious, though, how many types can we image in can be validated by
this method? If it really is just URL’s, then I’d actually lean towards
making this a compiler magic feature.

Someone else mentioned fetching the URL’s for a preview. Given that we
might be coding “deletes” in URL’s (yes, I recently met a backend developer
who coded a delete as a GET), I really highly suggest we not ping people’s
API’s artificially. At least we shouldn’t for non-file-scheme URLs. IMHO,
verifying that a service is active isn’t really the Swift compiler’s job.
It might happen as part of coordinated run-time tests, which sometimes have
to be balanced to keep test data correct, something the IDE wouldn’t know
how to enforce correctly.
-Ben

On Dec 19, 2016, at 1:41 AM, David Sweeris via swift-evolution < >>> swift-evolution@swift.org> wrote:

On Dec 17, 2016, at 1:12 PM, Micah Hainline via swift-evolution < >>> swift-evolution@swift.org> wrote:

I'd love a fleshed out elegant example for URL that shows what a
complete implementation of that special init method would look like.

Sorry this took so long… the weekend kinda got away from me.

Anyway, I was thinking something like this (which has been very
simplified on account of my regexing being sub-sketchy, and me not knowing
exactly what’s valid in an URL anyway):

#literalpatterns += (name: “URLLiteralType”, components: (name: url,
type: StringLiteralType, pattern: “(http|https)://(www.)?[a-z|A-Z|0-9]+
.(com|org|net)(/[a-z|A-Z|0-9]+)*(/[a-z|A-Z|0-9]+.[a-z|A-Z|0-9]+)?”),
protocol: ExpressibleByURLLiteral)

This would let the compiler know pretty much everything it needs to
know… that the “new” type is called “URLLiteralType", that it starts out
life as young StringLiteralType with a bright future in the computer
industry, that in order to succeed it has to match a given pattern, and
what protocol a type has to conform to in order to use an URLLiteral. In
practice, the compiler would synthesize a struct containing the specified
members and validate the literal with the specified pattern before making
an “instance” of it (since we’re talking about literals and compile-time
code here, I’m pretty sure that “instance" the wrong terminology… pardon my
ignorance)

struct URLLiteralType: {
    let url: StringLiteralType
}

A tuple would be better, IMHO, but according to the playground,
single-element tuples can’t have element labels. As for the
implementation of the init function:

init(urlLiteral value: URLLiteralType) {
    let urlString = value.url
    //Do whatever URL is doing now, except there’s no need to check for
errors since the compiler pre-validated it for us
}

If it’d be more useful, the pattern could be split into multiple pieces:

#literalpatterns += (name: “URLLiteralType”,
                     components: ((name: “`protocol`", type:
StringLiteralType, pattern: “(http|https)”),
                                  (name: _, type:
StringLiteralType, pattern: “://”),
                                  (name: “domain", type:
StringLiteralType, pattern: “(www.)?[a-z|A-Z|0-9]+.(com|org|net)”),
                                  (name: “path”, type:
StringLiteralType, pattern: "(/[a-z|A-Z|0-9]+)*(/[a-z|A-Z|0-9]+.
[a-z|A-Z|0-9]+)?”))
                     protocol: ExpressibleByURLLiteral)

This would result in URLLiteralType looking like this:

struct URLLiteralType: {
    let `protocol`: StringLiteralType
    let domain: StringLiteralType
    let path: StringLiteralType
}

And in the init would start out like this:

init(urlLiteral value: URLLiteralType) {
    let protocolType = value.protocol
    let domain = value.domain
    let path = value.path
    //Do whatever with the components
}

The “base” types of literals like Int or String that don’t refine
pre-existing literal types would still need a bit of compiler magic (or at
least a different mechanism for becoming actual types), but as long as
a type doesn’t take advantage of reference semantics in its stored
properties or something, I *think* pretty much any data type could become
“literalizeable” with something like this. Oh, and there’s nothing
particularly magical about regular expressions as far as this idea is
concerned; they’re just usually the first thing that comes to mind when I
think of pattern matching in a string.

I know this looks like a lot of code, but the scary-looking parts with
the regex stuff only has to be written once for each “type” of literal…
types that want to be expressible by such a literal just have to write an
init function.

It doesn’t have to be regex per se… instead of
#literalpatterns += (name: “URLLiteralType”, components: (name: url,
type: StringLiteralType, pattern: “(http|https)://(www.)?[a-z|A-Z|0-9]+
.(com|org|net)(/[a-z|A-Z|0-9]+)*(/[a-z|A-Z|0-9]+.[a-z|A-Z|0-9]+)?”),
protocol: ExpressibleByURLLiteral)
I probably should’ve written something more like:
#literalpatterns += (name: “URLLiteralType”, components: (name: url,
type: StringLiteralType, matching: Regex(“(http|https)://(ww
w.)?[a-z|A-Z|0-9]+.(com|org|net)(/[a-z|A-Z|0-9]+)*(/[a-z|A-Z|0-9]+.
[a-z|A-Z|0-9]+)?”)), protocol: ExpressibleByURLLiteral)
where the `matching` argument can be anything that can (“@purely”-ly)
use some specified mechanism (I’d vote for the ~= operator) with a literal
to test whether it matches. Also, there is no existing `Regex`
struct/class/mechanism in Swift, unless you count `NSRegularExpression`. I
didn’t want to use that for a couple reasons… 1) I don’t think it’s part of
the stdlib, and 2) it doesn’t have a non-failable init that just takes a
string, so using it unmodified would kinda put us in a “it’s turtles all
the way down” kind of situation. What I’d started doing was to look for the
existing mechanism for specifying literals in the compiler so I could use
the existing name for it (somehow I doubt there’s a actually an array of
patterns called “literalpatterns" in the compiler) and copy the existing
methods for specifying a valid literal. After being unsuccessful for some
amount of time, I decided I was getting too tired and made up what I sent
last night.

The more I think about it, the more I’m starting to be of the opinion
that we really ought to have two mechanisms here… One for specifying what
constitutes a “base” literal (like `43`, `[“foo”, “bar”]`, or `true`), and
one for types that merely need to perform some sort of validation on
existing “base” literals. The first mechanism probably should be fairly
arcane and involved, because you’d essentially be able to create new
syntaxes, which *should* be kinda scary and hard to understand because
it’s most certainly not an area beginners should be in. The second
mechanism — something like that `ExpressibleByValidatedStringLiteral`
idea — isn’t nearly as complicated. In the case of URLs, I’d vote the
second approach. We only really need two extra features to implement it
(“@constexpr” and the compiler being able to use the REPL to evaluate
@costexpr statements), and both of them have more uses other than just
getting a few more compile-time checks or allowing for more inits to be
non-failable. With both of those in place, getting an url “literal” becomes
just this:
protocol ExpressibleByValidatedStringLiteral {
    init?(stringLiteral value: StringLiteralType)
}
struct URL : ExpressibleByValidatedStringLiteral {
    //Stuff
    //...
    init?(stringLiteral value: StringLiteralType) {
        //Perform validation here; return nil if it fails
    }
    //...
    //Things
}
var lru: URL = "foo" //Compiler throws this to the init? function, it
returns nil, the compiler raises a syntax error
var url: URL = "http://www.some.valid.url.com" //Compiler throws this
to the init? function, it returns an optional URL, the compiler unwraps it
and does the assignment

I still very much want a way to define custom literals (precisely
because it’d let me make new syntaxes), but I’m starting to think that
something like the second, disappointingly easy idea, is probably the way
to go in this case.

- Dave Sweeris
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution