[Review] SE-0026 Abstract classes and methods

   • 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:

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

What is your evaluation of the proposal?

-1. While I believe abstract methods can be a great addition for dealing with contract-like constructs in object-oriented languages, they seem out-of-place in Swift, which is a protocol-oriented language. Adding abstract methods to Swift would encourage lazy developers to use them instead of protocols and value types.

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

Yes.

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

No. I believe it doesn't fit well in the direction Swift is taking.

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

Yes, PHP. While I must say that abstract classes and methods were a common and powerful tool in PHP, they do not fit well in Swift, which offers a much more powerful alternative – protocols.

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

A quick reading of the proposal document.

Pozdrawiam – Regards,
Adrian Kashivskyy

···

Wiadomość napisana przez Joe Groff via swift-evolution <swift-evolution@swift.org> w dniu 26.02.2016, o godz. 19:11:

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

I love protocols as much as the next guy, but if the problem I'm solving requires a hierarchy of

RubyInterpreter
SystemRubyInterpreter
HomebrewRubyInterpreter
RVMRubyInterpreter

then thank you, but no, I'll prefer to stick to the most simple and clear solution (an abstract class). Yes, I can turn that into a protocol with extensions, supercharged with some extra features we don't currently have. But why on earth would I want to?

There are no benefits to be had from a protocol here.

Things won't get more clear or readable.

Everyone in the world understands simple hierarchies.

Yes, it's a wrong modeling tool conceptually, but it's a very simple and practical one. Sometimes the problem doesn't call for anything else.

So many people will continue to prefer simple class hierarchies in these cases. Let us be clear about what we're choosing from here.

Our choice is between fatalError("Must override") and a keyword that makes that clear. I'll take a keyword any day, but if you deny me, I'll go on using fatalError.

But please don't live in a fantasy world where, due to lack of SE-0026, I switch to protocols for those very simple and isolated cases, unless you can demonstrate the benefits for those specific cases. Please do not be so high-handed.

A.

I’ve been solving this problem in Swift 2 by creating pairs of classes and protocols. For instance in one of my projects I have `ServerObject` and `ServerType`. Subclasses are expected to inherit from BOTH of these properties and `ServerObject` is not meant to be created directly. This works but creates a lot of overhead that this proposal would solve.

Some things that protocols can’t do:
- Enforce inheritance from a particular class.
- Have stored properties.
- Provide an implementation that can be overridden and called with super.

Some things that classes can’t do:
- Enforce properties and functions that subclasses must override.
- Enforce an instance is not created directly, but only through a subclass.

Using the hybrid approach requires a lot of generics to use properties and functions from both the class and the protocol and in some cases simply can’t be used at the same time since Swift doesn’t support hybrid types like ObjC does (ie ServerObject *<ServerType>).

David Beck
http://davidbeck.co
http://twitter.com/davbeck

···

Cc:swift-evolution<swift-evolution@swift.org>, swift-evolution-announce@swift.org
Subject:[swift-evolution] [Review] SE-0026 Abstract classes and methods
Date:February 26, 2016 at 10:32:43 AM PST

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(mailto: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 thetop 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 directionof 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 tothose?
> • 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(mailto:swift-evolution@swift.org)
> https://lists.swift.org/mailman/listinfo/swift-evolution

-1. I don’t think the protocol oriented programming has had enough time to sink in yet, and I’d like to see what else can be done with protocols as the generic system matures. Then maybe revisit this topic next year and see if abstract classes are still as desirable.

Others on this thread have suggested workarounds to accomplish the job of abstract classes, and I’m happy to do that for the time being rather than changing the language.

Matt

···

On Feb 26, 2016, at 11:58, Austin Zheng via swift-evolution <swift-evolution@swift.org> wrote:

  • 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.

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

From the other thread, quoting myself:

"Do not take me wrong, I really like protocols and structs and I understand
how to use them, but it seems that many of us believe that the is something
wrong with classes and the protocol/struct is the new Holy Grail. I
disagree. New possibilites and new way to do things are always welcome,
mainly if they are solid and consistent and really solves the
problem intended to be solved.

I also understand that the Swift team does not want to introduce any new
keywords to the language. To tell the truth I think I need to read again
all the information on Swift. I thought the Swift would be one thing, but
looks like it will be another. It is likely that the wrong one is me.

Provide ways to create abstract classes and abstract methods is not a
"keystroke saver". It is one of many concepts involved in OOP, IMHO."

-Van

···

On Fri, Feb 26, 2016 at 4:21 PM, Sean Heber via swift-evolution < swift-evolution@swift.org> wrote:

> 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.
:)

