# \[Pre-RFC\] Allow \`?\` in patterns

**URL:** <https://internals.rust-lang.org/t/pre-rfc-allow-in-patterns/4772>\
**Category:** Uncategorized\
**Created:** [February 11, 2017, 8:05pm UTC](https://internals.rust-lang.org/t/pre-rfc-allow-in-patterns/4772 "2017-02-11T20:05:33Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![stebalien](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/stebalien/32/228_2.png) [@stebalien](https://internals.rust-lang.org/u/stebalien)\
**Post date:** [February 11, 2017, 8:05pm UTC](https://internals.rust-lang.org/t/pre-rfc-allow-in-patterns/4772/1 "2017-02-11T20:05:33Z")

</div>

So, a common idiom when iterating over anything IO related is:

```rust
for item in my_io_iterator {
    let item = item?;
    // Something
}

```

If rust allowed `?` in patterns, one could write:

```rust
for item? in my_io_iterator {
    // Something
}

```

And even:

```rust
match thing {
    Some(item?) => ...,
    None => ...,
}

```

Thoughts? Is this too ✨ _magical_ ✨? One concern I have is that this would make the following legal:

```rust
let x? = can_fail();

```

---

<div class="post-metadata">

**Author:** ![withoutboats](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/withoutboats/32/4560_2.png) [@withoutboats](https://internals.rust-lang.org/u/withoutboats)\
**Post date:** [February 12, 2017, 12:48am UTC](https://internals.rust-lang.org/t/pre-rfc-allow-in-patterns/4772/2 "2017-02-12T00:48:01Z")

</div>

I do feel like this is pretty magical, but I also strongly feel the motivation. I’m not sure there’s any other solution to the `for item?` problem aside from TCP preserving closures (so you could `.map(|x| x?)` or something), which is a much more complex feature to add.

Basically I’d like an alternative solution, but if there isn’t one I think we should do this.

---

<div class="post-metadata">

**Author:** ![xen0n](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/xen0n/32/1561_2.png) [@xen0n](https://internals.rust-lang.org/u/xen0n)\
**Post date:** [February 12, 2017, 3:23am UTC](https://internals.rust-lang.org/t/pre-rfc-allow-in-patterns/4772/3 "2017-02-12T03:23:42Z")

</div>

The improvement of ergonomics in the suggested use case is real; however I think introducing multiple ways to do the same thing is bad in itself. It is sad that the proposal inevitably allows `let x? = f();` along with `let x = f()?;`, which makes spotting the error processing part much more difficult at a glance.

---

<div class="post-metadata">

**Author:** ![glaebhoerl](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/glaebhoerl/32/1978_2.png) [@glaebhoerl](https://internals.rust-lang.org/u/glaebhoerl)\
**Post date:** [February 12, 2017, 10:18am UTC](https://internals.rust-lang.org/t/pre-rfc-allow-in-patterns/4772/4 "2017-02-12T10:18:07Z")

</div>

This is a cool idea, but normally patterns _de_construct – it’s weird to have a feature which does the _same_ thing in a pattern and an expression, rather than the inverse.

---

<div class="post-metadata">

**Author:** ![thomash](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/thomash/32/2018_2.png) [@thomash](https://internals.rust-lang.org/u/thomash)\
**Post date:** [February 12, 2017, 2:12pm UTC](https://internals.rust-lang.org/t/pre-rfc-allow-in-patterns/4772/5 "2017-02-12T14:12:01Z")

</div>

I totally agree, the feature may be a good one but using the ? syntax is extremely confusing.

---

<div class="post-metadata">

**Author:** ![zackw](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/zackw/32/2071_2.png) [@zackw](https://internals.rust-lang.org/u/zackw)\
**Post date:** [February 12, 2017, 2:13pm UTC](https://internals.rust-lang.org/t/pre-rfc-allow-in-patterns/4772/6 "2017-02-12T14:13:44Z")

</div>

Question, does this work?

```
for item in my_io_iterator.into_iter().map(|x| x?) {
    // Something
}

```

I suspect that it doesn’t, because the closure can’t force the _parent_ function to return, can it? But if it could be _made_ to work, then

```
for item in my_io_iterator? {
    // Something
}

```

could be shorthand for it.

? in a closure returning from the parent function would also enable things like

```
let foo = my_io_iterator.into_iter().map(|x| Something(x?)).collect::<T>();

```

… but I’m sure someone’s about to tell me that they need ? in a closure to _not_ return from the parent, so I’ll stop now. 😉

---

<div class="post-metadata">

**Author:** ![stebalien](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/stebalien/32/228_2.png) [@stebalien](https://internals.rust-lang.org/u/stebalien)\
**Post date:** [February 12, 2017, 4:16pm UTC](https://internals.rust-lang.org/t/pre-rfc-allow-in-patterns/4772/7 "2017-02-12T16:16:30Z")

</div>

@glaebhoerl

> but normally patterns deconstruct

Patterns like `ref` construct. However, it does have a different name (`ref` v `&`). We could use `try` (as a contextual keyword?):

```rust
for try x in stuff {}

```

* * *

@zackw

> Question, does this work?

```
for item in my_io_iterator.into_iter().map(|x| x?) {
    // Something
}

```

Not in rust. Some languages like Kotlin allow things like that; they effectively treat `.map(...)` as an a form of inline macro (they call them inline functions but that means something different in rust).

> 

```
for item in my_io_iterator? {
    // Something
}

```

That's already a valid rust equivalent to:

```rust
let my_io_iterator = my_io_iterator?
for item in my_io_iterator {
    // Something
}

```

> ? in a closure returning from the parent function would also enable things like

Well, I don't know about others but **I'd** be really unhappy if rust introduced non-local returns like that.

---

<div class="post-metadata">

**Author:** ![zackw](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/zackw/32/2071_2.png) [@zackw](https://internals.rust-lang.org/u/zackw)\
**Post date:** [February 12, 2017, 11:28pm UTC](https://internals.rust-lang.org/t/pre-rfc-allow-in-patterns/4772/8 "2017-02-12T23:28:47Z")

</div>

> [@stebalien](#):
>
> That's already a valid rust equivalent to:
> 
> ````rust
> let my_io_iterator = my_io_iterator?
> for item in my_io_iterator {
> // Something
> }```
> 
> ````

Sure, but the type system can distinguish: yours is for when `my_io_iterator` is `Result<T=IntoIterator<Item=TT>, E>`, mine (and the OP's) is for when it is `IntoIterator<Item=Result<T, E>>`.

> Well, I don't know about others but I'd be really unhappy if rust introduced non-local returns like that.

It seems to me that both returning and not-returning from the parent would be useful...

---

<div class="post-metadata">

**Author:** ![sgrif](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/sgrif/32/3339_2.png) [@sgrif](https://internals.rust-lang.org/u/sgrif)\
**Post date:** [February 12, 2017, 11:46pm UTC](https://internals.rust-lang.org/t/pre-rfc-allow-in-patterns/4772/9 "2017-02-12T23:46:00Z")

</div>

FWIW, TCP preserving closures would solve a much larger and more general problem. (And one that I run to all the time. e.g. [https://twitter.com/sgrif/status/830857702691708928](https://twitter.com/sgrif/status/830857702691708928))

---

<div class="post-metadata">

**Author:** ![stebalien](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/stebalien/32/228_2.png) [@stebalien](https://internals.rust-lang.org/u/stebalien)\
**Post date:** [February 13, 2017, 5:07am UTC](https://internals.rust-lang.org/t/pre-rfc-allow-in-patterns/4772/10 "2017-02-13T05:07:51Z")

</div>

> [@zackw](#):
>
> Sure, but the type system can distinguish: yours is for when my\_io\_iterator is Result\<T=IntoIterator\<Item=TT\>, E\>, mine (and the OP's) is for when it is IntoIterator\<Item=Result\<T, E\>\>.

It can't (and I am OP). `Result` is just a type and there's no reason the standard library couldn't implement `IntoIterator<Item=Result<T, E>>` for `Result<T: IntoIterator<Item=T, E>>`. Regardless, that would be confusing as hell for programmers.

---

<div class="post-metadata">

**Author:** ![stebalien](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/stebalien/32/228_2.png) [@stebalien](https://internals.rust-lang.org/u/stebalien)\
**Post date:** [February 13, 2017, 5:26am UTC](https://internals.rust-lang.org/t/pre-rfc-allow-in-patterns/4772/11 "2017-02-13T05:26:45Z")

</div>

> [@sgrif](#):
>
> FWIW, TCP preserving closures would solve a much larger and more general problem. (And one that I run to all the time. e.g. [https://twitter.com/sgrif/status/830857702691708928](https://twitter.com/sgrif/status/830857702691708928)

They may be useful in some cases but really aren't worth the trouble in Rust. As a matter of fact, they almost certainly wouldn't help here because iterators are composable.

Currently, the only way to do a non-local return is to `panic!()` and `catch_unwind`. However, `catch_unwind` is severely restricted: it's not possible to mutably borrow (or pass a reference to a `RefCell`, `Cell`, or anything with interior mutability for that matter) across a `catch_unwind` barrier. This restriction is necessary to avoid exposing types with violated invariants (e.g. by violating some invariant, calling something that could panic, fixing the invariant).

To make TCP preserving closures useful, you'd have to drop these constraints. Then, to make them reasonably safe, you'd have to label functions that can perform this type of unrestricted non-local return in the type system (so you can avoid calling them while violating invariants). That's where you'd get into trouble with iterators.

Basically, `my_iterator.map(f)` doesn't actually _do_ anything; it just returns an iterator adapter (`Map`) that applies `f` to items produced by `my_iterator` whenever `Map::next` is called. So, to make this work, you'd either have to:

1. Label `Iterator::next` as potentially performing a non-local return. As this would affect _all_ iterators so it's obviously a non-starter.
2. Somehow parametrize the `Iterator` trait over some kind of non-local return property (something akin to a lifetime). Now you'd effectively have two lifetime systems.

So, you could make this work for the very simple case where you take a closure and call it immediately but, in that case, I'd just use a macro.

* * *

Note: In your case, you might want to consider proposing `RefMut::try_map`.

---

<div class="post-metadata">

**Author:** ![anon32976453](https://avatars.discourse-cdn.com/v4/letter/a/49beb7/32.png) [@anon32976453](https://internals.rust-lang.org/u/anon32976453)\
**Post date:** [February 13, 2017, 5:33am UTC](https://internals.rust-lang.org/t/pre-rfc-allow-in-patterns/4772/12 "2017-02-13T05:33:36Z")

</div>

Why is this a common idiom for iterators, in particular I/O ones? This reads very unnatural to me.

The usage here indicates that if any of the elements of the iterator are erroneous than the entire thing is erroneous. I’d expect in this case to indeed have:

```
for item in my_io_iterator? {
    // handle item
}

```

and the iterator should be of type `Result<impl Iterator<Item=T>, E>`

---

<div class="post-metadata">

**Author:** ![withoutboats](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/withoutboats/32/4560_2.png) [@withoutboats](https://internals.rust-lang.org/u/withoutboats)\
**Post date:** [February 13, 2017, 5:47am UTC](https://internals.rust-lang.org/t/pre-rfc-allow-in-patterns/4772/13 "2017-02-13T05:47:22Z")

</div>

Such a transformation cannot be performed without eagerly evaluating the iterator and collecting the items somehow.

---

<div class="post-metadata">

**Author:** ![anon32976453](https://avatars.discourse-cdn.com/v4/letter/a/49beb7/32.png) [@anon32976453](https://internals.rust-lang.org/u/anon32976453)\
**Post date:** [February 13, 2017, 6:12am UTC](https://internals.rust-lang.org/t/pre-rfc-allow-in-patterns/4772/14 "2017-02-13T06:12:11Z")

</div>

@withoutboats True, however the exact solution to this depends on the specific details of the problem at hand.

The user may want to do any of:

1. collect the items if the amount should be small and predetermined.
2. use async streams (when we get them 😉) to yield elements and let the stream wait until next available value instead of returning an error immediately if there aren’t enough elements ready.
3. use blocking i/o but implement re-try functionality of some sort.
4. anything else?

- point 2 refers to the RFC on stackless-coroutines and being able to do: `for item in stream`

---

<div class="post-metadata">

**Author:** ![zackw](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/zackw/32/2071_2.png) [@zackw](https://internals.rust-lang.org/u/zackw)\
**Post date:** [February 13, 2017, 1:39pm UTC](https://internals.rust-lang.org/t/pre-rfc-allow-in-patterns/4772/15 "2017-02-13T13:39:03Z")

</div>

> [@sgrif](#):
>
> TCP preserving closures

TCP? What does networking have to do with this? 😉

I managed to find an [older thread on this forum](https://internals.rust-lang.org/t/autoclosures-via-swift/3616/31) that reveals you mean "[Tennent's Correspondence Principle](http://yehudakatz.com/2012/01/10/javascript-needs-blocks/)," but that is a really _unfortunate_ acronym collision.

(I'm going to bow out of the discussion as it has gone well into territory that I haven't had enough experience to speak to.)

---

<div class="post-metadata">

**Author:** ![ahmedcharles](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/ahmedcharles/32/4041_2.png) [@ahmedcharles](https://internals.rust-lang.org/u/ahmedcharles)\
**Post date:** [February 17, 2017, 4:20am UTC](https://internals.rust-lang.org/t/pre-rfc-allow-in-patterns/4772/16 "2017-02-17T04:20:21Z")

</div>

My biggest issue with this so far is that pattern matching means ‘create bindings’, which in the ideal case, never requires executing any code. Obviously, code is required to determine which branch is taken in a match statement, etc.

Having `for item? in items {}` work, the compiler would have to execute code in addition to creating a binding.

---

<div class="post-metadata">

**Author:** ![stebalien](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/stebalien/32/228_2.png) [@stebalien](https://internals.rust-lang.org/u/stebalien)\
**Post date:** [February 17, 2017, 4:40am UTC](https://internals.rust-lang.org/t/pre-rfc-allow-in-patterns/4772/17 "2017-02-17T04:40:55Z")

</div>

That’s a very good point. Worse, once we get some form of stable `Carrier` trait, it will run arbitrary user code.

---

<div class="post-metadata">

**Author:** ![withoutboats](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/withoutboats/32/4560_2.png) [@withoutboats](https://internals.rust-lang.org/u/withoutboats)\
**Post date:** [February 17, 2017, 5:47am UTC](https://internals.rust-lang.org/t/pre-rfc-allow-in-patterns/4772/18 "2017-02-17T05:47:47Z")

</div>

I’m not convinced that’s a big problem. `for item in items { }` already runs arbitrary user code in the `IntoIterator` and `Iterator` implementations.

---

<div class="post-metadata">

**Author:** ![stebalien](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/stebalien/32/228_2.png) [@stebalien](https://internals.rust-lang.org/u/stebalien)\
**Post date:** [February 17, 2017, 6:11am UTC](https://internals.rust-lang.org/t/pre-rfc-allow-in-patterns/4772/19 "2017-02-17T06:11:04Z")

</div>

Maybe not a big issue but still a little weird. The following would run user-specified code before even entering the function proper:

```rust
fn maybe_add<A, B, E>(a?: Result<A, E>, b?: Result<B, E>) -> Result<A::Output, E>
    where A: Add<B>
{
    Ok(a + b)
}

```

---

<div class="post-metadata">

**Author:** ![withoutboats](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/withoutboats/32/4560_2.png) [@withoutboats](https://internals.rust-lang.org/u/withoutboats)\
**Post date:** [February 17, 2017, 6:20am UTC](https://internals.rust-lang.org/t/pre-rfc-allow-in-patterns/4772/20 "2017-02-17T06:20:56Z")

</div>

I dislike that totally aside from the fact that its running user code. In the argument position is a good example of why `?` is too magical in patterns.

Reflecting more, anywhere I’d use this I can instead just add a `let x = x?;` statement. The real issue with iterator/result situations is not when youre using a `for` loop, but when it makes combinators much worse. That suggests TCP-preserving closures are more worth it than something like this.

[Next page](https://internals.rust-lang.org/t/pre-rfc-allow-in-patterns/4772.md?page=2)
