Le 13/06/2017 à 14:43, Niall Douglas via Boost a écrit :
On 13/06/2017 06:54, Vicente J. Botet Escriba wrote:
Le 13/06/2017 à 01:01, Niall Douglas via Boost a écrit :
Finally, Rust and Swift have adopted a Result
model. It is generally viewed as a good design choice for its problem domain. Varying significantly from what the other system languages are doing needs to have very strong rationale. AFAIK [1], the proposed library and Swift error handling mechanism are very close. Syntax wise I can see what you mean. But in terms of ABI implementation, Swift implements under the bonnet direct returns of a Result
equivalent.
Not exactly. I will say it returns T? implicitly. This forces you to use try.
In Swift you signal that a function can throw adding throws() to the signature. Swift has builtin optionals and adding throw is almost like declaring it to return T? (optional<T>. That is one way of looking at it. I'd suggest a more accurate way is that all functions in Swift are noexcept. Adding "throws" is similar to adding "noexcept(false)".
Furthermore, Swift doesn't actually implement exception throwing.
What do you mean?
Yet another interpretation of "throws" could be "use a hidden Result
to return from this function". This, in terms of ABI, is the most accurate description, much more accurate than it returning optionals.
The function return type should not store E, so optional T seams closer. But I'm not an expert in Swift. I have just discovered it very recently. I like the protocol (traits) and extension (traits extensions) mechanism ;)
I will say that if Noexcept required this return_<T> type, it will be like outcome<T>, except that the error is transported using TLS instead of using the stack (please let me know if I'm wrong) The only remaining difference is the fragmented API using that TLS.
What do you mean?
However if Noexcept doesn't require a return_<T> then it is much difficult to force the use of the try functions. But it works yet.
I see advantages in this approach and I don't know which one is more efficient in the success and failure cases. Some measures will be more than welcome. SG14 folk would reject any mandatory use of TLS as its performance is not bounded on some platforms (hidden malloc).
Furthermore, at least on Windows both static and dynamic TLS is a limited resource, one can run out of TLS slots easily in large programs as there is a hard limit for the entire process. Library code should always avoid using TLS where possible, let the end user supply TLS to it instead.
I'm not aware of the performances of TLS, but I would expect that if there is a malloc hidden, we will need it only once. If this was integrated in the language, I would expect the compiler could reserve some efficient storage for the possible error (SBO).
do we want an error handling mechanism in C++ based on Swift error handling ;-) ? Do we want a library that emulates it as Boost.Noexcept in Boost?
I feel any design resembling C++ exceptions adds no value.
It seems that it adds some value in Swift ;-)
A design *complementing* C++ exceptions with a significantly different design makes much more sense, especially as you can then use both C++ exceptions AND your design together.
Swift exception model could complement the one in C++. It provides everything we are locking for when we don't want to use C++ exceptions.
do we want a monadic error handling in C++ as Result
in Boost? I've been getting quite a bit of private mail from SG14 folk regarding the Outcome review, specifically its rejection. As I said just earlier today to one such:
"It may not have been obvious that the review arrived at three different designs, so a flexible variant kind, a super-simple hard coded kind, and a monadic kind. Peter Dimov is taking the variant kind to the Toronto meeting I believe.
Great.
I'm currently refactoring Outcome to implement the super-simple kind which will be the most obviously suited for SG14 unless you like long build times.
Obviously.
The monadic kind I suspect Vicente will end up driving forwards, he and Peter need to disentangle the variant kind from the monadic kind first."
The two approaches are not incompatible. the variant is only the representation. The monadic interface is applicable to several representations.
All three kinds ought to be submitted to Boost in my opinion. They cover three separate, though overlapping, use cases.
I don't plan to submit a monadic interface in Boost, at least not yet. And if I do it one day, it will be independent of expected. In addition we have already monadic interface with Boost.Hana. All what we need is to adapt the concrete types. Just a last comment, Swift try is not the same as Haskell do-notation nor the proposed *monadic* coroutine TS await. Swift try is applicable to PossiblyValued types not to Monadic types. Vicente