Aliases for the most used shorthand argument names

$0 ... are here and will stay with us and think this naming scheme is perfectly fine.

But (even with many arguments against it, see below): I think code would look much "nicer" when there would be – in addition to that naming scheme – aliases for the two most used ones, namely $0 and $1 , I would like to use:

  • this as alias for $0

  • that as alias for $1

Example:

… sort { this > that }

Yes, many arguments against it:

  • syntax change just to have it look "nicer"

  • inventing two new keywords

  • idea comes maybe 5 years to late?

I would be interested in comments.

(See also an old thread.)

UPDATE: A real example:

document.elements(ofName: "formula")
    .filter { $0["entity"] != nil } ...

Much "nicer" (but with the first version staying completely valid!) would be:

document.elements(ofName: "formula")
    .filter { this["entity"] != nil } ...

Those names convey meaning that will rarely be applicable, if ever. (E.g. there is no reason that the first parameter would be called "this" in your example, or that that would be "that", instead of whatever "this" is.) Good names that express what you want may exist, but I'm not convinced they do.

Personally, I've always thought that we should go in the other direction, allowing for positional parameters to be used for functions as well as closures. There are plenty of cases, especially operators, where parameter names are not useful—only positions.

3 Likes

I think this/that is quite a foreign choice. I’m not sure what these names are supposed to represent, making it’s quite hard to evaluate the idea. That said, simple sugar tend to have a very high bar, and this sure look like one.

That’d take a lot of control away from the function/library author, which IMO is quite important, on par with clarity. Operators are the odd ones out at best since one doesn’t invoke them with function call syntax.

2 Likes

I think named closure arguments (e.g. (_ this: Element, _ that: Element) -> Bool) are a better solution to this problem. It allows the API designer to choose an appropriate name for each argument, rather than using generalized names for every closure argument.

When you double-click on a type placeholder for (_ this: Element, _ that: Element) -> Bool, Xcode already inserts { this, that in <#code#> }. (Swift Playgrounds for iPad doesn’t, though — that should be fixed).


Can you clarify what you mean by this? If I understand what @anon9791410 means (i.e. allowing something like func doSomething(Int, Int, finally last: Int) { print($0, $1, last) }), then I don’t see how it would take control from the programmer, since it would be opt-in.

2 Likes

I do not think that this would be a solution: In the application of my APIs (which are aimed at users at a "higher" application level), many "filter", "map" and "forEach" with closures have to be used, even adding "soandso in ..." would make everything much longer, so I am using $0 ... in the application of my APIs and in sample code, but I think the "$" are visually too strong (making the code visually "unbalanced"), and people who do not know Swift yet (and to whom I have to present my APIs) think that you are using something strange or complicated at those places. Many times I only need $0, sometimes $1. If there are more than two arguments, I do not have any problem to use $2 and so on or even $0, $1, $2, ... (having a more complicated case anyway, something my APIs try to avoid for the users).

Ah, in that case, I misunderstood what he meant. (it's a little tricky when you have only a few high-level sentences to work with.) You can disregard my comment above.

Any misunderstanding is a fault on my side... An example:

document.elements(ofName: "formula")
    .filter { $0["entity"] != nil } ...

Much "nicer" would be:

document.elements(ofName: "formula")
    .filter { this["entity"] != nil } ...

I think it's a little late to switch to HyperTalk style argument names. They don't seem to fit with the rest of the language, and they're just as arbitrary as using numeric identifiers.

4 Likes

I don't see any problem here. People who don't use Swift don't have to understand Swift, and people who are studying Swift can find $0 or $1 are some special kind of value and search and understand the behavior quickly. The behavior of shorthand argument names is enough simple to understand soon.

I don't think this/that are 'nicer' either. If you want to make meaning clearly, you can explicitly declare names like { a, b in ... }. But this/that is equal to $0/$1, a/b, x/y or first/second in that they don't convey any new information. My first thought when I saw this was literally "what is this?".

It doesn't seem worth to me to consume two more keywords to introduce more unnecessary flexibility for writers and more complexity for learners.

4 Likes

btw, you can tease your colleagues and put $ in names:

struct NeedSome$$$ {
}
let _$0 = 1
print(_$0)

perhaps for some "strong" variables :wink:

this that are not obvious and not scaleable to 3+ parameters. i'm with you in that $0 $1 looks foreign. i'd consider values[0] (making arguments a pseudo array), or values.0 or an interesting looking .0 .1 or _0 _1, or even a b c .... other languages do not have any issue here, coincidently other languages have lambda parameters outside of the brackets (like obj-c closures) so there is no need for the peculiar in that separates parameters from the rest of the closure. we are still quite far from the real world whereas this is obvious without nit-picking { y + 2*x + cos(z) }

Given that Swift provides a mechanism for naming the parameters of a closure in any way you like and it's pretty lightweight

array.sort { this, that in this < that }

I don't think there's any need to add a second way of implicitly naming closure parameters just because some people think $0 is a bit ugly..

7 Likes