[Review] SE-0026 Abstract classes and methods


(Joe Groff) #1

Hello Swift community,

The review of “Abstract classes and methods” begins now and runs through March 4, 2016. The proposal is available here:

https://github.com/apple/swift-evolution/blob/master/proposals/0026-abstract-classes-and-methods.md

Reviews are an important part of the Swift evolution process. All reviews should be sent to the swift-evolution mailing list at

https://lists.swift.org/mailman/listinfo/swift-evolution

or, if you would like to keep your feedback private, directly to the review manager. When replying, please try to keep the proposal link at the top of the message:

Proposal link:

https://github.com/apple/swift-evolution/blob/master/proposals/0026-abstract-classes-and-methods.md

Reply text

Other replies

What goes into a review?

The goal of the review process is to improve the proposal under review through constructive criticism and, eventually, determine the direction of Swift. When writing your review, here are some questions you might want to answer in your review:

  • What is your evaluation of the proposal?
  • Is the problem being addressed significant enough to warrant a change to Swift?
  • Does this proposal fit well with the feel and direction of Swift?
  • If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?
  • How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

More information about the Swift evolution process is available at:

https://github.com/apple/swift-evolution/blob/master/process.md

Thank you,

-Joe
Review Manager


(David Owens II) #2

What is your evaluation of the proposal?

-1. The examples are not compelling enough. The only value currently, that I see at least, is the ability to require a specific storage mechanism for properties and to provide default values for all implementations of those properties.

Is the problem being addressed significant enough to warrant a change to Swift?

Maybe, but I believe updates to protocols are the better path.

Does this proposal fit well with the feel and direction of Swift?

No.

If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?

Yes, such as C++ and C#. In the vast majority of cases, the usage seemed to break down into two basic categories: mixins and interfaces. I don't believe this proposal really addresses either of those use cases well.

How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

A quick reading.

-David

···

On Feb 26, 2016, at 10:11 AM, Joe Groff via swift-evolution <swift-evolution@swift.org> wrote:

Hello Swift community,

The review of “Abstract classes and methods” begins now and runs through March 4, 2016. The proposal is available here:

https://github.com/apple/swift-evolution/blob/master/proposals/0026-abstract-classes-and-methods.md
Reviews are an important part of the Swift evolution process. All reviews should be sent to the swift-evolution mailing list at

https://lists.swift.org/mailman/listinfo/swift-evolution
or, if you would like to keep your feedback private, directly to the review manager. When replying, please try to keep the proposal link at the top of the message:

Proposal link:

https://github.com/apple/swift-evolution/blob/master/proposals/0026-abstract-classes-and-methods.md
Reply text

Other replies

What goes into a review?

The goal of the review process is to improve the proposal under review through constructive criticism and, eventually, determine the direction of Swift. When writing your review, here are some questions you might want to answer in your review:

  • What is your evaluation of the proposal?
  • Is the problem being addressed significant enough to warrant a change to Swift?
  • Does this proposal fit well with the feel and direction of Swift?
  • If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?
  • How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

More information about the Swift evolution process is available at:

https://github.com/apple/swift-evolution/blob/master/process.md
Thank you,

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


(Austin Zheng) #3

• What is your evaluation of the proposal?

I am in favor of this proposal, for reasons described below.

• Is the problem being addressed significant enough to warrant a change to
Swift?

In my opinion, yes.

Currently (and for some time to come to come), one of Swift's primary use
cases will be building iOS and OS X applications using the Cocoa and Cocoa
Touch frameworks. These frameworks are object-oriented and
inheritance-based. They make use of the class cluster pattern and contain
classes that are meant only as templates for application subclasses.
Support for abstract classes would allow formalizing usage restrictions
that currently exist only as informal conventions, sternly worded
documentation comments, and runtime asserts.

Even if Cocoa is never augmented to take advantage of abstract Swift
classes (an idea: pragma directive to import an Objective-C class as
'abstract'?), there are quite a few app development patterns which involve
creating 'abstract' view controllers or UI elements with various
customization points meant to be filled in by subclasses. Abstract class
support would make this less error-prone.

• Does this proposal fit well with the feel and direction of Swift?

The question we should be asking is, "is inheritance-based object-oriented
programming using `class` a first-class Swift citizen?" Or is Swift's OO
subsystem something 'grudgingly' included in the language to facilitate
ObjC/Cocoa interop? I love POP and hate the misuse of inheritance as much
as anyone on this list, but I still think that inheritance-based modeling
is the best solution to at least some types of problems.

I don't think abstract classes unduly burden the rest of the language, and
I think they are an important part of object-oriented programming and
interop with existing frameworks that Objective-C could have benefitted
from. ('Burden' in this case is in contrast to something like inout, an
excellent feature which nonetheless has resulted in weird ramifications for
everything from tuple splatting to closure argument capture to currying.)

• If you have used other languages or libraries with a similar feature,
how do you feel that this proposal compares to those?

n/a, although the design seems like a thoroughly conventional one compared
to the same concept in other OO languages.

• How much effort did you put into your review? A glance, a quick reading,
or an in-depth study?

Close reading of proposal document. Following (and posted in) various
threads in which the topic came up.


(Sean Heber) #4

Proposal link:

https://github.com/apple/swift-evolution/blob/master/proposals/0026-abstract-classes-and-methods.md
  • What is your evaluation of the proposal?

I am mixed on this. I’ve mentioned wanting this myself on this list and have run into situations where I *really* wished I had it at the time (instead of having to do fatalError()), but ultimately I’ve almost always gone back to redesign those things to get rid of the abstract base class pattern and improved the design in the process. Perhaps this is an anti-pattern and Swift should not encourage it. I’m not sure.

  • Is the problem being addressed significant enough to warrant a change to Swift?

I’m not so sure. I feel like by not having it, Swift has often pushed me toward better design (at the cost of some of my hair).

  • Does this proposal fit well with the feel and direction of Swift?

Again, I’m not sure about this. I don’t think the potential of protocols have been fully explored yet and this feels like just adding an old feature from old languages because that’s the way we’re used to doing it. I feel like you could get the same effect by having a way to apply a single protocol to a class “abstractly” and have that *result in* an abstract class. This would more clearly separate the parts that are meant for subclasses to fill in vs. not. For example, to use the class from the proposal:

protocol RESTClientSubclass {
  var url : String { get }
}

class RESTClient: @abstract(RESTClientSubclass) {}

class MyRestServiceClient : RESTClient {
  var url : String { return "http://www.foo.com/client” }
}

“override” wouldn’t be necessary here because you’re not actually overriding anything and the methods/properties the subclass needs to implement are clearly grouped together in the RESTClientSubclass protocol. (In fact it might even be an error for RESTClient to implement *any* method itself in an abstract protocol conformance).

  • If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?

Yes and it doesn’t feel any different - which is what bothers me, perhaps. :slight_smile:

  • How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

Skimmed the discussions as they happened a bit, read the proposal, but did not spend significant time on it.

l8r
Sean


(Joshua Kopin) #5

## What is your evaluation of the proposal?

I vote -1 on the proposal as submitted. First of all, while I do appreciate the effort that went into writing the proposal, having read the whole document I still don't understand (i) exactly what problem is being solved here and (ii) why abstract classes are the necessary solution to those problems. This might just be a function of my lack of knowledge, but considering that this proposal is trying to extend the language with a significant new concept, I think the burden should be on its author to analyze the problem, sketch out a space of possible solutions to the problem as analyzed, weight these solutions against one another by examining each of their consequences, and demonstrate why the proposed solution is the best possible option in light of the alternatives.

## If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?

To put my cards on the table -- while I do acknowledge their utility I'm not a big fan on abstract classes. I think they're an ad-hoc solution to a deep problem that benefits from a more principled approach.

Here's my best attempt at a breakdown. In my view, if classes give programmers a concise way to specify a data structure, its interface, and its implementation in an open, hierarchically extensible fashion, abstract classes give programmers a concise way to *partially* specify a data structure, its interface, and its implementation in an open, hierarchically extensible fashion.

The issue I have with abstract classes is that there are much better, more principled ways to solve the problem of partial specification of an data structure / interface implementation in an extensible fashion (mixins, in particular, which I understand to be more or less protocols-with-storage that introduce a subtyping relationship with anything that mixes them in). Abstract classes are a convenient, nearly inevitable, and actually pretty decent incremental extension of the object-oriented paradigm. But when you break out the deep problems abstract classes are meant to solve, they emerge (in my opinion) as incomplete, limited, and ultimately unhelpful despite their utility.

The main reason for this is that they lock users into hierarchical inheritance (and hierarchical thinking) when it isn't needed, it isn't efficient, and it isn't as flexible as it could be. The flexibility afforded by mixins (especially if mixins themselves could inherit from and extend one another) would allow the user to reuse code in far more ways that abstract classes currently do. It would allow functionality to be factored out in all of the clever ways protocol extensions currently allow but without the storage-related limitations.

## Is the problem being addressed significant enough to warrant a change to Swift?

I'm not sure, partially because having read the proposal I'm still not clear exactly what the problem is. While I have on occasion missed something like abstract classes in Swift, that itch has always been minor, and it is often an indication that my architecture could use a good rethink. On top of that, as I outlined above, mixins have always seemed to me like a strictly more powerful solution to the same problem solved by abstract classes. I'd be willing to wait for protocols / protocol extensions to gain the ability to add storage to the structs and classes that adopt them.

## Does this proposal fit well with the feel and direction of Swift?

I don't think so, for the reasons above.

## How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

I read the whole proposal once and have followed the discussion a little bit.


(Robert Widmann) #6

What is your evaluation of the proposal?

I believe it is a well intended and certainly an interesting feature to have.

Is the problem being addressed significant enough to warrant a change to Swift?

No, but not strongly. Sure, there are cases where it would make more sense to use an "interface class" (a la Java) to implement an abstract data type, but I believe those kinds of design patterns are subsumed by protocols and Swift's general approach to designing data types in the large. Even a language as dedicated to OO as Objective-C didn't need abstract classes, and where necessary, were simply implemented with macros declaring a one-line stub that throws an exception. Even without macros, I don't believe the keystroke savings is enough to justify the inclusion of another keyword.

Does this proposal fit well with the feel and direction of Swift?

For the reasons above, I'm afraid not.

How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

A quick reading.

~Robert Widmann

2016/02/26 13:11、Joe Groff via swift-evolution <swift-evolution@swift.org> のメッセージ:

···

Hello Swift community,

The review of “Abstract classes and methods” begins now and runs through March 4, 2016. The proposal is available here:

https://github.com/apple/swift-evolution/blob/master/proposals/0026-abstract-classes-and-methods.md

Reviews are an important part of the Swift evolution process. All reviews should be sent to the swift-evolution mailing list at

https://lists.swift.org/mailman/listinfo/swift-evolution

or, if you would like to keep your feedback private, directly to the review manager. When replying, please try to keep the proposal link at the top of the message:

Proposal link:

https://github.com/apple/swift-evolution/blob/master/proposals/0026-abstract-classes-and-methods.md

Reply text

Other replies

What goes into a review?

The goal of the review process is to improve the proposal under review through constructive criticism and, eventually, determine the direction of Swift. When writing your review, here are some questions you might want to answer in your review:

  • What is your evaluation of the proposal?
  • Is the problem being addressed significant enough to warrant a change to Swift?
  • Does this proposal fit well with the feel and direction of Swift?
  • If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?
  • How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

More information about the Swift evolution process is available at:

https://github.com/apple/swift-evolution/blob/master/process.md

Thank you,

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


(David Waite) #7

https://github.com/apple/swift-evolution/blob/master/proposals/0026-abstract-classes-and-methods.md
  • What is your evaluation of the proposal?

-1.

  • Is the problem being addressed significant enough to warrant a change to Swift?

The functionality (to allow greater composability of code) is significant enough to warrant a change in swift, but the actual implementation (via abstract classes) is not. I would prefer additional trait/mixin functionality.

  • Does this proposal fit well with the feel and direction of Swift?

While Swift could use more functionality around mixin-like behavior and more sophisticated trait functionality, staying away from class inheritance more often than not results in better code.

Abstract base classes in particular have a strong tendency to become a composability anti-pattern, because you are not defining the behavior of the interacting objects but are requiring a specific form of implementation and specific, often undocumented side-effects.

As an example from the proposal:

The RESTClient abstract base class defined in the proposal has hard-coded a single URL. If I need multiple URLs (say, client side address randomization) then the behavior between var url and performNetworkCall is insufficient. It is likely that other code relying on RESTClient is using the base class name, and not some protocol, so my only hope for working with existing code is to figure out how to make my subclass behave properly when performNetworkCall is defined.

If I was working with RESTClient as a protocol, performNetworkCall would just be a required method to implement. I could choose to implement it however I want to. Because of the abstract base class, I need to worry about whether some other functionality in the base class I am forced to use for interoperability will conflict with my new definition. And of course, var url is still meaningless in my implementation, so I better just have it return a dummy value.

To be fair, RESTClient is a placeholder. It could be better designed if it were part of a system and not an example in a proposal.

However, this is the problem with abstract base classes - they always could be hypothetically designed better. Their goal is usually to provide some implementation details while allowing flexibility of a third party to extend with the actual functionality and behavior needed. But it is very difficult (perhaps impossible) to on one hand remain flexible while on the other hand dictate implementation details both as side effects required in your system and for convenience. Sure, abstract classes can always be better designed - when considered in retrospect. Thats because the author of the abstract class has gained experience and now understands some of the flexibility other developers required in implementation!

Better to define protocols, and provide implementations of those protocols based on the functionality you know people will need. Even more so if you can use traits to define behavior you commonly expect developers to need, such that they can take or leave such behaviors as they see fit.

  • If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?

In my professional experience, I have a tough time thinking of any abstract base class which I haven’t considered a poor design choice. That abstract base classes are often the simplest design choice makes me believe this feature would be abused.

Java is the language where I’ve hit the most abstract base class requirements. I have nothing to suggest be salvaged from there in this regard.

Ruby has both class inheritance and mix-in support, and both are used extensively. Class inheritance in Ruby is saved by late-bound typing - it is considered bad form to test that your code was given a specific type, instead encouraging either coercion of types or duck typing. Otherwise, the lack of protocols in the language would make developing code very difficult.

Design (including language design) is not just about what is there, but what is not. I feel promoting traits over abstract classes this is another opportunity for the Swift language to promote better code.

It is also worth noting that Objective-C does not support abstract classes, and this proposal did not attempt to define how that would be rectified as part of interoperability:
- Would abstract classes need also be defined in Objective-C?
- Does the entire hierarchy at and defending from the abstract class become un-exposable to Objective-C, or just the abstract classes themselves?
- If the initializable classes in the hierarchy are exposed to Objective-C, are the abstract classes exposed via e.g. +(Class) superclass; ?

  • How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

Participated in the discussion, in-depth study.

-DW


(plx) #8

Proposal link:

https://github.com/apple/swift-evolution/blob/master/proposals/0026-abstract-classes-and-methods.md
  • What is your evaluation of the proposal?

A tentative -1; although there are places abstract classes *would* be useful, I can’t think of a single such scenario for which an abstract class would be the *best* solution (or at least the solution I’d prefer).

Since the points I would make here have already been made I won’t belabor this point; suffice to say it’d be a lot more compelling a proposition if there were an example usage that fundamentally required the abstract-class approach (and couldn’t simply accept some parameters in `init`).

I do have some “fresh" concerns, however.

# Support For “Intermediate” Classes

As stated, it seems the proposal would force classes to be either or concrete; this is going to be limiting at times, and approaches like the below are often useful:

// fully-abstract
abstract class BaseClass {

  abstract func someFunction()
  abstract func someOtherFunction()

}

// partially-abstract
abstract class IntermediateClass : BaseClass {

  override func someFunction() { /* implementation here */ }

}

// fully-concrete
class TerminalClass : IntermediateClass {

  override func someOtherFunction() { /* implementation here */ }

}

…although I could be mis-reading the proposal.

# Access Control Issues: Mixed OK, or Not?

Abstract classes and access control issues would need to be addressed. EG: is the below allowed, or not:

abstract public class ClassWithInternalAbstractMembers {

  // abstract members less visible than the containing type:
  internal abstract func someFunctionOnlyVisibleWithinThisModule()
  private abstract func someFunctionOnlyVisibleWithinThisFile()

}

…?

I think *not* is more consistent with how Swift generally works, but if *not* is chosen it has some awkward implications for how useful the feature is (see next point).

# Can’t Use Nicely For a “Closed" Class-Cluster

I personally think the strongest case for abstract classes is as an aide to building class-clusters, but there seem to be major issues doing this from Swift, especially if you are hoping for a “closed” class-cluster (e.g. one that isn’t meant for subclassing "from outside the module”). That is, it should meet the following bullet-points:

- there’s an abstract public base class (as the public-API)
- this public base class is de-facto final (not meant for “external” subclassing)
- there are some “private”, concrete subclasses (specialized in various ways, and all `final`)

…(noting that you wouldn’t always *want* a closed cluster, but sometimes you would…).

One annoying issue here is that such a class-cluster can’t use `init`; even if we *could* have `init` return a subclass instance, the compiler would still presumably want to prevent us from “instantiating” an instance of our abstract class, and this seems awkward to really resolve…so we’re stuck with static factory functions (which will seem unnatural).

Most of the other issues I’d raise re really due to the lack of a way to say “this class/this method/etc. should be *treated* as final outside this module, even if it’s not actually `final` within the module”. But, without that kind of feature, it becomes hard to achieve a “de-facto `final`” approach, b/c:

- the abstract base class is public
- thus the abstract functions are also public (by no-mixed-visibility assumption)
- those methods can’t be marked final (we *need* to override them)
- thus we can’t achieve the closed-family (b/c the abstract methods are all public and non-final on a public and non-final class)

…which can be worked around if you keep all the *classes* module-internal and export, say, a public struct wrapper privately wrapping a class instance, but that’s getting pretty unwieldy and feels like it shouldn’t be necessary.

  • Is the problem being addressed significant enough to warrant a change to Swift?

I think it *exposes* a significant problem, but I’m not sure the fix is right.

  • Does this proposal fit well with the feel and direction of Swift?

It seems hard to fit into the rest of Swift in the details (e.g. the `init` issue, and the apparent lack of a satisfying way for the implementer to achieve a reasonable balance of visibility, overridability, and finality).

  • If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?

It seems broadly similar.

  • How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

Some thought, some observation of the discussion.

···

On Feb 26, 2016, at 12:11 PM, Joe Groff via swift-evolution <swift-evolution@swift.org> wrote:


(Patrick Gili) #9

  • What is your evaluation of the proposal?

It seems that programming languages are evolving in a way that rely less on pure object-oriented concepts that previous languages, such as C++ and Java, have relied upon. The reasons for this derive from experience. Some concepts have proven problematic and introduced more problems over the long-term than they solve. Multiple inheritance is a good example of one of these concepts. In my opinion, abstract declarations represents another.

In addition, the examples provided by the proposal do not provide a strong argument in favor. It isn't difficult to see that there are better patterns that could have been employed to solve the problem illustrated by the example.

  • Is the problem being addressed significant enough to warrant a change to Swift?

No.

  • Does this proposal fit well with the feel and direction of Swift?

No.

  • If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?

More modern languages like Ruby and Python do not support abstract definitions. I like Swift because it draws from design patterns based in modern languages such as these. I'd like to see Swift continue on the modern path.

  • How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

Read the proposal thorough and the original thread on which it was based.

···

Sent from my iPad

On Feb 26, 2016, at 1:11 PM, Joe Groff <jgroff@apple.com> wrote:


(Joseph Lord) #10

-1

Requiring sub classing is never necessary and equivalent effects can be achieved by having customisation points in the form of delegates with protocol types (I prefer separate delegates for different aspects of customisation). The delegates can be required in the initializer is they are necessary. If the client wants to subclass they still can and then set the delegate to self.

Inheritance isn't necessarily bad but it is a distinct design choice that should be left to the client code not forced by the library.

Summary:
Isn't necessary.
Complicates language.
Forces class and inheritance model on client code.
Single inheritance also puts limitations that don't exist with protocols.

The proposal does say that there are things that can't be achieved by protocols although I didn't understand what they are although it may have been saying protocol extensions which may have limits that delegation does not have.

I haven't followed the preceding discussion on this proposal but I have been thinking about such things in Swift for some time. This blog post was supporting the access control design and the lack of need for protected which has very similar arguments and alternative approaches as does abstract. There is also some discussion on the post.
http://blog.human-friendly.com/swift-access-controls-are-like-cs-and-that-isnt-necessarily-a-bad-thing

Aside:
One improvement to delegation I would like is to be able to create a property that is either weak or a value type so that delegates are not forced to be classes to avoid retain loops. Maybe it will be possible with property behaviours.

Joseph

···

On Feb 26, 2016, at 6:11 PM, Joe Groff <jgroff@apple.com> wrote:

Hello Swift community,

The review of “Abstract classes and methods” begins now and runs through March 4, 2016. The proposal is available here:

https://github.com/apple/swift-evolution/blob/master/proposals/0026-abstract-classes-and-methods.md

Reviews are an important part of the Swift evolution process. All reviews should be sent to the swift-evolution mailing list at

https://lists.swift.org/mailman/listinfo/swift-evolution

or, if you would like to keep your feedback private, directly to the review manager. When replying, please try to keep the proposal link at the top of the message:

Proposal link:

https://github.com/apple/swift-evolution/blob/master/proposals/0026-abstract-classes-and-methods.md

Reply text

Other replies

What goes into a review?

The goal of the review process is to improve the proposal under review through constructive criticism and, eventually, determine the direction of Swift. When writing your review, here are some questions you might want to answer in your review:

  • What is your evaluation of the proposal?
  • Is the problem being addressed significant enough to warrant a change to Swift?
  • Does this proposal fit well with the feel and direction of Swift?
  • If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?
  • How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

More information about the Swift evolution process is available at:

https://github.com/apple/swift-evolution/blob/master/process.md

Thank you,

-Joe
Review Manager
_______________________________________________
swift-evolution-announce mailing list
swift-evolution-announce@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution-announce


#11

What is your evaluation of the proposal?

In its current state: -1

I'd love for the proposal to present clear examples of problems that exist in Swift that cannot be solved in any other way. The "RESTClient" example is overly simplistic and can be solved easily using POP:

    protocol RESTClient {
        var: url: String { get }
    }
    extension RESTClient {
        performNetworkCall() {
            // impl
        }
    }
    final class MyRestServiceClient: RESTClient {
        let url = "http://www.foo.com/client"
    }

In fact, the problem it presents doesn't even need POP:

    final class RESTClient {
        let url: String
        init(url: String) { self.url = url }
        performNetworkCall() { /* impl */ }
    }

If the proposal were to be updated with better examples that _cannot_ be solved without abstract classes, or at the very least cannot be solved without significant sacrifices to the quality of the code, I would reconsider it.

I believe the proposal would also need to be updated to address other unanswered questions brought up in this thread.

···

--
Stephen


(Taras Zakharko) #12

  • What is your evaluation of the proposal?

I am against the proposal. I believe that protocols, mix-ins and composition are better answers to the problems that abstract classes are usually called to solve. In my experience, abstract classes lead to subpar design decisions.

  • Is the problem being addressed significant enough to warrant a change to Swift?

I do not believe so. There are most likely cases where current tools could be improved, by that should be done by improving support for behavior composition rather than forced subclassing

  • Does this proposal fit well with the feel and direction of Swift?

I do not believe so, for the reason outlined above

  • If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?
  • How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

A quick glance.

···

On 26 Feb 2016, at 19:11, Joe Groff via swift-evolution <swift-evolution@swift.org> wrote:

Hello Swift community,

The review of “Abstract classes and methods” begins now and runs through March 4, 2016. The proposal is available here:

https://github.com/apple/swift-evolution/blob/master/proposals/0026-abstract-classes-and-methods.md
Reviews are an important part of the Swift evolution process. All reviews should be sent to the swift-evolution mailing list at

https://lists.swift.org/mailman/listinfo/swift-evolution
or, if you would like to keep your feedback private, directly to the review manager. When replying, please try to keep the proposal link at the top of the message:

Proposal link:

https://github.com/apple/swift-evolution/blob/master/proposals/0026-abstract-classes-and-methods.md
Reply text

Other replies

What goes into a review?

The goal of the review process is to improve the proposal under review through constructive criticism and, eventually, determine the direction of Swift. When writing your review, here are some questions you might want to answer in your review:

  • What is your evaluation of the proposal?
  • Is the problem being addressed significant enough to warrant a change to Swift?
  • Does this proposal fit well with the feel and direction of Swift?
  • If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?
  • How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

More information about the Swift evolution process is available at:

https://github.com/apple/swift-evolution/blob/master/process.md
Thank you,

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


(Daniel Duan) #13

  • What is your evaluation of the proposal?

The proposal does not provide strong enough incentive for adding Abstract
Class. I'm against the proposed change.

  • Is the problem being addressed significant enough to warrant a change to
  Swift?

No. The provided example in the incentive section, as noted by the proposal
itself, can be achieved with protocols and default implementations. The only
problem solved by this example, as well as abstract class as proposed, is that
of a shared property value (port number). IMHO, this problem should be
addressed by enhancing Swift's protocol.

  • Does this proposal fit well with the feel and direction of Swift? • If
  you have used other languages or libraries with a similar feature, how do
  you feel that this

proposal compares to those?

Abstract class encourages inheritance (can't use it without), which is only
natural if one assume that OOP is the correct paradigm for problems at hand.
But both industry and academia admits that, historically, OOP had been
over-hyped, abused beyond the domains it actually were useful. Will people be
creating a class just so they can write helloworld in the next decade or two?
I'm sure some will, but I'd like to imagine they have a good reason to do so,
not because "it's the one true way to Swift". Encouraging inheritance in
a language designed for next few decades seems bad.

Trends and feelings aside, perhaps it's worth noting that in programming
languages such as C++, abstract class, in a lot of use cases, serves as
a workaround for the lack of interface/protocol. It's a "implementation
detail" of single-argument polymorphism. Its other characteristic,
late-binding, can be achieved in Swift in other means. These are the
fundamental reasons why it's hard to produce a convincing example to justify
abstract class.

(Do we like more ways to do the same thing in Swift is a whole different
discussion. I lean towards no on this one).

  • How much effort did you put into your review? A glance, a quick reading,
  or an in-depth study?

I read the proposal.


(Alex Hoppen) #14

+1 for the proposal.
As I said in the original discussion abstract classes allow you to override methods of existing classes, which protocols cannot do (and by definition will never be able to do). I think this is a major advantage that cannot be neglected.
To name an example: Without abstract classes there is no way to create NSOperations that perform preliminary setup (like checking dependencies, notifying observers, …) and call through to the actual operation’s implementation in between (I’m referring to the sample code of the Advanced NSOperation’s talk at last year’s WWDC, where Operation would have greatly benefitted from making the execute method abstract).
Sure, there are ways to work around this issue. As suggested several times you may define a delegate that does the actual operation’s work, which I don’t like because it a) defeats the concept of the operation performing the actual work, b) requires you to always think about two types (the operation and the delegate) when needing to override other methods of the actual operation and c) it does not make sense to create a raw (NS)Operation on its own. Alternatively there is the current way of doing it by creating a class that has a fatalError implementation but I guess nobody will argue that this is the right way to go. Or you may say that NSOperation should have been designed in another way so that it leverages protocols from the ground up. But it isn’t designed that way and there are huge amounts of code that were written before Swift introduced protocols and protocol extensions. I think from a point of interoperability it would simply be wrong to assume that this code does not exist.
Swift is a multi-paradigm programming language and POP isn’t the silver bullet that solves all our problems. IMO there are several use cases where abstract classes are the cleaner solution than a mix of protocols, extensions and classes (which have there use cases as well). It may, however, be beneficial to delay the introduction of abstract classes to Swift 4, so that people get more used to POP and see the benefits it brings with it and will not fall back to old (and maybe bad) patterns using abstract classes where POP would be the right way to go.

