[Proposal draff] abstract classes and methods


(David Scrève) #1

# Abstract classes and methods

* Author(s): David Scrève

## Introduction

When developing framework and reusable, we need to develop classes that are partially
abstract with partial implementation. Protocol and protocol extensions provide this, but
they cannot have attributes as classes have.
A partial class combines the behavior of a class with the requirement of implementing methods
in inherited class like protocols.

Swift-evolution thread: [link to the discussion thread for that proposal](https://lists.swift.org/pipermail/swift-evolution)

## Motivation
Like pure virtual methods in C++ and abtract classes in Java and C#, frameworks development
sometimes required abstract classes facility.
An abstract class is like a regular class, but some methods/properties are not implemented
and must be implemented in one of inherited classes.
An abstract class can inherit from other class, implements protocols and has members
attributes as opposite from protocols.
Only some methods and properties might be abstract.
The goal of abstract classes is to encapsulate a generic behavior that may need some
specific implementation methods which are not known in abstract class. This behavior
requires attributes that are used by internal abstract class method.

Example :
Considere a generic RESTClient that is included in a framework :

class RESTClient {
    
    var timeout = 3000
    
    var url : String {
        assert(false,"Must be overriden")
        return ""
    }
    
    func performNetworkCall() {
        let restURL = self.url
        print("Performing URL call to \(restURL) with timeout \(self.timeout)")
    }
}

And an implementation :

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

As you can see, url properties must be implemented by inherited class and should not be
implemented by ancestor.
As workaround, we have added assertion, but this error is only detected at runtime and not
at compile time and might create crash for end-user.

## Proposed solution
We propose to add a new keyword to indicate that a method or a property is abstract and
not implemented in current class.
This indicates that method or properties must be implemented in inherited class that can
be implemented.
We propose the keyword abstract that must be added to class and property/method :

abstract class RESTClient {    
     var timeout = 3000

    abstract var url : String { get }
    
    func performNetworkCall() {
        let restURL = self.url
        print("Performing URL call to \(restURL) with timeout \(self.timeout)")
    }
}

And an implementation :

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

## Detailed design
An abstract class cannot be instanciated.

If a class contains one or more abstract methods/properties, it must be declared abstract.

A class that inherits from abstract must be declared abstract if it does not implements
all inherited methods/properties.

If you try to implement an abstract class or a inherited class that implements partially
abstract methods/properties, you will get a compiler error.

As for override keyword, abstract properties apply on setter, getter and observers.

When declaring an abstract property, you must specify which methods must be implemented :
get, set, didSet, willSet.

If you do not specify anything, only setter and getter are made
abstracts as below :

    abstract var url : String

Observers provides default empty implementation.

Type is mandatory for abstract properties since it cannot be inferred.

## Impact on existing code
This change has no impact on existing code, but might change the ABI that is being
stabilizing in Swift 3.0.

## Alternatives considered
As first reading, it seems that protocols and protocol extensions might fit the need. It
actually does not because abstract classes can have attributs and properties that
protocols does not support.

An alternative solution would be to add attributes to protocols and protocol extensions,
but this might break compatibility with Objective-C runtime.


(charles@charlesism.com) #2

+1

I have loads of "pretend abstract" classes littered with stuff like this:

    var boo:Bool! { return nil /*DUMMY*/ }

It takes a significant amount of energy atm to plan a Swift project because there are quirky differences between: protocol / subclass / class extension. It's not so straightforward to pick the most appropriate one.

···

Sent from my iPhone

On Jan 7, 2016, at 9:55 AM, David Scrève via swift-evolution <swift-evolution@swift.org> wrote:

# Abstract classes and methods

* Author(s): David Scrève

## Introduction

When developing framework and reusable, we need to develop classes that are partially
abstract with partial implementation. Protocol and protocol extensions provide this, but
they cannot have attributes as classes have.
A partial class combines the behavior of a class with the requirement of implementing methods
in inherited class like protocols.

Swift-evolution thread: [link to the discussion thread for that proposal](https://lists.swift.org/pipermail/swift-evolution)

## Motivation
Like pure virtual methods in C++ and abtract classes in Java and C#, frameworks development
sometimes required abstract classes facility.
An abstract class is like a regular class, but some methods/properties are not implemented
and must be implemented in one of inherited classes.
An abstract class can inherit from other class, implements protocols and has members
attributes as opposite from protocols.
Only some methods and properties might be abstract.
The goal of abstract classes is to encapsulate a generic behavior that may need some
specific implementation methods which are not known in abstract class. This behavior
requires attributes that are used by internal abstract class method.

Example :
Considere a generic RESTClient that is included in a framework :

class RESTClient {

   var timeout = 3000

   var url : String {
       assert(false,"Must be overriden")
       return ""
   }

   func performNetworkCall() {
       let restURL = self.url
       print("Performing URL call to \(restURL) with timeout \(self.timeout)")
   }
}

And an implementation :

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

}

As you can see, url properties must be implemented by inherited class and should not be
implemented by ancestor.
As workaround, we have added assertion, but this error is only detected at runtime and not
at compile time and might create crash for end-user.

## Proposed solution
We propose to add a new keyword to indicate that a method or a property is abstract and
not implemented in current class.
This indicates that method or properties must be implemented in inherited class that can
be implemented.
We propose the keyword abstract that must be added to class and property/method :

abstract class RESTClient {    
    var timeout = 3000

   abstract var url : String { get }

   func performNetworkCall() {
       let restURL = self.url
       print("Performing URL call to \(restURL) with timeout \(self.timeout)")
   }
}

And an implementation :

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

}

## Detailed design
An abstract class cannot be instanciated.

If a class contains one or more abstract methods/properties, it must be declared abstract.

A class that inherits from abstract must be declared abstract if it does not implements
all inherited methods/properties.

If you try to implement an abstract class or a inherited class that implements partially
abstract methods/properties, you will get a compiler error.

As for override keyword, abstract properties apply on setter, getter and observers.

When declaring an abstract property, you must specify which methods must be implemented :
get, set, didSet, willSet.

If you do not specify anything, only setter and getter are made
abstracts as below :

   abstract var url : String

Observers provides default empty implementation.

Type is mandatory for abstract properties since it cannot be inferred.

## Impact on existing code
This change has no impact on existing code, but might change the ABI that is being
stabilizing in Swift 3.0.

## Alternatives considered
As first reading, it seems that protocols and protocol extensions might fit the need. It
actually does not because abstract classes can have attributs and properties that
protocols does not support.

An alternative solution would be to add attributes to protocols and protocol extensions,
but this might break compatibility with Objective-C runtime.

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


(David James) #3

Not sure the language direction should encourage inheritance based structures, which abstract classes and methods do. That’s not to say that inheritance is dead, but that a modern language should encourage and support compositional patterns rather than inheritance based patterns.

···

On Jan 7, 2016, at 7:19 PM, charles--- via swift-evolution <swift-evolution@swift.org> wrote:

+1

I have loads of "pretend abstract" classes littered with stuff like this:

   var boo:Bool! { return nil /*DUMMY*/ }

It takes a significant amount of energy atm to plan a Swift project because there are quirky differences between: protocol / subclass / class extension. It's not so straightforward to pick the most appropriate one.

Sent from my iPhone

On Jan 7, 2016, at 9:55 AM, David Scrève via swift-evolution <swift-evolution@swift.org> wrote:

# Abstract classes and methods

* Author(s): David Scrève

## Introduction

