URL Literals


(Micah Hainline) #1

I would like to be able to create a URL literal that is compile-time
checked for correct format. This would help avoid code like this:

    let url: URL = URL(string: "https://example.com")!

The cleanest way I can think of doing that would be to introduce a new
macro structure similar to #selector, though I'm open to other ideas.
I would think it should take a quoted literal string to avoid
problems. That would look like this:

    let url: URL = #url("https://example.com")

What does everyone think of that idea?


(Charles Srstka) #2

I’d like to see something like that for file path URLs. For something so commonly used, URL(fileURLWithPath:) is obnoxiously verbose.

Charles

···

On Dec 16, 2016, at 2:46 PM, Micah Hainline via swift-evolution <swift-evolution@swift.org> wrote:

I would like to be able to create a URL literal that is compile-time
checked for correct format. This would help avoid code like this:

   let url: URL = URL(string: "https://example.com")!

The cleanest way I can think of doing that would be to introduce a new
macro structure similar to #selector, though I'm open to other ideas.
I would think it should take a quoted literal string to avoid
problems. That would look like this:

   let url: URL = #url("https://example.com")

What does everyone think of that idea?
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(David Sweeris) #3

I would like to be able to create a URL literal that is compile-time
checked for correct format. This would help avoid code like this:

   let url: URL = URL(string: "https://example.com")!

The cleanest way I can think of doing that would be to introduce a new
macro structure similar to #selector, though I'm open to other ideas.
I would think it should take a quoted literal string to avoid
problems. That would look like this:

   let url: URL = #url("https://example.com")

What does everyone think of that idea?

I'd rather see the literal validation happen without special call-site syntax, like this:
    let url: URL = "https://example.com"

And move all the pseudo-magic to a user-definable "ExpressibleByURLLiteral" (in this case) protocol, which itself contains the validation mechanism, be it regex, compiler functions, pure functions, or something else.

- Dave Sweeris

···

Sent from my iPhone

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


(Micah Hainline) #4

Charles,

There's already something like that for file URLs in a playground,
though I'm not sure about compile-time checking or how that might work
outside of playgrounds.

https://lists.swift.org/pipermail/swift-evolution-announce/2016-March/000060.html

Of course, my proposal would work fine for file URLs, just not for
turning file paths INTO URLs.

···

On Fri, Dec 16, 2016 at 3:05 PM, Charles Srstka <cocoadev@charlessoft.com> wrote:

On Dec 16, 2016, at 2:46 PM, Micah Hainline via swift-evolution <swift-evolution@swift.org> wrote:

I would like to be able to create a URL literal that is compile-time
checked for correct format. This would help avoid code like this:

   let url: URL = URL(string: "https://example.com")!

The cleanest way I can think of doing that would be to introduce a new
macro structure similar to #selector, though I'm open to other ideas.
I would think it should take a quoted literal string to avoid
problems. That would look like this:

   let url: URL = #url("https://example.com")

What does everyone think of that idea?
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

I’d like to see something like that for file path URLs. For something so commonly used, URL(fileURLWithPath:) is obnoxiously verbose.

Charles


(Charlie Monroe) #5

I would like to be able to create a URL literal that is compile-time
checked for correct format. This would help avoid code like this:

  let url: URL = URL(string: "https://example.com")!

The cleanest way I can think of doing that would be to introduce a new
macro structure similar to #selector, though I'm open to other ideas.
I would think it should take a quoted literal string to avoid
problems. That would look like this:

  let url: URL = #url("https://example.com")

What does everyone think of that idea?
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

I’d like to see something like that for file path URLs. For something so commonly used, URL(fileURLWithPath:) is obnoxiously verbose.

Charles

Yes, but it's not a nullable initializer. With URL(string:) the incredible pain is that even compile-time URLs to your own website are nullable URL? and you need to force-unwrap them.

···

On Dec 16, 2016, at 10:05 PM, Charles Srstka via swift-evolution <swift-evolution@swift.org> wrote:

On Dec 16, 2016, at 2:46 PM, Micah Hainline via swift-evolution <swift-evolution@swift.org> wrote:

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


(Erica Sadun) #6

Take a peek at this: https://gist.github.com/erica/c92f6ab115af89d5c4b9161487df6a3c

--E

···

On Dec 16, 2016, at 2:58 PM, Micah Hainline via swift-evolution <swift-evolution@swift.org> wrote:

Charles,

There's already something like that for file URLs in a playground,
though I'm not sure about compile-time checking or how that might work
outside of playgrounds.

https://lists.swift.org/pipermail/swift-evolution-announce/2016-March/000060.html

Of course, my proposal would work fine for file URLs, just not for
turning file paths INTO URLs.

On Fri, Dec 16, 2016 at 3:05 PM, Charles Srstka > <cocoadev@charlessoft.com> wrote:

On Dec 16, 2016, at 2:46 PM, Micah Hainline via swift-evolution <swift-evolution@swift.org> wrote:

I would like to be able to create a URL literal that is compile-time
checked for correct format. This would help avoid code like this:

  let url: URL = URL(string: "https://example.com")!

The cleanest way I can think of doing that would be to introduce a new
macro structure similar to #selector, though I'm open to other ideas.
I would think it should take a quoted literal string to avoid
problems. That would look like this:

  let url: URL = #url("https://example.com")

What does everyone think of that idea?
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

I’d like to see something like that for file path URLs. For something so commonly used, URL(fileURLWithPath:) is obnoxiously verbose.

Charles

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


(Micah Hainline) #7

Exactly! It's not an earth-shattering pain, but it would be nice to have clean type safety there.

···

On Dec 16, 2016, at 4:01 PM, Charlie Monroe <charlie@charliemonroe.net> wrote:

On Dec 16, 2016, at 10:05 PM, Charles Srstka via swift-evolution <swift-evolution@swift.org> wrote:

On Dec 16, 2016, at 2:46 PM, Micah Hainline via swift-evolution <swift-evolution@swift.org> wrote:

I would like to be able to create a URL literal that is compile-time
checked for correct format. This would help avoid code like this:

let url: URL = URL(string: "https://example.com")!

The cleanest way I can think of doing that would be to introduce a new
macro structure similar to #selector, though I'm open to other ideas.
I would think it should take a quoted literal string to avoid
problems. That would look like this:

let url: URL = #url("https://example.com")

What does everyone think of that idea?
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

I’d like to see something like that for file path URLs. For something so commonly used, URL(fileURLWithPath:) is obnoxiously verbose.

Charles

Yes, but it's not a nullable initializer. With URL(string:) the incredible pain is that even compile-time URLs to your own website are nullable URL? and you need to force-unwrap them.

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


(Derrick Ho) #8

let url = URL(string: "https://example.com")!

let url = #url("https://example.com")

Are not that different in length. It really isn't saving you much.

I suppose you can try overloading an operator to get something to the
effect you want.

···

On Fri, Dec 16, 2016 at 6:19 PM Micah Hainline via swift-evolution < swift-evolution@swift.org> wrote:

Exactly! It's not an earth-shattering pain, but it would be nice to have
clean type safety there.

> On Dec 16, 2016, at 4:01 PM, Charlie Monroe <charlie@charliemonroe.net> > wrote:
>
>
>>> On Dec 16, 2016, at 10:05 PM, Charles Srstka via swift-evolution < > swift-evolution@swift.org> wrote:
>>>
>>> On Dec 16, 2016, at 2:46 PM, Micah Hainline via swift-evolution < > swift-evolution@swift.org> wrote:
>>>
>>> I would like to be able to create a URL literal that is compile-time
>>> checked for correct format. This would help avoid code like this:
>>>
>>> let url: URL = URL(string: "https://example.com")!
>>>
>>> The cleanest way I can think of doing that would be to introduce a new
>>> macro structure similar to #selector, though I'm open to other ideas.
>>> I would think it should take a quoted literal string to avoid
>>> problems. That would look like this:
>>>
>>> let url: URL = #url("https://example.com")
>>>
>>> What does everyone think of that idea?
>>> _______________________________________________
>>> swift-evolution mailing list
>>> swift-evolution@swift.org
>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>
>>
>> I’d like to see something like that for file path URLs. For something
so commonly used, URL(fileURLWithPath:) is obnoxiously verbose.
>>
>> Charles
>
> Yes, but it's not a nullable initializer. With URL(string:) the
incredible pain is that even compile-time URLs to your own website are
nullable URL? and you need to force-unwrap them.
>
>>
>> _______________________________________________
>> 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


(Micah Hainline) #9

True, but it's not at all about brevity, it's about type-safety and getting compile-time checking rather than runtime checking of the validity of the URL structure.

···

On Dec 16, 2016, at 5:50 PM, Derrick Ho <wh1pch81n@gmail.com> wrote:

let url = URL(string: "https://example.com")!

let url = #url("https://example.com")

Are not that different in length. It really isn't saving you much.

I suppose you can try overloading an operator to get something to the effect you want.

On Fri, Dec 16, 2016 at 6:19 PM Micah Hainline via swift-evolution <swift-evolution@swift.org> wrote:
Exactly! It's not an earth-shattering pain, but it would be nice to have clean type safety there.

> On Dec 16, 2016, at 4:01 PM, Charlie Monroe <charlie@charliemonroe.net> wrote:
>
>
>>> On Dec 16, 2016, at 10:05 PM, Charles Srstka via swift-evolution <swift-evolution@swift.org> wrote:
>>>
>>> On Dec 16, 2016, at 2:46 PM, Micah Hainline via swift-evolution <swift-evolution@swift.org> wrote:
>>>
>>> I would like to be able to create a URL literal that is compile-time
>>> checked for correct format. This would help avoid code like this:
>>>
>>> let url: URL = URL(string: "https://example.com")!
>>>
>>> The cleanest way I can think of doing that would be to introduce a new
>>> macro structure similar to #selector, though I'm open to other ideas.
>>> I would think it should take a quoted literal string to avoid
>>> problems. That would look like this:
>>>
>>> let url: URL = #url("https://example.com")
>>>
>>> What does everyone think of that idea?
>>> _______________________________________________
>>> swift-evolution mailing list
>>> swift-evolution@swift.org
>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>
>>
>> I’d like to see something like that for file path URLs. For something so commonly used, URL(fileURLWithPath:) is obnoxiously verbose.
>>
>> Charles
>
> Yes, but it's not a nullable initializer. With URL(string:) the incredible pain is that even compile-time URLs to your own website are nullable URL? and you need to force-unwrap them.
>
>>
>> _______________________________________________
>> 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


(Micah Hainline) #10

I'm not sure I fully understand the value proposition of having all those different kinds of literals, but one piece of feedback I have on that is the previously established format for the # notation should be #camelCase rather than #dot.separated.

···

On Dec 16, 2016, at 5:41 PM, Erica Sadun <erica@ericasadun.com> wrote:

Take a peek at this: https://gist.github.com/erica/c92f6ab115af89d5c4b9161487df6a3c

--E

On Dec 16, 2016, at 2:58 PM, Micah Hainline via swift-evolution <swift-evolution@swift.org> wrote:

Charles,

There's already something like that for file URLs in a playground,
though I'm not sure about compile-time checking or how that might work
outside of playgrounds.

https://lists.swift.org/pipermail/swift-evolution-announce/2016-March/000060.html

Of course, my proposal would work fine for file URLs, just not for
turning file paths INTO URLs.

On Fri, Dec 16, 2016 at 3:05 PM, Charles Srstka >> <cocoadev@charlessoft.com> wrote:

On Dec 16, 2016, at 2:46 PM, Micah Hainline via swift-evolution <swift-evolution@swift.org> wrote:

I would like to be able to create a URL literal that is compile-time
checked for correct format. This would help avoid code like this:

  let url: URL = URL(string: "https://example.com")!

The cleanest way I can think of doing that would be to introduce a new
macro structure similar to #selector, though I'm open to other ideas.
I would think it should take a quoted literal string to avoid
problems. That would look like this:

  let url: URL = #url("https://example.com")

What does everyone think of that idea?
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

I’d like to see something like that for file path URLs. For something so commonly used, URL(fileURLWithPath:) is obnoxiously verbose.

Charles

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


(Xiaodi Wu) #11

True, but it's not at all about brevity, it's about type-safety and
getting compile-time checking rather than runtime checking of the validity
of the URL structure.

While I understand that what you're after is compile-time checking of
validity, I'm not convinced that it is materially useful. I also don't see
how it's contributing to type safety. Perhaps you could illuminate what use
case has persuaded you of these things? Here's my thinking:

Nine times out of ten when I mistype a URL, or paste only a fragment of a
URL, it's a mistake that results in a plausible but unintended URL and a
compile-time check for validity will not help at all. To guard against such
an error, I need to write tests anyway and could never depend on the
compiler. In fact, I'd imagine that doing anything useful with a URL--even
a hardcoded one--will require some thought as to how to deal with error
handling at runtime. How is it helpful to have only the lowest bar (a
technically valid URL format) ensured at compile time instead of runtime?
By contrast, Swift selectors help to guarantee that any particular function
I'm referring to actually exists; when that is ensured at compile time, I
know it will be the case at runtime. There's no corresponding guarantee by
having a compile-time check for URL validity that the resource pointed to
will actually exist. That the nonexistent resource was denoted by a string
that had the correct format of a URL is cold comfort, no?

···

On Fri, Dec 16, 2016 at 5:54 PM, Micah Hainline via swift-evolution < swift-evolution@swift.org> wrote:

On Dec 16, 2016, at 5:50 PM, Derrick Ho <wh1pch81n@gmail.com> wrote:

let url = URL(string: "https://example.com")!

let url = #url("https://example.com")

Are not that different in length. It really isn't saving you much.

I suppose you can try overloading an operator to get something to the
effect you want.
On Fri, Dec 16, 2016 at 6:19 PM Micah Hainline via swift-evolution < > swift-evolution@swift.org> wrote:

Exactly! It's not an earth-shattering pain, but it would be nice to have
clean type safety there.

> On Dec 16, 2016, at 4:01 PM, Charlie Monroe <charlie@charliemonroe.net> >> wrote:
>
>
>>> On Dec 16, 2016, at 10:05 PM, Charles Srstka via swift-evolution < >> swift-evolution@swift.org> wrote:
>>>
>>> On Dec 16, 2016, at 2:46 PM, Micah Hainline via swift-evolution < >> swift-evolution@swift.org> wrote:
>>>
>>> I would like to be able to create a URL literal that is compile-time
>>> checked for correct format. This would help avoid code like this:
>>>
>>> let url: URL = URL(string: "https://example.com")!
>>>
>>> The cleanest way I can think of doing that would be to introduce a new
>>> macro structure similar to #selector, though I'm open to other ideas.
>>> I would think it should take a quoted literal string to avoid
>>> problems. That would look like this:
>>>
>>> let url: URL = #url("https://example.com")
>>>
>>> What does everyone think of that idea?
>>> _______________________________________________
>>> swift-evolution mailing list
>>> swift-evolution@swift.org
>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>
>>
>> I’d like to see something like that for file path URLs. For something
so commonly used, URL(fileURLWithPath:) is obnoxiously verbose.
>>
>> Charles
>
> Yes, but it's not a nullable initializer. With URL(string:) the
incredible pain is that even compile-time URLs to your own website are
nullable URL? and you need to force-unwrap them.
>
>>
>> _______________________________________________
>> 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


(Micah Hainline) #12

It's not super strong, but it's as strong as the URL type itself.

Even if I do checking related to the resource being unavailable, I also have to do checking to account for the possibility of a nil URL. The two checks aren't closely related. It does help to have one of them accounted for by the compiler if possible.

I'm trying to teach some less experienced developers to think of force-unwrapping as a code smell, but it's not the best to have to say "except for URLs". I realize the utility of the proposed change is reasonably small, but I also think it's purely additive and consistent with the rest of the language. :slightly_smiling_face:

···

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

On Fri, Dec 16, 2016 at 5:54 PM, Micah Hainline via swift-evolution <swift-evolution@swift.org> wrote:
True, but it's not at all about brevity, it's about type-safety and getting compile-time checking rather than runtime checking of the validity of the URL structure.