– Alex

···

On 26 Feb 2016, at 19:11, Joe Groff <jgroff@apple.com> wrote:

Hello Swift community,

The review of “Abstract classes and methods” begins now and runs through March 4, 2016. The proposal is available here:

https://github.com/apple/swift-evolution/blob/master/proposals/0026-abstract-classes-and-methods.md
Reviews are an important part of the Swift evolution process. All reviews should be sent to the swift-evolution mailing list at

https://lists.swift.org/mailman/listinfo/swift-evolution
or, if you would like to keep your feedback private, directly to the review manager. When replying, please try to keep the proposal link at the top of the message:

Proposal link:

https://github.com/apple/swift-evolution/blob/master/proposals/0026-abstract-classes-and-methods.md
Reply text

Other replies

What goes into a review?

The goal of the review process is to improve the proposal under review through constructive criticism and, eventually, determine the direction of Swift. When writing your review, here are some questions you might want to answer in your review:

  • What is your evaluation of the proposal?
  • Is the problem being addressed significant enough to warrant a change to Swift?
  • Does this proposal fit well with the feel and direction of Swift?
  • If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?
  • How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

More information about the Swift evolution process is available at:

https://github.com/apple/swift-evolution/blob/master/process.md
Thank you,

-Joe
Review Manager
_______________________________________________
swift-evolution-announce mailing list
swift-evolution-announce@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution-announce