When developing framework and reusable, we need to develop classes that are partially
abstract with partial implementation. Protocol and protocol extensions provide this, but
they cannot have attributes as classes have.
A partial class combines the behavior of a class with the requirement of implementing methods
in inherited class like protocols.

Swift-evolution thread: [link to the discussion thread for that proposal](https://lists.swift.org/pipermail/swift-evolution)

## Motivation
Like pure virtual methods in C++ and abtract classes in Java and C#, frameworks development
sometimes required abstract classes facility.
An abstract class is like a regular class, but some methods/properties are not implemented
and must be implemented in one of inherited classes.
An abstract class can inherit from other class, implements protocols and has members
attributes as opposite from protocols.
Only some methods and properties might be abstract.
The goal of abstract classes is to encapsulate a generic behavior that may need some
specific implementation methods which are not known in abstract class. This behavior
requires attributes that are used by internal abstract class method.

Example :
Considere a generic RESTClient that is included in a framework :

class RESTClient {

  var timeout = 3000

  var url : String {
      assert(false,"Must be overriden")
      return ""
  }

  func performNetworkCall() {
      let restURL = self.url
      print("Performing URL call to \(restURL) with timeout \(self.timeout)")
  }
}

And an implementation :

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

}

As you can see, url properties must be implemented by inherited class and should not be
implemented by ancestor.
As workaround, we have added assertion, but this error is only detected at runtime and not
at compile time and might create crash for end-user.

## Proposed solution
We propose to add a new keyword to indicate that a method or a property is abstract and
not implemented in current class.
This indicates that method or properties must be implemented in inherited class that can
be implemented.
We propose the keyword abstract that must be added to class and property/method :

abstract class RESTClient {    
   var timeout = 3000

  abstract var url : String { get }

  func performNetworkCall() {
      let restURL = self.url
      print("Performing URL call to \(restURL) with timeout \(self.timeout)")
  }
}

And an implementation :

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

}

## Detailed design
An abstract class cannot be instanciated.

If a class contains one or more abstract methods/properties, it must be declared abstract.

A class that inherits from abstract must be declared abstract if it does not implements
all inherited methods/properties.

If you try to implement an abstract class or a inherited class that implements partially
abstract methods/properties, you will get a compiler error.

As for override keyword, abstract properties apply on setter, getter and observers.

When declaring an abstract property, you must specify which methods must be implemented :
get, set, didSet, willSet.

If you do not specify anything, only setter and getter are made
abstracts as below :

  abstract var url : String

Observers provides default empty implementation.

Type is mandatory for abstract properties since it cannot be inferred.

## Impact on existing code
This change has no impact on existing code, but might change the ABI that is being
stabilizing in Swift 3.0.

## Alternatives considered
As first reading, it seems that protocols and protocol extensions might fit the need. It
actually does not because abstract classes can have attributs and properties that
protocols does not support.

An alternative solution would be to add attributes to protocols and protocol extensions,
but this might break compatibility with Objective-C runtime.

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

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

David James


(Chris Lattner) #4

I tend to agree that adding abstract methods (and classes) is the right thing to do. OOP is an important part of Swift, and is a great way for modeling certain classes of problems.

I wonder if we could simplify our initializer model if we had this, for example, could “required" initializers go away?

-Chris

···

On Jan 7, 2016, at 9:55 AM, David Scrève via swift-evolution <swift-evolution@swift.org> wrote:

# Abstract classes and methods

* Author(s): David Scrève

## Introduction

When developing framework and reusable, we need to develop classes that are partially
abstract with partial implementation. Protocol and protocol extensions provide this, but
they cannot have attributes as classes have.
A partial class combines the behavior of a class with the requirement of implementing methods
in inherited class like protocols.


(Charles Constant) #5

I am not sure that the language should discourage a feature it supports

and impose friction on it because it could be abused.

Especially since the OOP philosophy is falling out of fashion anyway.
Thousands of CompSci profs, and programming blogs, all saying "we've come
to our senses, OOP is confusing". Adding Abstract classes to Swift isn't
going to turn that ship around.

···

On Thu, Jan 7, 2016 at 11:27 AM, Goffredo Marocchi <panajev@gmail.com> wrote:

Hello David,

I am not sure that the language should discourage a feature it supports
and impose friction on it because it could be abused. Composition does not
mean you should never subclass and Swift should not make it trickier to
implement inheritance although I could agree it should not bend over
backwards for it either.
I think this proposal goes along this direction.

With that said, this is where protocols and protocol extensions with
default methods come in, but there we have the static dispatching of the
methods declare in the protocol extension with the default implementation
unless they were also created in the original protocol in which case the
default implementation is only used if the type implementing the protocol
does not override it... That area needs some revisiting too perhaps.

Sent from my iPhone

On 7 Jan 2016, at 18:42, David James via swift-evolution < > swift-evolution@swift.org> wrote:

Not sure the language direction should *encourage* inheritance based
structures, which abstract classes and methods do. That’s not to say that
inheritance is dead, but that a modern language should encourage and
support compositional patterns rather than inheritance based patterns.

On Jan 7, 2016, at 7:19 PM, charles--- via swift-evolution < > swift-evolution@swift.org> wrote:

+1

I have loads of "pretend abstract" classes littered with stuff like this:

   var boo:Bool! { return nil /*DUMMY*/ }

It takes a significant amount of energy atm to plan a Swift project
because there are quirky differences between: protocol / subclass / class
extension. It's not so straightforward to pick the most appropriate one.

Sent from my iPhone

On Jan 7, 2016, at 9:55 AM, David Scrève via swift-evolution < > swift-evolution@swift.org> wrote:

# Abstract classes and methods

* Author(s): David Scrève

## Introduction

When developing framework and reusable, we need to develop classes that
are partially
abstract with partial implementation. Protocol and protocol extensions
provide this, but
they cannot have attributes as classes have.
A partial class combines the behavior of a class with the requirement of
implementing methods
in inherited class like protocols.

Swift-evolution thread: [link to the discussion thread for that proposal](
https://lists.swift.org/pipermail/swift-evolution)

## Motivation
Like pure virtual methods in C++ and abtract classes in Java and C#,
frameworks development
sometimes required abstract classes facility.
An abstract class is like a regular class, but some methods/properties are
not implemented
and must be implemented in one of inherited classes.
An abstract class can inherit from other class, implements protocols and
has members
attributes as opposite from protocols.
Only some methods and properties might be abstract.
The goal of abstract classes is to encapsulate a generic behavior that may
need some
specific implementation methods which are not known in abstract class.
This behavior
requires attributes that are used by internal abstract class method.

Example :
Considere a generic RESTClient that is included in a framework :

class RESTClient {

  var timeout = 3000

  var url : String {
      assert(false,"Must be overriden")
      return ""
  }

  func performNetworkCall() {
      let restURL = self.url
      print("Performing URL call to \(restURL) with timeout
\(self.timeout)")
  }
}

And an implementation :

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

}

As you can see, url properties must be implemented by inherited class and
should not be
implemented by ancestor.
As workaround, we have added assertion, but this error is only detected at
runtime and not
at compile time and might create crash for end-user.

## Proposed solution
We propose to add a new keyword to indicate that a method or a property is
abstract and
not implemented in current class.
This indicates that method or properties must be implemented in inherited
class that can
be implemented.
We propose the keyword abstract that must be added to class and
property/method :

abstract class RESTClient {
   var timeout = 3000

  abstract var url : String { get }

  func performNetworkCall() {
      let restURL = self.url
      print("Performing URL call to \(restURL) with timeout
\(self.timeout)")
  }
}

And an implementation :

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

}

## Detailed design
An abstract class cannot be instanciated.

If a class contains one or more abstract methods/properties, it must be
declared abstract.

A class that inherits from abstract must be declared abstract if it does
not implements
all inherited methods/properties.

If you try to implement an abstract class or a inherited class that
implements partially
abstract methods/properties, you will get a compiler error.

As for override keyword, abstract properties apply on setter, getter and
observers.

When declaring an abstract property, you must specify which methods must
be implemented :
get, set, didSet, willSet.

If you do not specify anything, only setter and getter are made
abstracts as below :

  abstract var url : String

Observers provides default empty implementation.

Type is mandatory for abstract properties since it cannot be inferred.

## Impact on existing code
This change has no impact on existing code, but might change the ABI that
is being
stabilizing in Swift 3.0.

## Alternatives considered
As first reading, it seems that protocols and protocol extensions might
fit the need. It
actually does not because abstract classes can have attributs and
properties that
protocols does not support.

An alternative solution would be to add attributes to protocols and
protocol extensions,
but this might break compatibility with Objective-C runtime.

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

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

David James

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


(Matthew Johnson) #6

Not sure the language direction should encourage inheritance based structures, which abstract classes and methods do. That’s not to say that inheritance is dead, but that a modern language should encourage and support compositional patterns rather than inheritance based patterns.

+1 to these comments. This proposal notes that protocols would provide very similar behavior if they were allowed to have stored properties. That has already been discussed a little bit. I think it would be best to decide whether that will happen or not before introducing abstract classes and methods.

Matthew

···

On Jan 7, 2016, at 12:42 PM, David James via swift-evolution <swift-evolution@swift.org> wrote:

On Jan 7, 2016, at 7:19 PM, charles--- via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

+1

I have loads of "pretend abstract" classes littered with stuff like this:

   var boo:Bool! { return nil /*DUMMY*/ }

It takes a significant amount of energy atm to plan a Swift project because there are quirky differences between: protocol / subclass / class extension. It's not so straightforward to pick the most appropriate one.

Sent from my iPhone

On Jan 7, 2016, at 9:55 AM, David Scrève via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

# Abstract classes and methods

* Author(s): David Scrève

## Introduction

When developing framework and reusable, we need to develop classes that are partially
abstract with partial implementation. Protocol and protocol extensions provide this, but
they cannot have attributes as classes have.
A partial class combines the behavior of a class with the requirement of implementing methods
in inherited class like protocols.

Swift-evolution thread: [link to the discussion thread for that proposal](https://lists.swift.org/pipermail/swift-evolution)

## Motivation
Like pure virtual methods in C++ and abtract classes in Java and C#, frameworks development
sometimes required abstract classes facility.
An abstract class is like a regular class, but some methods/properties are not implemented
and must be implemented in one of inherited classes.
An abstract class can inherit from other class, implements protocols and has members
attributes as opposite from protocols.
Only some methods and properties might be abstract.
The goal of abstract classes is to encapsulate a generic behavior that may need some
specific implementation methods which are not known in abstract class. This behavior
requires attributes that are used by internal abstract class method.

Example :
Considere a generic RESTClient that is included in a framework :

class RESTClient {

  var timeout = 3000

  var url : String {
      assert(false,"Must be overriden")
      return ""
  }

  func performNetworkCall() {
      let restURL = self.url
      print("Performing URL call to \(restURL) with timeout \(self.timeout)")
  }
}

And an implementation :

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

}

As you can see, url properties must be implemented by inherited class and should not be
implemented by ancestor.
As workaround, we have added assertion, but this error is only detected at runtime and not
at compile time and might create crash for end-user.

## Proposed solution
We propose to add a new keyword to indicate that a method or a property is abstract and
not implemented in current class.
This indicates that method or properties must be implemented in inherited class that can
be implemented.
We propose the keyword abstract that must be added to class and property/method :

abstract class RESTClient {    
   var timeout = 3000

  abstract var url : String { get }

  func performNetworkCall() {
      let restURL = self.url
      print("Performing URL call to \(restURL) with timeout \(self.timeout)")
  }
}

And an implementation :

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

}

## Detailed design
An abstract class cannot be instanciated.

If a class contains one or more abstract methods/properties, it must be declared abstract.

A class that inherits from abstract must be declared abstract if it does not implements
all inherited methods/properties.

If you try to implement an abstract class or a inherited class that implements partially
abstract methods/properties, you will get a compiler error.

As for override keyword, abstract properties apply on setter, getter and observers.

When declaring an abstract property, you must specify which methods must be implemented :
get, set, didSet, willSet.

If you do not specify anything, only setter and getter are made
abstracts as below :

  abstract var url : String

Observers provides default empty implementation.

Type is mandatory for abstract properties since it cannot be inferred.

## Impact on existing code
This change has no impact on existing code, but might change the ABI that is being
stabilizing in Swift 3.0.

## Alternatives considered
As first reading, it seems that protocols and protocol extensions might fit the need. It
actually does not because abstract classes can have attributs and properties that
protocols does not support.

An alternative solution would be to add attributes to protocols and protocol extensions,
but this might break compatibility with Objective-C runtime.

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

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

David James

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


(Goffredo Marocchi) #7

Hello David,

I am not sure that the language should discourage a feature it supports and impose friction on it because it could be abused. Composition does not mean you should never subclass and Swift should not make it trickier to implement inheritance although I could agree it should not bend over backwards for it either.
I think this proposal goes along this direction.

With that said, this is where protocols and protocol extensions with default methods come in, but there we have the static dispatching of the methods declare in the protocol extension with the default implementation unless they were also created in the original protocol in which case the default implementation is only used if the type implementing the protocol does not override it... That area needs some revisiting too perhaps.

···

Sent from my iPhone

On 7 Jan 2016, at 18:42, David James via swift-evolution <swift-evolution@swift.org> wrote:

Not sure the language direction should encourage inheritance based structures, which abstract classes and methods do. That’s not to say that inheritance is dead, but that a modern language should encourage and support compositional patterns rather than inheritance based patterns.

On Jan 7, 2016, at 7:19 PM, charles--- via swift-evolution <swift-evolution@swift.org> wrote:

+1

I have loads of "pretend abstract" classes littered with stuff like this:

   var boo:Bool! { return nil /*DUMMY*/ }

It takes a significant amount of energy atm to plan a Swift project because there are quirky differences between: protocol / subclass / class extension. It's not so straightforward to pick the most appropriate one.

Sent from my iPhone

On Jan 7, 2016, at 9:55 AM, David Scrève via swift-evolution <swift-evolution@swift.org> wrote:

# Abstract classes and methods

* Author(s): David Scrève

## Introduction

When developing framework and reusable, we need to develop classes that are partially
abstract with partial implementation. Protocol and protocol extensions provide this, but
they cannot have attributes as classes have.
A partial class combines the behavior of a class with the requirement of implementing methods
in inherited class like protocols.

Swift-evolution thread: [link to the discussion thread for that proposal](https://lists.swift.org/pipermail/swift-evolution)

## Motivation
Like pure virtual methods in C++ and abtract classes in Java and C#, frameworks development
sometimes required abstract classes facility.
An abstract class is like a regular class, but some methods/properties are not implemented
and must be implemented in one of inherited classes.
An abstract class can inherit from other class, implements protocols and has members
attributes as opposite from protocols.
Only some methods and properties might be abstract.
The goal of abstract classes is to encapsulate a generic behavior that may need some
specific implementation methods which are not known in abstract class. This behavior
requires attributes that are used by internal abstract class method.

Example :
Considere a generic RESTClient that is included in a framework :

class RESTClient {

  var timeout = 3000

  var url : String {
      assert(false,"Must be overriden")
      return ""
  }

  func performNetworkCall() {
      let restURL = self.url
      print("Performing URL call to \(restURL) with timeout \(self.timeout)")
  }
}

And an implementation :

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

}

As you can see, url properties must be implemented by inherited class and should not be
implemented by ancestor.
As workaround, we have added assertion, but this error is only detected at runtime and not
at compile time and might create crash for end-user.

## Proposed solution
We propose to add a new keyword to indicate that a method or a property is abstract and
not implemented in current class.
This indicates that method or properties must be implemented in inherited class that can
be implemented.
We propose the keyword abstract that must be added to class and property/method :

abstract class RESTClient {    
   var timeout = 3000

  abstract var url : String { get }

  func performNetworkCall() {
      let restURL = self.url
      print("Performing URL call to \(restURL) with timeout \(self.timeout)")
  }
}

And an implementation :

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

}

## Detailed design
An abstract class cannot be instanciated.

If a class contains one or more abstract methods/properties, it must be declared abstract.

A class that inherits from abstract must be declared abstract if it does not implements
all inherited methods/properties.

If you try to implement an abstract class or a inherited class that implements partially
abstract methods/properties, you will get a compiler error.

As for override keyword, abstract properties apply on setter, getter and observers.

When declaring an abstract property, you must specify which methods must be implemented :
get, set, didSet, willSet.

If you do not specify anything, only setter and getter are made
abstracts as below :

  abstract var url : String

Observers provides default empty implementation.

Type is mandatory for abstract properties since it cannot be inferred.

## Impact on existing code
This change has no impact on existing code, but might change the ABI that is being
stabilizing in Swift 3.0.

## Alternatives considered
As first reading, it seems that protocols and protocol extensions might fit the need. It
actually does not because abstract classes can have attributs and properties that
protocols does not support.

An alternative solution would be to add attributes to protocols and protocol extensions,
but this might break compatibility with Objective-C runtime.

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

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

David James

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


(Goffredo Marocchi) #8

True too, but I think there is some overreaction too especially with the heavy push from FP programmers. Truth is that composition, inheritance, and functional programming are all tools and not religions. We can learn from each how to code better in general and mix and match.

Although this talk predates Swift's default methods/mixins, and so it stops earlier than you might like, it makes a lot of valid points:

Watch “Somewhere Between Tomorrowland and Frontierland - Daniel Steinberg” on Vimeo: https://vimeo.com/124349158

···

Sent from my iPhone

On 7 Jan 2016, at 19:41, Charles Constant <charles@charlesism.com> wrote:

> I am not sure that the language should discourage a feature it supports and impose friction on it because it could be abused.

Especially since the OOP philosophy is falling out of fashion anyway. Thousands of CompSci profs, and programming blogs, all saying "we've come to our senses, OOP is confusing". Adding Abstract classes to Swift isn't going to turn that ship around.

On Thu, Jan 7, 2016 at 11:27 AM, Goffredo Marocchi <panajev@gmail.com> wrote:
Hello David,

I am not sure that the language should discourage a feature it supports and impose friction on it because it could be abused. Composition does not mean you should never subclass and Swift should not make it trickier to implement inheritance although I could agree it should not bend over backwards for it either.
I think this proposal goes along this direction.

With that said, this is where protocols and protocol extensions with default methods come in, but there we have the static dispatching of the methods declare in the protocol extension with the default implementation unless they were also created in the original protocol in which case the default implementation is only used if the type implementing the protocol does not override it... That area needs some revisiting too perhaps.

Sent from my iPhone

On 7 Jan 2016, at 18:42, David James via swift-evolution <swift-evolution@swift.org> wrote:

Not sure the language direction should encourage inheritance based structures, which abstract classes and methods do. That’s not to say that inheritance is dead, but that a modern language should encourage and support compositional patterns rather than inheritance based patterns.

On Jan 7, 2016, at 7:19 PM, charles--- via swift-evolution <swift-evolution@swift.org> wrote:

+1

I have loads of "pretend abstract" classes littered with stuff like this:

   var boo:Bool! { return nil /*DUMMY*/ }

It takes a significant amount of energy atm to plan a Swift project because there are quirky differences between: protocol / subclass / class extension. It's not so straightforward to pick the most appropriate one.

Sent from my iPhone

On Jan 7, 2016, at 9:55 AM, David Scrève via swift-evolution <swift-evolution@swift.org> wrote:

# Abstract classes and methods

* Author(s): David Scrève

## Introduction

When developing framework and reusable, we need to develop classes that are partially
abstract with partial implementation. Protocol and protocol extensions provide this, but
they cannot have attributes as classes have.
A partial class combines the behavior of a class with the requirement of implementing methods
in inherited class like protocols.

Swift-evolution thread: [link to the discussion thread for that proposal](https://lists.swift.org/pipermail/swift-evolution)

## Motivation
Like pure virtual methods in C++ and abtract classes in Java and C#, frameworks development
sometimes required abstract classes facility.
An abstract class is like a regular class, but some methods/properties are not implemented
and must be implemented in one of inherited classes.
An abstract class can inherit from other class, implements protocols and has members
attributes as opposite from protocols.
Only some methods and properties might be abstract.
The goal of abstract classes is to encapsulate a generic behavior that may need some
specific implementation methods which are not known in abstract class. This behavior
requires attributes that are used by internal abstract class method.

Example :
Considere a generic RESTClient that is included in a framework :

class RESTClient {

  var timeout = 3000

  var url : String {
      assert(false,"Must be overriden")
      return ""
  }

  func performNetworkCall() {
      let restURL = self.url
      print("Performing URL call to \(restURL) with timeout \(self.timeout)")
  }
}

And an implementation :

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

}

As you can see, url properties must be implemented by inherited class and should not be
implemented by ancestor.
As workaround, we have added assertion, but this error is only detected at runtime and not
at compile time and might create crash for end-user.

## Proposed solution
We propose to add a new keyword to indicate that a method or a property is abstract and
not implemented in current class.
This indicates that method or properties must be implemented in inherited class that can
be implemented.
We propose the keyword abstract that must be added to class and property/method :

abstract class RESTClient {    
   var timeout = 3000

  abstract var url : String { get }

  func performNetworkCall() {
      let restURL = self.url
      print("Performing URL call to \(restURL) with timeout \(self.timeout)")
  }
}

And an implementation :

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

}

## Detailed design
An abstract class cannot be instanciated.

If a class contains one or more abstract methods/properties, it must be declared abstract.

A class that inherits from abstract must be declared abstract if it does not implements
all inherited methods/properties.

If you try to implement an abstract class or a inherited class that implements partially
abstract methods/properties, you will get a compiler error.

As for override keyword, abstract properties apply on setter, getter and observers.

When declaring an abstract property, you must specify which methods must be implemented :
get, set, didSet, willSet.

If you do not specify anything, only setter and getter are made
abstracts as below :

  abstract var url : String

Observers provides default empty implementation.

Type is mandatory for abstract properties since it cannot be inferred.

## Impact on existing code
This change has no impact on existing code, but might change the ABI that is being
stabilizing in Swift 3.0.

## Alternatives considered
As first reading, it seems that protocols and protocol extensions might fit the need. It
actually does not because abstract classes can have attributs and properties that
protocols does not support.

An alternative solution would be to add attributes to protocols and protocol extensions,
but this might break compatibility with Objective-C runtime.

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

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

David James

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


#9

I agree that the support for stored properties in protocols should definitely help avoiding the need for an abstract classes in many cases.

The problem, though, is that abstract classes still have something that protocol do not, and this is the encapsulation of implementation details. Protocols, on the other side, are open in the wide, expose all their inner guts. The problem with convenience protocols that expose too much implementation details is that they make refactoring very difficult, if possible at all. Abstract classes don’t have this issue.

So I think protocols still have a long, long, way before they can match abstract classes.

Gwendal

···

Le 7 janv. 2016 à 19:44, Matthew Johnson via swift-evolution <swift-evolution@swift.org> a écrit :

On Jan 7, 2016, at 12:42 PM, David James via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Not sure the language direction should encourage inheritance based structures, which abstract classes and methods do. That’s not to say that inheritance is dead, but that a modern language should encourage and support compositional patterns rather than inheritance based patterns.

+1 to these comments. This proposal notes that protocols would provide very similar behavior if they were allowed to have stored properties. That has already been discussed a little bit. I think it would be best to decide whether that will happen or not before introducing abstract classes and methods.


#10

It’s not only about fashion, is it?

Let’s take a practical example, and consider a Swift library that accesses a database. Its writer has jumped in the protocol-oriented wagon, and provides protocols that grants adopting types fetching and persistence methods:

- RowConvertible: types that can be converted from a database row can be fetched:

  Person.fetch(database, "SELECT …")

- TableMapping: types that are linked to a database table. On top of RowConvertible, it grants fetching by primary key:

  Person.fetch(database, key: 12)

- DatabasePersistable (inherits from TableMapping): types that can be saved in the database:

  Person(name: "Arthur").insert(database)

So far, so good. How does look a user type that uses all those features?

  struct Person: RowConvertible, TableMapping, DatabasePersistable { … }

That’s quite a long declaration, but it works.

Enter another feature: changes tracking. Changes tracking requires remembering reference data in order to see what’s changed. Protocols don’t (yet) provide stored properties, so the library, today, has to expose a class for this purpose. That class is *abstract* since subclasses *have* to override the method that tells the table name.

  class Record: RowConvertible, TableMapping, DatabasePersistable { … }

How does look a user type that provides the full toolkit (fetching + persistence + changes tracking) ?

  class Person: Record { … }

Sweet! Can you see how the abstract Record class provides:

1. less mental overhead for the library user (a single type provides the full toolkit)
2. Succinct user types declaration (you don’t have to learn about the three core protocols, just inherit from Record)
3. features that protocols can’t provide (here, changes tracking)

In conclusion: protocol-oriented programming is *more complex* than class-based programming. I think that it is important that the Swift ecosystem lets libraries expose simple entry points even though they provide a list of small and focused protocols that can be composed, because protocol composition requires more engagement from library users.

In the example above, the Record class would benefit from being declared abstract, if the language would support such feature. BTW, that Record class exists: https://github.com/groue/GRDB.swift#database-protocols-and-record.

Gwendal

···

Le 7 janv. 2016 à 20:41, Charles Constant via swift-evolution <swift-evolution@swift.org> a écrit :

> I am not sure that the language should discourage a feature it supports and impose friction on it because it could be abused.

Especially since the OOP philosophy is falling out of fashion anyway. Thousands of CompSci profs, and programming blogs, all saying "we've come to our senses, OOP is confusing". Adding Abstract classes to Swift isn't going to turn that ship around.


(David Scrève) #11

I’m not sure that we should remove required initializers because they handle a different semantic : a required initializer has a default implementation whereas abstract initializer does not.

But I agree that required keyword is less useful if we introduce the abstract concept and I admit I do not have any real use case of this.

I think this should be introduced in another proposal where we also might discuss about the extensibility of required keyword to any method in classes.

David

···

Le 9 janv. 2016 à 20:02, Chris Lattner <clattner@apple.com> a écrit :

On Jan 7, 2016, at 9:55 AM, David Scrève via swift-evolution <swift-evolution@swift.org> wrote:

# Abstract classes and methods

* Author(s): David Scrève

## Introduction

When developing framework and reusable, we need to develop classes that are partially
abstract with partial implementation. Protocol and protocol extensions provide this, but
they cannot have attributes as classes have.
A partial class combines the behavior of a class with the requirement of implementing methods
in inherited class like protocols.

I tend to agree that adding abstract methods (and classes) is the right thing to do. OOP is an important part of Swift, and is a great way for modeling certain classes of problems.

I wonder if we could simplify our initializer model if we had this, for example, could “required" initializers go away?

-Chris


(Douglas Gregor) #12

# Abstract classes and methods

* Author(s): David Scrève

## Introduction

When developing framework and reusable, we need to develop classes that are partially
abstract with partial implementation. Protocol and protocol extensions provide this, but
they cannot have attributes as classes have.
A partial class combines the behavior of a class with the requirement of implementing methods
in inherited class like protocols.

I tend to agree that adding abstract methods (and classes) is the right thing to do. OOP is an important part of Swift, and is a great way for modeling certain classes of problems.

I’m not nearly as convinced that it’s worth doing. It’s a small feature with a small win, and I tend to think that protocols are a better answer for most problems for which one would reflexively reach for an abstract class.

I wonder if we could simplify our initializer model if we had this, for example, could “required" initializers go away?

No, it doesn’t help with required, but the differences between “abstract” and “required” would be sure to cause confusion. “abstract” means “some class along the inheritance path below me must implement this”, whereas “required” means “every class along the inheritance path below me must implement this."

  - Doug

···

On Jan 9, 2016, at 11:02 AM, Chris Lattner via swift-evolution <swift-evolution@swift.org> wrote:

On Jan 7, 2016, at 9:55 AM, David Scrève via swift-evolution <swift-evolution@swift.org> wrote:


(Matthew Johnson) #13

Not sure the language direction should encourage inheritance based structures, which abstract classes and methods do. That’s not to say that inheritance is dead, but that a modern language should encourage and support compositional patterns rather than inheritance based patterns.

+1 to these comments. This proposal notes that protocols would provide very similar behavior if they were allowed to have stored properties. That has already been discussed a little bit. I think it would be best to decide whether that will happen or not before introducing abstract classes and methods.

I agree that the support for stored properties in protocols should definitely help avoiding the need for an abstract classes in many cases.

The problem, though, is that abstract classes still have something that protocol do not, and this is the encapsulation of implementation details. Protocols, on the other side, are open in the wide, expose all their inner guts. The problem with convenience protocols that expose too much implementation details is that they make refactoring very difficult, if possible at all. Abstract classes don’t have this issue.

That doesn’t have to be the case. In fact, if an enhancement came along that allowed protocols to have stored properties I think there will be a request to allow access control on those properties. If they aren’t required to have initial values some way to initialize them would also be necessary. This would allow pretty strong encapsulation.

It is also possible that stored properties in protocols won’t be adopted or would be adopted without allowing for encapsulation. If that is the path that we follow then you make good points. I am just suggesting that we might want to wait and see before considering abstract classes. It might turn out that they really aren’t necessary.

···

On Jan 7, 2016, at 12:57 PM, Gwendal Roué <gwendal.roue@gmail.com> wrote:

Le 7 janv. 2016 à 19:44, Matthew Johnson via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> a écrit :

On Jan 7, 2016, at 12:42 PM, David James via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

So I think protocols still have a long, long, way before they can match abstract classes.

Gwendal


#14

The problem, though, is that abstract classes still have something that protocol do not, and this is the encapsulation of implementation details. Protocols, on the other side, are open in the wide, expose all their inner guts. The problem with convenience protocols that expose too much implementation details is that they make refactoring very difficult, if possible at all. Abstract classes don’t have this issue.

That doesn’t have to be the case. In fact, if an enhancement came along that allowed protocols to have stored properties I think there will be a request to allow access control on those properties. If they aren’t required to have initial values some way to initialize them would also be necessary. This would allow pretty strong encapsulation.

You clearly address the hiding of implementation details from the code that uses types adopting such a protocol. But I’m not sure those implementation details can be hidden from the adopting types themselves?

It is also possible that stored properties in protocols won’t be adopted or would be adopted without allowing for encapsulation. If that is the path that we follow then you make good points. I am just suggesting that we might want to wait and see before considering abstract classes. It might turn out that they really aren’t necessary.

And we’ll continue fatalError("subclass must override") :slight_smile:

Gwendal

···

Le 7 janv. 2016 à 20:01, Matthew Johnson <matthew@anandabits.com> a écrit :


(Austin Zheng) #15

I agree that abstract classes/methods are useful and probably belong in Swift. Inheritance is still (in my opinion) the most natural way to model certain problem domains, even if it has been falsely touted as a panacea for far too long, and I feel like its inclusion in Swift is more than just a sop to Objective-C interoperability.

Practically speaking, iOS/OS X GUI applications written using Apple's existing frameworks are going to be a major part of Swift's future for a long time to come, and the ability to define abstract classes is a natural fit for Cocoa, UIKit, and Foundation's inheritance-based paradigm. Abstract classes serve a purpose (e.g. abstract subclasses of UITableViewController intended to break out shared app-specific functionality) that protocol extensions can't fulfill. You can also go through the documentation and note the many classes which are intended to be subclassed (with mandatory extension points), but cannot express misuse to the programmer until they are used at runtime.

Austin

···

On Jan 7, 2016, at 11:22 PM, Gwendal Roué via swift-evolution <swift-evolution@swift.org> wrote:

Le 7 janv. 2016 à 20:41, Charles Constant via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> a écrit :

> I am not sure that the language should discourage a feature it supports and impose friction on it because it could be abused.

Especially since the OOP philosophy is falling out of fashion anyway. Thousands of CompSci profs, and programming blogs, all saying "we've come to our senses, OOP is confusing". Adding Abstract classes to Swift isn't going to turn that ship around.

It’s not only about fashion, is it?

Let’s take a practical example, and consider a Swift library that accesses a database. Its writer has jumped in the protocol-oriented wagon, and provides protocols that grants adopting types fetching and persistence methods:

- RowConvertible: types that can be converted from a database row can be fetched:

  Person.fetch(database, "SELECT …")

- TableMapping: types that are linked to a database table. On top of RowConvertible, it grants fetching by primary key:

  Person.fetch(database, key: 12)

- DatabasePersistable (inherits from TableMapping): types that can be saved in the database:

  Person(name: "Arthur").insert(database)

So far, so good. How does look a user type that uses all those features?

  struct Person: RowConvertible, TableMapping, DatabasePersistable { … }

That’s quite a long declaration, but it works.

Enter another feature: changes tracking. Changes tracking requires remembering reference data in order to see what’s changed. Protocols don’t (yet) provide stored properties, so the library, today, has to expose a class for this purpose. That class is *abstract* since subclasses *have* to override the method that tells the table name.

  class Record: RowConvertible, TableMapping, DatabasePersistable { … }

How does look a user type that provides the full toolkit (fetching + persistence + changes tracking) ?

  class Person: Record { … }

Sweet! Can you see how the abstract Record class provides:

1. less mental overhead for the library user (a single type provides the full toolkit)
2. Succinct user types declaration (you don’t have to learn about the three core protocols, just inherit from Record)
3. features that protocols can’t provide (here, changes tracking)

In conclusion: protocol-oriented programming is *more complex* than class-based programming. I think that it is important that the Swift ecosystem lets libraries expose simple entry points even though they provide a list of small and focused protocols that can be composed, because protocol composition requires more engagement from library users.

In the example above, the Record class would benefit from being declared abstract, if the language would support such feature. BTW, that Record class exists: https://github.com/groue/GRDB.swift#database-protocols-and-record.

Gwendal

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


(Tim Hawkins) #16

Just for my own education, what is the difference between "protocols" and
"traits" or are they different in name only.

Im a new swift programmer, and im trying to map things back to languages i
have experience with, the languages i have used in anger are c++, modern
(post 5.2) php, javascript and golang, to be truthfull the thing that is
driving me away from golang and towards swift is go's lack of extensive oop
support. In particular the lack of classes and inheritance.

···

On Jan 8, 2016 3:50 AM, "Goffredo Marocchi via swift-evolution" < swift-evolution@swift.org> wrote:

True too, but I think there is some overreaction too especially with the
heavy push from FP programmers. Truth is that composition, inheritance, and
functional programming are all tools and not religions. We can learn from
each how to code better in general and mix and match.

Although this talk predates Swift's default methods/mixins, and so it
stops earlier than you might like, it makes a lot of valid points:

Watch “Somewhere Between Tomorrowland and Frontierland - Daniel Steinberg”
on Vimeo: https://vimeo.com/124349158

Sent from my iPhone

On 7 Jan 2016, at 19:41, Charles Constant <charles@charlesism.com> wrote:

> I am not sure that the language should discourage a feature it supports
and impose friction on it because it could be abused.

Especially since the OOP philosophy is falling out of fashion anyway.
Thousands of CompSci profs, and programming blogs, all saying "we've come
to our senses, OOP is confusing". Adding Abstract classes to Swift isn't
going to turn that ship around.

On Thu, Jan 7, 2016 at 11:27 AM, Goffredo Marocchi <panajev@gmail.com> > wrote:

Hello David,

I am not sure that the language should discourage a feature it supports
and impose friction on it because it could be abused. Composition does not
mean you should never subclass and Swift should not make it trickier to
implement inheritance although I could agree it should not bend over
backwards for it either.
I think this proposal goes along this direction.

With that said, this is where protocols and protocol extensions with
default methods come in, but there we have the static dispatching of the
methods declare in the protocol extension with the default implementation
unless they were also created in the original protocol in which case the
default implementation is only used if the type implementing the protocol
does not override it... That area needs some revisiting too perhaps.

Sent from my iPhone

On 7 Jan 2016, at 18:42, David James via swift-evolution < >> swift-evolution@swift.org> wrote:

Not sure the language direction should *encourage* inheritance based
structures, which abstract classes and methods do. That’s not to say that
inheritance is dead, but that a modern language should encourage and
support compositional patterns rather than inheritance based patterns.

On Jan 7, 2016, at 7:19 PM, charles--- via swift-evolution < >> swift-evolution@swift.org> wrote:

+1

I have loads of "pretend abstract" classes littered with stuff like this:

   var boo:Bool! { return nil /*DUMMY*/ }

It takes a significant amount of energy atm to plan a Swift project
because there are quirky differences between: protocol / subclass / class
extension. It's not so straightforward to pick the most appropriate one.

Sent from my iPhone

On Jan 7, 2016, at 9:55 AM, David Scrève via swift-evolution < >> swift-evolution@swift.org> wrote:

# Abstract classes and methods

* Author(s): David Scrève

## Introduction

When developing framework and reusable, we need to develop classes that
are partially
abstract with partial implementation. Protocol and protocol extensions
provide this, but
they cannot have attributes as classes have.
A partial class combines the behavior of a class with the requirement of
implementing methods
in inherited class like protocols.

Swift-evolution thread: [link to the discussion thread for that proposal](
https://lists.swift.org/pipermail/swift-evolution)

## Motivation
Like pure virtual methods in C++ and abtract classes in Java and C#,
frameworks development
sometimes required abstract classes facility.
An abstract class is like a regular class, but some methods/properties
are not implemented
and must be implemented in one of inherited classes.
An abstract class can inherit from other class, implements protocols and
has members
attributes as opposite from protocols.
Only some methods and properties might be abstract.
The goal of abstract classes is to encapsulate a generic behavior that
may need some
specific implementation methods which are not known in abstract class.
This behavior
requires attributes that are used by internal abstract class method.

Example :
Considere a generic RESTClient that is included in a framework :

class RESTClient {

  var timeout = 3000

  var url : String {
      assert(false,"Must be overriden")
      return ""
  }

  func performNetworkCall() {
      let restURL = self.url
      print("Performing URL call to \(restURL) with timeout
\(self.timeout)")
  }
}

And an implementation :

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

}

As you can see, url properties must be implemented by inherited class and
should not be
implemented by ancestor.
As workaround, we have added assertion, but this error is only detected
at runtime and not
at compile time and might create crash for end-user.

## Proposed solution
We propose to add a new keyword to indicate that a method or a property
is abstract and
not implemented in current class.
This indicates that method or properties must be implemented in inherited
class that can
be implemented.
We propose the keyword abstract that must be added to class and
property/method :

abstract class RESTClient {
   var timeout = 3000

  abstract var url : String { get }

  func performNetworkCall() {
      let restURL = self.url
      print("Performing URL call to \(restURL) with timeout
\(self.timeout)")
  }
}

And an implementation :

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

}

## Detailed design
An abstract class cannot be instanciated.

If a class contains one or more abstract methods/properties, it must be
declared abstract.

A class that inherits from abstract must be declared abstract if it does
not implements
all inherited methods/properties.

If you try to implement an abstract class or a inherited class that
implements partially
abstract methods/properties, you will get a compiler error.

As for override keyword, abstract properties apply on setter, getter and
observers.

When declaring an abstract property, you must specify which methods must
be implemented :
get, set, didSet, willSet.

If you do not specify anything, only setter and getter are made
abstracts as below :

  abstract var url : String

Observers provides default empty implementation.

Type is mandatory for abstract properties since it cannot be inferred.

## Impact on existing code
This change has no impact on existing code, but might change the ABI that
is being
stabilizing in Swift 3.0.

## Alternatives considered
As first reading, it seems that protocols and protocol extensions might
fit the need. It
actually does not because abstract classes can have attributs and
properties that
protocols does not support.

An alternative solution would be to add attributes to protocols and
protocol extensions,
but this might break compatibility with Objective-C runtime.

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

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

David James

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

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


(Goffredo Marocchi) #17

Agreed, thanks for the example too. It was clear before, but this brings a huge +1 from me.

···

Sent from my iPhone

On 8 Jan 2016, at 07:22, Gwendal Roué <gwendal.roue@gmail.com> wrote:

Le 7 janv. 2016 à 20:41, Charles Constant via swift-evolution <swift-evolution@swift.org> a écrit :

> I am not sure that the language should discourage a feature it supports and impose friction on it because it could be abused.

Especially since the OOP philosophy is falling out of fashion anyway. Thousands of CompSci profs, and programming blogs, all saying "we've come to our senses, OOP is confusing". Adding Abstract classes to Swift isn't going to turn that ship around.

It’s not only about fashion, is it?

Let’s take a practical example, and consider a Swift library that accesses a database. Its writer has jumped in the protocol-oriented wagon, and provides protocols that grants adopting types fetching and persistence methods:

- RowConvertible: types that can be converted from a database row can be fetched:

  Person.fetch(database, "SELECT …")

- TableMapping: types that are linked to a database table. On top of RowConvertible, it grants fetching by primary key:

  Person.fetch(database, key: 12)

- DatabasePersistable (inherits from TableMapping): types that can be saved in the database:

  Person(name: "Arthur").insert(database)

So far, so good. How does look a user type that uses all those features?

  struct Person: RowConvertible, TableMapping, DatabasePersistable { … }

That’s quite a long declaration, but it works.

Enter another feature: changes tracking. Changes tracking requires remembering reference data in order to see what’s changed. Protocols don’t (yet) provide stored properties, so the library, today, has to expose a class for this purpose. That class is *abstract* since subclasses *have* to override the method that tells the table name.

  class Record: RowConvertible, TableMapping, DatabasePersistable { … }

How does look a user type that provides the full toolkit (fetching + persistence + changes tracking) ?

  class Person: Record { … }

Sweet! Can you see how the abstract Record class provides:

1. less mental overhead for the library user (a single type provides the full toolkit)
2. Succinct user types declaration (you don’t have to learn about the three core protocols, just inherit from Record)
3. features that protocols can’t provide (here, changes tracking)

In conclusion: protocol-oriented programming is *more complex* than class-based programming. I think that it is important that the Swift ecosystem lets libraries expose simple entry points even though they provide a list of small and focused protocols that can be composed, because protocol composition requires more engagement from library users.

In the example above, the Record class would benefit from being declared abstract, if the language would support such feature. BTW, that Record class exists: https://github.com/groue/GRDB.swift#database-protocols-and-record.

Gwendal


(David Sweeris) #18

Not if you can’t figure out how to write the protocol such that it doesn’t refer to Self, have typealiases, or do something else that means you can only use it as a generic constraint rather than an actual type.

···

On Jan 10, 2016, at 20:59, Douglas Gregor via swift-evolution <swift-evolution@swift.org> wrote:

I’m not nearly as convinced that it’s worth doing. It’s a small feature with a small win, and I tend to think that protocols are a better answer for most problems for which one would reflexively reach for an abstract class.


(Matthew Johnson) #19

The problem, though, is that abstract classes still have something that protocol do not, and this is the encapsulation of implementation details. Protocols, on the other side, are open in the wide, expose all their inner guts. The problem with convenience protocols that expose too much implementation details is that they make refactoring very difficult, if possible at all. Abstract classes don’t have this issue.

That doesn’t have to be the case. In fact, if an enhancement came along that allowed protocols to have stored properties I think there will be a request to allow access control on those properties. If they aren’t required to have initial values some way to initialize them would also be necessary. This would allow pretty strong encapsulation.

You clearly address the hiding of implementation details from the code that uses types adopting such a protocol. But I’m not sure those implementation details can be hidden from the adopting types themselves?

Yes, it would be possible to have `private` stored properties in a protocol that were only visible within the file declaring the protocol. Presumably they would be used by default implementations or `final` methods added in an extension in the same file.

I do not know whether Swift will go down the path of allowing this or not but it would be possible.

It is also possible that stored properties in protocols won’t be adopted or would be adopted without allowing for encapsulation. If that is the path that we follow then you make good points. I am just suggesting that we might want to wait and see before considering abstract classes. It might turn out that they really aren’t necessary.

And we’ll continue fatalError("subclass must override") :slight_smile:

If we end up in that situation I would not be surprised to see a proposal for abstract classes. But I’d rather wait and see.

···

On Jan 7, 2016, at 1:18 PM, Gwendal Roué <gwendal.roue@gmail.com> wrote:

Le 7 janv. 2016 à 20:01, Matthew Johnson <matthew@anandabits.com <mailto:matthew@anandabits.com>> a écrit :

Gwendal


(Goffredo Marocchi) #20

Think of a protocol as an abstract contract a type can adopt. A protocol helps by decoupling the promise the protocol makes to the code using a type conforming to it from the actual implementation of said functionality. You can adopt one or more protocols depending on the behaviours your object wants to support.

This helps testing and refactoring the code greatly.

A trait differs from a protocol in that it provides a method implementation too (protocol extensions allow to specify default method implementations). A mixin differs from a trait in that you can add stored properties to it as well.

Some resources: http://matthijshollemans.com/2015/07/22/mixins-and-traits-in-swift-2/?utm_campaign=This%2BWeek%2Bin%2BSwift&utm_medium=rss&utm_source=This_Week_in_Swift_67

The code in the video referenced earlier on augmented with protocol extensions: http://kelan.io/2015/approachable-functional-thinking-using-protocol-extensions/?utm_campaign=This%2BWeek%2Bin%2BSwift&utm_medium=rss&utm_source=This_Week_in_Swift_67.

···

Sent from my iPhone

On 7 Jan 2016, at 19:59, Tim Hawkins <tim.thawkins@gmail.com> wrote:

Just for my own education, what is the difference between "protocols" and "traits" or are they different in name only.

Im a new swift programmer, and im trying to map things back to languages i have experience with, the languages i have used in anger are c++, modern (post 5.2) php, javascript and golang, to be truthfull the thing that is driving me away from golang and towards swift is go's lack of extensive oop support. In particular the lack of classes and inheritance.

On Jan 8, 2016 3:50 AM, "Goffredo Marocchi via swift-evolution" <swift-evolution@swift.org> wrote:
True too, but I think there is some overreaction too especially with the heavy push from FP programmers. Truth is that composition, inheritance, and functional programming are all tools and not religions. We can learn from each how to code better in general and mix and match.

Although this talk predates Swift's default methods/mixins, and so it stops earlier than you might like, it makes a lot of valid points:

Watch “Somewhere Between Tomorrowland and Frontierland - Daniel Steinberg” on Vimeo: https://vimeo.com/124349158

Sent from my iPhone

On 7 Jan 2016, at 19:41, Charles Constant <charles@charlesism.com> wrote:

> I am not sure that the language should discourage a feature it supports and impose friction on it because it could be abused.

Especially since the OOP philosophy is falling out of fashion anyway. Thousands of CompSci profs, and programming blogs, all saying "we've come to our senses, OOP is confusing". Adding Abstract classes to Swift isn't going to turn that ship around.

On Thu, Jan 7, 2016 at 11:27 AM, Goffredo Marocchi <panajev@gmail.com> wrote:
Hello David,

I am not sure that the language should discourage a feature it supports and impose friction on it because it could be abused. Composition does not mean you should never subclass and Swift should not make it trickier to implement inheritance although I could agree it should not bend over backwards for it either.
I think this proposal goes along this direction.

With that said, this is where protocols and protocol extensions with default methods come in, but there we have the static dispatching of the methods declare in the protocol extension with the default implementation unless they were also created in the original protocol in which case the default implementation is only used if the type implementing the protocol does not override it... That area needs some revisiting too perhaps.

Sent from my iPhone

On 7 Jan 2016, at 18:42, David James via swift-evolution <swift-evolution@swift.org> wrote:

Not sure the language direction should encourage inheritance based structures, which abstract classes and methods do. That’s not to say that inheritance is dead, but that a modern language should encourage and support compositional patterns rather than inheritance based patterns.

On Jan 7, 2016, at 7:19 PM, charles--- via swift-evolution <swift-evolution@swift.org> wrote:

+1

I have loads of "pretend abstract" classes littered with stuff like this:

   var boo:Bool! { return nil /*DUMMY*/ }

It takes a significant amount of energy atm to plan a Swift project because there are quirky differences between: protocol / subclass / class extension. It's not so straightforward to pick the most appropriate one.

Sent from my iPhone

On Jan 7, 2016, at 9:55 AM, David Scrève via swift-evolution <swift-evolution@swift.org> wrote:

# Abstract classes and methods

* Author(s): David Scrève

## Introduction

When developing framework and reusable, we need to develop classes that are partially
abstract with partial implementation. Protocol and protocol extensions provide this, but
they cannot have attributes as classes have.
A partial class combines the behavior of a class with the requirement of implementing methods
in inherited class like protocols.

Swift-evolution thread: [link to the discussion thread for that proposal](https://lists.swift.org/pipermail/swift-evolution)

## Motivation
Like pure virtual methods in C++ and abtract classes in Java and C#, frameworks development
sometimes required abstract classes facility.
An abstract class is like a regular class, but some methods/properties are not implemented
and must be implemented in one of inherited classes.
An abstract class can inherit from other class, implements protocols and has members
attributes as opposite from protocols.
Only some methods and properties might be abstract.
The goal of abstract classes is to encapsulate a generic behavior that may need some
specific implementation methods which are not known in abstract class. This behavior
requires attributes that are used by internal abstract class method.

Example :
Considere a generic RESTClient that is included in a framework :

class RESTClient {

  var timeout = 3000

  var url : String {
      assert(false,"Must be overriden")
      return ""
  }

  func performNetworkCall() {
      let restURL = self.url
      print("Performing URL call to \(restURL) with timeout \(self.timeout)")
  }
}

And an implementation :

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

}

As you can see, url properties must be implemented by inherited class and should not be
implemented by ancestor.
As workaround, we have added assertion, but this error is only detected at runtime and not
at compile time and might create crash for end-user.

## Proposed solution
We propose to add a new keyword to indicate that a method or a property is abstract and
not implemented in current class.
This indicates that method or properties must be implemented in inherited class that can
be implemented.
We propose the keyword abstract that must be added to class and property/method :

abstract class RESTClient {    
   var timeout = 3000

  abstract var url : String { get }

  func performNetworkCall() {
      let restURL = self.url
      print("Performing URL call to \(restURL) with timeout \(self.timeout)")
  }
}

And an implementation :

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

}

## Detailed design
An abstract class cannot be instanciated.

If a class contains one or more abstract methods/properties, it must be declared abstract.

A class that inherits from abstract must be declared abstract if it does not implements
all inherited methods/properties.

If you try to implement an abstract class or a inherited class that implements partially
abstract methods/properties, you will get a compiler error.

As for override keyword, abstract properties apply on setter, getter and observers.

When declaring an abstract property, you must specify which methods must be implemented :
get, set, didSet, willSet.

If you do not specify anything, only setter and getter are made
abstracts as below :

  abstract var url : String

Observers provides default empty implementation.

Type is mandatory for abstract properties since it cannot be inferred.

## Impact on existing code
This change has no impact on existing code, but might change the ABI that is being
stabilizing in Swift 3.0.

## Alternatives considered
As first reading, it seems that protocols and protocol extensions might fit the need. It
actually does not because abstract classes can have attributs and properties that
protocols does not support.

An alternative solution would be to add attributes to protocols and protocol extensions,
but this might break compatibility with Objective-C runtime.

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

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

David James

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

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