> • 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

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

I am on the road at the moment so hard to do a full reply to the
proposal... so I just want to say basically ditto to what Austin posted.

It improve class support in Swift while not getting in the way of other
Swift paradigms.

···

On Fri, Feb 26, 2016 at 11:58 AM Austin Zheng via swift-evolution < swift-evolution@swift.org> wrote:

• 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.

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

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

+1

I do not see his proposal as forcing inheritance, but letting it fight more and more without a hand tied behind its back. Composition and mixins should be strengthened, but that does not mean that inheritance should not be improved.

Trust coders to make the right decisions, do not withhold tools from them. Inheritance is part of Swift and a supported paradigm, nothing wrong with using it well and this proposal adds a tool to the inheritance toolbox, without forcing people to use that pattern or withholding progress for functional aspects of the language and other patterns.

The proposal does not force inheritance but anyone using abstract does force it on code using the abstract class.

In my view it is those who want abstract classes that are not trusting coders. If you want to use inheritance please do, I sometimes do too although with decreasing frequency over time. Making abstract classes forces all users of your code to subclass

My -1 is probably a bit strong, maybe minus 0.5 is more like but I do think that it would encourage patterns that:
a) I don't particularly like
b) tend to have effects that pervade deeply into code bases.

When I programmed in Java and C++ in the fairly distant past I used abstract classes heavily (although often for interfaces/protocols) but since developing in Objective-C and more recently Swift and using Cocoa Touch libraries I've really come to appreciate delegation. I have also over time become more concerned with the risks and complexities of inheritance which I think should be regarded as an advanced rather than a basic technique. I fear this proposal would force library users to adopt inheritance. I think abstract classes are best discouraged rather than supported.

Joseph

···

On Feb 26, 2016, at 9:58 PM, <Sender redacted as they replied to me not list> 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

  • What is your evaluation of the proposal?

Positive.

Many voices here have a major bias for POP against OOP, and the Crusty character of the founding WWDC15 - Videos - Apple Developer session was indeed a very well-done marketing coup both in favor of POP, and against OOP.

Yet I think that code that uses abstract classes is not, per se, bad code which needs refactoring using POP. It’s just code that uses abstract classes, and it may have its (excellent) reasons.

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

I think so, for two reasons:

1. Many abstract classes exist in the wild, and they currently have to fallback to runtime errors like "subclass must override". Compiler support would be a great bonus.

2. Protocol-based refactoring of abstract classes falls short because protocols miss three major features provided only by base classes: `super`, properties, and encapsulation of implementation details that allows easy refactoring of inner guts. For more details: [swift-evolution] [Proposal draff] abstract classes and methods, https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160104/005862.html\.

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

Yes it does, since Swift does provide class inheritance as a matter of fact, and fosters safety at the compile time.

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

Other languages do not have the Swift protocols that are the main argument of opponents to abstract classes. So the comparison with other languages may be useless here.

Yet if Swift would support it, it could help a lot welcoming programmers that are familiar with other languages, and bring their OOP experience to the community.

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

A quick reading of the proposal. It may be rough on some edges.

Gwendal Roué

Ditto. Also I believe this goes against the spirit of Protocol Oriented Programming that Swift is trying to push.

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

>
> 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 at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

  Coleman,

···

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

Of course, why not? This allows template methods (protected would be even more nice for those) which is an important use case for abstract classes IMO.

-Thorsten

···

Am 26.02.2016 um 22:51 schrieb plx via swift-evolution <swift-evolution@swift.org>:

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()

}

Actually multiple inheritance is not a good example as it
- never was implemented right except in Eiffel
- interfaces/protocols are widely presumed not to have the problems of multiple inheritance but in fact they do have just the same problems when two interfaces/protocols are implemented/conformed to, which have the same member but with different semantics (the diamond problem related to state has the exact same solution as the problem just mentioned, i.e. renaming)
- multiple inheritance is popping up in more and more languages, i.e. in Java with default implementations of interfaces, in Swift with protocol extensions, etc.

-Thorsten

···

Am 27.02.2016 um 00:20 schrieb Patrick R. Gili via swift-evolution <swift-evolution@swift.org>:

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.

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'm all for enhancing protocols.

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.

Just a note: This would require naming the concrete super protocol to use, because multiple parents might provide the relevant member (and by virtue of protocol extensions they might even gain this member after the fact of defining the protocol containing the super call). Knowing which super to call is the advantage of and reason for the restriction to single inheritance when deriving from a parent class.

3. Being able to declare stored properties in protocol extensions, as long as they were declared in the same module as the protocol.

That would be nice.

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.

Sorry, I don't understand that.

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.

That would be an important requirement as soon as protocols can contain properties.

I'm missing an important feature in your list: being able to declare protocol members with access scopes different from that of the protocol, i.e. private or internal in a public protocol.
This is a very important requirement for something like template methods.

Another important feature quite related to that is a "protected" scope.

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.

That is a marked disadvantage which prohibits defining partial behavior which is filled in by concrete types!
If protocols should remain like that then that alone is a decisive argument for adding abstract classes.

-Thorsten

···

Am 01.03.2016 um 01:37 schrieb Brent Royal-Gordon via swift-evolution <swift-evolution@swift.org>:

* 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

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

- What is your evaluation of the proposal?

I could not more strongly support the proposal to add abstract classes, functions and properties to Swift.

None of the proposals involving protocols as a solution to this have addressed the fundamental issue:

*ONLY* abstract classes ON THEIR OWN allow the compiler to enforce providing an implementation for a given function.

For example -- and not picking against the author of this, it's just the most recent example to grace my inbox:

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.

This does not address the fundamental concern of abstract classes.

Yes, a protocol will force you to provide an implementation. However, a protocol *by itself* cannot force the implementor of a class to provide an implementation unless that class declares itself in conformance with that protocol.

ONLY an abstract class, ON ITS OWN, can force concrete subclassers to provide an implementation for a given thing.

Protocols can't do this, because if you forget to declare conformance with the protocol, the compiler can't enforce anything. This pushes what could be caught at compile-time to a runtime (potentially crashing) problem.

Abstract classes enforce a requirement that a given portion of the class hierarchy provide an implementation of X.

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

Yes.

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

No, protocols *do not implement* this functionality. They provide something else, and are orthogonal to the class hierarchy.

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

Absolutely. Swift is about safety, about letting the compiler perform safety checks. ONLY abstract classes allow the compiler to enforce that an implementor of a given subclass has provided an implementation for a given function.

Solutions that require the use of protocols can only be checked for correctness if the implementor of the subclass in question ALSO declares conformance to the protocol.

In other words, a protocol-based solution can only be checked by the compiler if the developer does 2 things correctly (declares protocol conformance and provides an implementation), whereas abstract classes allow the compiler to perform checks as long as the developer does 1 thing (subclass a given class).

No. It goes against protocol oriented programming.

Swift isn't ONLY about protocol oriented programming. Classes are here for a reason, and they should not be relegated to second-class status where people refuse to consider class-only functionality just because the concept can't be shoehorned into something protocol-related.

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.

Rather than reject this proposal because "this is only for classes," perhaps recognize that this is only for classes PRECISELY because this type of problem--the one that abstract classes addresses--only occurs with a class hierarchy.

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

C++ and have found them EXTREMELY useful. This proposal is in line with that.

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

I've been following this discussion very closely, and before I realized there was already a proposal in the queue for abstract classes, I also wrote a similar proposal:

There has been a proposal floated (by Dave Abrahams if I recall--and if I'm wrong, sorry!) to change protocols so conformance is NOT inherited by subclasses by default.

I would just like to point out that if that happens, all of the arguments against abstract classes go out the window, and we absolutely WILL need abstract classes, because all the convoluted gymnastics required to get protocols to kinda-sorta (but not really) provide some of what abstract classes provide won't be possible.

Long live the class hierarchy!

We have a hammer and pliers. Now we invented a screwdriver, let's throw the
hammer in the trash. (If it was a sonic screwdriver would be cool.)

I believe that each tool is used for a purpose. Taking the possibility of
other tools just because there is a new way to another does not seem to
make sense.

Otherwise, what about eliminate classes for good? What do you (plural)
think? So the Swift will be fully POP. (This remember me: "POP goes my
heart!" I can swear I'm listening someone singing this song here.)

I like POP anda I like OOP. I'd like to use both in Swift development.

Remembering that Cocoa/CocoaTouch is fundamentally made using classes and
subclasses in mind. I know that Objective-C does not have abstract classes,
but this is a defect, not a quality.

Well... Maybe we have a whole new set of frameworks for OS
X/iOS/watchOS/tvOS coming and I do not know?

-Van

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

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.

Just a note: This would require naming the concrete super protocol to use, because multiple parents might provide the relevant member (and by virtue of protocol extensions they might even gain this member after the fact of defining the protocol containing the super call). Knowing which super to call is the advantage of and reason for the restriction to single inheritance when deriving from a parent class.

I think you're talking about this problem:

    1> protocol A {}; extension A { func foo() { print("A") } }
    2> protocol B {}; extension B { func foo() { print("B") } }
    3> struct X: A, B {}
    4> X().foo()
  repl.swift:4:1: error: ambiguous use of 'foo()'

That's not really related to the point above, which is about allowing protocol extensions to override superclass members.

  protocol ActivityViewControlling: UIViewController {
    ...
  }
  extension ActivityViewController {
    override func viewWillAppear(animated: Bool) {
      super.viewWillAppear(animated)
      ...
    }
  }

However, handling conflicts between protocol extensions with identically-named members *is* an issue with protocols in general. I think we should look into that as a problem with protocols as a whole, rather than thinking of it as something specific to this proposal.

4. Being able to declare conformance only to the protocol in a class, and have the required inheritance be implied.

Sorry, I don't understand that.

That simply means that, instead of saying this:

  class MyActivityViewController: UIViewController, ActivityViewControlling {
    ...
  }

It'd be nice if you could say this:

  class MyActivityViewController: ActivityViewControlling {
    ...
  }

And have the inheritance from UIViewController be implied.

5. Being able to add factory initializers to the protocol which could initialize any conforming type.

That would be an important requirement as soon as protocols can contain properties.

Factory initializers are actually not related to properties. They're more about encapsulating the selection of a concrete implementation—basically, they're for patterns like class clusters.

  extension ActivityViewControlling {
    factory init(userInterfaceIdiom: UIUserInterfaceIdiom) {
      switch userInterfaceIdiom {
      case .Phone:
        self = PhoneActivityViewController()
      case .TV:
        self = TVActivityViewController()
      default:
        self = PadActivityViewController()
    }
  }

There will probably need to be a way to initialize stored properties—particularly private ones—added by extensions, but this is also necessary for allowing stored properties in concrete type extensions, so we can reuse whatever mechanism we end up with there.

I'm missing an important feature in your list: being able to declare protocol members with access scopes different from that of the protocol, i.e. private or internal in a public protocol.

Extension methods can always have different access control scopes from the protocol as a whole. The required/abstract methods are a different story, but I'll get into that later.

Another important feature quite related to that is a "protected" scope.

Let's keep the simultaneously open cans of worms to a minimum.

* No problems with private abstract members of public types; all protocol requirements are already as public as the protocol itself.

That is a marked disadvantage which prohibits defining partial behavior which is filled in by concrete types!
If protocols should remain like that then that alone is a decisive argument for adding abstract classes.

This is actually an issue with both approaches. You cannot conform to a protocol/inherit from an abstract class unless you fulfill all of the requirements/implement all of the abstract members. This implies that all of those required/abstract members must be visible to any code which can conform/inherit.

In fact, this situation is actually slightly *better* for protocols, because you can always make a protocol more private than its concrete conforming types; the relationship between those types just won't be visible. A subclass, on the other hand, cannot be more visible than its superclass, so you have to make abstract superclasses and their abstract members fully visible.

This issue can be solved by allowing you to make a protocol/class more visible than the ability to conform to/inherit from it (basically, the "sealed" proposal that has come out of the resilience work); then you could give each requirement/abstract member a visibility anywhere between the ability to conform and the ability to see the type.

But in any case, this is an issue for both constructs; I don't think it should cause us to prefer one of them over the other.

···

***

Actually, that reminds me that there's another, more procedural, reason we should reject SE-0026: The proposal is woefully incomplete, more of a sketch than a detailed plan ready to be implemented.

Technical gaps:

1. The aforementioned visibility concern. Can abstract members be less visible than the type they belong to? If so, what does that mean for the visibility of abstract classes and their subclasses?
2. Who is responsible for initializing an abstract stored property: the parent class or the child? Only the child knows it's stored, but the parent might need a particular initial value. Perhaps it's the child's responsibility unless the parent explicitly says it will initialize the value? How would it say so?
3. How does abstractness interact with resiliency? Can abstract members become non-abstract? Can an abstract class become concrete?
4. Can you have abstract `let`s? How about `subscript`s? `init`s? A `deinit`? Class members? Any other kinds of members I might have forgotten?
5. Can you have partially-abstract properties? For instance, can you have a property with a concrete getter and an abstract setter? Or concrete accessors but abstract observers?
6. Can abstract classes have associated types? That would be a powerful feature, but it would open a whole 'nother can of worms.
7. If you can have abstract inits, can you also have concrete inits which initialize the class's concrete stored properties? What are the inheritance rules for them?
8. Can you nest types inside of abstract classes? Can those types themselves be abstract? If so, would concrete classes have to implement those types? What if you want them to be value types?

Proposal justification gaps:

9. Why is `override` used when you're implementing abstract members? They're not overriding anything.
10. What's the purpose of abstract `willSet`/`didSet`?
11. As several other reviews have lamented, there are no particularly good use cases in the proposal.
12. There is no in-depth exploration of alternative approaches. (This would be much easier to do if we had use cases; then we could look at how alternatives would fare.)

I really think that this review has only two reasonable outcomes: reject because we don't want the feature, or reject because the proposal still needs more work. SE-0026 is just not ready for prime time.

--
Brent Royal-Gordon
Architechies

I 100% support this point. Today all declarations in a protocol are as public as the protocol itself. Only "abstract classes", as known from languages that support this concept, are able to hide some implementation details.

As long as protocols keep "flat" access control, there will be a need for abstract classes, the ready-made concept that already provides data hiding and encapsulation.

Gwendal

···

Le 1 mars 2016 à 07:08, Thorsten Seitz via swift-evolution <swift-evolution@swift.org> a écrit :

I'm missing an important feature in your list: being able to declare protocol members with access scopes different from that of the protocol, i.e. private or internal in a public protocol.
This is a very important requirement for something like template methods.

Another important feature quite related to that is a "protected" scope.

[…]

* No problems with private abstract members of public types; all protocol requirements are already as public as the protocol itself.

That is a marked disadvantage which prohibits defining partial behavior which is filled in by concrete types!
If protocols should remain like that then that alone is a decisive argument for adding abstract classes.

-Thorsten

Don’t you go too fast? Methods declared in protocol extensions are very different from methods declared inside the protocol: they are not dynamically dispatched.

I, too, am concerned about the flat world of protocols' access control.

Gwendal

···

Le 1 mars 2016 à 11:29, Brent Royal-Gordon via swift-evolution <swift-evolution@swift.org> a écrit :

I'm missing an important feature in your list: being able to declare protocol members with access scopes different from that of the protocol, i.e. private or internal in a public protocol.

Extension methods can always have different access control scopes from the protocol as a whole. The required/abstract methods are a different story, but I'll get into that later.

That was me. I only proposed it as an *option* for the conformer, though, not as a sweeping change.

-Joe

···

On Mar 3, 2016, at 12:42 PM, Evan Maloney <emaloney@gilt.com> wrote:

There has been a proposal floated (by Dave Abrahams if I recall--and if I'm wrong, sorry!) to change protocols so conformance is NOT inherited by subclasses by default.

I would just like to point out that if that happens, all of the arguments against abstract classes go out the window, and we absolutely WILL need abstract classes, because all the convoluted gymnastics required to get protocols to kinda-sorta (but not really) provide some of what abstract classes provide won't be possible.

Long live the class hierarchy!