While I understand that what you're after is compile-time checking of validity, I'm not convinced that it is materially useful. I also don't see how it's contributing to type safety. Perhaps you could illuminate what use case has persuaded you of these things? Here's my thinking:

Nine times out of ten when I mistype a URL, or paste only a fragment of a URL, it's a mistake that results in a plausible but unintended URL and a compile-time check for validity will not help at all. To guard against such an error, I need to write tests anyway and could never depend on the compiler. In fact, I'd imagine that doing anything useful with a URL--even a hardcoded one--will require some thought as to how to deal with error handling at runtime. How is it helpful to have only the lowest bar (a technically valid URL format) ensured at compile time instead of runtime? By contrast, Swift selectors help to guarantee that any particular function I'm referring to actually exists; when that is ensured at compile time, I know it will be the case at runtime. There's no corresponding guarantee by having a compile-time check for URL validity that the resource pointed to will actually exist. That the nonexistent resource was denoted by a string that had the correct format of a URL is cold comfort, no?

On Dec 16, 2016, at 5:50 PM, Derrick Ho <wh1pch81n@gmail.com> wrote:

let url = URL(string: "https://example.com")!

let url = #url("https://example.com")

Are not that different in length. It really isn't saving you much.

I suppose you can try overloading an operator to get something to the effect you want.

On Fri, Dec 16, 2016 at 6:19 PM Micah Hainline via swift-evolution <swift-evolution@swift.org> wrote:
Exactly! It's not an earth-shattering pain, but it would be nice to have clean type safety there.

> On Dec 16, 2016, at 4:01 PM, Charlie Monroe <charlie@charliemonroe.net> wrote:
>
>
>>> On Dec 16, 2016, at 10:05 PM, Charles Srstka via swift-evolution <swift-evolution@swift.org> wrote:
>>>
>>> On Dec 16, 2016, at 2:46 PM, Micah Hainline via swift-evolution <swift-evolution@swift.org> wrote:
>>>
>>> I would like to be able to create a URL literal that is compile-time
>>> checked for correct format. This would help avoid code like this:
>>>
>>> let url: URL = URL(string: "https://example.com")!
>>>
>>> The cleanest way I can think of doing that would be to introduce a new
>>> macro structure similar to #selector, though I'm open to other ideas.
>>> I would think it should take a quoted literal string to avoid
>>> problems. That would look like this:
>>>
>>> let url: URL = #url("https://example.com")
>>>
>>> What does everyone think of that idea?
>>> _______________________________________________
>>> swift-evolution mailing list
>>> swift-evolution@swift.org
>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>
>>
>> I’d like to see something like that for file path URLs. For something so commonly used, URL(fileURLWithPath:) is obnoxiously verbose.
>>
>> Charles
>
> Yes, but it's not a nullable initializer. With URL(string:) the incredible pain is that even compile-time URLs to your own website are nullable URL? and you need to force-unwrap them.
>
>>
>> _______________________________________________
>> 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


(Mark Sands) #13

I have to agree with your line of thinking, Micah. We've been in the exact same position when it comes to teaching beginners to avoid force unwrapping except URLs.

+1 on this from me!

Mark

···

On Dec 16, 2016, at 19:01, Micah Hainline via swift-evolution <swift-evolution@swift.org> wrote:

It's not super strong, but it's as strong as the URL type itself.

Even if I do checking related to the resource being unavailable, I also have to do checking to account for the possibility of a nil URL. The two checks aren't closely related. It does help to have one of them accounted for by the compiler if possible.

I'm trying to teach some less experienced developers to think of force-unwrapping as a code smell, but it's not the best to have to say "except for URLs". I realize the utility of the proposed change is reasonably small, but I also think it's purely additive and consistent with the rest of the language. :slightly_smiling_face:

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

On Fri, Dec 16, 2016 at 5:54 PM, Micah Hainline via swift-evolution <swift-evolution@swift.org> wrote:
True, but it's not at all about brevity, it's about type-safety and getting compile-time checking rather than runtime checking of the validity of the URL structure.

While I understand that what you're after is compile-time checking of validity, I'm not convinced that it is materially useful. I also don't see how it's contributing to type safety. Perhaps you could illuminate what use case has persuaded you of these things? Here's my thinking:

Nine times out of ten when I mistype a URL, or paste only a fragment of a URL, it's a mistake that results in a plausible but unintended URL and a compile-time check for validity will not help at all. To guard against such an error, I need to write tests anyway and could never depend on the compiler. In fact, I'd imagine that doing anything useful with a URL--even a hardcoded one--will require some thought as to how to deal with error handling at runtime. How is it helpful to have only the lowest bar (a technically valid URL format) ensured at compile time instead of runtime? By contrast, Swift selectors help to guarantee that any particular function I'm referring to actually exists; when that is ensured at compile time, I know it will be the case at runtime. There's no corresponding guarantee by having a compile-time check for URL validity that the resource pointed to will actually exist. That the nonexistent resource was denoted by a string that had the correct format of a URL is cold comfort, no?

On Dec 16, 2016, at 5:50 PM, Derrick Ho <wh1pch81n@gmail.com> wrote:

let url = URL(string: "https://example.com")!

let url = #url("https://example.com")

Are not that different in length. It really isn't saving you much.

I suppose you can try overloading an operator to get something to the effect you want.

On Fri, Dec 16, 2016 at 6:19 PM Micah Hainline via swift-evolution <swift-evolution@swift.org> wrote:
Exactly! It's not an earth-shattering pain, but it would be nice to have clean type safety there.

> On Dec 16, 2016, at 4:01 PM, Charlie Monroe <charlie@charliemonroe.net> wrote:
>
>
>>> On Dec 16, 2016, at 10:05 PM, Charles Srstka via swift-evolution <swift-evolution@swift.org> wrote:
>>>
>>> On Dec 16, 2016, at 2:46 PM, Micah Hainline via swift-evolution <swift-evolution@swift.org> wrote:
>>>
>>> I would like to be able to create a URL literal that is compile-time
>>> checked for correct format. This would help avoid code like this:
>>>
>>> let url: URL = URL(string: "https://example.com")!
>>>
>>> The cleanest way I can think of doing that would be to introduce a new
>>> macro structure similar to #selector, though I'm open to other ideas.
>>> I would think it should take a quoted literal string to avoid
>>> problems. That would look like this:
>>>
>>> let url: URL = #url("https://example.com")
>>>
>>> What does everyone think of that idea?
>>> _______________________________________________
>>> swift-evolution mailing list
>>> swift-evolution@swift.org
>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>
>>
>> I’d like to see something like that for file path URLs. For something so commonly used, URL(fileURLWithPath:) is obnoxiously verbose.
>>
>> Charles
>
> Yes, but it's not a nullable initializer. With URL(string:) the incredible pain is that even compile-time URLs to your own website are nullable URL? and you need to force-unwrap them.
>
>>
>> _______________________________________________
>> 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


(Xiaodi Wu) #14

It's not super strong, but it's as strong as the URL type itself.

Even if I do checking related to the resource being unavailable, I also
have to do checking to account for the possibility of a nil URL. The two
checks aren't closely related.

When you use a URL, what would you do differently when a resource is
unavailable versus when the URL is malformed, especially if you're
hardcoding the URL?

It does help to have one of them accounted for by the compiler if possible.

I'm trying to teach some less experienced developers to think of
force-unwrapping as a code smell,

There have been a few people who have said a similar thing on the list, but
I don't think this is the official line about force-unwrapping. Force
unwrapping is an explicitly supported part of the language that has its
uses. If you *know* at the time of writing that a failable initializer
should never fail, then `!` is an expressive, clear, concise, entirely
appropriate, and I would even say the *best* way of indicating that to your
reader.

It should be noted that `let url = URL(string: "http://example.com/")!` is
one example of this usage, but not at all the only one. I have previously
written, for example, `"L".cString(using: .utf8)!`. This is also no code
smell, as what I'm doing is stating my absolute confidence (and indicating
that confidence to the reader) that the letter L can be encoded using UTF-8.

but it's not the best to have to say "except for URLs". I realize the

···

On Fri, Dec 16, 2016 at 7:01 PM, Micah Hainline <micah.hainline@gmail.com> wrote:

utility of the proposed change is reasonably small, but I also think it's
purely additive and consistent with the rest of the language. :slightly_smiling_face:

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

