# A dedicated function for evaluating Void returning closures when Optional instance is not nil

**URL:** <https://forums.swift.org/t/a-dedicated-function-for-evaluating-void-returning-closures-when-optional-instance-is-not-nil/27367>\
**Category:** Pitches\
**Tags:** foundation, optional\
**Created:** [July 27, 2019, 6:52pm UTC](https://forums.swift.org/t/a-dedicated-function-for-evaluating-void-returning-closures-when-optional-instance-is-not-nil/27367 "2019-07-27T18:52:03Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![deanha](https://avatars.discourse-cdn.com/v4/letter/d/eb8c5e/32.png) [@deanha](https://forums.swift.org/u/deanha)\
**Post date:** [July 27, 2019, 6:52pm UTC](https://forums.swift.org/t/a-dedicated-function-for-evaluating-void-returning-closures-when-optional-instance-is-not-nil/27367/1 "2019-07-27T18:52:04Z")

</div>

Consider the following example:

```swift
var number: Int? = 42
// TODO: print number, if it contains a value.

```

Currently, Swift provides different ways to deal with Optional values.  
The first technique that might come to mind is **Optional Binding** :

```swift
if let number = number {
   print(number)
}

```

However, one could say that using a _control structure_ is quite a verbose pick for such a simple task. This can be seen in the re-introduction of a now unwrapped `number` variable, merely for calling a single function on it on the next line.

Another technique, **Optional Chaining** , is irrelevant in this case, as we're not accessing properties/methods on the `number` variable.

The **Nil-Coalescing Operator** is yet another technique, perhaps in the form of:

```swift
print(number ?? _)

```

However, this is not currently possible, as there is no way to "bail out" without providing a _default value_.

A final option that might come to mind is taking advantage of Swift's higher-order functions:

```swift
number.map { print($0) }

```

The `map(_:)` function definitely has the shape required for the task:

```swift
func map<U>(_ transform: (Wrapped) throws -> U) rethrows -> U?

```

In this example, The `transform` closure has a signature of `(Int) -> Void`, and the entire function is evaluated concretely to be `((Int) -> Void) -> Void?`

However, going back to our original intention it's clear that nor are we _mapping_ `number` to a different value, neither we're interested in the outer return value - an Optional Void - which on itself seems unusual.

A transformation of this shape, i.e one that **returns nothing** , is not uncommon in our day-to-day tasks, and in my opinion deserves a _name_ which clearly and conspicuously translates the writer's intent in call-site.

In this respect, another Container type in Swift that has been added a dedicated method to handle such "transformations" is the `Array` type. Consider the following functions:

- `func map<T>(_ transform: (Element) throws -> T) rethrows -> [T]`
- `func forEach(_ body: (Element) throws -> Void) rethrows`

While we would all agree that `forEach(_:)` is not a necessity, we can also agree that for the task of _printing all elements in an array_, this:  
`[4, 2].forEach { print($0) }`  
reads much nicer than this:  
`_ = [4, 2].map { print($0) }`

Thus I propose adding a parallel function to `Array`'s `forEach(_:)`, taking advantage of a similar naming for convenience:

```swift
public extension Optional {
    func forValue(_ body: (Wrapped) throws -> Void) rethrows {
        guard let value = self else { return }
        try body(value)
    }
}

```

##### IMPORTANT NOTE:

* * *

A [similar pitch](https://forums.swift.org/t/add-an-ifpresent-function-to-optional/1759) was raised a couple of years ago, suggesting to add an `ifPresent(_:)` function with a similar signature:  
`func ifPresent(@noescape f: (Wrapped) throws -> Void) rethrows`

Unfortunately, the discussion quickly turned into a debate of whether to make `Optional` into a `CollectionType`.  
Towards the end the misleading nature of `map(_:)` was actually raised, but discussion didn't make any progress, and more specifically - didn't make the case for handling a particular kind of closure shape passed to a higher order function.

###### PS:

I'd like to thank my fellow iOS team members @Vimeo, Amir Aharon and Liron Yehoshua, for their wise input on this issue.

---

<div class="post-metadata">

**Author:** ![cukr](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/cukr/32/889_2.png) [@cukr](https://forums.swift.org/u/cukr)\
**Post date:** [July 27, 2019, 7:03pm UTC](https://forums.swift.org/t/a-dedicated-function-for-evaluating-void-returning-closures-when-optional-instance-is-not-nil/27367/2 "2019-07-27T19:03:45Z")

</div>

While it's abuse of a function, you can use `map` for that:

```swift
number.map { print($0) }

```

or, when without using a closure

```swift
number.map(someFunctionTakingInt)

```

I like to think about Optional as a Sequence of zero or one elements, and there should be `forEach` method on it too, that way we won't abuse `map`, but I imagine a lot of people would dislike the name.

Edit:  
After you finished your post I see that we're thinking in exactly the same way. +1!

---

<div class="post-metadata">

**Author:** ![DevAndArtist](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/devandartist/32/287_2.png) [@DevAndArtist](https://forums.swift.org/u/DevAndArtist)\
**Post date:** [July 27, 2019, 7:03pm UTC](https://forums.swift.org/t/a-dedicated-function-for-evaluating-void-returning-closures-when-optional-instance-is-not-nil/27367/3 "2019-07-27T19:03:54Z")

</div>

Hi and welcome to the SE forums. This idea was pitched quite a lot, if you intend to push it forward I would love if you would sum up and link previous threads. It is always good if you could provide new insights about the problem, because otherwise we would simply re-hashing everything that has been already said. 😉

---

<div class="post-metadata">

**Author:** ![deanha](https://avatars.discourse-cdn.com/v4/letter/d/eb8c5e/32.png) [@deanha](https://forums.swift.org/u/deanha)\
**Post date:** [July 27, 2019, 7:51pm UTC](https://forums.swift.org/t/a-dedicated-function-for-evaluating-void-returning-closures-when-optional-instance-is-not-nil/27367/4 "2019-07-27T19:51:11Z")

</div>

Hi,

Please take a look at my revised pitch. I've addressed both.

---

<div class="post-metadata">

**Author:** ![deanha](https://avatars.discourse-cdn.com/v4/letter/d/eb8c5e/32.png) [@deanha](https://forums.swift.org/u/deanha)\
**Post date:** [July 27, 2019, 7:53pm UTC](https://forums.swift.org/t/a-dedicated-function-for-evaluating-void-returning-closures-when-optional-instance-is-not-nil/27367/5 "2019-07-27T19:53:22Z")

</div>

Hi,

Thanks for the warm welcome 🙂  
I've added a link to the only thread I've found discussing this, and indicated my why the point wasn't made clear enough IMHO.

I hope I've provided valuable information and thoughts to make this discussion more fruitful and possibly to get a review on this.

---

<div class="post-metadata">

**Author:** ![suyashsrijan](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/suyashsrijan/32/5292_2.png) [@suyashsrijan](https://forums.swift.org/u/suyashsrijan)\
**Post date:** [July 27, 2019, 8:14pm UTC](https://forums.swift.org/t/a-dedicated-function-for-evaluating-void-returning-closures-when-optional-instance-is-not-nil/27367/6 "2019-07-27T20:14:31Z")

</div>

You can do something like

```swift
extension Optional {
  func `let`(_ unwrapped: (Wrapped) -> Void) {
	switch self {
	  case let .some(value):
		unwrapped(value)
	  case .none:
		break
	}
  }
}

let number: Int? = 1
number.let {
  print($0) // 1
}

let anotherNumber: Int? = nil
anotherNumber.let { // Won't be called
  print($0)
}

```

but this is basically like a `map`, but with a different name (you can call it whatever you want - `ifLet`, `unwrap`, etc)

---

<div class="post-metadata">

**Author:** ![Jean-Daniel](https://avatars.discourse-cdn.com/v4/letter/j/977dab/32.png) [@Jean-Daniel](https://forums.swift.org/u/Jean-Daniel)\
**Post date:** [July 27, 2019, 8:34pm UTC](https://forums.swift.org/t/a-dedicated-function-for-evaluating-void-returning-closures-when-optional-instance-is-not-nil/27367/7 "2019-07-27T20:34:49Z")

</div>

This is so similar to `map` that I would rather implement it like this:

```swift
extension Optional {
  func `let`(_ unwrapped: (Wrapped) -> Void) {
	map(unwrapped)
  }
}

```

---

<div class="post-metadata">

**Author:** ![suyashsrijan](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/suyashsrijan/32/5292_2.png) [@suyashsrijan](https://forums.swift.org/u/suyashsrijan)\
**Post date:** [July 27, 2019, 8:37pm UTC](https://forums.swift.org/t/a-dedicated-function-for-evaluating-void-returning-closures-when-optional-instance-is-not-nil/27367/8 "2019-07-27T20:37:38Z")

</div>

Yep.

---

<div class="post-metadata">

**Author:** ![liron\_y](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/liron_y/32/8583_2.png) [@liron\_y](https://forums.swift.org/u/liron_y)\
**Post date:** [July 27, 2019, 9:18pm UTC](https://forums.swift.org/t/a-dedicated-function-for-evaluating-void-returning-closures-when-optional-instance-is-not-nil/27367/9 "2019-07-27T21:18:12Z")

</div>

Actually I really like the idea of a dedicated function for Optionals for using their unwrapped value.  
It always feels wrong to me to use the `map(_:)` function for just using the unwrapping it provides.

I like @suyashsrijan idea with the `let(_:)` function, it is Kotlin-like 🙂.

Great pitch! 👏

---

<div class="post-metadata">

**Author:** ![Jean-Daniel](https://avatars.discourse-cdn.com/v4/letter/j/977dab/32.png) [@Jean-Daniel](https://forums.swift.org/u/Jean-Daniel)\
**Post date:** [July 27, 2019, 9:21pm UTC](https://forums.swift.org/t/a-dedicated-function-for-evaluating-void-returning-closures-when-optional-instance-is-not-nil/27367/10 "2019-07-27T21:21:36Z")

</div>

I'm not sure being `kotlin-like` is a convincing argument to reuse `let` in this context.  
In Kotlin, `let` is not a keyword used elsewhere, which is obviously not the case in Swift.

---

<div class="post-metadata">

**Author:** ![toph42](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/toph42/32/7807_2.png) [@toph42](https://forums.swift.org/u/toph42)\
**Post date:** [July 27, 2019, 10:33pm UTC](https://forums.swift.org/t/a-dedicated-function-for-evaluating-void-returning-closures-when-optional-instance-is-not-nil/27367/11 "2019-07-27T22:33:10Z")

</div>

This seems cosmetic and anyone who doesn’t like the look of `map` could just write an extension to use a more palatable name for them.

---

<div class="post-metadata">

**Author:** ![mayoff](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/mayoff/32/613_2.png) [@mayoff](https://forums.swift.org/u/mayoff)\
**Post date:** [July 27, 2019, 10:50pm UTC](https://forums.swift.org/t/a-dedicated-function-for-evaluating-void-returning-closures-when-optional-instance-is-not-nil/27367/12 "2019-07-27T22:50:44Z")

</div>

> [@Jean-Daniel](#):
>
> I'm not sure being `kotlin-like` is a convincing argument to reuse `let` in this context.  
> In Kotlin, `let` is not a keyword used elsewhere, which is obviously not the case in Swift.

In Swift, it should obviously be named `val`. 😅

---

<div class="post-metadata">

**Author:** ![deanha](https://avatars.discourse-cdn.com/v4/letter/d/eb8c5e/32.png) [@deanha](https://forums.swift.org/u/deanha)\
**Post date:** [July 28, 2019, 6:04am UTC](https://forums.swift.org/t/a-dedicated-function-for-evaluating-void-returning-closures-when-optional-instance-is-not-nil/27367/14 "2019-07-28T06:04:48Z")

</div>

Would you say the same about `Array`'s `forEach(_:) `?

---

<div class="post-metadata">

**Author:** ![toph42](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/toph42/32/7807_2.png) [@toph42](https://forums.swift.org/u/toph42)\
**Post date:** [July 28, 2019, 12:03pm UTC](https://forums.swift.org/t/a-dedicated-function-for-evaluating-void-returning-closures-when-optional-instance-is-not-nil/27367/15 "2019-07-28T12:03:09Z")

</div>

Since `forEach` made sense to me long before I could grok `map` there, I will concede there is value there for general readability and code comprehension. I’ll change my vote from “but, why?” to “+1” accordingly.

---

<div class="post-metadata">

**Author:** ![Amiraharon](https://avatars.discourse-cdn.com/v4/letter/a/7bcc69/32.png) [@Amiraharon](https://forums.swift.org/u/Amiraharon)\
**Post date:** [July 28, 2019, 1:35pm UTC](https://forums.swift.org/t/a-dedicated-function-for-evaluating-void-returning-closures-when-optional-instance-is-not-nil/27367/16 "2019-07-28T13:35:09Z")

</div>

I find "forValue" not intuitive since "for" reminds me a loop, while in this case the Optional is not

Also "let" is not self explanatory.

I think "evaluateIfNotNil" is self explanatory and precise.  
maybe simple "evaluate" is more swiftly...

for example:

> number.evaluateIfNotNil { print($0) }

or

> number.evaluate { print($0) }

---

<div class="post-metadata">

**Author:** ![spadafiva](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/spadafiva/32/6635_2.png) [@spadafiva](https://forums.swift.org/u/spadafiva)\
**Post date:** [July 28, 2019, 1:59pm UTC](https://forums.swift.org/t/a-dedicated-function-for-evaluating-void-returning-closures-when-optional-instance-is-not-nil/27367/17 "2019-07-28T13:59:47Z")

</div>

I think personally I would be okay with it being named 'let', since it basically sugar around an if let value = value check.

---

<div class="post-metadata">

**Author:** ![flowtoolz](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/flowtoolz/32/13358_2.png) [@flowtoolz](https://forums.swift.org/u/flowtoolz)\
**Post date:** [July 28, 2019, 2:36pm UTC](https://forums.swift.org/t/a-dedicated-function-for-evaluating-void-returning-closures-when-optional-instance-is-not-nil/27367/18 "2019-07-28T14:36:32Z")

</div>

Just to throw in one more: `number.ifLet { print($0) }`

---

<div class="post-metadata">

**Author:** ![deanha](https://avatars.discourse-cdn.com/v4/letter/d/eb8c5e/32.png) [@deanha](https://forums.swift.org/u/deanha)\
**Post date:** [July 28, 2019, 3:14pm UTC](https://forums.swift.org/t/a-dedicated-function-for-evaluating-void-returning-closures-when-optional-instance-is-not-nil/27367/19 "2019-07-28T15:14:13Z")

</div>

I agree that `evaluateIfNotNil(_:)` is precise, but it's a bit too verbose IMHO. We should take advantage of the fact that in call-site it's clear that `number` is an optional.

`evaluate(_:)` actually seems even less appropriate considering the [history of `eval`](https://en.wikipedia.org/wiki/Eval):

> _Eval_ is understood to be the step of converting a quoted string into a callable function and its arguments

I went with `forValue(_:)` to be symmetrical with `Array`'s `forEach(_:)`, and don't think that the _for_ prefix necessarily associated itself with a for loop, when read in one breath, the same way that synonyms like _for example_ don't.

However, if this is an issue perhaps alternative such as `withValue(_:)` or `usingValue(_:)` might suffice.

---

<div class="post-metadata">

**Author:** ![idrougge](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/idrougge/32/3885_2.png) [@idrougge](https://forums.swift.org/u/idrougge)\
**Post date:** [July 28, 2019, 3:54pm UTC](https://forums.swift.org/t/a-dedicated-function-for-evaluating-void-returning-closures-when-optional-instance-is-not-nil/27367/20 "2019-07-28T15:54:25Z")

</div>

I think `ifLet` corresponds quite well to `if let` in the same way that `forEach` corresponds to a `for` loop.

---

<div class="post-metadata">

**Author:** ![deanha](https://avatars.discourse-cdn.com/v4/letter/d/eb8c5e/32.png) [@deanha](https://forums.swift.org/u/deanha)\
**Post date:** [July 28, 2019, 4:10pm UTC](https://forums.swift.org/t/a-dedicated-function-for-evaluating-void-returning-closures-when-optional-instance-is-not-nil/27367/21 "2019-07-28T16:10:34Z")

</div>

Meaning you support an `ifLet(_:)` naming?

[Next page](https://forums.swift.org/t/a-dedicated-function-for-evaluating-void-returning-closures-when-optional-instance-is-not-nil/27367.md?page=2)
