Description
I am aware that syntactic sugar is no priority at all, but the optional syntax in Kotlin and Swift is one of my favourite features of those languages and it is one of the features I miss the most in C++ today. It makes the code compact and very easy to read. Additionally by the fact that cppfront requires variables to be initialized and forbids nullptr for pointers, optionals are IMHO the way to go for most concepts that can have a value or not. Especially the possibility to chain calls offers a much more compact way to express the actual intend and avoids boilerplate code.
A simple (and maybe a bit naive) example using an optional std::string to illustrate what I mean:
Short syntax to initialize an empty optional:
p: std::string?;
could be translated to something like
p = std::optional<std::string>();
Elvis operator in Kotlin, take value if present, otherwise take what is following ?:
, respective ??
:
i = p ?: "nothing"; // Kotlin
i = p ?? "nothing"; // Swift
could be just
i = p.value_or("nothing");
Get value, throw exception if not present:
i = p!!;
would become
i = p.value();
Call member function if present, otherwise return an empty optional:
length = p?.size();
could be transformed to
length = inspect (p) -> std::optional<std::size_t> {
is void = std::optional();
is _ = p.value().size();
};
Chaining should theoretically be possible too as the following example shows:
u: std::vector<std::string>?
// ...
length1 = u?.front()?.size();
a solution could be (I do not know if inspect could be used with an expression directly, so I added the placeholder __1
:
u = std::optional<std::vector<std::string>();
// ...
__1 = inspect (u) -> std::optional<std::string> { is void = std::optional(); is _ = u.value().front(); };
length1 = inspect(__1) -> std::optional<std::size_t> { is void = std::optional(); is _ = __1.size(); };
Especially save member calling using ? and the possibility to chain those calls makes the code much more readable and compact.