On Fri, Dec 16, 2016 at 5:54 PM, Micah Hainline via swift-evolution < > swift-evolution@swift.org> wrote:

True, but it's not at all about brevity, it's about type-safety and
getting compile-time checking rather than runtime checking of the validity
of the URL structure.

While I understand that what you're after is compile-time checking of
validity, I'm not convinced that it is materially useful. I also don't see
how it's contributing to type safety. Perhaps you could illuminate what use
case has persuaded you of these things? Here's my thinking:

Nine times out of ten when I mistype a URL, or paste only a fragment of a
URL, it's a mistake that results in a plausible but unintended URL and a
compile-time check for validity will not help at all. To guard against such
an error, I need to write tests anyway and could never depend on the
compiler. In fact, I'd imagine that doing anything useful with a URL--even
a hardcoded one--will require some thought as to how to deal with error
handling at runtime. How is it helpful to have only the lowest bar (a
technically valid URL format) ensured at compile time instead of runtime?
By contrast, Swift selectors help to guarantee that any particular function
I'm referring to actually exists; when that is ensured at compile time, I
know it will be the case at runtime. There's no corresponding guarantee by
having a compile-time check for URL validity that the resource pointed to
will actually exist. That the nonexistent resource was denoted by a string
that had the correct format of a URL is cold comfort, no?

On Dec 16, 2016, at 5:50 PM, Derrick Ho <wh1pch81n@gmail.com> wrote:

let url = URL(string: "https://example.com")!

let url = #url("https://example.com")

Are not that different in length. It really isn't saving you much.

I suppose you can try overloading an operator to get something to the
effect you want.
On Fri, Dec 16, 2016 at 6:19 PM Micah Hainline via swift-evolution < >> swift-evolution@swift.org> wrote:

Exactly! It's not an earth-shattering pain, but it would be nice to have
clean type safety there.

> On Dec 16, 2016, at 4:01 PM, Charlie Monroe <charlie@charliemonroe.net> >>> wrote:
>
>
>>> On Dec 16, 2016, at 10:05 PM, Charles Srstka via swift-evolution < >>> swift-evolution@swift.org> wrote:
>>>
>>> On Dec 16, 2016, at 2:46 PM, Micah Hainline via swift-evolution < >>> swift-evolution@swift.org> wrote:
>>>
>>> I would like to be able to create a URL literal that is compile-time
>>> checked for correct format. This would help avoid code like this:
>>>
>>> let url: URL = URL(string: "https://example.com")!
>>>
>>> The cleanest way I can think of doing that would be to introduce a
new
>>> macro structure similar to #selector, though I'm open to other ideas.
>>> I would think it should take a quoted literal string to avoid
>>> problems. That would look like this:
>>>
>>> let url: URL = #url("https://example.com")
>>>
>>> What does everyone think of that idea?
>>> _______________________________________________
>>> swift-evolution mailing list
>>> swift-evolution@swift.org
>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>
>>
>> I’d like to see something like that for file path URLs. For something
so commonly used, URL(fileURLWithPath:) is obnoxiously verbose.
>>
>> Charles
>
> Yes, but it's not a nullable initializer. With URL(string:) the
incredible pain is that even compile-time URLs to your own website are
nullable URL? and you need to force-unwrap them.
>
>>
>> _______________________________________________
>> 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


(Micah Hainline) #15

Noted, but again while force-unwrapping it is the best we have, compile-time checking would be even better.

···

On Dec 16, 2016, at 7:30 PM, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

On Fri, Dec 16, 2016 at 7:01 PM, Micah Hainline <micah.hainline@gmail.com> wrote:
It's not super strong, but it's as strong as the URL type itself.

Even if I do checking related to the resource being unavailable, I also have to do checking to account for the possibility of a nil URL. The two checks aren't closely related.

When you use a URL, what would you do differently when a resource is unavailable versus when the URL is malformed, especially if you're hardcoding the URL?

It does help to have one of them accounted for by the compiler if possible.

I'm trying to teach some less experienced developers to think of force-unwrapping as a code smell,

There have been a few people who have said a similar thing on the list, but I don't think this is the official line about force-unwrapping. Force unwrapping is an explicitly supported part of the language that has its uses. If you *know* at the time of writing that a failable initializer should never fail, then `!` is an expressive, clear, concise, entirely appropriate, and I would even say the *best* way of indicating that to your reader.

It should be noted that `let url = URL(string: "http://example.com/")!` is one example of this usage, but not at all the only one. I have previously written, for example, `"L".cString(using: .utf8)!`. This is also no code smell, as what I'm doing is stating my absolute confidence (and indicating that confidence to the reader) that the letter L can be encoded using UTF-8.

but it's not the best to have to say "except for URLs". I realize the utility of the proposed change is reasonably small, but I also think it's purely additive and consistent with the rest of the language. :slightly_smiling_face:

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

On Fri, Dec 16, 2016 at 5:54 PM, Micah Hainline via swift-evolution <swift-evolution@swift.org> wrote:
True, but it's not at all about brevity, it's about type-safety and getting compile-time checking rather than runtime checking of the validity of the URL structure.

While I understand that what you're after is compile-time checking of validity, I'm not convinced that it is materially useful. I also don't see how it's contributing to type safety. Perhaps you could illuminate what use case has persuaded you of these things? Here's my thinking:

Nine times out of ten when I mistype a URL, or paste only a fragment of a URL, it's a mistake that results in a plausible but unintended URL and a compile-time check for validity will not help at all. To guard against such an error, I need to write tests anyway and could never depend on the compiler. In fact, I'd imagine that doing anything useful with a URL--even a hardcoded one--will require some thought as to how to deal with error handling at runtime. How is it helpful to have only the lowest bar (a technically valid URL format) ensured at compile time instead of runtime? By contrast, Swift selectors help to guarantee that any particular function I'm referring to actually exists; when that is ensured at compile time, I know it will be the case at runtime. There's no corresponding guarantee by having a compile-time check for URL validity that the resource pointed to will actually exist. That the nonexistent resource was denoted by a string that had the correct format of a URL is cold comfort, no?

On Dec 16, 2016, at 5:50 PM, Derrick Ho <wh1pch81n@gmail.com> wrote:

let url = URL(string: "https://example.com")!

let url = #url("https://example.com")

Are not that different in length. It really isn't saving you much.

I suppose you can try overloading an operator to get something to the effect you want.

On Fri, Dec 16, 2016 at 6:19 PM Micah Hainline via swift-evolution <swift-evolution@swift.org> wrote:
Exactly! It's not an earth-shattering pain, but it would be nice to have clean type safety there.

> On Dec 16, 2016, at 4:01 PM, Charlie Monroe <charlie@charliemonroe.net> wrote:
>
>
>>> On Dec 16, 2016, at 10:05 PM, Charles Srstka via swift-evolution <swift-evolution@swift.org> wrote:
>>>
>>> On Dec 16, 2016, at 2:46 PM, Micah Hainline via swift-evolution <swift-evolution@swift.org> wrote:
>>>
>>> I would like to be able to create a URL literal that is compile-time
>>> checked for correct format. This would help avoid code like this:
>>>
>>> let url: URL = URL(string: "https://example.com")!
>>>
>>> The cleanest way I can think of doing that would be to introduce a new
>>> macro structure similar to #selector, though I'm open to other ideas.
>>> I would think it should take a quoted literal string to avoid
>>> problems. That would look like this:
>>>
>>> let url: URL = #url("https://example.com")
>>>
>>> What does everyone think of that idea?
>>> _______________________________________________
>>> swift-evolution mailing list
>>> swift-evolution@swift.org
>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>
>>
>> I’d like to see something like that for file path URLs. For something so commonly used, URL(fileURLWithPath:) is obnoxiously verbose.
>>
>> Charles
>
> Yes, but it's not a nullable initializer. With URL(string:) the incredible pain is that even compile-time URLs to your own website are nullable URL? and you need to force-unwrap them.
>
>>
>> _______________________________________________
>> 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


(Xiaodi Wu) #16

Noted, but again while force-unwrapping it is the best we have,
compile-time checking would be even better.

