Proposal: Finalization in protocol extensions and default implementations


(Adrian Zubarev) #1

Hello there,

I wonder if it is a good idea to be able to finalize in protocols and default implementations.

Here is an example:

protocol MagicType {
     
    final var foo: Int { get }
    final func boo()
}

class X: MagicType {
     
    final var foo: Int {
         
        return 42
    }
     
    final func boo() {
         
        print("magic")
    }
}

class Y: X {
     
    // can't override func boo or var foo in here
}

//===================================================//

protocol SomeType {}

extension SomeType {
     
    final func foo() {
         
        print("Hello World")
    }
}

class A: SomeType {}

class B: SomeType {
     
    /* this should raise an error, because the class B shouldn't */
    /* be able to override that function from SomeType */
     
    func foo() {
        // do something else
    }
}

···


Regards Adrian


Introducing role keywords to reduce hard-to-find bugs
(Adrian Zubarev) #2

I’d like to revive this idea I posted long time ago. There is only one thing I need to update here:
protocol MagicType: class /* missed the class constraint */ {
      
    final var foo: Int { get }
    final func boo()
}
What do you guys think? Is there any technical reason why this is not possible?

···

--
Adrian Zubarev
Sent with Airmail

Am 5. Dezember 2015 bei 16:26:23, Adrian Zubarev (adrian.zubarev@devandartist.com) schrieb:

Hello there,

I wonder if it is a good idea to be able to finalize in protocols and default implementations.

Here is an example:

protocol MagicType {
      
    final var foo: Int { get }
    final func boo()
}

class X: MagicType {
      
    final var foo: Int {
          
        return 42
    }
      
    final func boo() {
          
        print("magic")
    }
}

class Y: X {
      
    // can't override func boo or var foo in here
}

//===================================================//

protocol SomeType {}

extension SomeType {
      
    final func foo() {
          
        print("Hello World")
    }
}

class A: SomeType {}

class B: SomeType {
      
    /* this should raise an error, because the class B shouldn't */
    /* be able to override that function from SomeType */
      
    func foo() {
        // do something else
    }
}


Regards Adrian


(Matthew Johnson) #3

I’d like to revive this idea I posted long time ago. There is only one thing I need to update here:

protocol MagicType: class /* missed the class constraint */ {
      
    final var foo: Int { get }
    final func boo()
}

What benefit is there in defining a protocol requirement as final?

What do you guys think? Is there any technical reason why this is not possible?
--
Adrian Zubarev
Sent with Airmail

Am 5. Dezember 2015 bei 16:26:23, Adrian Zubarev (adrian.zubarev@devandartist.com <mailto:adrian.zubarev@devandartist.com>) schrieb:

Hello there,

I wonder if it is a good idea to be able to finalize in protocols and default implementations.

Here is an example:

protocol MagicType {
      
    final var foo: Int { get }
    final func boo()
}

class X: MagicType {
      
    final var foo: Int {
          
        return 42
    }
      
    final func boo() {
          
        print("magic")
    }
}

class Y: X {
      
    // can't override func boo or var foo in here
}

//===================================================//

protocol SomeType {}

extension SomeType {
      
    final func foo() {
          
        print("Hello World")
    }
}

class A: SomeType {}

class B: SomeType {
      
    /* this should raise an error, because the class B shouldn't */
    /* be able to override that function from SomeType */
      
    func foo() {
        // do something else
    }
}

How do you anticipate this would interact with retroactive modeling of types which would conform the requirements of `SomeType` but also happen to have a `foo` method?

···

On May 18, 2016, at 12:53 PM, Adrian Zubarev via swift-evolution <swift-evolution@swift.org> wrote:


Regards Adrian

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


(Sean Heber) #4

Putting “final” on a default method implementation that is inside of a protocol extension could maybe make some sense to prevent other implementations of that method, but final in the protocol itself doesn’t make sense to me.

l8r
Sean

···

On May 18, 2016, at 2:18 PM, Leonardo Pessoa via swift-evolution <swift-evolution@swift.org> wrote:

Adrian, what would be the meaning of this final declaration? In my
understanding, a final means there can be no more overrides of that
method but there are no implementations in a protocol so I really
don't understand this use.

On 18 May 2016 at 16:15, Matthew Johnson via swift-evolution > <swift-evolution@swift.org> wrote:

On May 18, 2016, at 12:53 PM, Adrian Zubarev via swift-evolution >> <swift-evolution@swift.org> wrote:

I’d like to revive this idea I posted long time ago. There is only one thing
I need to update here:

protocol MagicType: class /* missed the class constraint */ {

   final var foo: Int { get }
   final func boo()
}

What benefit is there in defining a protocol requirement as final?

What do you guys think? Is there any technical reason why this is not
possible?

--
Adrian Zubarev
Sent with Airmail

Am 5. Dezember 2015 bei 16:26:23, Adrian Zubarev
(adrian.zubarev@devandartist.com) schrieb:

Hello there,

I wonder if it is a good idea to be able to finalize in protocols and
default implementations.

Here is an example:

protocol MagicType {

   final var foo: Int { get }
   final func boo()
}

class X: MagicType {

   final var foo: Int {

       return 42
   }

   final func boo() {

       print("magic")
   }
}

class Y: X {

   // can't override func boo or var foo in here
}

//===================================================//

protocol SomeType {}

extension SomeType {

   final func foo() {

       print("Hello World")
   }
}

class A: SomeType {}

class B: SomeType {

   /* this should raise an error, because the class B shouldn't */
   /* be able to override that function from SomeType */

   func foo() {
       // do something else
   }
}

How do you anticipate this would interact with retroactive modeling of types
which would conform the requirements of `SomeType` but also happen to have a
`foo` method?


Regards Adrian

_______________________________________________
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

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


(Matthew Johnson) #5

Putting “final” on a default method implementation that is inside of a protocol extension could maybe make some sense to prevent other implementations of that method, but final in the protocol itself doesn’t make sense to me.

It makes sense until you consider retroactive modeling. When you do that it becomes unclear whether the two are compatible and retroactive modeling is far more important.

···

On May 18, 2016, at 2:21 PM, Sean Heber via swift-evolution <swift-evolution@swift.org> wrote:

l8r
Sean

On May 18, 2016, at 2:18 PM, Leonardo Pessoa via swift-evolution <swift-evolution@swift.org> wrote:

Adrian, what would be the meaning of this final declaration? In my
understanding, a final means there can be no more overrides of that
method but there are no implementations in a protocol so I really
don't understand this use.

On 18 May 2016 at 16:15, Matthew Johnson via swift-evolution >> <swift-evolution@swift.org> wrote:

On May 18, 2016, at 12:53 PM, Adrian Zubarev via swift-evolution >>> <swift-evolution@swift.org> wrote:

I’d like to revive this idea I posted long time ago. There is only one thing
I need to update here:

protocol MagicType: class /* missed the class constraint */ {

  final var foo: Int { get }
  final func boo()
}

What benefit is there in defining a protocol requirement as final?

What do you guys think? Is there any technical reason why this is not
possible?

--
Adrian Zubarev
Sent with Airmail

Am 5. Dezember 2015 bei 16:26:23, Adrian Zubarev
(adrian.zubarev@devandartist.com) schrieb:

Hello there,

I wonder if it is a good idea to be able to finalize in protocols and
default implementations.

Here is an example:

protocol MagicType {

  final var foo: Int { get }
  final func boo()
}

class X: MagicType {

  final var foo: Int {

      return 42
  }

  final func boo() {

      print("magic")
  }
}

class Y: X {

  // can't override func boo or var foo in here
}

//===================================================//

protocol SomeType {}

extension SomeType {

  final func foo() {

      print("Hello World")
  }
}

class A: SomeType {}

class B: SomeType {

  /* this should raise an error, because the class B shouldn't */
  /* be able to override that function from SomeType */

  func foo() {
      // do something else
  }
}

How do you anticipate this would interact with retroactive modeling of types
which would conform the requirements of `SomeType` but also happen to have a
`foo` method?


Regards Adrian

_______________________________________________
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

_______________________________________________
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


(Leonardo Pessoa) #6

Adrian, what would be the meaning of this final declaration? In my
understanding, a final means there can be no more overrides of that
method but there are no implementations in a protocol so I really
don't understand this use.

···

