[Pitch] Allow trailing argument labels


#1

Sorry, that turned into a bit of a rant, though hopefully a constructive one. I wasn't directing this at you in particular; I just wanted to properly get those points across.

No worries at all, we're all working towards the same goal here.

While I agree that the current proposals feel heavy, equally heavy is creating an entire type, a one-case enum, for the sake of one function. It may fit into the current language design but it is not (IMO) nice by any means. I'm also not a huge fan of the existing proposals, including my own dollar-sign proposal. But I would like to see some version of this added to the language because it does feel awkward to have to rearrange the sentence structure of a function to fit Swift's syntax. Just as ending a sentence with a preposition is something up with which some people won't put, but which is nevertheless useful to avoid awkward sentence structure, I'd prefer not to have to rearrange the English sentence structure of a sentence to comply with Swift's syntactical rules — I'd like to avoid the awkwardness. So I'll throw one more idea out there.

Older versions of Swift used # to indicate "special" behavior regarding parameter labels. Since that use has been deprecated, maybe we could resurrect # for trailing argument labels — in theory, for any positional argument labels, but one step at a time. This would also fit nicely with the current use of #selector, since when used for trailing arguments, # would *select* the function.

// Define
func adding(_ other: Self) // default behavior
func adding(_ other: Self, #reportingOverflow)) // overflow reported

// Call
x.adding(y)
x.adding(y, #reportingOverflow)

// Selectors
#selector(adding(_:))
#selector(adding(_:, #reportingOverflow))


(Haravikk) #2

Looks like you've unintentionally split off into a separate topic, which may make things a bit confusing.

As you say, some kind of syntax is required for disambiguation, as doing without would mean relying on IDE support for label highlighting, which we've agreed in the past shouldn't be necessary (i.e- the language should work just as well in a black and white text-editor).

I'm not sure that the dollar sign is the right choice though, as it still implies a variable due to its usage in closures (where it could still become ambiguous), and just historically in other languages as well. A hash does make a bit more sense, but it's the symbol for compiler directives so it again does lead to potential ambiguity as #reportingOverflow isn't a known directive.

Did you see the discussion between myself and Vladimir S. on the subject? He proposed using a leading colon instead, as it's part of the syntax for labels already, but by making it a leading symbol it's unambiguous. Like-so:

  x.adding(y, :reportingOverflow)

However, he also suggested another syntax which I've found quite interesting, which is to think of it more like a trailing method label (rather than an argument label), like so:

  func adding(_ other:Self):reportingOverflow -> (Self, Bool)
  x.adding(y):reportingOverflow

I quite like this alternative, but you have to think of it in terms of selecting return values. Basically, after you've typed x.adding(y) you've selected all adding(Self) methods of x, but haven't yet chosen a specific one until you either hit colon and add the trailing label, or move onto a new line (leaving it as the default method).

Ultimately though the question that really needs answered on the subject is; do people prefer the idea of using labels to select methods, or are they happy with elongated method names (such as addingWithOverflow)? If most people favour the latter then there's not much point in adding the feature, but if people like the idea of having grouped methods with identical names then it's a worthy addition, personally I like it, and I assume you do too, but it requires broad support to justify it.

···

On 25 Feb 2017, at 01:25, Robert Bennett via swift-evolution <swift-evolution@swift.org> wrote:

Sorry, that turned into a bit of a rant, though hopefully a constructive one. I wasn't directing this at you in particular; I just wanted to properly get those points across.

No worries at all, we're all working towards the same goal here.

While I agree that the current proposals feel heavy, equally heavy is creating an entire type, a one-case enum, for the sake of one function. It may fit into the current language design but it is not (IMO) nice by any means. I'm also not a huge fan of the existing proposals, including my own dollar-sign proposal. But I would like to see some version of this added to the language because it does feel awkward to have to rearrange the sentence structure of a function to fit Swift's syntax. Just as ending a sentence with a preposition is something up with which some people won't put, but which is nevertheless useful to avoid awkward sentence structure, I'd prefer not to have to rearrange the English sentence structure of a sentence to comply with Swift's syntactical rules — I'd like to avoid the awkwardness. So I'll throw one more idea out there.

Older versions of Swift used # to indicate "special" behavior regarding parameter labels. Since that use has been deprecated, maybe we could resurrect # for trailing argument labels — in theory, for any positional argument labels, but one step at a time. This would also fit nicely with the current use of #selector, since when used for trailing arguments, # would *select* the function.

// Define
func adding(_ other: Self) // default behavior
func adding(_ other: Self, #reportingOverflow)) // overflow reported

// Call
x.adding(y)
x.adding(y, #reportingOverflow)

// Selectors
#selector(adding(_:))
#selector(adding(_:, #reportingOverflow))