+1. Tony’s static evaluation idea also crossed my mind when reading this thread.
> On Dec 17, 2016, at 10:52 AM, Tony Allevato via swift-evolution > <[email protected]> wrote: > > If folks want to go down this path, it: > > * shouldn't require compiler magic > * shouldn't be restricted to specific types > * should be something that anyone can take advantage of in types that they > write. > > The most general approach that jumps immediately to my mind is letting users > write code in a restricted subset of the language that would be evaluated at > statically at compile time. It's getting into C++ "constexpr" territory, but > I wouldn't want to settle for something that tightly couples special behavior > to just a few types. > > Quick back of the napkin sketch, I haven't thought too much about syntax > details yet: > > struct URL: ExpressibleByStringLiteral { > // the #, or something similar, indicates this > // is compile-time evaluation > #init?(_ stringLiteral: StaticString) { > // validate the string. We'd be able to use > // loops and access individual characters > // in the static string... regexes would be > // trickier. > if valid { > // if we get here, everything we did > // will essentially "collapse" to this > // initializer call in the generated code > self.init(...)! > } else { > return nil > // need a way of emitting a more > // informational error message? > } > } > } > > There's still a lot of open questions to think through, like should this only > apply to literal conversions or any initializer signature where the > arguments' value can be known at compile time, but I wanted to toss out a > seedling of a different idea. I also don't know how much would have to change > within the compiler to provide this level of compile-time evaluation. > > > On Sat, Dec 17, 2016 at 5:57 AM Step C via swift-evolution > <[email protected] <mailto:[email protected]>> wrote: > Do you have a treatment in mind? > > Perhaps the compiler recognizes types/initializers it can check at compile > time (how?). Then it could synthesize non-failable initializers. > > Or would the author write a non-failable init with some type of annotation > that the parameters must be literals? (Here I am using literals to mean > values that are understood by the compiler.) > > - Step > > On Dec 16, 2016, at 9:46 PM, Xiaodi Wu via swift-evolution > <[email protected] <mailto:[email protected]>> wrote: > >> 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 <[email protected] >> <mailto:[email protected]>> 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 <[email protected] >> <mailto:[email protected]>> wrote: >> >>> On Fri, Dec 16, 2016 at 8:00 PM, Micah Hainline <[email protected] >>> <mailto:[email protected]>> 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 <[email protected] >>> <mailto:[email protected]>> wrote: >>> >>>> On Fri, Dec 16, 2016 at 7:44 PM, Micah Hainline <[email protected] >>>> <mailto:[email protected]>> 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/ <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 <[email protected] >>>> <mailto:[email protected]>> wrote: >>>> >>>>> On Fri, Dec 16, 2016 at 7:01 PM, Micah Hainline <[email protected] >>>>> <mailto:[email protected]>> 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/ >>>>> <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 <[email protected] >>>>> <mailto:[email protected]>> wrote: >>>>> >>>>>> On Fri, Dec 16, 2016 at 5:54 PM, Micah Hainline via swift-evolution >>>>>> <[email protected] <mailto:[email protected]>> 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 <[email protected] >>>>>> <mailto:[email protected]>> wrote: >>>>>> >>>>>>> let url = URL(string: "https://example.com <https://example.com/>")! >>>>>>> >>>>>>> let url = #url("https://example.com <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 >>>>>>> <[email protected] <mailto:[email protected]>> 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 >>>>>>> > <[email protected] <mailto:[email protected]>> wrote: >>>>>>> >>>>>>> >>>>>>> > >>>>>>> >>>>>>> >>>>>>> > >>>>>>> >>>>>>> >>>>>>> >>> On Dec 16, 2016, at 10:05 PM, Charles Srstka via swift-evolution >>>>>>> >>> <[email protected] <mailto:[email protected]>> >>>>>>> >>> wrote: >>>>>>> >>>>>>> >>>>>>> >>> >>>>>>> >>>>>>> >>>>>>> >>> On Dec 16, 2016, at 2:46 PM, Micah Hainline via swift-evolution >>>>>>> >>> <[email protected] <mailto:[email protected]>> >>>>>>> >>> 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 >>>>>>> >>> <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 <https://example.com/>") >>>>>>> >>>>>>> >>>>>>> >>> >>>>>>> >>>>>>> >>>>>>> >>> What does everyone think of that idea? >>>>>>> >>>>>>> >>>>>>> >>> _______________________________________________ >>>>>>> >>>>>>> >>>>>>> >>> swift-evolution mailing list >>>>>>> >>>>>>> >>>>>>> >>> [email protected] <mailto:[email protected]> >>>>>>> >>>>>>> >>>>>>> >>> https://lists.swift.org/mailman/listinfo/swift-evolution >>>>>>> >>> <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 >>>>>>> >>>>>>> >>>>>>> >> [email protected] <mailto:[email protected]> >>>>>>> >>>>>>> >>>>>>> >> https://lists.swift.org/mailman/listinfo/swift-evolution >>>>>>> >> <https://lists.swift.org/mailman/listinfo/swift-evolution> >>>>>>> >>>>>>> >>>>>>> > >>>>>>> >>>>>>> >>>>>>> _______________________________________________ >>>>>>> >>>>>>> >>>>>>> swift-evolution mailing list >>>>>>> >>>>>>> >>>>>>> [email protected] <mailto:[email protected]> >>>>>>> >>>>>>> >>>>>>> https://lists.swift.org/mailman/listinfo/swift-evolution >>>>>>> <https://lists.swift.org/mailman/listinfo/swift-evolution> >>>>>>> >>>>>>> >>>>>>> >>>>>>> >>>>>> >>>>>> _______________________________________________ >>>>>> >>>>>> >>>>>> swift-evolution mailing list >>>>>> >>>>>> >>>>>> [email protected] <mailto:[email protected]> >>>>>> >>>>>> >>>>>> https://lists.swift.org/mailman/listinfo/swift-evolution >>>>>> <https://lists.swift.org/mailman/listinfo/swift-evolution> >>>>>> >>>>>> >>>>>> >>>>>> >>>>>> >>>>>> >>>>> >>>>> >>>>> >>>> >>>> >>>> >>> >>> >>> >> >> >> _______________________________________________ >> swift-evolution mailing list >> [email protected] <mailto:[email protected]> >> https://lists.swift.org/mailman/listinfo/swift-evolution >> <https://lists.swift.org/mailman/listinfo/swift-evolution> > _______________________________________________ > > swift-evolution mailing list > > [email protected] <mailto:[email protected]> > > https://lists.swift.org/mailman/listinfo/swift-evolution > <https://lists.swift.org/mailman/listinfo/swift-evolution> > > _______________________________________________ > swift-evolution mailing list > [email protected] > https://lists.swift.org/mailman/listinfo/swift-evolution
_______________________________________________ swift-evolution mailing list [email protected] https://lists.swift.org/mailman/listinfo/swift-evolution
