TL;DR: What do you think about creating a new flavour of control-flow statements (in particular "return") that could return from outer/parent scope?

In the thread "Initialisers in ternary operators" we had this example:
std::optional<std::string> FindUsersCity(bool non_default) {
   std::optional<ContactsServer> contacts = GetOrOpenContactsServerConnection();
   if(!contacts)
      return std::nullopt;
   std::optional<UserId> uid = contacts->GetUserId();
   if(!uid)
      return std::nullopt;
   std::optional<GeoServer> geo = GetOrOpenGeoServerConnection();
   if(!geo)
      return std::nullopt;
   std::optional<Location> uloc = geo->GetLocation(*uid);
   if(!uloc)
      return std::nullopt;
   return uloc->GetCityName();
}


It seems, that there are many situations with the following pattern:
  1. there is a type
  2. that defines some invalid state (in case of iterator the state is "being equal to end()", in case of Result/Outcome/Expected the state is "representing an error", in case of optional it is "nullopt", and so on...)
  3. attempts of using which in the invalid state are supposed to "return" (from the scope where it is used). We can take a step back and consider other control-flow statements.

Without going into implementation details, what do you think about the idea (on a conceptual level) of being able to describe this pattern somewhere somehow?

If conceptually it is fine, then what do you think about implementing the idea by creating another flavour of return statements that can return not only from its own scope, but also from outer/parent scope?
If you wish, this new flavour can be viewed as a middle ground between (1) regular return's (which often requires boilerplate for handling the pattern above) and (2) exceptions (which are too non-local and implicit and can "jump" at an arbitrary place).

The code above would look like this:
std::optional<std::string> FindUsersCity() {
   std::optional<ContactsServer> contacts = GetOrOpenContactsServerConnection();
   std::optional<UserId>         uid      = contacts.GetOrReturnNullOpt()->GetUserId();
   std::optional<GeoServer>      geo      = GetOrOpenGeoServerConnection();
   std::optional<Location>       uloc     = geo.GetOrReturnNullOpt()->GetLocation(*uid);
   return uloc.GetOrReturnNullOpt()->GetCityName();
}

where GetOrReturnNullOpt() is a method that (1) either returns a value if std::optional is not empty, (2) or returns from FindUsersCity() if std::optional is empty.


I think it could solve

Any thoughts?


--
Dmitry
Sent from gmail