(Ondrej Barina) #15

What is your evaluation of the proposal?

+1

Is the problem being addressed significant enough to warrant a change to Swift?

Yes. Abstract methods and classes have its usage

Does this proposal fit well with the feel and direction of Swift?

yes

How much effort did you put into your review? A glance, a quick
reading, or an in-depth study?

I have read the whole discussion. (including draft)

Ondrej Barina

···

On Fri, Feb 26, 2016 at 7:11 PM, Joe Groff via swift-evolution <swift-evolution@swift.org> wrote:

Hello Swift community,

The review of “Abstract classes and methods” begins now and runs through
March 4, 2016. The proposal is available here:

https://github.com/apple/swift-evolution/blob/master/proposals/0026-abstract-classes-and-methods.md

Reviews are an important part of the Swift evolution process. All reviews
should be sent to the swift-evolution mailing list at

https://lists.swift.org/mailman/listinfo/swift-evolution

or, if you would like to keep your feedback private, directly to the review
manager. When replying, please try to keep the proposal link at the top of
the message:

Proposal link:

https://github.com/apple/swift-evolution/blob/master/proposals/0026-abstract-classes-and-methods.md

Reply text

Other replies

What goes into a review?

The goal of the review process is to improve the proposal under review
through constructive criticism and, eventually, determine the direction of
Swift. When writing your review, here are some questions you might want to
answer in your review:

• What is your evaluation of the proposal?
• Is the problem being addressed significant enough to warrant a change to
Swift?
• Does this proposal fit well with the feel and direction of Swift?
• If you have used other languages or libraries with a similar feature, how
do you feel that this proposal compares to those?
• How much effort did you put into your review? A glance, a quick reading,
or an in-depth study?

More information about the Swift evolution process is available at:

https://github.com/apple/swift-evolution/blob/master/process.md

Thank you,

-Joe
Review Manager

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


(Matthew Johnson) #16

  • What is your evaluation of the proposal?

-1. I would prefer to focus on protocol-oriented solutions which I believe are generally more robust. I passionately dislike a requirement to subclass by libraries and frameworks and would prefer to guide the Swift community away from that approach. Introducing abstract classes would do the opposite.

I would prefer to see the the generics and protocol-related features fully fleshed out in Swift 3 and Swift 4 and allow the community to identify approaches to design that do not rely on inheritance.

If there remain use cases addressed by abstract classes for which we do not have an acceptable protocol-oriented alternative we could consider the feature again at that time with better knowledge of what use cases are uniquely addressed by the more brittle and inflexible inheritance-based approach.

  • Is the problem being addressed significant enough to warrant a change to Swift?

Maybe, but I am not convinced yet. We should allow the language to evolve a bit more before making a final judgment about this.

  • Does this proposal fit well with the feel and direction of Swift?

No. It is a classic OO inheritance feature and Swift leans heavily in the direction of protocols.

  • If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?

It is about the same, including the all downsides of library designs that require subclassing by consumers.

  • How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

A brief glance. However, my review is informed by lots of experience with both implementing and using libraries and frameworks that require subclassing (including use of abstract classes). This experience has taught me that it is generally best to look for other solutions.

···

More information about the Swift evolution process is available at:

https://github.com/apple/swift-evolution/blob/master/process.md
Thank you,

-Joe
Review Manager
_______________________________________________
swift-evolution-announce mailing list
swift-evolution-announce@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution-announce


(Jeremy W. Sherman) #17

This is a review of [SE-0026 "Abstract classes and methods".](https://github.com/apple/swift-evolution/blob/master/proposals/0026-abstract-classes-and-methods.md) <https://github.com/apple/swift-evolution/blob/master/proposals/0026-abstract-classes-and-methods.md>

I am **against** the acceptance of this proposal:

- It lacks a clear problem.
- The leap from a nebulous problem to abstract classes as the solution is a *non sequitur.*
- Its arguments are insufficient to justify the complication it would add to Swift, which is contrary the simplification and clarification aims of the Swift community.

The contrast is sharpened by comparison to the Python Enhancement Proposal that accompanied the introduction of abstract base class into Python. The present proposal fails to provide a correspondingly thoughtful rationale.

## No Clear Problem
The proposal itself does little to define a practical problem, and less to explain how abstract classes solve this problem better than alternatives. It feels like a solution in want of a problem, which is the opposite of a considered addition to the language.

As best I can determine, the primary problem introduced is that of wanting to have abstract properties. The example given is better resolved by providing the `url` as a constructor argument, as [noted by Stephen Celis.](https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160222/011207.html) <https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160222/011207.html> Further, the immediate solution appears to be to argue in favor of [uniform access](https://en.wikipedia.org/wiki/Uniform_access_principle) <https://en.wikipedia.org/wiki/Uniform_access_principle> as found in Self and Eiffel, not abstract base classes, which compound non-uniform access by a further serving of complexity.

Another problem mentioned is lack of easy delegation of implementation in the context of protocols; providing a simple way to proxy calls to another object would present a promising and useful avenue for resolving this problem that would also compose more generally with the rest of the language. `NSProxy` has always been somewhat awkward in this regard; perhaps we can do better in Swift?

## No Clear Significance
Without a clear problem to address, it becomes difficult to evaluate the significance of the problem.

Ultimately, it's unclear precisely what the problem under consideration is, unless the problem is stated simply as, "Swift doesn't have abstract base classes." If that is the true problem considered to address, then it seems especially insignificant; Swift also lacks good support for relational programming à la mini-kanren, but a difference does not a problem make.

If we focus on "no abstract classes" as the problem, then the problem appears insignificant: Smalltalk and Objective-C have both made do without formal support for abstract classes. Objective-C went so far as to remove `subclassResponsibility` from the common language vocabulary, which eliminated all inbuilt support for abstract classes. Never have I heard either Smalltalker or Obj-C hacker end up despondent and cursing over the lack of built-in abstract class support in these languages.

## Compared to Python's Rationale for Adding Abstract Classes
It is interesting to consider the motivation for adding abstract base class support to Python as explained in [PEP 3119](https://www.python.org/dev/peps/pep-3119/). <https://www.python.org/dev/peps/pep-3119/>

In Python's case, the decision was motivated by the desire for a reliable means to test particularly for some shared quality of a group of objects - basically, a reliable `respondsToSelector:` or `isKindOfClass:` that allows detecting this quality without incidental risk of false positives or negatives (["Rationale"](https://www.python.org/dev/peps/pep-3119/#rationale) <https://www.python.org/dev/peps/pep-3119/#rationale>).

As a result, Python adopted abstract base classes as an alternative to interfaces (["ABCs vs. Interfaces"](https://www.python.org/dev/peps/pep-3119/#abcs-vs-interfaces) <https://www.python.org/dev/peps/pep-3119/#abcs-vs-interfaces>). But Swift already has interfaces in the form of protocols; this answers the need that motivated the addition of abstract base classes to Swift.

Because we cannot borrow the rationale used for adding abstract base classes to Python, and the document before us spends its effort explaining abstract base classes rather than the problem they would solve, it remains for those arguing for the added formal complexity of abstract base classes to motivate their addition in the context of Swift. The current proposal is manifestly lacking in this regard.

# Out of Alignment with Swift
Adding abstract class support to Swift seems unprincipled. I cannot see what problem would be solved, and Swift is working towards considered language growth, and even better, language contraction, at this point in time. Adding abstract base classes would feel like nodding to feature agglutination by cargo cult, not the careful evolution we aspire to.

# Effort
I read the article and then looked at the arguments in favor of supporting abstract base classes in Python for comparison. I would love to see a rationale as tailored to Swift and to real problems as PEP 3119 was to Python and its programmers' problems! In Python's case, "[m]uch of the thinking that went into the proposal [was] not about the specific mechanism of ABCs, as contrasted with Interfaces or Generic Functions (GFs), but about clarifying philosophical issues…" This sort of laborious semantic work is a necessary accompaniment to any significant proposed changes to an object system, and that thought is unfortunately not apparent in this proposal.

···

El 26 feb 2016, a las 13:11, Joe Groff via swift-evolution <swift-evolution@swift.org> escribió:

--
Jeremy W. Sherman
https://jeremywsherman.com/


(Alsey Coleman Miller) #18

- What is your evaluation of the proposal?

I am against the proposal because I feel it goes against the Protocol Oriented Programming patterns found in the Swift Standard Library. Current protocol functionality can provide a solution for the given example. If a protocol property is not implemented, the compiler will not let you compile.

• Is the problem being addressed significant enough to warrant a change to Swift?

No, protocols implement this functionality, but with a different syntax. There is no lacking or additional functionality this proposal provides.

• Does this proposal fit well with the feel and direction of Swift?

No. It goes against protocol oriented programming. Furthermore, this is only for classes, structs are being excluded in this case. I feel that with most of the standard library being implemented as structs, this is not acceptable.

• If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?

Similar to C# or Java abstract classes. Not much to add here.

• How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

In-depth study. I understand the proposer’s point of view, but I feel this is only a syntax change in the wrong direction. No new functionality is being provided that protocols don’t already have.

Hello Swift community,

The review of “Abstract classes and methods” begins now and runs through March 4, 2016. The proposal is available here:

https://github.com/apple/swift-evolution/blob/master/proposals/0026-abstract-classes-and-methods.md

Reviews are an important part of the Swift evolution process. All reviews should be sent to the swift-evolution mailing list at

https://lists.swift.org/mailman/listinfo/swift-evolution

or, if you would like to keep your feedback private, directly to the review manager. When replying, please try to keep the proposal link at the top of the message:

Proposal link:

https://github.com/apple/swift-evolution/blob/master/proposals/0026-abstract-classes-and-methods.md

Reply text

Other replies

What goes into a review?

The goal of the review process is to improve the proposal under review through constructive criticism and, eventually, determine the direction of Swift. When writing your review, here are some questions you might want to answer in your review:

• What is your evaluation of the proposal?
• Is the problem being addressed significant enough to warrant a change to Swift?
• Does this proposal fit well with the feel and direction of Swift?
• If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?
• How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

More information about the Swift evolution process is available at:

https://github.com/apple/swift-evolution/blob/master/process.md

Thank you,

-Joe
Review Manager

  Coleman,


(Brent Royal-Gordon) #19

https://github.com/apple/swift-evolution/blob/master/proposals/0026-abstract-classes-and-methods.md

  • What is your evaluation of the proposal?

-1.

Swift already has a means to create abstract types; we call them "protocols". Protocols cannot yet do all of the things that abstract classes can. But I think we would be better served by enhancing protocols to fill these gaps, rather than creating a parallel construct which muddies the conceptual simplicity of our current classes.

I believe the missing functionality would include:

1. Being able to constrain a protocol so that conforming types must inherit from a particular class.
2. Being able to use `override` and `super` in a protocol extension as long as the protocol has a must-inherit requirement ensuring the relevant member exists.
3. Being able to declare stored properties in protocol extensions, as long as they were declared in the same module as the protocol.

Three more things would be nice-to-haves:

4. Being able to declare conformance only to the protocol in a class, and have the required inheritance be implied.
4. Being able to add static members which could be called on the protocol itself, not just types conforming to it.
5. Being able to add factory initializers to the protocol which could initialize any conforming type.

With these six features in place, I believe Corelibs Foundation could implement its class clusters (NSArray et.al.) as protocols constrained to subclass NSObject, and clients of both libraries could be source-compatible.

I see the following benefits in going with protocols:

* Draws a bright line between abstract and concrete types.
* Required language changes are incremental.
* No problems with private abstract members of public types; all protocol requirements are already as public as the protocol itself.
* Allows for more flexible application (e.g. `UITextField` can conform to `protocol TextualView: UIView` even though it's actually a grandchild class of `UIView`).

  • Is the problem being addressed significant enough to warrant a change to Swift?

Yes. Just not *this* change.

  • Does this proposal fit well with the feel and direction of Swift?

No, I don't think so. Currently Swift draws a bright line between concrete and abstract types: protocols are abstract and all other types are concrete. Allowing abstract classes would blur this distinction.

  • If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?

I have used abstract classes, but only in languages with an "everything is a class" approach. I always found them clumsy and wished for something better.

I have also used languages (including Objective-C) with no effective solution to the problem abstract classes attempt to solve other than the equivalent of `fatalError("not implemented")`. That sucked too. I quite agree with the desire to find a solution to this problem.

  • How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

I have read the proposal and all prior reviews, and participated in pre-proposal discussions.

···

--
Brent Royal-Gordon
Architechies


(David Hart) #20

  • What is your evaluation of the proposal?

-1. I'm strongly against this proposal because they are already language features that provide similar benefits. Even if Swift is a multi-paradigm language, it has always meshed together orthogonal concepts: functional + oop + systems. Whereas in a his case, the proposal suggests adding a different syntax for something that can almost be completely expressed with protocols and protocol extensions.

  • Is the problem being addressed significant enough to warrant a change to Swift?

As POP can already provide similar behaviour without subclassing, I'd say the problem is pretty much non-existent.

  • Does this proposal fit well with the feel and direction of Swift?

No. I believe it goes contrary to the philosophy and paradigms of Swift as I understand them.

  • If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?

Yes, Java and C#. Abstract classes were useful in those languages, but fairly rarely used (as far as I'm concerned). And we now have protocol extensions to do the same.

  • How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

In-depth reading, followed he discussion.

···

On 26 Feb 2016, at 19:11, Joe Groff via swift-evolution <swift-evolution@swift.org> wrote: