-
Notifications
You must be signed in to change notification settings - Fork 205
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
A null-aware exception catching expression. #2656
Comments
Interesting! Note that this feature is somewhat similar to the proposals about adding other expressions with control flow, #2025, so it might be good to think about them as group. |
I would like await mutex.lock();
var ret = try<E>(retrieveData()) finally { mutex.unlock(); }; In comparison with the example below, the type of await mutex.lock();
RetType? ret;
try {
ret = retrieveData();
} on E {
ret = null;
} finally {
mutex.unlock();
} |
I like the Maybe make |
I am not a syntax man, so I don't stick to such syntax.
I'm not sure what does it mean. await mutex.lock();
var ret = try /* <E> */ (retrieveData()) finally { mutex.unlock(); }; can't be treated as await mutex.lock();
RetType? ret;
try {
ret = retrieveData();
} catch (e) {
ret = null;
} finally {
mutex.unlock();
} ? |
The point is that if you only want the await mutex.lock();
RetType ret;
try {
ret = retrieveData();
} finally {
mutex.unlock();
} then you couldn't just do So we could change That's why I suggested: try (e) // Catches any thrown object and converts it to `null`
try<E>(e) // Catches `E`s and converts them to `null`
try (e) finally {s} // Catches no objects, executes {s}` afterwards. (Does not promote to nullable).
try<E>(e) finally {S} // catches `E`s and converts them to `null`, executes `{s}` afterwards. That gives the shortest syntax to the simplest usable behavior, but allows you to explicitly write a catch type to override it. You can still write |
I did wanted catch all errors in my previous example. I want some syntax not to catch any errors, as well. |
The idea of an expression try/catch came up in #1884, as a shorthand for declaring variables whose initialization processes can fail. Instead of needing to write a whole try block with the declaration outside it so the variable stays in the scope you need it in, you could just declare it and its fallback all in one line: FooType v;
try {
v = getValue();
}
on Object{
v = fallback;
} Having it evaluate to null rather than falling into a subsequent Though if |
Sometimes you want to catch an exception and just return
null
to signal that something went wrong. That's currently cumbersome since catching exceptions can only happen as a statement.You can write a function like:
It suffers from needing two type arguments, where you only want to provide the
E
one, and you need to introduce a closure when using it, so:I propose introducing an expression form of
try
looking like:The
try
operator evaluatesexpression
to a value. Ifexpression
throws (if a type argument is provided, then only if it throws anE
), thetry
expression evaluates tonull
, otherwise it evaluates to the result of evaluatingexpression
.Proposal
Grammar:
It's a compile-time error if there is more than one type argument.
An expression of the form
try(e)
is equivalent to an expression of the formtry<Object>(e)
, whereObject
refers to the type fromdart:core
(whether it's in scope or not). You're allowed to writeObject?
ordynamic
as the type argument, it won't make any difference, the type is only used for subtype checks on values that are non-null
.We won't need to restrict an expression statement from starting with
try
, since the grammar fortry
expressions andtry
statements differ at the second token. The first token after an expressiontry
is(
or<, and it's
{` for the statement, so there is no parsing ambiguity.Semantics
Let e be an expression of the form
try<T>(e2)
or `try(e2)~.Static
Static typing of e with context type schema C proceeds as:
<Object>
, and letT
beObject
in the following.e
with context type schema NON_NULL(C) to a typeT2
. (We do not enforce the context type, or insert downcasts or implicit coercions here, any actual value will be passed through unchanged.)T2?
.Runtime
Evaluation of e proceeds as follows:
e2
.e2
completes with a 9c/value v, then evaluation of e completes with the value v.e2
throws a error o and stack trace s,T
, evaluation of e completes with the valuenull
.The text was updated successfully, but these errors were encountered: