[Pitch] Update to Alternative Types (i.e. strong typedef) Proposal

Proposal at <https://gist.github.com/CTMacUser/c493f775075e946efdcfd85d38473291>, uploaded revision 4.

Changes:

Since the original setup was a poor copy of how raw-style enumerations use RawRepresentable, changed the model to actually use RawRepresentable. Actually, it uses a sub-protocol, AnyAlternative, which adds an associated type for the implementing non-alternative type. AnyAlternative also serves a function like AnyObject.
Removed the old library support type since it’s obsolete. Added back a (now global) function to upcast to the implementation type without needing to name it.
Added option to initialize alternative by assigning to “super.” Using “super” by itself isn’t allowed in the grammar (It has to be followed by a member specification), so I added it.
Added note about pointer compatibility.
The model change led to a lot of rewording. And new/changed technical terms.

···


Daryle Walker
Mac, Internet, and Video Game Junkie
darylew AT mac DOT com

I feel like I should mention that Clang has __attribute__((__swift_newtype__)) type attribute that replaces the imported type from typealias to a new RawRepresentable struct. Clang has a variety of poorly documented swift compatibility extensions like this (a lot of which I managed to discover, play with and determine the effect myself). I think this should be mentioned in your proposal, because it looks like this Clang attribute is begging to be re-modeled to use your alters.

···

On Jul 30, 2017, at 2:01 AM, Daryle Walker via swift-evolution <swift-evolution@swift.org> wrote:

Proposal at <https://gist.github.com/CTMacUser/c493f775075e946efdcfd85d38473291>, uploaded revision 4.

Changes:

Since the original setup was a poor copy of how raw-style enumerations use RawRepresentable, changed the model to actually use RawRepresentable. Actually, it uses a sub-protocol, AnyAlternative, which adds an associated type for the implementing non-alternative type. AnyAlternative also serves a function like AnyObject.
Removed the old library support type since it’s obsolete. Added back a (now global) function to upcast to the implementation type without needing to name it.
Added option to initialize alternative by assigning to “super.” Using “super” by itself isn’t allowed in the grammar (It has to be followed by a member specification), so I added it.
Added note about pointer compatibility.
The model change led to a lot of rewording. And new/changed technical terms.


Daryle Walker
Mac, Internet, and Video Game Junkie
darylew AT mac DOT com

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

