Associatedtype Naming Conventions


(Steven Brunwasser) #1

Hi,

I have a library which uses a few generic protocols with identically named
associated types that may not always be specified identically by
implementors.

protocol Foo {
associatedtype Container
associatedtype Element
}

protocol Bar {
associatedtype Container
associatedtype Element
}

struct Baz: Foo, Bar {
// Implement using two different Container/Element types.
}

Is there a consensus on some naming convention for associatedtypes to
mitigate name collisions?
Would it be acceptable to add namespace prefixes to these types?

protocol Foo {
associatedtype FooContainer
associatedtype FooElement
}

I’m using the dictionary and thesaurus to find some alternative names I
could use, but the ones already used are so the most sensical semantically.

Do you have any suggestions?

Thanks,
- Steve Brunwasser


(Slava Pestov) #2

Can you give an example of a problematic name collision? Does fully qualifying names not help?

Slava

···

On May 31, 2017, at 4:01 PM, Steven Brunwasser via swift-users <swift-users@swift.org> wrote:

Hi,

I have a library which uses a few generic protocols with identically named associated types that may not always be specified identically by implementors.

  protocol Foo {
    associatedtype Container
    associatedtype Element
  }

  protocol Bar {
    associatedtype Container
    associatedtype Element
  }

  struct Baz: Foo, Bar {
    // Implement using two different Container/Element types.
  }

Is there a consensus on some naming convention for associatedtypes to mitigate name collisions?
Would it be acceptable to add namespace prefixes to these types?

  protocol Foo {
    associatedtype FooContainer
    associatedtype FooElement
  }

I’m using the dictionary and thesaurus to find some alternative names I could use, but the ones already used are so the most sensical semantically.

Do you have any suggestions?

Thanks,
- Steve Brunwasser
_______________________________________________
swift-users mailing list
swift-users@swift.org <mailto:swift-users@swift.org>
https://lists.swift.org/mailman/listinfo/swift-users


(Steven Brunwasser) #3

By fully qualifying names, do you mean something like this?

struct Baz: Foo, Bar {
typealias Foo.Container = A
typealias Bar.Container = B
}

This seems to be invalid, at least in Swift 3.1.

Basically, my library contains a bunch of collection-like protocols, which
can be combined in different ways and can be compatible with each other in
certain combinations when the proper types align. Naturally, they all have
an Element associatedtype, but I need to allow for the possibility where
two of these collection protocols are implemented in the same structure
that requires different type definitions for each protocols' Element.

I’ve been trying to make some other protocols to simplify some definitions,
but specifying a parent protocol’s associated type within a child protocol
doesn’t seem to work.

protocol Buzz: Bar {
typealias Container = A
}

struct BuzzImpl: Buzz {} // *error: type ‘BuzzImpl' does not conform to
protocol ‘Buzz'*

···

On May 31, 2017 at 4:02:43 PM, Slava Pestov (spestov@apple.com) wrote:

Can you give an example of a problematic name collision? Does fully
qualifying names not help?

Slava

On May 31, 2017, at 4:01 PM, Steven Brunwasser via swift-users < swift-users@swift.org> wrote:

Hi,

I have a library which uses a few generic protocols with identically named
associated types that may not always be specified identically by
implementors.

protocol Foo {
associatedtype Container
associatedtype Element
}

protocol Bar {
associatedtype Container
associatedtype Element
}

struct Baz: Foo, Bar {
// Implement using two different Container/Element types.
}

Is there a consensus on some naming convention for associatedtypes to
mitigate name collisions?
Would it be acceptable to add namespace prefixes to these types?

protocol Foo {
associatedtype FooContainer
associatedtype FooElement
}

I’m using the dictionary and thesaurus to find some alternative names I
could use, but the ones already used are so the most sensical semantically.

Do you have any suggestions?

Thanks,
- Steve Brunwasser
_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


(Slava Pestov) #4

Basically, my library contains a bunch of collection-like protocols, which can be combined in different ways and can be compatible with each other in certain combinations when the proper types align. Naturally, they all have an Element associatedtype, but I need to allow for the possibility where two of these collection protocols are implemented in the same structure that requires different type definitions for each protocols' Element.

Oh, I understand now. This is intentionally not supported — associated types with the same name from different protocols must all be implemented by the same typealias in the conforming type.

Slava

···

On May 31, 2017, at 4:16 PM, Steven Brunwasser <sbrunwasser@gmail.com> wrote:

I’ve been trying to make some other protocols to simplify some definitions, but specifying a parent protocol’s associated type within a child protocol doesn’t seem to work.

  protocol Buzz: Bar {
    typealias Container = A
  }

  struct BuzzImpl: Buzz {} // error: type ‘BuzzImpl' does not conform to protocol ‘Buzz'

On May 31, 2017 at 4:02:43 PM, Slava Pestov (spestov@apple.com <mailto:spestov@apple.com>) wrote:

Can you give an example of a problematic name collision? Does fully qualifying names not help?

Slava

On May 31, 2017, at 4:01 PM, Steven Brunwasser via swift-users <swift-users@swift.org <mailto:swift-users@swift.org>> wrote:

Hi,

I have a library which uses a few generic protocols with identically named associated types that may not always be specified identically by implementors.

protocol Foo {
associatedtype Container
associatedtype Element
}

protocol Bar {
associatedtype Container
associatedtype Element
}

struct Baz: Foo, Bar {
// Implement using two different Container/Element types.
}

Is there a consensus on some naming convention for associatedtypes to mitigate name collisions?
Would it be acceptable to add namespace prefixes to these types?

protocol Foo {
associatedtype FooContainer
associatedtype FooElement
}

I’m using the dictionary and thesaurus to find some alternative names I could use, but the ones already used are so the most sensical semantically.

Do you have any suggestions?

Thanks,
- Steve Brunwasser
_______________________________________________
swift-users mailing list
swift-users@swift.org <mailto:swift-users@swift.org>
https://lists.swift.org/mailman/listinfo/swift-users


(Steven Brunwasser) #5

Yes, I understand this. I was just wondering if there was a naming
convention I should use to differentiate them.

Should I use a few letters as a prefix? Should I use the full protocol name
as a prefix? Or is there another suggestion for a naming convention?

I'm also curious about any naming conventions I should use to get around
collisions with other libraries' protocol associatedtypes.

···

On May 31, 2017 at 16:26:52, Slava Pestov (spestov@apple.com) wrote:

On May 31, 2017, at 4:16 PM, Steven Brunwasser <sbrunwasser@gmail.com> > wrote:

Basically, my library contains a bunch of collection-like protocols, which
can be combined in different ways and can be compatible with each other in
certain combinations when the proper types align. Naturally, they all have
an Element associatedtype, but I need to allow for the possibility where
two of these collection protocols are implemented in the same structure
that requires different type definitions for each protocols' Element.

Oh, I understand now. This is intentionally not supported — associated
types with the same name from different protocols must all be implemented
by the same typealias in the conforming type.

Slava

I’ve been trying to make some other protocols to simplify some
definitions, but specifying a parent protocol’s associated type within a
child protocol doesn’t seem to work.

protocol Buzz: Bar {
typealias Container = A
}

struct BuzzImpl: Buzz {} // *error: type ‘BuzzImpl' does not conform to
protocol ‘Buzz'*

On May 31, 2017 at 4:02:43 PM, Slava Pestov (spestov@apple.com) wrote:

Can you give an example of a problematic name collision? Does fully
qualifying names not help?

Slava

On May 31, 2017, at 4:01 PM, Steven Brunwasser via swift-users < > swift-users@swift.org> wrote:

Hi,

I have a library which uses a few generic protocols with identically named
associated types that may not always be specified identically by
implementors.

protocol Foo {
associatedtype Container
associatedtype Element
}

protocol Bar {
associatedtype Container
associatedtype Element
}

struct Baz: Foo, Bar {
// Implement using two different Container/Element types.
}

Is there a consensus on some naming convention for associatedtypes to
mitigate name collisions?
Would it be acceptable to add namespace prefixes to these types?

protocol Foo {
associatedtype FooContainer
associatedtype FooElement
}

I’m using the dictionary and thesaurus to find some alternative names I
could use, but the ones already used are so the most sensical semantically.

Do you have any suggestions?

Thanks,
- Steve Brunwasser
_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


(Dave Abrahams) #6

Yes, I understand this. I was just wondering if there was a naming
convention I should use to differentiate them.

I would try to find something more specific and descriptive than
“Container” and “Element” if you think there's a chance they would ever
arise as associated types of the same type but with distinct identity.

Another possibility, if you think that might be about to happen, is that
you're using conformance when you should use aggregation. For example,
an Int has everything it needs to be a Sequence and/or Iterator (n to
infinity), a Collection (of numbers from zero to its bitWidth), etc.,
but *should* it conform to those protocols? IMO probably not. If you
find yourself hard pressed to describe what something *is* in a few
words, it may be conforming to too many protocols.

···

on Wed May 31 2017, Steven Brunwasser <swift-users-AT-swift.org> wrote:

Should I use a few letters as a prefix? Should I use the full protocol name
as a prefix? Or is there another suggestion for a naming convention?

I'm also curious about any naming conventions I should use to get around
collisions with other libraries' protocol associatedtypes.

On May 31, 2017 at 16:26:52, Slava Pestov (spestov@apple.com) wrote:

On May 31, 2017, at 4:16 PM, Steven Brunwasser <sbrunwasser@gmail.com> >> wrote:

Basically, my library contains a bunch of collection-like protocols, which
can be combined in different ways and can be compatible with each other in
certain combinations when the proper types align. Naturally, they all have
an Element associatedtype, but I need to allow for the possibility where
two of these collection protocols are implemented in the same structure
that requires different type definitions for each protocols' Element.

Oh, I understand now. This is intentionally not supported — associated
types with the same name from different protocols must all be implemented
by the same typealias in the conforming type.

Slava

I’ve been trying to make some other protocols to simplify some
definitions, but specifying a parent protocol’s associated type within a
child protocol doesn’t seem to work.

protocol Buzz: Bar {
typealias Container = A
}

struct BuzzImpl: Buzz {} // *error: type ‘BuzzImpl' does not conform to
protocol ‘Buzz'*

On May 31, 2017 at 4:02:43 PM, Slava Pestov (spestov@apple.com) wrote:

Can you give an example of a problematic name collision? Does fully
qualifying names not help?

Slava

On May 31, 2017, at 4:01 PM, Steven Brunwasser via swift-users < >> swift-users@swift.org> wrote:

Hi,

I have a library which uses a few generic protocols with identically named
associated types that may not always be specified identically by
implementors.

protocol Foo {
associatedtype Container
associatedtype Element
}

protocol Bar {
associatedtype Container
associatedtype Element
}

struct Baz: Foo, Bar {
// Implement using two different Container/Element types.
}

Is there a consensus on some naming convention for associatedtypes to
mitigate name collisions?
Would it be acceptable to add namespace prefixes to these types?

protocol Foo {
associatedtype FooContainer
associatedtype FooElement
}

I’m using the dictionary and thesaurus to find some alternative names I
could use, but the ones already used are so the most sensical semantically.

Do you have any suggestions?

Thanks,
- Steve Brunwasser
_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users

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

--
-Dave


(Karl) #7

Additionally, I find that when a type is representable in multiple overlapping ways (where “overlapping” is meant quite broadly), it can be good to create wrappers for those conformances.

For example, you might try:

Struct MyThing {
}

extension MyThing {

    var foo: Foo { return MyThing.FooWrapper(self) }
    var bar: Bar { return MyThing.BarWrapper(self) }

    struct FooWrapper: Foo {
        let base: MyThing
        init(_ wrapping: MyThing) { self.base = wrapping }

        // Implement ‘Foo’ using data from ‘base’.
    }
}

let something = MyThing()

takesAFoo(something.foo)
takesABar(something.bar)

This is analogous to how String is represented — the data is stored once, and there are multiple Collection conformances which interpret the data in different ways (as graphemes, or as a collection of non-character-boundary code-units in various encodings).

···

On 7. Jun 2017, at 00:25, Dave Abrahams via swift-users <swift-users@swift.org> wrote:

on Wed May 31 2017, Steven Brunwasser <swift-users-AT-swift.org <http://swift-users-at-swift.org/>> wrote:

Yes, I understand this. I was just wondering if there was a naming
convention I should use to differentiate them.

I would try to find something more specific and descriptive than
“Container” and “Element” if you think there's a chance they would ever
arise as associated types of the same type but with distinct identity.

Another possibility, if you think that might be about to happen, is that
you're using conformance when you should use aggregation. For example,
an Int has everything it needs to be a Sequence and/or Iterator (n to
infinity), a Collection (of numbers from zero to its bitWidth), etc.,
but *should* it conform to those protocols? IMO probably not. If you
find yourself hard pressed to describe what something *is* in a few
words, it may be conforming to too many protocols.


(Dave Abrahams) #8

Yes, I understand this. I was just wondering if there was a naming
convention I should use to differentiate them.

I would try to find something more specific and descriptive than
“Container” and “Element” if you think there's a chance they would ever
arise as associated types of the same type but with distinct identity.

Another possibility, if you think that might be about to happen, is that
you're using conformance when you should use aggregation. For example,
an Int has everything it needs to be a Sequence and/or Iterator (n to
infinity), a Collection (of numbers from zero to its bitWidth), etc.,
but *should* it conform to those protocols? IMO probably not. If you
find yourself hard pressed to describe what something *is* in a few
words, it may be conforming to too many protocols.

Additionally, I find that when a type is representable in multiple
overlapping ways (where “overlapping” is meant quite broadly), it can
be good to create wrappers for those conformances.

Jah, that's what I meant to imply, but failed to spell out. Thanks for
clarifying, Karl!

···

on Tue Jun 06 2017, Karl Wagner <razielim-AT-gmail.com> wrote:

On 7. Jun 2017, at 00:25, Dave Abrahams via swift-users <swift-users@swift.org> wrote:
on Wed May 31 2017, Steven Brunwasser <swift-users-AT-swift.org > <http://swift-users-at-swift.org/>> wrote:

For example, you might try:

Struct MyThing {
}

extension MyThing {

    var foo: Foo { return MyThing.FooWrapper(self) }
    var bar: Bar { return MyThing.BarWrapper(self) }

    struct FooWrapper: Foo {
        let base: MyThing
        init(_ wrapping: MyThing) { self.base = wrapping }

        // Implement ‘Foo’ using data from ‘base’.
    }
}

let something = MyThing()

takesAFoo(something.foo)
takesABar(something.bar)

This is analogous to how String is represented — the data is stored once, and there are multiple
Collection conformances which interpret the data in different ways (as graphemes, or as a collection
of non-character-boundary code-units in various encodings).

--
-Dave