#ControlFlow
Pre-RFC: "Fat Try" Another attempt to re-design the Try trait
Here's what the traits could look like if we keep `Try::Kind` and minimal "break types" but extend it with support for complex try types. `TryAs` and homogenous try is the same as OP. This can work with or without `From` in `?` desugaring. pub const trait Try: TryFromBreak<Self::Break, Self::Kind> { type Kind; type Continue; type Break; fn branch(self) -> ControlFlow<Self::Break, Self::Continue>; fn from_continue(c: Self::Continue) -> Self; } pub const trait TryFromBreak<Break, Kind> { fn from_break(b: Break) -> Self; } pub const trait TryAs<T>: Try { type Try: Try< Kind = Self::Kind, Break = Self::Break, Continue = T, >; } Example impl: impl<T, E> ops::Try for Result<T, E> { type Kind = Result<!, !>; type Continue = T; type Break = E; fn branch(self) -> ControlFlow<E, T> { match self { Err(e) => ControlFlow::Break(e), Ok(v) => ControlFlow::Continue(v), } } fn from_continue(t: T) -> Self { Ok(t) } } impl<T, E> TryFromBreak<E, Result<!, !>> for Result<T, E> { fn from_break(e: E) -> Result<T, E>{ Err(e) } } **The Heterogeneous`?` Rule**: Let `T` = the `?` target. Let `R` = the try scope result R: TryFromBreak<<T as Try>::Break, <T as Try>::Kind> * * * This maintains the advantage of higher re-usability for a custom result type. If you use `Try::Kind = Result<!, !>`, you get two-way interoperability with std `Result` with writing only one `impl TryFromBreak`.
internals.rust-lang.org
September 28, 2026 at 4:36 PM
Pre-RFC: "Fat Try" Another attempt to re-design the Try trait
This is an attempt to re-design the `Try` and `Residual` traits to be simpler while generally maintaining functionality. I call it "fat try" because it stuffs most everything into `Try` instead of breaking it up into several traits. I believe this is workable solution but the "ControlFlow Wrinkle" below is one non-trivial obstacle. I have a local branch as a POC where I have been able to prove that this generally works, including changes to try desugaring. * * * Here are the traits. There's only two: pub const trait Try { type Kind; type Continue; type Break; fn from_continue(output: Self::Continue) -> Self; fn from_break(output: Self::Break) -> Self; fn branch(self) -> ControlFlow<Self::Break, Self::Continue>; } pub const trait TryAs<T>: Try { type Try: Try< Kind = Self::Kind, Break = Self::Break, Continue = T, >; } Example implementation: impl<T, E> ops::Try for Result<T, E> { type Kind = Result<!, !>; type Continue = T; type Break = E; fn from_continue(t: T) -> Self { Ok(t) } fn from_break(e: E) -> Self { Err(e) } fn branch(self) -> ControlFlow<E, T> { match self { Err(e) => ControlFlow::Break(e), Ok(v) => ControlFlow::Continue(v), } } } impl<T, U, E> TryAs<U> for Result<T, E> { type Try = Result<U, E>; } For `Option`, `Kind` is `Option<!>` and `Break` is `()`. ## Try::Kind (This is the main thing that makes this proposal different.) **The`Try::Kind` Rule:** All `?` operators must have a target whose `Try::Kind` is equal to the `Try::Kind` of the result of the surrounding try scope (function or try block). `Try::Kind` is a marker type (never constructed at runtime) which ascribes a _semantic_ to the `?` operator for the implemented type. The `Try::Kind` for `Result` and `Option` are `Result<!, !>` and `Option<!>` respectively. You can think of it as an answer to the question: "What does the `?` operator _test_ for this type?". `Try::Kind=Result<!, !>` means "`?` tests for the presence of an error". And `Try::Kind=Option<!>` means "`?` tests for the absence of a value". Note that the `Try::Kind` does _not_ necessarily indicate the actual type. For example, you may have `CustomError as Try<Kind=Result<!, !>>`. ## Custom Try Types When implementing a custom `Try` type, you will need to decide what the `Kind` will be, and whether to re-use a std `Try::Kind` (`Result<!, !>` or `Option<!>`) or define your own. Perhaps the most common choice would be to use `Result<!, !>`, thus declaring your type to be a "custom result", and having the same semantic of "`?` tests the presence of an error". Or you may define a new `Try::Kind` to signify some domain-specific semantic. But then your type cannot be used in try scopes which produce a std type. Choosing a std `Try::Kind` gives you interoperability with the corresponding std type "for free". That is, you may use `?` on your custom error in a try scope that returns `Result` and visa versa. ## `?` uses `From` The `?` operator includes a `From` conversion to convert the `?` target's `Break` type into the try scope output's `Try::Break` type. So we can say that these are the full requirements for using `?`: * The `Try::Kind` rule above * The `Try::Break` of the `?` target must convert to the `Try::Break` of the try scope result using `From`. `From` conversion on the `Break` value is **not** included in homogeneous try blocks. More on that later. ## The `TryAs` Trait The `TryAs` trait draws a relationship between `Try` types that are the same type but with the `Continue` type interchanged. For example, `io::Result<u32> as TryAs<String>::Try = io::Result<String>`. Note that a `TryAs` conversion maintains that `Try::Kind` and `Try::Break` are unchanged. Also note that `TryAs` should maintain the same outer type, so it is more constrained than `Try::Kind`. The `TryAs` trait is useful in function signatures that are generic over `Try`, and where the `Continue` type is changed. For example, here is a function signature for `std::array::try_from_fn` (some details omitted): pub fn try_from_fn<T, R, const N: usize, F>(f: F) -> <R as TryAs<[T; N]>>::Try where F: FnMut(usize) -> R, R: Try<Continue = T> + TryAs<[T; N]> ## Homogeneous Try Blocks Homogeneous try blocks generally work as described in the RFC. The underlying type requirements just look different. Where heterogeneous try scopes use `Try::Kind` to enforce a relationship between types, homogeneous try blocks use `TryAs` instead. **The Homogeneous`TryAs` Rule:** For every `?` operator within a homogeneous try block, given the `?` target is `T` and the try scope result is `R`, `<T as TryAs<<R as Try>::Continue>> = R`. In other words, the `?` target type can be related to the try scope result type via `TryAs`. ## `ControlFlow` Wrinkle `ControlFlow` is stabilized with no `From` conversion in its `?` support. I don't know how to resolve this unfortunately. My preference is to use a time machine to reverse the stabilization, but I am unable to supply a time machine at this time. ## Comparison with `try_trait_v2`, discussion * No "residual" types. The `Break` type in "fat try" is intended to be fully minimized and not carry any information about the originating `Try` type. The burden of defining which `Try` types are interoperable is fully shifted to the `Try` trait itself, particularly with `Try::Kind`. Also there is no more need "unwrap" the residual type in `from_residual`. * No `FromResidual` implementations. With `Try::Kind`, all `Try` types of the same `Kind` are allowed to be used with each other (a `?` target paired with a try scope result) without implementing a trait for every pair within the set. You only need to implement `From` to convert `Break` types as needed. * No `Residual` trait. (Generally replaced with `TryAs`) * Less fine control over which types are inter-convertible. I think this is totally fine. But this is putting some faith in `Try::Kind` that it will make sense across use cases. * `From` conversion is built into `?`. With `try_trait_v2`, you need to include `From` conversion into `FromResidual` implementations if desired. I think the advent of homogeneous try blocks at least partially negates some of the motive to remove universal `From` support. And I fear that having both variable `From` _and_ two types of try blocks is too much complexity overall. * `Try::Kind` is kind of strange as a "marker type". Though I believe this is just relocating the strangeness of "residual types" like `Result<!, E>` and giving it a more dedicated place. * Addition of `TryAs`. This trait might feel a bit ad-hoc, admittedly. You don't need it until you try to use homogeneous blocks or certain functions that use it in the interface. * `TryAs` implementations tend to have a lot of generic parameters and this can be confusing. I wonder if there is a way to auto-derive these based on the `Try` impl. * `TryAs` for types with a non-generic `Continue` is possible but strange to implement. * `TryAs` isn't strict enough - it should be required to be round-trippable: `<R as TryAs<R::Continue>>::Try = R`. This could be a lint.
internals.rust-lang.org
September 25, 2026 at 10:04 PM
Pre-RFC: "Fat Try" Another attempt to re-design the Try trait
This is an attempt to re-design the `Try` and `Residual` traits to be simpler while generally maintaining functionality. I call it "fat try" because it stuffs most everything into `Try` instead of breaking it up into several traits. I believe this is workable solution but the "ControlFlow Wrinkle" below is one non-trivial obstacle. I have a local branch as a POC where I have been able to prove that this generally works, including changes to try desugaring. * * * Here are the traits. There's only two: pub const trait Try { type Kind; type Continue; type Break; fn from_continue(output: Self::Continue) -> Self; fn from_break(output: Self::Break) -> Self; fn branch(self) -> ControlFlow<Self::Break, Self::Continue>; } pub const trait TryAs<T>: Try { type Try: Try< Kind = Self::Kind, Break = Self::Break, Continue = T, >; } Example implementation: impl<T, E> ops::Try for Result<T, E> { type Kind = Result<!, !>; type Continue = T; type Break = E; fn from_continue(t: T) -> Self { Ok(t) } fn from_break(e: E) -> Self { Err(e) } fn branch(self) -> ControlFlow<E, T> { match self { Err(e) => ControlFlow::Break(e), Ok(v) => ControlFlow::Continue(v), } } } impl<T, U, E> TryAs<U> for Result<T, E> { type Try = Result<U, E>; } For `Option`, `Kind` is `Option<!>` and `Break` is `()`. ## Try::Kind (This is the main thing that makes this proposal different.) **The`Try::Kind` Rule:** All `?` operators must have a target whose `Try::Kind` is equal to the `Try::Kind` of the result of the surrounding try scope (function or try block). `Try::Kind` is a marker type (never constructed at runtime) which ascribes a _semantic_ to the `?` operator for the implemented type. The `Try::Kind` for `Result` and `Option` are `Result<!, !>` and `Option<!>` respectively. You can think of it as an answer to the question: "What does the `?` operator _test_ for this type?". `Try::Kind=Result<!, !>` means "`?` tests for the presence of an error". And `Try::Kind=Option<!>` means "`?` tests for the absence of a value". Note that the `Try::Kind` does _not_ necessarily indicate the actual type. For example, you may have `CustomError as Try<Kind=Result<!, !>>`. ## Custom Try Types When implementing a custom `Try` type, you will need to decide what the `Kind` will be, and whether to re-use a std `Try::Kind` (`Result<!, !>` or `Option<!>`) or define your own. Perhaps the most common choice would be to use `Result<!, !>`, thus declaring your type to be a "custom result", and having the same semantic of "`?` tests the presence of an error". Or you may define a new `Try::Kind` to signify some domain-specific semantic. But then your type cannot be used in try scopes which produce a std type. Choosing a std `Try::Kind` gives you interoperability with the corresponding std type "for free". That is, you may use `?` on your custom error in a try scope that returns `Result` and visa versa. ## `?` uses `From` The `?` operator includes a `From` conversion to convert the `?` target's `Break` type into the try scope output's `Try::Break` type. So we can say that these are the full requirements for using `?`: * The `Try::Kind` rule above * The `Try::Break` of the `?` target must convert to the `Try::Break` of the try scope result using `From`. `From` conversion on the `Break` value is **not** included in homogeneous try blocks. More on that later. ## The `TryAs` Trait The `TryAs` trait draws a relationship between `Try` types that are the same type but with the `Continue` type interchanged. For example, `io::Result<u32> as TryAs<String>::Try = io::Result<String>`. Note that a `TryAs` conversion maintains that `Try::Kind` and `Try::Break` are unchanged. Also note that `TryAs` should maintain the same outer type, so it is more constrained than `Try::Kind`. The `TryAs` trait is useful in function signatures that are generic over `Try`, and where the `Continue` type is changed. For example, here is a function signature for `std::array::try_from_fn` (some details omitted): pub fn try_from_fn<T, R, const N: usize, F>(f: F) -> <R as TryAs<[T; N]>>::Try where F: FnMut(usize) -> R, R: Try<Continue = T> + TryAs<[T; N]> ## Homogeneous Try Blocks Homogeneous try blocks generally work as described in the RFC. The underlying type requirements just look different. Where heterogeneous try scopes use `Try::Kind` to enforce a relationship between types, homogeneous try blocks use `TryAs` instead. **The Homogeneous`TryAs` Rule:** For every `?` operator within a homogeneous try block, given the `?` target is `T` and the try scope result is `R`, `<T as TryAs<<R as Try>::Continue>> = R`. In other words, the `?` target type can be related to the try scope result type via `TryAs`. ## `ControlFlow` Wrinkle `ControlFlow` is stabilized with no `From` conversion in its `?` support. I don't know how to resolve this unfortunately. My preference is to use a time machine to reverse the stabilization, but I am unable to supply a time machine at this time. ## Comparison with `try_trait_v2`, discussion * No "residual" types. The `Break` type in "fat try" is intended to be fully minimized and not carry any information about the originating `Try` type. The burden of defining which `Try` types are interoperable is fully shifted to the `Try` trait itself, particularly with `Try::Kind`. Also there is no more need "unwrap" the residual type in `from_residual`. * No `FromResidual` implementations. With `Try::Kind`, all `Try` types of the same `Kind` are allowed to be used with each other (a `?` target paired with a try scope result) without implementing a trait for every pair within the set. You only need to implement `From` to convert `Break` types as needed. * No `Residual` trait. (Generally replaced with `TryAs`) * Less fine control over which types are inter-convertible. I think this is totally fine. But this is putting some faith in `Try::Kind` that it will make sense across use cases. * `From` conversion is built into `?`. With `try_trait_v2`, you need to include `From` conversion into `FromResidual` implementations if desired. I think the advent of homogeneous try blocks at least partially negates some of the motive to remove universal `From` support. And I fear that having both variable `From` _and_ two types of try blocks is too much complexity overall. * `Try::Kind` is kind of strange as a "marker type". Though I believe this is just relocating the strangeness of "residual types" like `Result<!, E>` and giving it a more dedicated place. * Addition of `TryAs`. This trait might feel a bit ad-hoc, admittedly. You don't need it until you try to use homogeneous blocks or certain functions that use it in the interface. * `TryAs` implementations tend to have a lot of generic parameters and this can be confusing. I wonder if there is a way to auto-derive these based on the `Try` impl. * `TryAs` for types with a non-generic `Continue` is possible but strange to implement. * `TryAs` isn't strict enough - it should be required to be round-trippable: `<R as TryAs<R::Continue>>::Try = R`. This could be a lint.
internals.rust-lang.org
September 26, 2026 at 4:05 PM
oh ok i think i interpreted the question more broadly (using LLMs in general) but as far as controlflow I think the only vectorstore support is an implementation detail of memory so I suspect that section might be old / LLM hallucinated 🙂

but @jlowin.dev might correct me
January 9, 2025 at 12:19 PM
September 3, 2025 at 3:46 PM
PrefectHQ/ControlFlow
Check out PrefectHQ/ControlFlow on GitHub
github.com
February 7, 2025 at 4:27 AM
ControlFlow is a Python framework for building and orchestrating AI-powered workflows by defining tasks, assigning AI agents, and managing workflow execution with integrated observability and error handling.
February 7, 2025 at 4:27 AM
February 5, 2025 at 4:01 PM
as an evil third position you can use ControlFlow for this
July 11, 2026 at 12:47 AM
Today, I wrote and article and recorded a video about

Control the execution order using the Output state in #MicrosoftFabric #DataFactory #DataPipeline

some basic principles for your everyday #ETL #ControlFlow setup

radacad.com/control-the-...

#DataAnalytics
Control the Execution Order and Output State in Fabric Data Pipeline
Learn about the execution order of activities in Fabric Data Pipeline, the output state, the parallel or sequential execution plans.
radacad.com
February 5, 2025 at 3:48 AM
So I realised I want to refactor ~all of the methods in our 10k+ Rustlang JS engine to move one ZST param from second place to last. Going to be a fun PR.

Also, I just added a bunch of methods that return Option<T> and now I realize I want to return ControlFlow<JsResult<()>, T> instead.