I agree with the overall usefulness of newtype-style (

···

On Jul 29, 2017, at 4:01 PM, Daryle Walker via swift-evolution <swift-evolution@swift.org> wrote:

Proposal at <https://gist.github.com/CTMacUser/c493f775075e946efdcfd85d38473291>, uploaded revision 4.

Changes:

Since the original setup was a poor copy of how raw-style enumerations use RawRepresentable, changed the model to actually use RawRepresentable. Actually, it uses a sub-protocol, AnyAlternative, which adds an associated type for the implementing non-alternative type. AnyAlternative also serves a function like AnyObject.
Removed the old library support type since it’s obsolete. Added back a (now global) function to upcast to the implementation type without needing to name it.
Added option to initialize alternative by assigning to “super.” Using “super” by itself isn’t allowed in the grammar (It has to be followed by a member specification), so I added it.
Added note about pointer compatibility.
The model change led to a lot of rewording. And new/changed technical terms.


Daryle Walker
Mac, Internet, and Video Game Junkie
darylew AT mac DOT com

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

(Excuse me, my last reply was sent prematurely)

As I was saying, I agree with the overall usefulness of newtype-style declarations, but I don’t understand why we need so much syntax for what should just be a pattern in Swift. Specifically, the idea of automatic delegation of an interface is antithetical to the very reason why Haskell has newtype in the first place. And in the situations in which I would create an alternate definition of a type, I expect to never inherit the interface of the underlying type because I intend for it to be completely distinct.

Additionally, the use of inheritance in alternate definitions seems out of place and the casting section breaks encapsulation.

~Robert Widmann

···

On Jul 29, 2017, at 4:01 PM, Daryle Walker via swift-evolution <swift-evolution@swift.org> wrote:

Proposal at <https://gist.github.com/CTMacUser/c493f775075e946efdcfd85d38473291>, uploaded revision 4.

Changes:

Since the original setup was a poor copy of how raw-style enumerations use RawRepresentable, changed the model to actually use RawRepresentable. Actually, it uses a sub-protocol, AnyAlternative, which adds an associated type for the implementing non-alternative type. AnyAlternative also serves a function like AnyObject.
Removed the old library support type since it’s obsolete. Added back a (now global) function to upcast to the implementation type without needing to name it.
Added option to initialize alternative by assigning to “super.” Using “super” by itself isn’t allowed in the grammar (It has to be followed by a member specification), so I added it.
Added note about pointer compatibility.
The model change led to a lot of rewording. And new/changed technical terms.


Daryle Walker
Mac, Internet, and Video Game Junkie
darylew AT mac DOT com

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

As I was saying, I agree with the overall usefulness of newtype-style declarations, but I don’t understand why we need so much syntax for what should just be a pattern in Swift. Specifically, the idea of automatic delegation of an interface is antithetical to the very reason why Haskell has newtype in the first place. And in the situations in which I would create an alternate definition of a type, I expect to never inherit the interface of the underlying type because I intend for it to be completely distinct.

What would this pattern look like?

An alternative inherits nothing by default. You have to explicitly publish members from the underlying type to the current one. And you don’t have to; you can leave members out, or implement trampolines yourself. I wanted something between Go’s taking everything and C++’s taking nothing, more selectable like Haskell. (But I don’t really understand Haskell.)

Additionally, the use of inheritance in alternate definitions seems out of place and the casting section breaks encapsulation.

Enumerations use similar syntax to specify their raw type. What word, which may have to be new, should be used to serve a similar function as “super” within the main initializer?

Isn’t breaking (or at least bending) encapsulation a point of casting? And shorter than calling “rawValue” and/or “init?” a bunch of times?

···

On Jul 31, 2017, at 1:45 PM, Robert Widmann <rwidmann@apple.com> wrote:


Daryle Walker
Mac, Internet, and Video Game Junkie
darylew AT mac DOT com

As I was saying, I agree with the overall usefulness of newtype-style declarations, but I don’t understand why we need so much syntax for what should just be a pattern in Swift. Specifically, the idea of automatic delegation of an interface is antithetical to the very reason why Haskell has newtype in the first place. And in the situations in which I would create an alternate definition of a type, I expect to never inherit the interface of the underlying type because I intend for it to be completely distinct.

What would this pattern look like?

Today, a struct wrapping a single stored property will give you both the static and dynamic semantics you’re looking for. All that’s left is the delegation.

An alternative inherits nothing by default. You have to explicitly publish members from the underlying type to the current one. And you don’t have to; you can leave members out, or implement trampolines yourself. I wanted something between Go’s taking everything and C++’s taking nothing, more selectable like Haskell. (But I don’t really understand Haskell.)

Haskell’s newtype feature does not provide this kind of delegation. It’s in the “taking nothing” camp.

Additionally, the use of inheritance in alternate definitions seems out of place and the casting section breaks encapsulation.

Enumerations use similar syntax to specify their raw type. What word, which may have to be new, should be used to serve a similar function as “super” within the main initializer?

Treating an alternate like a protocol is fine - there is prior art in protocols for that. But having alternatives refine each other doesn’t make much sense to me without a more salient example than the one in the proposal.

Isn’t breaking (or at least bending) encapsulation a point of casting? And shorter than calling “rawValue” and/or “init?” a bunch of times?

A cast in C and C++ may be so, but we encourage checked casts where possible and allow you access to the old “a promise to the compiler” kind of casting with unsafeBitCast - and even then we check sizes. We should try to avoid leaking implementation details like this.

~Robert Widmann

···

On Jul 31, 2017, at 4:08 PM, Daryle Walker <darylew@mac.com> wrote:

On Jul 31, 2017, at 1:45 PM, Robert Widmann <rwidmann@apple.com <mailto:rwidmann@apple.com>> wrote:


Daryle Walker
Mac, Internet, and Video Game Junkie
darylew AT mac DOT com

Additionally, the use of inheritance in alternate definitions seems out of place and the casting section breaks encapsulation.

Enumerations use similar syntax to specify their raw type. What word, which may have to be new, should be used to serve a similar function as “super” within the main initializer?

Treating an alternate like a protocol is fine - there is prior art in protocols for that. But having alternatives refine each other doesn’t make much sense to me without a more salient example than the one in the proposal.

It’s more for being orthogonal; there’s no reason to ban it. Whatever value type you have: give me equal or fewer states and a clean break in the interface (which can be selectively added back). It doesn’t matter which kind of value type the source was. I guess almost no-one would cast more than to/from the immediate underlying type, but the very design of alternatives lets me do multiple levels for free. Type punning is generally the only thing needed, no code except for downcasts (or the downcast phase of cross-casts) of non-basic alternatives, which must be kept for safety.

···

On Jul 31, 2017, at 8:38 PM, Robert Widmann <rwidmann@apple.com> wrote:

On Jul 31, 2017, at 4:08 PM, Daryle Walker <darylew@mac.com <mailto:darylew@mac.com>> wrote:

On Jul 31, 2017, at 1:45 PM, Robert Widmann <rwidmann@apple.com <mailto:rwidmann@apple.com>> wrote:

Isn’t breaking (or at least bending) encapsulation a point of casting? And shorter than calling “rawValue” and/or “init?” a bunch of times?

A cast in C and C++ may be so, but we encourage checked casts where possible and allow you access to the old “a promise to the compiler” kind of casting with unsafeBitCast - and even then we check sizes. We should try to avoid leaking implementation details like this.


Daryle Walker
Mac, Internet, and Video Game Junkie
darylew AT mac DOT com

Terms of Service

Privacy Policy

Cookie Policy