Skip to content

Feature Request: Add .toggle() extension for bool in Dart #4257

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

Closed
dbspoudel opened this issue Feb 6, 2025 · 5 comments
Closed

Feature Request: Add .toggle() extension for bool in Dart #4257

dbspoudel opened this issue Feb 6, 2025 · 5 comments
Labels
feature Proposed language feature that solves one or more problems

Comments

@dbspoudel
Copy link

In Swift, the Bool type has a built-in .toggle() method that flips the value between true and false. It simplifies boolean state management and avoids repetitive expressions like:

isEnabled = !isEnabled;

I propose adding a .toggle() method for bool in Dart, which would allow:

bool isEnabled = false;
isEnabled.toggle();  // Now isEnabled is true
print(isEnabled) // true

Use Case
This feature would improve readability and reduce redundancy, especially in stateful applications where toggling booleans is common.

Proposed Implementation
A simple method can be added to bool class in the Dart SDK:

/// Toggles the value of this boolean and stores it back in the same variable.
///
/// Example:
/// ```dart
/// bool value = true;
/// value.toggle();
/// print(value); // false
/// ```
void toggle() {
    this = !this;
  }

Adding .toggle() to bool would improve developer experience, reduce verbosity, and align Dart with other modern programming languages.

References
Swift's toggle() method: here

@dbspoudel dbspoudel added the feature Proposed language feature that solves one or more problems label Feb 6, 2025
@mateusfccp
Copy link
Contributor

This is not possible with how bool works today. Roughly speaking, bool works like a primitive and is a stateless object. There's no way to "flip" its value.

It would be possible to do it if we introduced a wrapper-like object (something similar to what Java does with his boolean and Boolean).

Something like this:

void main() {
  final boolean = True;
  
  print(boolean);
  boolean.toggle();
  print(boolean);
  
  if (boolean == false) {
    print("Boolean is false");
  }
  
  if (false == boolean) {
    print("false is Boolean");
  }
}

/// A stateful wrapper to `bool`.
final class Bool {
  Bool._(this._value);

  // The internal boolean value.
  bool _value;

  /// Toggles the boolean value.
  void toggle() {
    _value = !_value;
  }
  
  @override
  String toString() => '$_value';

  @override
  bool operator ==(Object other) {
    if (identical(this, other)) {
      return true;
    } else if (other is bool) {
      return _value == other;
    } else if (other is Bool) {
      return _value == other._value;
    } else {
      return false;
    }
  }

  int get hashCode => _value.hashCode;
}

/// The true [Bool] value.
// ignore: non_constant_identifier_names
get True => Bool._(true);

/// The false [Bool] value.
// ignore: non_constant_identifier_names
get False => Bool._(false);

Note that there's a limitation on this approach, in that boolean == false will return true, but false == boolean will return false, as demonstrated in the code above.

This happens, because there's no way to define the "truthiness" of an object, so we rely on == to check if they are equal, and we can't override bool's == to include the same logic.

@ghost
Copy link

ghost commented Feb 6, 2025

In swift, the implementation is

extension Bool {
  /// Useful when operating on long chains:
  ///    myVar.prop1.prop2.enabled.toggle()
  mutating func toggle() {
    self = !self
  }
}
//
myVar.prop1.prop2.enabled.toggle();

There's nothing like this in dart.
Maybe with the proposed anonymous methods, we would be able to define a more general feature (using the analogy with myvar+=42;)

myVar.prop1.prop2.enabled.={!this};

@lrhn
Copy link
Member

lrhn commented Feb 7, 2025

Dart doesn't have reference parameters, so you cannot abstract over variables, only values.
Without that, a toggle isn't really possible as a library function. It has to be a full stand-alone language feature, an effort which I don't think it warrants.

Assume that Dart does get reference parameters (#1911), say using a prefix &.
Then you could do:

void toggle (bool &v) { x = !x;}

and possibly

extension BoolToggle on bool &v {
  void toggle() {
    v= !v;
  }
}

(I'd like to allow extension on types to be declaration patterns, so you can have free destructuring.)

Until then, no toggle.

@lrhn lrhn changed the title Feature Request: Add .toggle() extension for bool in Dart #60064 Feature Request: Add .toggle() extension for bool in Dart Feb 7, 2025
@munificent
Copy link
Member

As others have said, Dart doesn't have first-class lvalues, so it's not possible to implement this an extension and it doesn't seem to warrant a language feature. I'm going to go ahead and close this, but I appreciate you filing the issue and kicking off this discussion. :)

@munificent munificent closed this as not planned Won't fix, can't repro, duplicate, stale Feb 7, 2025
@dbspoudel
Copy link
Author

Appreciate the discussion and insights from everyone. Given Dart's lack of first-class lvalues and reference parameters, I see why .toggle() as an extension method isn't feasible. While it would have been a syntactic improvement for state management, implementing it would require deeper language changes that likely don’t justify the cost.

The suggested wrapper-based approach is interesting but comes with trade-offs. I also see potential if Dart introduces reference parameters in the future. Thanks again for the constructive discussion.

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

4 participants