[swift-evolution] URL Literals

Xiaodi Wu xiaodi.wu at gmail.com
Fri Dec 16 20:14:36 CST 2016


On Fri, Dec 16, 2016 at 8:00 PM, Micah Hainline <micah.hainline at 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 at gmail.com> wrote:
>
> On Fri, Dec 16, 2016 at 7:44 PM, Micah Hainline <micah.hainline at 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 at gmail.com> wrote:
>>
>> On Fri, Dec 16, 2016 at 7:01 PM, Micah Hainline <micah.hainline at 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. 🙂
>>>
>>> On Dec 16, 2016, at 6:45 PM, Xiaodi Wu <xiaodi.wu at gmail.com> wrote:
>>>
>>> On Fri, Dec 16, 2016 at 5:54 PM, Micah Hainline via swift-evolution <
>>> swift-evolution at 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 at 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 at 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 at charliemonroe.net> wrote:
>>>>> >
>>>>> >
>>>>> >>> On Dec 16, 2016, at 10:05 PM, Charles Srstka via swift-evolution <
>>>>> swift-evolution at swift.org> wrote:
>>>>> >>>
>>>>> >>> On Dec 16, 2016, at 2:46 PM, Micah Hainline via swift-evolution <
>>>>> swift-evolution at 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 at 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 at swift.org
>>>>> >> https://lists.swift.org/mailman/listinfo/swift-evolution
>>>>> >
>>>>> _______________________________________________
>>>>> swift-evolution mailing list
>>>>> swift-evolution at swift.org
>>>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>>>>
>>>>
>>>> _______________________________________________
>>>> swift-evolution mailing list
>>>> swift-evolution at swift.org
>>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>>>
>>>>
>>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20161216/b411689b/attachment.html>


More information about the swift-evolution mailing list