[swift-evolution] Pitch: Limit typealias extensions to the typealias

Will Field-Thompson will.a.ft at gmail.com
Fri Jun 9 10:41:50 CDT 2017


I feel like this might be better served by something like newtype which I
know I've seen floating around on this list before. The idea is that
something like:

newtype HeaderKey = String

would serve roughly as syntactic sugar for something like

struct HeaderKey {
   let value: String
   init(_ value: String) { self.value = value }
   /* Possibly insert methods from String here, possibly do something else,
whatever */
}

I've always thought this might be interesting, but there's a few reasons I
suggest it in place of extending a typealias:
1) Backwards compatibility — this could very easily break existing code
2) Semantically it seems to me that an *alias* is a useful distinction
from *"let's
make a new type" *— sometimes you actually just want to call one type by
another name in some context

Regardless, I think you could solve your particular problem like this:

public struct HeaderKey {
   let value: String
   public init(_ value: String) { self.value = value }
}

and conform HeaderKey to ExpressibleByStringLiteral. That way your
framework's users can still use headers[.lastModified] and
headers["X-MyHeader"] syntax, and it makes your library's code only very
slightly more complicated.

Not trying to tell you how to write your library, but this approach worked
really well for me recently.

Best,

Will

On Fri, Jun 9, 2017 at 12:14 AM Yvo van Beek via swift-evolution <
swift-evolution at swift.org> wrote:

> Typealiases can greatly reduce the complexity of code. But I think one
> change in how the compiler handles them could make them even more powerful.
>
> Let's say I'm creating a web server framework and I've created a simple
> dictionary to store HTTP headers (I know that headers are more complex than
> that, but as an example). I could write something like this:
>
>     typealias HeaderKey = String
>
>   var headers = [HeaderKey: String]()
>   headers["Host"] = "domain.com"
>
> Now I can define a couple of default headers like this:
>
>   extension HeaderKey {
>     static var lastModified: String { return "Last-Modified" }
>     static var host: String { return "Host" }
>   }
>
> After that I can do this:
>
>   var headers = [HeaderKey: String]()
>   headers[.host] = "domain.com"
>   headers[.lastModified] = "some date"
>   headers["X-MyHeader"] = "This still works too"
>
> But unfortunately the extension is also applied to normal strings:
>
>     var normalString: String = .host
>
> Perhaps it would be better if the extension would only apply to the parts
> of my code where I use the HeaderKey typealias and not to all Strings. This
> could be a great tool to specialize classes by creating a typealias and
> adding functionality to it. Another example I can think of is typealiases
> for dictionaries or arrays with added business logic through extensions
> (especially since you can't inherit from structs).
>
> If you want to create an extension that adds functionality to all Strings
> you could have created an extension for String instead of HeaderKey.
>
> Please let me know what you think. I'm not sure how complex this change
> would be.
> I could write a proposal if you're interested.
>
> Kind regards,
> Yvo
> _______________________________________________
> 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/20170609/5ebe8a67/attachment.html>


More information about the swift-evolution mailing list