Disallow local parameter names in protocols


(James Froggatt) #1

Made a draft proposal to start this discussion, and help define the problem. I'm not too biased either way, this isn't a particularly major aspect of the language, but obviously the proposal has to justify the potential change to the language. This is something due for re-evaluation since Swift 3 removed the ‘first-argument hide-by-default’ rule, which now makes this simplification possible.

Hoping to get an idea of what people's opinions are on this, and the subject of local parameter names leaking to the user in general. Please let me know if my reasoning is flawed, anywhere.

## Introduction

Swift's current treatment of local parameter names is rather odd. They're hidden from the caller most of the timer, where an external parameter label is specified, but otherwise (if a ‘_’ is used), they actually leak out into Xcode's autocomplete. External labels are intended to add clarity, so the local names seem like they should be an implementation detail. Otherwise, why don't local names show up for labelled parameters, too?

The main point in the language affected by this ambiguity is in the protocol definition, where local names can be specified, but are only in any way useful for autocomplete when implementing the protocol, making them useless to the language itself. This proposal, if accepted, would simplify the language by removing the ability to declare local parameter names from protocols, reducing their function signatures to just the actual requirements - label and type.

## Motivation

Consider the following code:

protocol ExampleProtocol {

	func move(from source: Int, to destination: Int)
	
	func max(_ a: Int, _ b: Int) -> Int
	
	func find(_: String, in: String)
}

struct ExampleStruct1: ExampleProtocol {

	func move(from source: Int, to destination: Int) { return }
	
	func max(_ a: Int, _ b: Int) -> Int { return 0 }
	
	func find(_: String, in: String) { return }
}

//still conforms, despite differences to the protocol signature
struct ExampleStruct2: ExampleProtocol {

	func move(from: Int, to: Int) { return }
	
	func max(_ first: Int, _ second: Int) -> Int { return 0 }
	
	func find(_ substring: String, in string: String) { return }
}

ExampleStruct2 conforms to ExampleProtocol, yet clearly has some differences to the signatures defined in the protocol. In ExampleStruct2, its `move` function has no local parameter names, despite their presence in the protocol definition. Its `max` function has differing local names, and `find` has names which aren't present in the protocol.

In functions, it is the purpose of external parameter labels serve to add clarity to the call site. The local names become variables in the function's scope, and are generally invisible to the caller. While these local names can be declared in the protocol, they aren't enforced, and are effectively useless. A confused user may expect that this will enforce the local names, or otherwise specify a requirement, similar to other protocol semantics.

## Proposed solution

Remove the ability to specify local parameter names from protocols.

## Detailed design

Specification of local parameter names in protocols would trigger a compiler error, explaining that local parameter names are not enforced, with a fixit to remove the local name from the parameter list.

## Impact on existing code

This will break existing protocols which declare local parameter names, but should be easily fixable with the migrator, or the previously mentioned fixit.

## Alternatives considered

Leave protocols as they are now, or enforce local parameter names where specified.


(Dave Abrahams) #2

Made a draft proposal to start this discussion, and help define the
problem. I'm not too biased either way, this isn't a particularly
major aspect of the language, but obviously the proposal has to
justify the potential change to the language. This is something due
for re-evaluation since Swift 3 removed the ‘first-argument
hide-by-default’ rule, which now makes this simplification possible.

Hoping to get an idea of what people's opinions are on this, and the
subject of local parameter names leaking to the user in
general. Please let me know if my reasoning is flawed, anywhere.

## Introduction

Swift's current treatment of local parameter names is rather
odd. They're hidden from the caller most of the timer, where an
external parameter label is specified, but otherwise (if a ‘_’ is
used), they actually leak out into Xcode's autocomplete. External
labels are intended to add clarity, so the local names seem like they
should be an implementation detail. Otherwise, why don't local names
show up for labelled parameters, too?

The main point in the language affected by this ambiguity is in the
protocol definition, where local names can be specified, but are only
in any way useful for autocomplete when implementing the protocol,
making them useless to the language itself.

They're useful in documentation comments, which you might have realized
if you had included them in your examples :wink:

This proposal, if accepted, would simplify the language by removing
the ability to declare local parameter names from protocols, reducing
their function signatures to just the actual requirements - label and
type.

Code completion and doc comments are good enough reasons (for me) to
keep this capability. I am opposed to any change here.

···

on Tue Jul 19 2016, James Froggatt <swift-evolution@swift.org> wrote:

## Motivation

Consider the following code:

protocol ExampleProtocol {

	func move(from source: Int, to destination: Int)

	func max(_ a: Int, _ b: Int) -> Int

	func find(_: String, in: String)
}

struct ExampleStruct1: ExampleProtocol {

	func move(from source: Int, to destination: Int) { return }

	func max(_ a: Int, _ b: Int) -> Int { return 0 }

	func find(_: String, in: String) { return }
}

//still conforms, despite differences to the protocol signature
struct ExampleStruct2: ExampleProtocol {

	func move(from: Int, to: Int) { return }

	func max(_ first: Int, _ second: Int) -> Int { return 0 }

	func find(_ substring: String, in string: String) { return }
}

ExampleStruct2 conforms to ExampleProtocol, yet clearly has some
differences to the signatures defined in the protocol. In
ExampleStruct2, its `move` function has no local parameter names,
despite their presence in the protocol definition. Its `max` function
has differing local names, and `find` has names which aren't present
in the protocol.

In functions, it is the purpose of external parameter labels serve to
add clarity to the call site. The local names become variables in the
function's scope, and are generally invisible to the caller. While
these local names can be declared in the protocol, they aren't
enforced, and are effectively useless. A confused user may expect that
this will enforce the local names, or otherwise specify a requirement,
similar to other protocol semantics.

## Proposed solution

Remove the ability to specify local parameter names from protocols.

## Detailed design

Specification of local parameter names in protocols would trigger a
compiler error, explaining that local parameter names are not
enforced, with a fixit to remove the local name from the parameter
list.

## Impact on existing code

This will break existing protocols which declare local parameter
names, but should be easily fixable with the migrator, or the
previously mentioned fixit.

## Alternatives considered

Leave protocols as they are now, or enforce local parameter names where specified.

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

--
Dave


(Karl) #3

Ditto. That’s what I use them for.

Karl

···

On 20 Jul 2016, at 00:30, Dave Abrahams via swift-evolution <swift-evolution@swift.org> wrote:

on Tue Jul 19 2016, James Froggatt <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Made a draft proposal to start this discussion, and help define the
problem. I'm not too biased either way, this isn't a particularly
major aspect of the language, but obviously the proposal has to
justify the potential change to the language. This is something due
for re-evaluation since Swift 3 removed the ‘first-argument
hide-by-default’ rule, which now makes this simplification possible.

Hoping to get an idea of what people's opinions are on this, and the
subject of local parameter names leaking to the user in
general. Please let me know if my reasoning is flawed, anywhere.

## Introduction

Swift's current treatment of local parameter names is rather
odd. They're hidden from the caller most of the timer, where an
external parameter label is specified, but otherwise (if a ‘_’ is
used), they actually leak out into Xcode's autocomplete. External
labels are intended to add clarity, so the local names seem like they
should be an implementation detail. Otherwise, why don't local names
show up for labelled parameters, too?

The main point in the language affected by this ambiguity is in the
protocol definition, where local names can be specified, but are only
in any way useful for autocomplete when implementing the protocol,
making them useless to the language itself.

They're useful in documentation comments, which you might have realized
if you had included them in your examples :wink:

This proposal, if accepted, would simplify the language by removing
the ability to declare local parameter names from protocols, reducing
their function signatures to just the actual requirements - label and
type.

Code completion and doc comments are good enough reasons (for me) to
keep this capability. I am opposed to any change here.


(Goffredo Marocchi) #4

Made a draft proposal to start this discussion, and help define the
problem. I'm not too biased either way, this isn't a particularly
major aspect of the language, but obviously the proposal has to
justify the potential change to the language. This is something due
for re-evaluation since Swift 3 removed the ‘first-argument
hide-by-default’ rule, which now makes this simplification possible.

Hoping to get an idea of what people's opinions are on this, and the
subject of local parameter names leaking to the user in
general. Please let me know if my reasoning is flawed, anywhere.

## Introduction

Swift's current treatment of local parameter names is rather
odd. They're hidden from the caller most of the timer, where an
external parameter label is specified, but otherwise (if a ‘_’ is
used), they actually leak out into Xcode's autocomplete. External
labels are intended to add clarity, so the local names seem like they
should be an implementation detail. Otherwise, why don't local names
show up for labelled parameters, too?

The main point in the language affected by this ambiguity is in the
protocol definition, where local names can be specified, but are only
in any way useful for autocomplete when implementing the protocol,
making them useless to the language itself.

They're useful in documentation comments, which you might have realized
if you had included them in your examples :wink:

This proposal, if accepted, would simplify the language by removing
the ability to declare local parameter names from protocols, reducing
their function signatures to just the actual requirements - label and
type.

Code completion and doc comments are good enough reasons (for me) to
keep this capability. I am opposed to any change here.

Thank you :).

···

Sent from my iPhone

On 19 Jul 2016, at 23:30, Dave Abrahams via swift-evolution <swift-evolution@swift.org> wrote:

on Tue Jul 19 2016, James Froggatt <swift-evolution@swift.org> wrote:

## Motivation

Consider the following code:

protocol ExampleProtocol {

   func move(from source: Int, to destination: Int)

   func max(_ a: Int, _ b: Int) -> Int

   func find(_: String, in: String)
}

struct ExampleStruct1: ExampleProtocol {

   func move(from source: Int, to destination: Int) { return }

   func max(_ a: Int, _ b: Int) -> Int { return 0 }

   func find(_: String, in: String) { return }
}

//still conforms, despite differences to the protocol signature
struct ExampleStruct2: ExampleProtocol {

   func move(from: Int, to: Int) { return }

   func max(_ first: Int, _ second: Int) -> Int { return 0 }

   func find(_ substring: String, in string: String) { return }
}

ExampleStruct2 conforms to ExampleProtocol, yet clearly has some
differences to the signatures defined in the protocol. In
ExampleStruct2, its `move` function has no local parameter names,
despite their presence in the protocol definition. Its `max` function
has differing local names, and `find` has names which aren't present
in the protocol.

In functions, it is the purpose of external parameter labels serve to
add clarity to the call site. The local names become variables in the
function's scope, and are generally invisible to the caller. While
these local names can be declared in the protocol, they aren't
enforced, and are effectively useless. A confused user may expect that
this will enforce the local names, or otherwise specify a requirement,
similar to other protocol semantics.

## Proposed solution

Remove the ability to specify local parameter names from protocols.

## Detailed design

Specification of local parameter names in protocols would trigger a
compiler error, explaining that local parameter names are not
enforced, with a fixit to remove the local name from the parameter
list.

## Impact on existing code

This will break existing protocols which declare local parameter
names, but should be easily fixable with the migrator, or the
previously mentioned fixit.

## Alternatives considered

Leave protocols as they are now, or enforce local parameter names where specified.

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

--
Dave

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