Skip to content

Ability to return and throw from ?? expression. #3293

Closed
@BirjuVachhani

Description

@BirjuVachhani

I am familiar with Elvis operator ?: Kotlin. The dart equivalent of this would be ?? in most cases. While ?? works great, there is no way to return from it or throw in the same line of the expression without writing a bit of boilerplate code.

Example:

Dart as of now,

Version checkHasVersion(Map<String, dynamic> json) {
  final versionString = json['current'];
  if (versionString == null) throw Exception('Not found'); // extra line for null check.

  return Version.parse(versionString);
}

With ability to throw from ?? expression

Version checkHasVersion(Map<String, dynamic> json) {
  final versionString = json['current'] ?? throw Exception('Not found');

  return Version.parse(versionString);
}

Same for returning values:

Version checkHasVersion(Map<String, dynamic> json) {
  final String versionString = json['current'] ?? return Version(0, 0, 0);

  return Version.parse(versionString);
}

Kotlin version:

fun test(map: Map<String, Int>): Int {
    val version: Int = map["version"] ?: return -1
    return version + 2
}

Activity

added
featureProposed language feature that solves one or more problems
on Aug 19, 2023
lrhn

lrhn commented on Aug 19, 2023

@lrhn
Member

See #3052 for return.

You can use throw, it just needs parentheses:

  final versionString = json['current'] ?? (throw Exception('Not found'));

Closing as duplicate of #2025.

BirjuVachhani

BirjuVachhani commented on Aug 20, 2023

@BirjuVachhani
Author

I see. Thanks for the explanation and links to other related issues @lrhn.

However, I am wondering why these parenthesis are needed? It seems less intuitive.

lrhn

lrhn commented on Aug 20, 2023

@lrhn
Member

The reason the parentheses are needed is that someone argued, back whenthrow was made an expression, that it should bind weakly to its operand, which meant that it became a special <expression> instead of a prefix-operator.
That was me, I was wrong. Sorry.

That meant that there are places in the grammar it cannot occur. We have actually fixed that for conditional expressions. According to the spec grammar, you should be able to have a throw as the operand of a conditional expression, because <expressionWithoutCascade> can now be a throw. So no parentheses needed.

BirjuVachhani

BirjuVachhani commented on Aug 20, 2023

@BirjuVachhani
Author

Ah, I see. I didn't know that conditional expressions could have it w/o {}. I just tried it and it works as expected and I like it. Thanks!

Would it be possible to have the same behavior for ?? too? no parentheses? Would be great actually! I hate whenever I have to wrap something in parenthesis specially when it affects the readability of the code.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    featureProposed language feature that solves one or more problemsstate-duplicateThis issue or pull request already exists

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @lrhn@BirjuVachhani

        Issue actions

          Ability to return and throw from ?? expression. · Issue #3293 · dart-lang/language