Skip to content
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

literal-conforming assignment operator #3409

Open
danielatk opened this issue Oct 18, 2023 · 3 comments
Open

literal-conforming assignment operator #3409

danielatk opened this issue Oct 18, 2023 · 3 comments
Labels
feature Proposed language feature that solves one or more problems

Comments

@danielatk
Copy link

danielatk commented Oct 18, 2023

Let's say we're developing the system for a sneaky bank. In this bank, if the client's balance is 0, the system shows they have 100 to encourage them to take even more money. This function would like something like this:

int getBankBalance(String id) {
  int bankBalance = doSomeConsultation(id);
  if (bankBalance == 0) {
    return 100;
  }
  return bankBalance;
}

Alternatively one can use a ternary operator:

int getBankBalance(String id) {
  int bankBalance = doSomeConsultation(id);
  return (bankBalance == 0) ? 100 : bankBalance;
}

But there is no practical way of doing this with a one-liner. That's where the literal-conforming assignment operator would be useful. The proposed syntax is similar to the null-coalescing assignment operator:

int getBankBalance(String id) {
  return doSomeConsultation(id) ?== 0 => 100;
}

It would be an easy way of performing assignments when there are conditional requirements based on any literals, which goes beyond null safety.

Edit 1: after the suggestion made by @julemand101 the syntax was changed from a ?= b : c to a ?== b => c

@julemand101
Copy link

Not sure if "one-liner" here means it is only allowed to be on one single line, of if we allow it to be a single expression. If the last, we can do the following with the new switch expression:

int getBankBalance(String id) => switch (doSomeConsultation(id)) {
      0 => 100,
      var bankBalance => bankBalance,
    };

For the suggested proposal, I feel the syntax is too close to the traditional ternary syntax which makes it rather hard to read.

It is also not clear if the goal is to support all operators of if we only add a specific syntax for the equal operation? Also, I think it is kinda confusing that ?= will trigger the == operator. So maybe, especially if further operators should be supported, the syntax should be ?==.

But that is just my own personal taste.

@danielatk
Copy link
Author

danielatk commented Oct 18, 2023

@julemand101 the solution using the new switch syntax is very nice, indeed I need to retract my statement that it's not possible to perform with a one liner.

I also agree with your other two points, that maybe the ideal operator should be ?== and that the syntax is too similar to the ternary operator. For this second point maybe the use of => instead of : would be better suited.

@lrhn
Copy link
Member

lrhn commented Oct 20, 2023

If we get case syntax into the conditional expression, it would be:

  (doSomeConsultation(id) case != 0 && var c) ? c : 100

Still needs to introduce a variable to carry the value out of the match again.

You can introduce an extension methods:

extension OrNull<T> on T {
  T? nullIf(T value) => this == value ? null : value;
  T try(T from, T to) => this == from ? to : value;
}

and do

doSomeConsultation(id).nullIf(0) ?? 100
// or
doSomeConsultation(id).tr(0, 100)

If it can be solved by a library function, it probably doesn't require special language syntax.

@lrhn lrhn added the feature Proposed language feature that solves one or more problems label Oct 23, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature Proposed language feature that solves one or more problems
Projects
None yet
Development

No branches or pull requests

3 participants