Sure, I'm certainly not opposed to flagging more errors at compile time.
But it's possible to do that without adding new syntax to the language,
which (just MHO) is rarely the best solution when a good alternative exists.

Here, for instance, one could add compiler magic that warns at compile time
that `URL(string: "notavalidurl")!` is guaranteed to fail. That could be a
diagnostics/QoI improvement that almost certainly wouldn't require going
through the evolution process.

What I was trying to point out is that I agree with Derrick that the
_spelling_ `URL(string: "https://example.com/")!` is perfectly fine and not
in need of improvement, and that I disagree strongly that force unwrapping
is problematic as a matter of style.

···

On Fri, Dec 16, 2016 at 7:44 PM, Micah Hainline <micah.hainline@gmail.com> wrote:

On Dec 16, 2016, at 7:30 PM, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

On Fri, Dec 16, 2016 at 7:01 PM, Micah Hainline <micah.hainline@gmail.com> > wrote:

It's not super strong, but it's as strong as the URL type itself.

Even if I do checking related to the resource being unavailable, I also
have to do checking to account for the possibility of a nil URL. The two
checks aren't closely related.

When you use a URL, what would you do differently when a resource is
unavailable versus when the URL is malformed, especially if you're
hardcoding the URL?

It does help to have one of them accounted for by the compiler if possible.

I'm trying to teach some less experienced developers to think of
force-unwrapping as a code smell,

There have been a few people who have said a similar thing on the list,
but I don't think this is the official line about force-unwrapping. Force
unwrapping is an explicitly supported part of the language that has its
uses. If you *know* at the time of writing that a failable initializer
should never fail, then `!` is an expressive, clear, concise, entirely
appropriate, and I would even say the *best* way of indicating that to your
reader.

It should be noted that `let url = URL(string: "http://example.com/")!`
is one example of this usage, but not at all the only one. I have
previously written, for example, `"L".cString(using: .utf8)!`. This is also
no code smell, as what I'm doing is stating my absolute confidence (and
indicating that confidence to the reader) that the letter L can be encoded
using UTF-8.

but it's not the best to have to say "except for URLs". I realize the

utility of the proposed change is reasonably small, but I also think it's
purely additive and consistent with the rest of the language. :slightly_smiling_face:

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

On Fri, Dec 16, 2016 at 5:54 PM, Micah Hainline via swift-evolution < >> swift-evolution@swift.org> wrote:

True, but it's not at all about brevity, it's about type-safety and
getting compile-time checking rather than runtime checking of the validity
of the URL structure.

While I understand that what you're after is compile-time checking of
validity, I'm not convinced that it is materially useful. I also don't see
how it's contributing to type safety. Perhaps you could illuminate what use
case has persuaded you of these things? Here's my thinking:

Nine times out of ten when I mistype a URL, or paste only a fragment of a
URL, it's a mistake that results in a plausible but unintended URL and a
compile-time check for validity will not help at all. To guard against such
an error, I need to write tests anyway and could never depend on the
compiler. In fact, I'd imagine that doing anything useful with a URL--even
a hardcoded one--will require some thought as to how to deal with error
handling at runtime. How is it helpful to have only the lowest bar (a
technically valid URL format) ensured at compile time instead of runtime?
By contrast, Swift selectors help to guarantee that any particular function
I'm referring to actually exists; when that is ensured at compile time, I
know it will be the case at runtime. There's no corresponding guarantee by
having a compile-time check for URL validity that the resource pointed to
will actually exist. That the nonexistent resource was denoted by a string
that had the correct format of a URL is cold comfort, no?

On Dec 16, 2016, at 5:50 PM, Derrick Ho <wh1pch81n@gmail.com> wrote:

let url = URL(string: "https://example.com")!

let url = #url("https://example.com")

Are not that different in length. It really isn't saving you much.

I suppose you can try overloading an operator to get something to the
effect you want.
On Fri, Dec 16, 2016 at 6:19 PM Micah Hainline via swift-evolution < >>> swift-evolution@swift.org> wrote:

Exactly! It's not an earth-shattering pain, but it would be nice to
have clean type safety there.

> On Dec 16, 2016, at 4:01 PM, Charlie Monroe < >>>> charlie@charliemonroe.net> wrote:
>
>
>>> On Dec 16, 2016, at 10:05 PM, Charles Srstka via swift-evolution < >>>> swift-evolution@swift.org> wrote:
>>>
>>> On Dec 16, 2016, at 2:46 PM, Micah Hainline via swift-evolution < >>>> swift-evolution@swift.org> wrote:
>>>
>>> I would like to be able to create a URL literal that is compile-time
>>> checked for correct format. This would help avoid code like this:
>>>
>>> let url: URL = URL(string: "https://example.com")!
>>>
>>> The cleanest way I can think of doing that would be to introduce a
new
>>> macro structure similar to #selector, though I'm open to other
ideas.
>>> I would think it should take a quoted literal string to avoid
>>> problems. That would look like this:
>>>
>>> let url: URL = #url("https://example.com")
>>>
>>> What does everyone think of that idea?
>>> _______________________________________________
>>> swift-evolution mailing list
>>> swift-evolution@swift.org
>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>
>>
>> I’d like to see something like that for file path URLs. For
something so commonly used, URL(fileURLWithPath:) is obnoxiously verbose.
>>
>> Charles
>
> Yes, but it's not a nullable initializer. With URL(string:) the
incredible pain is that even compile-time URLs to your own website are
nullable URL? and you need to force-unwrap them.
>
>>
>> _______________________________________________
>> 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


(Micah Hainline) #17

We'll have to agree to disagree about the value of getting rid of the force-unwrap.

···

On Dec 16, 2016, at 7:54 PM, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

On Fri, Dec 16, 2016 at 7:44 PM, Micah Hainline <micah.hainline@gmail.com> wrote:
Noted, but again while force-unwrapping it is the best we have, compile-time checking would be even better.

Sure, I'm certainly not opposed to flagging more errors at compile time. But it's possible to do that without adding new syntax to the language, which (just MHO) is rarely the best solution when a good alternative exists.

Here, for instance, one could add compiler magic that warns at compile time that `URL(string: "notavalidurl")!` is guaranteed to fail. That could be a diagnostics/QoI improvement that almost certainly wouldn't require going through the evolution process.

What I was trying to point out is that I agree with Derrick that the _spelling_ `URL(string: "https://example.com/")!` is perfectly fine and not in need of improvement, and that I disagree strongly that force unwrapping is problematic as a matter of style.

On Dec 16, 2016, at 7:30 PM, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

On Fri, Dec 16, 2016 at 7:01 PM, Micah Hainline <micah.hainline@gmail.com> wrote:
It's not super strong, but it's as strong as the URL type itself.

Even if I do checking related to the resource being unavailable, I also have to do checking to account for the possibility of a nil URL. The two checks aren't closely related.

When you use a URL, what would you do differently when a resource is unavailable versus when the URL is malformed, especially if you're hardcoding the URL?

It does help to have one of them accounted for by the compiler if possible.

I'm trying to teach some less experienced developers to think of force-unwrapping as a code smell,

There have been a few people who have said a similar thing on the list, but I don't think this is the official line about force-unwrapping. Force unwrapping is an explicitly supported part of the language that has its uses. If you *know* at the time of writing that a failable initializer should never fail, then `!` is an expressive, clear, concise, entirely appropriate, and I would even say the *best* way of indicating that to your reader.

It should be noted that `let url = URL(string: "http://example.com/")!` is one example of this usage, but not at all the only one. I have previously written, for example, `"L".cString(using: .utf8)!`. This is also no code smell, as what I'm doing is stating my absolute confidence (and indicating that confidence to the reader) that the letter L can be encoded using UTF-8.

but it's not the best to have to say "except for URLs". I realize the utility of the proposed change is reasonably small, but I also think it's purely additive and consistent with the rest of the language. :slightly_smiling_face:

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

On Fri, Dec 16, 2016 at 5:54 PM, Micah Hainline via swift-evolution <swift-evolution@swift.org> wrote:
True, but it's not at all about brevity, it's about type-safety and getting compile-time checking rather than runtime checking of the validity of the URL structure.

While I understand that what you're after is compile-time checking of validity, I'm not convinced that it is materially useful. I also don't see how it's contributing to type safety. Perhaps you could illuminate what use case has persuaded you of these things? Here's my thinking:

Nine times out of ten when I mistype a URL, or paste only a fragment of a URL, it's a mistake that results in a plausible but unintended URL and a compile-time check for validity will not help at all. To guard against such an error, I need to write tests anyway and could never depend on the compiler. In fact, I'd imagine that doing anything useful with a URL--even a hardcoded one--will require some thought as to how to deal with error handling at runtime. How is it helpful to have only the lowest bar (a technically valid URL format) ensured at compile time instead of runtime? By contrast, Swift selectors help to guarantee that any particular function I'm referring to actually exists; when that is ensured at compile time, I know it will be the case at runtime. There's no corresponding guarantee by having a compile-time check for URL validity that the resource pointed to will actually exist. That the nonexistent resource was denoted by a string that had the correct format of a URL is cold comfort, no?

On Dec 16, 2016, at 5:50 PM, Derrick Ho <wh1pch81n@gmail.com> wrote:

let url = URL(string: "https://example.com")!

let url = #url("https://example.com")

Are not that different in length. It really isn't saving you much.

I suppose you can try overloading an operator to get something to the effect you want.

On Fri, Dec 16, 2016 at 6:19 PM Micah Hainline via swift-evolution <swift-evolution@swift.org> wrote:
Exactly! It's not an earth-shattering pain, but it would be nice to have clean type safety there.

> On Dec 16, 2016, at 4:01 PM, Charlie Monroe <charlie@charliemonroe.net> wrote:
>
>
>>> On Dec 16, 2016, at 10:05 PM, Charles Srstka via swift-evolution <swift-evolution@swift.org> wrote:
>>>
>>> On Dec 16, 2016, at 2:46 PM, Micah Hainline via swift-evolution <swift-evolution@swift.org> wrote:
>>>
>>> I would like to be able to create a URL literal that is compile-time
>>> checked for correct format. This would help avoid code like this:
>>>
>>> let url: URL = URL(string: "https://example.com")!
>>>
>>> The cleanest way I can think of doing that would be to introduce a new
>>> macro structure similar to #selector, though I'm open to other ideas.
>>> I would think it should take a quoted literal string to avoid
>>> problems. That would look like this:
>>>
>>> let url: URL = #url("https://example.com")
>>>
>>> What does everyone think of that idea?
>>> _______________________________________________
>>> swift-evolution mailing list
>>> swift-evolution@swift.org
>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>
>>
>> I’d like to see something like that for file path URLs. For something so commonly used, URL(fileURLWithPath:) is obnoxiously verbose.
>>
>> Charles
>
> Yes, but it's not a nullable initializer. With URL(string:) the incredible pain is that even compile-time URLs to your own website are nullable URL? and you need to force-unwrap them.
>
>>
>> _______________________________________________
>> 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


(Xiaodi Wu) #18

We'll have to agree to disagree about the value of getting rid of the
force-unwrap.

I suppose we may have to. But I hope to have convinced you that what you're
really getting at here are two issues that can be separated. The two are:

1. The developer experience of using failable initializers invoked with
hardcoded arguments is sub-par. For URL, or for any other type where
success or failure of initialization is determined entirely by the
arguments passed in, it would be nice to have the compiler tell you _at
compile time_ if the hardcoded arguments are guaranteed to cause the
initializer to return nil. I think this is quite an insightful point.

2. You do not like working with force unwrapping. While certainly entitled
to that opinion, I do not think this opinion alone (since it is separable
from (1)) can justify additions or subtractions to the language. Either
force unwrapping is a legitimate part of the language--that is, the
community that designs Swift can agree on specific patterns where its use
is considered best practice--or it is an anti-pattern that should be
deprecated and eventually removed. It cannot be a lingering yet fully
supported first-class anti-pattern that we design standard and core library
APIs actively to avoid.

···

On Fri, Dec 16, 2016 at 8:00 PM, Micah Hainline <micah.hainline@gmail.com> wrote:

On Dec 16, 2016, at 7:54 PM, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

On Fri, Dec 16, 2016 at 7:44 PM, Micah Hainline <micah.hainline@gmail.com> > wrote:

Noted, but again while force-unwrapping it is the best we have,
compile-time checking would be even better.

Sure, I'm certainly not opposed to flagging more errors at compile time.
But it's possible to do that without adding new syntax to the language,
which (just MHO) is rarely the best solution when a good alternative exists.

Here, for instance, one could add compiler magic that warns at compile
time that `URL(string: "notavalidurl")!` is guaranteed to fail. That could
be a diagnostics/QoI improvement that almost certainly wouldn't require
going through the evolution process.

What I was trying to point out is that I agree with Derrick that the
_spelling_ `URL(string: "https://example.com/")!` is perfectly fine and
not in need of improvement, and that I disagree strongly that force
unwrapping is problematic as a matter of style.

On Dec 16, 2016, at 7:30 PM, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

On Fri, Dec 16, 2016 at 7:01 PM, Micah Hainline <micah.hainline@gmail.com >> > wrote:

It's not super strong, but it's as strong as the URL type itself.

Even if I do checking related to the resource being unavailable, I also
have to do checking to account for the possibility of a nil URL. The two
checks aren't closely related.

When you use a URL, what would you do differently when a resource is
unavailable versus when the URL is malformed, especially if you're
hardcoding the URL?

It does help to have one of them accounted for by the compiler if

possible.

I'm trying to teach some less experienced developers to think of
force-unwrapping as a code smell,

There have been a few people who have said a similar thing on the list,
but I don't think this is the official line about force-unwrapping. Force
unwrapping is an explicitly supported part of the language that has its
uses. If you *know* at the time of writing that a failable initializer
should never fail, then `!` is an expressive, clear, concise, entirely
appropriate, and I would even say the *best* way of indicating that to your
reader.

It should be noted that `let url = URL(string: "http://example.com/")!`
is one example of this usage, but not at all the only one. I have
previously written, for example, `"L".cString(using: .utf8)!`. This is also
no code smell, as what I'm doing is stating my absolute confidence (and
indicating that confidence to the reader) that the letter L can be encoded
using UTF-8.

but it's not the best to have to say "except for URLs". I realize the

utility of the proposed change is reasonably small, but I also think it's
purely additive and consistent with the rest of the language. :slightly_smiling_face:

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

On Fri, Dec 16, 2016 at 5:54 PM, Micah Hainline via swift-evolution < >>> swift-evolution@swift.org> wrote:

True, but it's not at all about brevity, it's about type-safety and
getting compile-time checking rather than runtime checking of the validity
of the URL structure.

While I understand that what you're after is compile-time checking of
validity, I'm not convinced that it is materially useful. I also don't see
how it's contributing to type safety. Perhaps you could illuminate what use
case has persuaded you of these things? Here's my thinking:

Nine times out of ten when I mistype a URL, or paste only a fragment of
a URL, it's a mistake that results in a plausible but unintended URL and a
compile-time check for validity will not help at all. To guard against such
an error, I need to write tests anyway and could never depend on the
compiler. In fact, I'd imagine that doing anything useful with a URL--even
a hardcoded one--will require some thought as to how to deal with error
handling at runtime. How is it helpful to have only the lowest bar (a
technically valid URL format) ensured at compile time instead of runtime?
By contrast, Swift selectors help to guarantee that any particular function
I'm referring to actually exists; when that is ensured at compile time, I
know it will be the case at runtime. There's no corresponding guarantee by
having a compile-time check for URL validity that the resource pointed to
will actually exist. That the nonexistent resource was denoted by a string
that had the correct format of a URL is cold comfort, no?

On Dec 16, 2016, at 5:50 PM, Derrick Ho <wh1pch81n@gmail.com> wrote:

let url = URL(string: "https://example.com")!

let url = #url("https://example.com")

Are not that different in length. It really isn't saving you much.

I suppose you can try overloading an operator to get something to the
effect you want.
On Fri, Dec 16, 2016 at 6:19 PM Micah Hainline via swift-evolution < >>>> swift-evolution@swift.org> wrote:

Exactly! It's not an earth-shattering pain, but it would be nice to
have clean type safety there.

> On Dec 16, 2016, at 4:01 PM, Charlie Monroe < >>>>> charlie@charliemonroe.net> wrote:
>
>
>>> On Dec 16, 2016, at 10:05 PM, Charles Srstka via swift-evolution < >>>>> swift-evolution@swift.org> wrote:
>>>
>>> On Dec 16, 2016, at 2:46 PM, Micah Hainline via swift-evolution < >>>>> swift-evolution@swift.org> wrote:
>>>
>>> I would like to be able to create a URL literal that is
compile-time
>>> checked for correct format. This would help avoid code like this:
>>>
>>> let url: URL = URL(string: "https://example.com")!
>>>
>>> The cleanest way I can think of doing that would be to introduce a
new
>>> macro structure similar to #selector, though I'm open to other
ideas.
>>> I would think it should take a quoted literal string to avoid
>>> problems. That would look like this:
>>>
>>> let url: URL = #url("https://example.com")
>>>
>>> What does everyone think of that idea?
>>> _______________________________________________
>>> swift-evolution mailing list
>>> swift-evolution@swift.org
>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>
>>
>> I’d like to see something like that for file path URLs. For
something so commonly used, URL(fileURLWithPath:) is obnoxiously verbose.
>>
>> Charles
>
> Yes, but it's not a nullable initializer. With URL(string:) the
incredible pain is that even compile-time URLs to your own website are
nullable URL? and you need to force-unwrap them.
>
>>
>> _______________________________________________
>> 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


(Micah Hainline) #19

Absolutely. Good breakdown of the issues. I will draw a parallel with #selector though for past precedent. It wouldn't have been much different to just use the string-based Selector creation instead of creating a new language feature and just validate string literals in that context to verify they're okay in much the same way you describe here. There was value in breaking that out differently though, partly because it makes very clear what will and what will not be validated.

I don't think force-unwrapping is exactly an anti pattern, but it is one of the less desirable patterns, and I do think it should be avoided where cleanly possible.

···

On Dec 16, 2016, at 8:14 PM, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

On Fri, Dec 16, 2016 at 8:00 PM, Micah Hainline <micah.hainline@gmail.com> wrote:

We'll have to agree to disagree about the value of getting rid of the force-unwrap.

I suppose we may have to. But I hope to have convinced you that what you're really getting at here are two issues that can be separated. The two are:

1. The developer experience of using failable initializers invoked with hardcoded arguments is sub-par. For URL, or for any other type where success or failure of initialization is determined entirely by the arguments passed in, it would be nice to have the compiler tell you _at compile time_ if the hardcoded arguments are guaranteed to cause the initializer to return nil. I think this is quite an insightful point.

2. You do not like working with force unwrapping. While certainly entitled to that opinion, I do not think this opinion alone (since it is separable from (1)) can justify additions or subtractions to the language. Either force unwrapping is a legitimate part of the language--that is, the community that designs Swift can agree on specific patterns where its use is considered best practice--or it is an anti-pattern that should be deprecated and eventually removed. It cannot be a lingering yet fully supported first-class anti-pattern that we design standard and core library APIs actively to avoid.

On Dec 16, 2016, at 7:54 PM, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

On Fri, Dec 16, 2016 at 7:44 PM, Micah Hainline <micah.hainline@gmail.com> wrote:
Noted, but again while force-unwrapping it is the best we have, compile-time checking would be even better.

Sure, I'm certainly not opposed to flagging more errors at compile time. But it's possible to do that without adding new syntax to the language, which (just MHO) is rarely the best solution when a good alternative exists.

Here, for instance, one could add compiler magic that warns at compile time that `URL(string: "notavalidurl")!` is guaranteed to fail. That could be a diagnostics/QoI improvement that almost certainly wouldn't require going through the evolution process.

What I was trying to point out is that I agree with Derrick that the _spelling_ `URL(string: "https://example.com/")!` is perfectly fine and not in need of improvement, and that I disagree strongly that force unwrapping is problematic as a matter of style.

On Dec 16, 2016, at 7:30 PM, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

On Fri, Dec 16, 2016 at 7:01 PM, Micah Hainline <micah.hainline@gmail.com> wrote:
It's not super strong, but it's as strong as the URL type itself.

Even if I do checking related to the resource being unavailable, I also have to do checking to account for the possibility of a nil URL. The two checks aren't closely related.

When you use a URL, what would you do differently when a resource is unavailable versus when the URL is malformed, especially if you're hardcoding the URL?

It does help to have one of them accounted for by the compiler if possible.

I'm trying to teach some less experienced developers to think of force-unwrapping as a code smell,

There have been a few people who have said a similar thing on the list, but I don't think this is the official line about force-unwrapping. Force unwrapping is an explicitly supported part of the language that has its uses. If you *know* at the time of writing that a failable initializer should never fail, then `!` is an expressive, clear, concise, entirely appropriate, and I would even say the *best* way of indicating that to your reader.

It should be noted that `let url = URL(string: "http://example.com/")!` is one example of this usage, but not at all the only one. I have previously written, for example, `"L".cString(using: .utf8)!`. This is also no code smell, as what I'm doing is stating my absolute confidence (and indicating that confidence to the reader) that the letter L can be encoded using UTF-8.

but it's not the best to have to say "except for URLs". I realize the utility of the proposed change is reasonably small, but I also think it's purely additive and consistent with the rest of the language. :slightly_smiling_face:

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

On Fri, Dec 16, 2016 at 5:54 PM, Micah Hainline via swift-evolution <swift-evolution@swift.org> wrote:
True, but it's not at all about brevity, it's about type-safety and getting compile-time checking rather than runtime checking of the validity of the URL structure.

While I understand that what you're after is compile-time checking of validity, I'm not convinced that it is materially useful. I also don't see how it's contributing to type safety. Perhaps you could illuminate what use case has persuaded you of these things? Here's my thinking:

Nine times out of ten when I mistype a URL, or paste only a fragment of a URL, it's a mistake that results in a plausible but unintended URL and a compile-time check for validity will not help at all. To guard against such an error, I need to write tests anyway and could never depend on the compiler. In fact, I'd imagine that doing anything useful with a URL--even a hardcoded one--will require some thought as to how to deal with error handling at runtime. How is it helpful to have only the lowest bar (a technically valid URL format) ensured at compile time instead of runtime? By contrast, Swift selectors help to guarantee that any particular function I'm referring to actually exists; when that is ensured at compile time, I know it will be the case at runtime. There's no corresponding guarantee by having a compile-time check for URL validity that the resource pointed to will actually exist. That the nonexistent resource was denoted by a string that had the correct format of a URL is cold comfort, no?

On Dec 16, 2016, at 5:50 PM, Derrick Ho <wh1pch81n@gmail.com> wrote:

let url = URL(string: "https://example.com")!

let url = #url("https://example.com")

Are not that different in length. It really isn't saving you much.

I suppose you can try overloading an operator to get something to the effect you want.

On Fri, Dec 16, 2016 at 6:19 PM Micah Hainline via swift-evolution <swift-evolution@swift.org> wrote:
Exactly! It's not an earth-shattering pain, but it would be nice to have clean type safety there.

> On Dec 16, 2016, at 4:01 PM, Charlie Monroe <charlie@charliemonroe.net> wrote:
>
>
>>> On Dec 16, 2016, at 10:05 PM, Charles Srstka via swift-evolution <swift-evolution@swift.org> wrote:
>>>
>>> On Dec 16, 2016, at 2:46 PM, Micah Hainline via swift-evolution <swift-evolution@swift.org> wrote:
>>>
>>> I would like to be able to create a URL literal that is compile-time
>>> checked for correct format. This would help avoid code like this:
>>>
>>> let url: URL = URL(string: "https://example.com")!
>>>
>>> The cleanest way I can think of doing that would be to introduce a new
>>> macro structure similar to #selector, though I'm open to other ideas.
>>> I would think it should take a quoted literal string to avoid
>>> problems. That would look like this:
>>>
>>> let url: URL = #url("https://example.com")
>>>
>>> What does everyone think of that idea?
>>> _______________________________________________
>>> swift-evolution mailing list
>>> swift-evolution@swift.org
>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>
>>
>> I’d like to see something like that for file path URLs. For something so commonly used, URL(fileURLWithPath:) is obnoxiously verbose.
>>
>> Charles
>
> Yes, but it's not a nullable initializer. With URL(string:) the incredible pain is that even compile-time URLs to your own website are nullable URL? and you need to force-unwrap them.
>
>>
>> _______________________________________________
>> 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


