Use of Anonymous Label AND Parameter Name

Hello Swift enthusiasts. While doing some Swifty research on the foundation of the very nice videos of Nottingham University’s YouTube channel called “computerphile”, I stumbled over a subtlety which made me formulate this post.

Consider the following function declaration and an example of making a call to it:

func doNotPanic(_: Int, _: String) {
    print("I've got my towel with me.")
}

doNotPanic(42, "Don't panic.")

It compiles perfectly fine, but I question the use of anonymous labels in combination with anonymous parameter names, which means I cannot gain access to the input parameters, right?

The current Swift documentation does not mention this edge case, and I’m not sure whether I’m missing a point. In my role as an educator I’d rather like to understand the behaviour of the language and compiler instead of just wondering and doing away with it.

Any comment and clarification including hints to useful examples are very welcome.

Happy Swifting

Mati

I think it's described in the reference manual under the heading Special Kinds of Parameters:

An underscore ( _ ) parameter is explicitly ignored and can’t be accessed within the body of the function.

I guess it's not explicitly spelled out in prose that the _ in place of the argument label and the _ in place of the parameter name can be combined into a single _. The grammar in the reference manual allows it.

2 Likes

Such a method may need to have those parameters in its signature to satisfy a protocol conformance, but the parameters themselves may be completely ignored by the implementation.

To catch and prevent unneeded parameters, many projects run a static analysis check for any named parameters which are never referenced from the function body. Usually that would be a cue that the parameter can be removed, but if it is a protocol conformance, then removal would be impossible. _ is Swift’s way of making explicit that there is something there but that it’s being deliberately ignored. It is used for the same sort of purpose in other constructions as well:

_ = iKnowThereIsAReturnValueButIDoNotNeedIt()

switch tuple {
case (_, .a):
  print("The second half is “a”, but the first half is irrelevant.")
case (_, .b):
  print("The second half is “b”, but the first half is irrelevant.")
2 Likes

Thanks for pointing this out in the docs. This makes it at least more comfortable for me in terms of expected behaviour of the compiler. Now I’m just looking for an explanation of WHY this should be acceptable. :wink:

P.S. I moved this thread to “Using Swift”. The “Development” category is intended for discussions about development of Swift, not development with Swift.

Thanks, this is a good example for an anonymous return value. :+1:t3: And the hint towards protocol conformance is something I thought about, too.

Agreed. :ok_hand:t3: First I was under the impression that it might have been a glitch in the compiler itself. Now that it is treated as expected behaviour it’s completely fine to classify it as the “usage”. :innocent:

Here's an example of use:

func describe<T>(_: T.Type) {
  print("The type `\(T.self)` has a size of \(MemoryLayout<T>.size) bytes, " +
    "a stride of \(MemoryLayout<T>.stride) bytes and an alignment " +
    "of \(MemoryLayout<T>.alignment) bytes.")
}

describe(Float?.self)
// The type `Optional<Float>` has a size of 5 bytes, a stride of 8 bytes and an alignment of 4 bytes.

describe(Void.self)
// The type `()` has a size of 0 bytes, a stride of 1 bytes and an alignment of 1 bytes.
6 Likes

This is the most common example in Swift. Sometimes with a generic function you need a way to say what type you actually want, when it is not easy to obtain from the parameters. The type argument is not actually used in the function body, it’s just used to tell the compiler what T should be.

useful examples are very welcome.

Here’s an example I hit regularly:

func didTimeOut(_: Timer) {
    … code …
}

Timer.scheduledTimer(withTimeInterval: 1.0, repeats: false, block: didTimeOut)

The timer passes itself to the callback because, in the case of a repeating timer, it’s useful to have the timer handy so that you can invalidate it. However, in the case of a one-shot timer that’s unnecessary and the _ makes it clear that I planned to ignore it.

Share and Enjoy

Quinn “The Eskimo!” @ DTS @ Apple

1 Like

That’s actually a very good use which, to be honest, I also practised in a slightly modified way before I came to know the possibility to use anonymous parameters. Now I can optimise my code without blurring the readability. Such examples just make the beauty of Swift clear to me. Thanks for sharing this. :slightly_smiling_face:

1 Like

Another brilliant explanation. Thanks for sharing this. It got the way into my “Hall of Educated Examples”. :innocent: