[swift-evolution] [Discussion] What is the future of tuples in Swift?

Tony Allevato tony.allevato at gmail.com
Thu Mar 2 18:56:26 CST 2017


newtype feels like a leaky abstraction. Since the new type carries all the
protocol conformance and members of the original type, in your example, I
could add or divide RecordIds; but if they're database concepts, why would
I want to do that?

If the original type were extended to add members or protocols, would the
newtype gain those as well? It must, since types can be split into
extensions like that in Swift a priori. So the new type is always
effectively a subtype of the original, when what you often want is
something that starts off with a smaller subset of its operations instead,
and people can extend it in ways you don't expect.

I'm trying to imagine types where I automatically want *every* operation of
its originating type, and having trouble. Even for a unit-like API, there
are likely to be arithmetic operations that don't make sense.

I think a better model would be a general protocol forwarding mechanism for
existing type constructs. Then I could define RecordId as a struct,
internally it might have an underlying Int representation, but I would
explicitly state which protocols I wanted the type to conform to and which
of those are forwarded to that underlying Int. This allows us to maintain
the semantic importance of protocols and build types in a way that fits
existing Swift patterns, and without the magic/danger that newtype could
provide.

The drawback is that if you want only a subset of operations in a protocol,
you don't get that easily for free. But you could define your own protocol,
retroactively conform the origin type to it *internally*, and then publicly
conform the new type and forward... and as far as I can tell, that plugs
the abstraction's leaks.
On Thu, Mar 2, 2017 at 4:08 PM Anton Zhilin via swift-evolution <
swift-evolution at swift.org> wrote:

> 2017-03-03 2:13 GMT+03:00 Slava Pestov <spestov at apple.com>:
>
> Does newtype add any new capability that’s not already covered by defining
> a struct?
>
> newtype would forward all members and conformances of the underlying type:
>
> newtype RecordId = Int
> let x: RecordId = 5let y = x + 10
> extension RecordId {
>     func load() -> String { … }
> }
> let a = x.load()let b = 42.load()  // error
>
> newtypes aim to carry purely semantic information, in this case, that
> those integers can be used to fetch records from a database. We get
> additional members only when we are sure that semantic of current instance
> is appropriate.
>
> As a side effect, it essentially allows to declare one-liner structs with
> pattern matching. But I agree with Jaden, just adding pattern matching to
> structs feels more practical. And this feature is more or less orthogonal
> to the core functionality of newtype.
>> _______________________________________________
> 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/20170303/59dae4ef/attachment.html>


More information about the swift-evolution mailing list