[swift-evolution] URL Literals

Xiaodi Wu xiaodi.wu at gmail.com
Mon Dec 19 03:26:16 CST 2016


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/>. 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 at 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 at swift.org> wrote:
>
>
> On Dec 17, 2016, at 1:12 PM, Micah Hainline via swift-evolution <
> swift-evolution at 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 at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
>
>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20161219/614cea5e/attachment.html>


More information about the swift-evolution mailing list