(Xiaodi Wu) #20

Actually, a syntax similar to the one I described was considered for
selectors; it was rejected in favor of #selector because something like
Selector(Foo.bar) is apparently more difficult to implement, and the core
team said that "on balance, we didn't want to introduce type system
complexities for relatively rare ObjC interop features".

However, I would think that the general issue of compiler help to indicate
when certain initializers are guaranteed to fail is the opposite of a
"relatively rare interop feature" and deserves perhaps a more holistic
treatment rather than a selector-like quick-fix for URLs only.

···

On Fri, Dec 16, 2016 at 20:33 Micah Hainline <micah.hainline@gmail.com> wrote:

Absolutely. Good breakdown of the issues. I will draw a parallel with
#selector though for past precedent. It wouldn't have been much different
to just use the string-based Selector creation instead of creating a new
language feature and just validate string literals in that context to
verify they're okay in much the same way you describe here. There was value
in breaking that out differently though, partly because it makes very clear
what will and what will not be validated.

I don't think force-unwrapping is exactly an anti pattern, but it is one
of the less desirable patterns, and I do think it should be avoided where
cleanly possible.

On Dec 16, 2016, at 8:14 PM, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

On Fri, Dec 16, 2016 at 8:00 PM, Micah Hainline <micah.hainline@gmail.com> > wrote:

We'll have to agree to disagree about the value of getting rid of the
force-unwrap.

I suppose we may have to. But I hope to have convinced you that what
you're really getting at here are two issues that can be separated. The two
are:

1. The developer experience of using failable initializers invoked with
hardcoded arguments is sub-par. For URL, or for any other type where
success or failure of initialization is determined entirely by the
arguments passed in, it would be nice to have the compiler tell you _at
compile time_ if the hardcoded arguments are guaranteed to cause the
initializer to return nil. I think this is quite an insightful point.

2. You do not like working with force unwrapping. While certainly entitled
to that opinion, I do not think this opinion alone (since it is separable
from (1)) can justify additions or subtractions to the language. Either
force unwrapping is a legitimate part of the language--that is, the
community that designs Swift can agree on specific patterns where its use
is considered best practice--or it is an anti-pattern that should be
deprecated and eventually removed. It cannot be a lingering yet fully
supported first-class anti-pattern that we design standard and core library
APIs actively to avoid.

On Dec 16, 2016, at 7:54 PM, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

On Fri, Dec 16, 2016 at 7:44 PM, Micah Hainline <micah.hainline@gmail.com> > wrote:

Noted, but again while force-unwrapping it is the best we have,
compile-time checking would be even better.

Sure, I'm certainly not opposed to flagging more errors at compile time.
But it's possible to do that without adding new syntax to the language,
which (just MHO) is rarely the best solution when a good alternative exists.

Here, for instance, one could add compiler magic that warns at compile
time that `URL(string: "notavalidurl")!` is guaranteed to fail. That could
be a diagnostics/QoI improvement that almost certainly wouldn't require
going through the evolution process.

What I was trying to point out is that I agree with Derrick that the
_spelling_ `URL(string: "https://example.com/")!` is perfectly fine and
not in need of improvement, and that I disagree strongly that force
unwrapping is problematic as a matter of style.

On Dec 16, 2016, at 7:30 PM, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

On Fri, Dec 16, 2016 at 7:01 PM, Micah Hainline <micah.hainline@gmail.com> > wrote:

It's not super strong, but it's as strong as the URL type itself.

Even if I do checking related to the resource being unavailable, I also
have to do checking to account for the possibility of a nil URL. The two
checks aren't closely related.

When you use a URL, what would you do differently when a resource is
unavailable versus when the URL is malformed, especially if you're
hardcoding the URL?

It does help to have one of them accounted for by the compiler if possible.

I'm trying to teach some less experienced developers to think of
force-unwrapping as a code smell,

There have been a few people who have said a similar thing on the list,
but I don't think this is the official line about force-unwrapping. Force
unwrapping is an explicitly supported part of the language that has its
uses. If you *know* at the time of writing that a failable initializer
should never fail, then `!` is an expressive, clear, concise, entirely
appropriate, and I would even say the *best* way of indicating that to your
reader.

It should be noted that `let url = URL(string: "http://example.com/")!`
is one example of this usage, but not at all the only one. I have
previously written, for example, `"L".cString(using: .utf8)!`. This is also
no code smell, as what I'm doing is stating my absolute confidence (and
indicating that confidence to the reader) that the letter L can be encoded
using UTF-8.

but it's not the best to have to say "except for URLs". I realize the
utility of the proposed change is reasonably small, but I also think it's
purely additive and consistent with the rest of the language. :slightly_smiling_face:

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

On Fri, Dec 16, 2016 at 5:54 PM, Micah Hainline via swift-evolution < > swift-evolution@swift.org> wrote:

True, but it's not at all about brevity, it's about type-safety and
getting compile-time checking rather than runtime checking of the validity
of the URL structure.

While I understand that what you're after is compile-time checking of
validity, I'm not convinced that it is materially useful. I also don't see
how it's contributing to type safety. Perhaps you could illuminate what use
case has persuaded you of these things? Here's my thinking:

Nine times out of ten when I mistype a URL, or paste only a fragment of a
URL, it's a mistake that results in a plausible but unintended URL and a
compile-time check for validity will not help at all. To guard against such
an error, I need to write tests anyway and could never depend on the
compiler. In fact, I'd imagine that doing anything useful with a URL--even
a hardcoded one--will require some thought as to how to deal with error
handling at runtime. How is it helpful to have only the lowest bar (a
technically valid URL format) ensured at compile time instead of runtime?
By contrast, Swift selectors help to guarantee that any particular function
I'm referring to actually exists; when that is ensured at compile time, I
know it will be the case at runtime. There's no corresponding guarantee by
having a compile-time check for URL validity that the resource pointed to
will actually exist. That the nonexistent resource was denoted by a string
that had the correct format of a URL is cold comfort, no?

On Dec 16, 2016, at 5:50 PM, Derrick Ho <wh1pch81n@gmail.com> wrote:

let url = URL(string: "https://example.com")!

let url = #url("https://example.com")

Are not that different in length. It really isn't saving you much.

I suppose you can try overloading an operator to get something to the
effect you want.
On Fri, Dec 16, 2016 at 6:19 PM Micah Hainline via swift-evolution < > swift-evolution@swift.org> wrote:

Exactly! It's not an earth-shattering pain, but it would be nice to have
clean type safety there.

> On Dec 16, 2016, at 4:01 PM, Charlie Monroe <charlie@charliemonroe.net> > wrote:
>
>
>>> On Dec 16, 2016, at 10:05 PM, Charles Srstka via swift-evolution < > swift-evolution@swift.org> wrote:
>>>
>>> On Dec 16, 2016, at 2:46 PM, Micah Hainline via swift-evolution < > swift-evolution@swift.org> wrote:
>>>
>>> I would like to be able to create a URL literal that is compile-time
>>> checked for correct format. This would help avoid code like this:
>>>
>>> let url: URL = URL(string: "https://example.com")!
>>>
>>> The cleanest way I can think of doing that would be to introduce a new
>>> macro structure similar to #selector, though I'm open to other ideas.
>>> I would think it should take a quoted literal string to avoid
>>> problems. That would look like this:
>>>
>>> let url: URL = #url("https://example.com")
>>>
>>> What does everyone think of that idea?
>>> _______________________________________________
>>> swift-evolution mailing list
>>> swift-evolution@swift.org
>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>
>>
>> I’d like to see something like that for file path URLs. For something
so commonly used, URL(fileURLWithPath:) is obnoxiously verbose.
>>
>> Charles
>
> Yes, but it's not a nullable initializer. With URL(string:) the
incredible pain is that even compile-time URLs to your own website are
nullable URL? and you need to force-unwrap them.
>
>>
>> _______________________________________________
>> 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