[Pitch] Add toplevel keyword for protocols


(Patrick Pijnappel) #1

For some protocols we'd like to require top-level (free) functions, e.g.
for many math functions such as abs() or sin(). We already do this
implicitly for operators.

*Proposal*
Allow top-level function/property requirements in protocols, e.g.:

public protocol AbsoluteValuable : SignedNumber { /// Returns the absolute
value of `x`. @warn_unused_result toplevel func abs(_ x: Self) -> Self }

We'd probably want to require this for operators. This also opens up syntax
if we ever get dynamically dispatched operators.

public protocol SignedNumber : Comparable, IntegerLiteralConvertible { ///
Returns the result of negating `x`. @warn_unused_result toplevel prefix func
- (x: Self) -> Self }

Currently this is done using the combination of a static method and a
top-level generic function on that protocol. As I understand that approach
does have some benefits in terms of type-checker performance, though I'm
not sure whether that is likely to stay relevant in the future.

*Advantages*

   - Cleaner than current approach (esp. floating point types have tons of
   top-level functions)
   - Makes operators less of a special case
   - Opens up syntax for member operators
   - Could also apply to top-level properties (esp. useful if we get
   generic properties, for e.g. π<...>)


(Leonardo Pessoa) #2

To me this makes more sense for operators than for other functions or
properties. For the former you could create conflict with previously
declared function (or properties with variables) and there is no
restriction in Swift that says you cannot or should not create a top level
function or property.

In this sense, having an operator declared inside a class/struct/enum would
already make them top level as you proposed, no need for another keyword. I
would only add one requirement: that the first argument should always be of
type Self (and have it checked by the compiler). It ensures the operator
operates on that type and helps minimising conflicts with a previously
declared operator.

- Leonardo

···

On 13 May 2016 at 04:12, Patrick Pijnappel via swift-evolution < swift-evolution@swift.org> wrote:

For some protocols we'd like to require top-level (free) functions, e.g.
for many math functions such as abs() or sin(). We already do this
implicitly for operators.

*Proposal*
Allow top-level function/property requirements in protocols, e.g.:

public protocol AbsoluteValuable : SignedNumber { /// Returns the
absolute value of `x`. @warn_unused_result toplevel func abs(_ x: Self) ->
Self }

We'd probably want to require this for operators. This also opens up
syntax if we ever get dynamically dispatched operators.

public protocol SignedNumber : Comparable, IntegerLiteralConvertible { ///
Returns the result of negating `x`. @warn_unused_result toplevel prefix
func - (x: Self) -> Self }

Currently this is done using the combination of a static method and a
top-level generic function on that protocol. As I understand that approach
does have some benefits in terms of type-checker performance, though I'm
not sure whether that is likely to stay relevant in the future.

*Advantages*

   - Cleaner than current approach (esp. floating point types have tons
   of top-level functions)
   - Makes operators less of a special case
   - Opens up syntax for member operators
   - Could also apply to top-level properties (esp. useful if we get
   generic properties, for e.g. π<...>)

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


(Chris Lattner) #3

For some protocols we'd like to require top-level (free) functions, e.g. for many math functions such as abs() or sin(). We already do this implicitly for operators.

Hi Patrick,

FYI, we’re very likely to remove this special behavior for operators, by making operator requirements only find operators declared in a conforming type. This would eliminate the special case for operators that exists now, and has other advantages as well. Check out this proposal for more information:

-Chris

···

On May 13, 2016, at 12:12 AM, Patrick Pijnappel via swift-evolution <swift-evolution@swift.org> wrote:

Proposal
Allow top-level function/property requirements in protocols, e.g.:

public protocol AbsoluteValuable : SignedNumber {
  /// Returns the absolute value of `x`.
  @warn_unused_result
  toplevel func abs(_ x: Self) -> Self
}

We'd probably want to require this for operators. This also opens up syntax if we ever get dynamically dispatched operators.

public protocol SignedNumber : Comparable, IntegerLiteralConvertible {
  /// Returns the result of negating `x`.
  @warn_unused_result
  toplevel prefix func - (x: Self) -> Self
}

Currently this is done using the combination of a static method and a top-level generic function on that protocol. As I understand that approach does have some benefits in terms of type-checker performance, though I'm not sure whether that is likely to stay relevant in the future.

Advantages
Cleaner than current approach (esp. floating point types have tons of top-level functions)
Makes operators less of a special case
Opens up syntax for member operators
Could also apply to top-level properties (esp. useful if we get generic properties, for e.g. π<...>)
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Patrick Pijnappel) #4

Hmm good point. Defining a toplevel function or property could reserve that
name in toplevel scope, but you'd be in trouble when two protocols from
different modules require a toplevel function or property with the same
signature.

I'm not sure how operators deal with this because they should have the
same problem...

···

On Friday, 13 May 2016, Leonardo Pessoa via swift-evolution < swift-evolution@swift.org> wrote:

To me this makes more sense for operators than for other functions or
properties. For the former you could create conflict with previously
declared function (or properties with variables) and there is no
restriction in Swift that says you cannot or should not create a top level
function or property.

In this sense, having an operator declared inside a class/struct/enum
would already make them top level as you proposed, no need for another
keyword. I would only add one requirement: that the first argument should
always be of type Self (and have it checked by the compiler). It ensures
the operator operates on that type and helps minimising conflicts with a
previously declared operator.

- Leonardo

On 13 May 2016 at 04:12, Patrick Pijnappel via swift-evolution < > swift-evolution@swift.org > <javascript:_e(%7B%7D,'cvml','swift-evolution@swift.org');>> wrote:

For some protocols we'd like to require top-level (free) functions, e.g.
for many math functions such as abs() or sin(). We already do this
implicitly for operators.

*Proposal*
Allow top-level function/property requirements in protocols, e.g.:

public protocol AbsoluteValuable : SignedNumber { /// Returns the
absolute value of `x`. @warn_unused_result toplevel func abs(_ x: Self)
-> Self }

We'd probably want to require this for operators. This also opens up
syntax if we ever get dynamically dispatched operators.

public protocol SignedNumber : Comparable, IntegerLiteralConvertible { ///
Returns the result of negating `x`. @warn_unused_result toplevel prefix
func - (x: Self) -> Self }

Currently this is done using the combination of a static method and a
top-level generic function on that protocol. As I understand that approach
does have some benefits in terms of type-checker performance, though I'm
not sure whether that is likely to stay relevant in the future.

*Advantages*

   - Cleaner than current approach (esp. floating point types have tons
   of top-level functions)
   - Makes operators less of a special case
   - Opens up syntax for member operators
   - Could also apply to top-level properties (esp. useful if we get
   generic properties, for e.g. π<...>)

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
<javascript:_e(%7B%7D,'cvml','swift-evolution@swift.org');>
https://lists.swift.org/mailman/listinfo/swift-evolution


(Patrick Pijnappel) #5

Hi Patrick,
FYI, we’re very likely to remove this special behavior for operators, by
making operator requirements only find operators declared in a conforming
type. This would eliminate the special case for operators that exists now,
and has other advantages as well. Check out this proposal for more
information:

https://github.com/apple/swift-evolution/blob/master/proposals/0091-improving-operators-in-protocols.md

Thanks, hadn't seen that one yet! Looks like a good solution.

···

On Sun, May 15, 2016 at 7:10 AM, Chris Lattner <clattner@apple.com> wrote:

On May 13, 2016, at 12:12 AM, Patrick Pijnappel via swift-evolution < > swift-evolution@swift.org> wrote:

For some protocols we'd like to require top-level (free) functions, e.g.
for many math functions such as abs() or sin(). We already do this
implicitly for operators.

Hi Patrick,

FYI, we’re very likely to remove this special behavior for operators, by
making operator requirements only find operators declared in a conforming
type. This would eliminate the special case for operators that exists now,
and has other advantages as well. Check out this proposal for more
information:

https://github.com/apple/swift-evolution/blob/master/proposals/0091-improving-operators-in-protocols.md

-Chris

*Proposal*
Allow top-level function/property requirements in protocols, e.g.:

public protocol AbsoluteValuable : SignedNumber { /// Returns the
absolute value of `x`. @warn_unused_result toplevel func abs(_ x: Self) ->
Self }

We'd probably want to require this for operators. This also opens up
syntax if we ever get dynamically dispatched operators.

public protocol SignedNumber : Comparable, IntegerLiteralConvertible { ///
Returns the result of negating `x`. @warn_unused_result toplevel prefix
func - (x: Self) -> Self }

Currently this is done using the combination of a static method and a
top-level generic function on that protocol. As I understand that approach
does have some benefits in terms of type-checker performance, though I'm
not sure whether that is likely to stay relevant in the future.

*Advantages*

   - Cleaner than current approach (esp. floating point types have tons
   of top-level functions)
   - Makes operators less of a special case
   - Opens up syntax for member operators
   - Could also apply to top-level properties (esp. useful if we get
   generic properties, for e.g. π<...>)

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


(Leonardo Pessoa) #6

Operators will overload the function with new arguments. That's why I
suggested this change in syntax only for operators and force them to have
the first argument or the type Self.

- Leonardo

···

On 14 May 2016 at 03:39, Patrick Pijnappel via swift-evolution < swift-evolution@swift.org> wrote:

Hmm good point. Defining a toplevel function or property could reserve
that name in toplevel scope, but you'd be in trouble when two protocols
from different modules require a toplevel function or property with the
same signature.

I'm not sure how operators deal with this because they should have the
same problem...

On Friday, 13 May 2016, Leonardo Pessoa via swift-evolution < > swift-evolution@swift.org> wrote:

To me this makes more sense for operators than for other functions or
properties. For the former you could create conflict with previously
declared function (or properties with variables) and there is no
restriction in Swift that says you cannot or should not create a top level
function or property.

In this sense, having an operator declared inside a class/struct/enum
would already make them top level as you proposed, no need for another
keyword. I would only add one requirement: that the first argument should
always be of type Self (and have it checked by the compiler). It ensures
the operator operates on that type and helps minimising conflicts with a
previously declared operator.

- Leonardo

On 13 May 2016 at 04:12, Patrick Pijnappel via swift-evolution < >> swift-evolution@swift.org> wrote:

For some protocols we'd like to require top-level (free) functions, e.g.
for many math functions such as abs() or sin(). We already do this
implicitly for operators.

*Proposal*
Allow top-level function/property requirements in protocols, e.g.:

public protocol AbsoluteValuable : SignedNumber { /// Returns the
absolute value of `x`. @warn_unused_result toplevel func abs(_ x: Self)
-> Self }

We'd probably want to require this for operators. This also opens up
syntax if we ever get dynamically dispatched operators.

public protocol SignedNumber : Comparable, IntegerLiteralConvertible { ///
Returns the result of negating `x`. @warn_unused_result toplevel prefix
func - (x: Self) -> Self }

Currently this is done using the combination of a static method and a
top-level generic function on that protocol. As I understand that approach
does have some benefits in terms of type-checker performance, though I'm
not sure whether that is likely to stay relevant in the future.

*Advantages*

   - Cleaner than current approach (esp. floating point types have tons
   of top-level functions)
   - Makes operators less of a special case
   - Opens up syntax for member operators
   - Could also apply to top-level properties (esp. useful if we get
   generic properties, for e.g. π<...>)

_______________________________________________
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