+/- 10k <3
December 10, 2024 at 7:28 AM
More const stability: fmt::from_fn, ControlFlow::is_break/continue, and useful Layout methods like repeat, extend_packed, dangling_ptr.

Plus: destabilized JSON target specs on stable (mostly affects advanced users), and the usual Cargo/Clippy improvements.
April 16, 2026 at 6:06 PM
Go 语言“内战”迎来终局?Go 圣经作者亲自下场,为“三元运算符”发起折中提案! 本文永久链接 – https://tonybai.com/2026/04/28/go-conditional-expressions-prop...

#技术志 #AlanDonovan #BackwardCompatibility #CodeStandards #ConditionalExpressions #ControlFlow #expression #Go #Golang #GoLanguage #Go程序设计语言

Origin | Interest | Match
Go 语言“内战”迎来终局?Go 圣经作者亲自下场,为“三元运算符”发起折中提案! - Tony Bai
本文永久链接 - https://tonybai.com/2026/04/28/go-conditional-expressions-propsal 大家好,我是Tony Bai。 在 Go 语言的江湖里,有一个话题,像幽灵一样,每隔几个月就会重燃战火。它引发的争论之激烈、持续
tonybai.com
April 28, 2026 at 12:37 AM
In today's video:

🔥What Angular @switch is and when to use it
🔥What’s new with @case in Angular v21.1
🔥Best practices for using @switch with signals

youtu.be/4tM4CZf9pPI

#angular #controlflow
Angular @switch Template Control Flow Explained (+ New @case in v21.1)
YouTube video by Deborah Kurata
youtu.be
January 21, 2026 at 4:41 PM
Who has time to migrate their Angular templates to the new control flow syntax?

Luckily, there is a Angular CLI schematic that automatically migrates templates for us!

Check out the migration tool in my latest video: youtu.be/fkAFHMhjJsQ

#angular #controlflow
Automatically Migrate to Angular's New Control Flow Template Syntax
With Angular's new control flow syntax, we can simplify our templates, improve performance, and reduce bundle sizes. But do we really have time to manually c...
youtu.be
April 4, 2024 at 3:18 PM
Check out my latest YT video -> Angular's new template syntax: control flow.

Why do we need a new template syntax? In this video, we examine the new @if and @for control flow blocks. Then answer the "why?" question.

#angular #controlflow @angular

youtu.be/j9VTGRGyE-o
Angular's New Template Syntax: Control Flow
Starting in Angular version 17, we have the option of using new techniques for building our templates. This new block template syntax replaces the NgIf, NgFo...
youtu.be
April 2, 2024 at 3:27 PM
Thanks to all the attendees joining my talk at DevDays Europe! Here are the slides of my session “The New #Angular: Maximizing Performance and Productivity”: speakerdeck.com/christianlie... #signals #standalone #controlflow #ssr #devdayseurope
The New Angular: Maximizing Performance and Productivity
Angular has undergone significant modifications in recent times. Notably, the introduction of the new control flow syntax, standalone components, signals, and the new approach of server-side rendering...
speakerdeck.com
May 24, 2024 at 8:04 AM
If you're in DC and you're into data science, come hang at our new office and check out ControlFlow (link in 🧵)

www.meetup.com/data-science...
Holiday Happy Hour and Agentic AI Workflows with ControlFlow, Wed, Dec 11, 2024, 5:00 PM | Meetup
Join the DC data community for food, drinks, socializing, and holiday cheer! We’ll also see a demo of [ControlFlow](https://controlflow.ai), an open source Python framewor
www.meetup.com
December 2, 2024 at 6:13 PM