On 18 May 2016 at 16:15, Matthew Johnson via swift-evolution <swift-evolution@swift.org> wrote:

On May 18, 2016, at 12:53 PM, Adrian Zubarev via swift-evolution > <swift-evolution@swift.org> wrote:

I’d like to revive this idea I posted long time ago. There is only one thing
I need to update here:

protocol MagicType: class /* missed the class constraint */ {

    final var foo: Int { get }
    final func boo()
}

What benefit is there in defining a protocol requirement as final?

What do you guys think? Is there any technical reason why this is not
possible?

--
Adrian Zubarev
Sent with Airmail

Am 5. Dezember 2015 bei 16:26:23, Adrian Zubarev
(adrian.zubarev@devandartist.com) schrieb:

Hello there,

I wonder if it is a good idea to be able to finalize in protocols and
default implementations.

Here is an example:

protocol MagicType {

    final var foo: Int { get }
    final func boo()
}

class X: MagicType {

    final var foo: Int {

        return 42
    }

    final func boo() {

        print("magic")
    }
}

class Y: X {

    // can't override func boo or var foo in here
}

//===================================================//

protocol SomeType {}

extension SomeType {

    final func foo() {

        print("Hello World")
    }
}

class A: SomeType {}

class B: SomeType {

    /* this should raise an error, because the class B shouldn't */
    /* be able to override that function from SomeType */

    func foo() {
        // do something else
    }
}

How do you anticipate this would interact with retroactive modeling of types
which would conform the requirements of `SomeType` but also happen to have a
`foo` method?


Regards Adrian

_______________________________________________
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


(Adrian Zubarev) #7

That is exactly what I was thinking about back then when I posted this idea, but this doesn’t work, at least right now. I’m not sure if this will change if we’ll be forced to use `override` when there is a default implementation provided by the protocol. I’d hope for that behavior. Described here: https://github.com/apple/swift/blob/master/docs/GenericsManifesto.md#allowing-subclasses-to-override-requirements-satisfied-by-defaults-

···

--
Adrian Zubarev
Sent with Airmail

Am 18. Mai 2016 bei 21:21:40, Sean Heber via swift-evolution (swift-evolution@swift.org) schrieb:

Putting “final” on a default method implementation that is inside of a protocol extension could maybe make some sense to prevent other implementations of that method, but final in the protocol itself doesn’t make sense to me.

l8r
Sean

On May 18, 2016, at 2:18 PM, Leonardo Pessoa via swift-evolution <swift-evolution@swift.org> wrote:

Adrian, what would be the meaning of this final declaration? In my
understanding, a final means there can be no more overrides of that
method but there are no implementations in a protocol so I really
don't understand this use.

On 18 May 2016 at 16:15, Matthew Johnson via swift-evolution > <swift-evolution@swift.org> wrote:

On May 18, 2016, at 12:53 PM, Adrian Zubarev via swift-evolution >> <swift-evolution@swift.org> wrote:

I’d like to revive this idea I posted long time ago. There is only one thing
I need to update here:

protocol MagicType: class /* missed the class constraint */ {

final var foo: Int { get }
final func boo()
}

What benefit is there in defining a protocol requirement as final?

What do you guys think? Is there any technical reason why this is not
possible?

--
Adrian Zubarev
Sent with Airmail

Am 5. Dezember 2015 bei 16:26:23, Adrian Zubarev
(adrian.zubarev@devandartist.com) schrieb:

Hello there,

I wonder if it is a good idea to be able to finalize in protocols and
default implementations.

Here is an example:

protocol MagicType {

final var foo: Int { get }
final func boo()
}

class X: MagicType {

final var foo: Int {

return 42
}

final func boo() {

print("magic")
}
}

class Y: X {

// can't override func boo or var foo in here
}

//===================================================//

protocol SomeType {}

extension SomeType {

final func foo() {

print("Hello World")
}
}

class A: SomeType {}

class B: SomeType {

/* this should raise an error, because the class B shouldn't */
/* be able to override that function from SomeType */

func foo() {
// do something else
}
}

How do you anticipate this would interact with retroactive modeling of types
which would conform the requirements of `SomeType` but also happen to have a
`foo` method?


Regards Adrian

_______________________________________________
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

_______________________________________________
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