Skip to main content

Proposed changes for equality

Posted by Gilad Bracha


UPDATE: This post is no longer accurate. Please refer to the Dart language spec for the most up-to-date rules regarding equality.
This is a draft specification for the revised handling of equality. The essence of the change is as follows:
The == operator is no longer user definable. It has fixed behavior, that is however customizable via the operator/method equals(). Specifically, given x == y:
  • If x === y then return true. Otherwise
  • if either x or y is null, return false. Otherwise
  • return the result of x.equals(y)
The question arises, do we need the special story with operators for negate, call and equals? Can we just say that the operators are hardwired to invoke the methods involved?



Operators

Operators are instance methods with special names.
operatorSignature:
      returnType? operator operator formalParameterList
    ;

operator:
      unaryOperator
    | binaryOperator
    | '[' ']'
    | '[' ']' '='
    | negate
    | call
    | equals
    ;
    
unaryOperator:
      negateOperator
    ;

binaryOperator:
      multiplicativeOperator
    | additiveOperator
    | shiftOperator
    | relationalOperator
    | equalityOperator
    | bitwiseOperator
    ;

prefixOperator:
      '-'
    | negateOperator
    ;


negateOperator:
      '!'
    | '~'
    ;
An operator declaration is identified with built-in identifier operator.
The following names are allowed for user-defined operators: <, >, <=, >=, -, +, /, ~/, *, %, |, ^, &, <<, >>, []=, [], ~, callequalsnegate.
The built-in identifier negate is used to denote unary minus. The built-in identifier call is used to denote function application ( () ). The built-in identifier equals is used to denote equality (==).
Defining a nullary method named call, equals or negate will have the same effect as defining an operator, but is considered bad style, and will cause a static warning.
It is tempting to define it to be a compile-time error to declare a method named call, equals or negate. However, this causes compatibility problems. Since these are all built-in identifiers, unsanctioned use will cause a static warning, which is arguably sufficient to alert the programmer to the fact that the ported code is likely not intended to define an operator. In fresh Dart code, the warning will indicate that either the built-in identifier operator was forgotten, or that the method should have a different name.
It is a compile-time error if the number of formal parameters of the user-declared operator []= is not 2. It is a compile time error if the number of formal parameters of a user-declared operator with one of the names: equals, <, >, <=, >=, -, +, /, ~/, *, %, |, ^, &, <<, >>, [] is not 1. It is a compile time error if the arity of a user-declared operator with one of the names: ~, negate is not 0.
It is a compile-time error to declare an optional named parameter in an operator. The operator callcan have any arity.
It is a compile-time error to declare an optional named parameter in an operator, with the exception of the operator call.
It is a static warning if the return type of the user-declared operator []= is explicitly declared and notvoidIt is a static warning if the return type of the operator equals is explicitly declared and is not bool. It is a static warning if the return type of the operator negate is explicitly declared and not a numerical type.

Equality

Equality expressions test objects for identity or equality.
equalityExpression:
      relationalExpression (equalityOperator relationalExpression)?
    | super equalityOperator relationalExpression
    ;

equalityOperator:
      '=='
    | '!='
    | '==='
    | '!=='
    ;
An equality expression is either a relational expression, or an invocation of a equality operator on on either super or an expression e1, with argument e2.
Evaluation of an equality expression ee of the form e1 == e2 proceeds as follows:
  • The expression e1 is evaluated to an object o1.
  • The expression e2 is evaluated to an object o2.
  • If o1 === o2 evaluates to true, then ee evaluates to true. Otherwise,
  • If either o1 or o2 is null, then ee evaluates to false. Otherwise,
  • ee is equivalent to the method invocation o1.equals(o2).
Evaluation of an equality expression ee of the form super == e proceeds as follows:
  • The expression e is evaluated to an object o.
  • If this === o evaluates to true, then ee evaluates to true. Otherwise,
  • If either this or o is null, then ee evaluates to false. Otherwise,
  • ee is equivalent to the method invocation super.equals(o).
As a result of the above definition, user defined equals() methods can assume that their argument is not this and is non-null, and avoid the standard boiler-plate prelude:
    if (this === arg) return true;
    if (null === arg) return false;
  
Another implication is that there is never a need to use === to test against null, nor should anyone ever worry about whether to write null == e or e = = null.
An equality expression of the form e1 != e2 is equivalent to the expression !(e1 == e2 ). An equality expression of the form super != e is equivalent to the expression !(super == e)).
Evaluation of an equality expression ee of the form e1 === e2 proceeds as follows:
The expression e1 is evaluated to an object o1; then the expression e2 is evaluated to an object o2. Next, if o1 and o2 are the same object, then ee evaluates to true, otherwise ee evaluates to false.
An equality expression of the form super === e is equivalent to the expression this === e.
An equality expression of the form e1 !== e2 is equivalent to the expression !(e1 === e2 ). An equality expression of the form super !== e is equivalent to the expression !(super === e).
The static type of an equality expression of the form e1 === e2 is bool.
The static types of other equality expressions follow from the definitions above. The forms e1 != e2, e1 !== e2 , super != e and super !== e are negations and have static type bool. The expression e1 == e2 is typed as a method invocation so its static type depends on the operator method declaration. It had better be bool.

Popular posts from this blog

Dart in 2016: The fastest growing programming language at Google, 2nd fastest growing in TIOBE Index

Dart was the fastest growing programming language at Google in 2016 with millions of lines of code written. It also made it to TIOBE Index Top 20 this month (see TIOBE's methodology).

It takes time to build something as ambitious as Dart and, in some ways, Dart is still in its infancy. But we're glad the hard work is starting to pay off.

Many thanks to our amazing community!

We're going to celebrate by ... releasing 1.22 next week (as per our usual 6 week release schedule).

AngularDart is going all Dart

Until now, the multiple language flavors of Angular 2 were written as TypeScript source, and then automatically compiled to both JavaScript and Dart. We're happy to announce that we’re splitting the Angular 2 codebase into two flavors – a Dart version and a TypeScript/JavaScript version – and creating a dedicated AngularDart team.

This is amazing news for Dart developers because:

The framework will feel more like idiomatic Dart.It will make use of Dart features that couldn't work with the TypeScript flavor. It will be faster.
This is equally great news for our TypeScript and JavaScript developers, by the way. Cleaner API, performance gains, easier contributions. Read more on the Angular blog.

Angular 2 for Dart is used by many teams at Google. Most famously by the AdWords team, but many other Google teams build large, mobile-friendly web apps. Some of the top requests from these teams were: make the API feel like Dart, provide a faster edit-refresh cycle, and improve applicat…

The new AdWords UI uses Dart — we asked why

Google just announced a re-designed AdWords experience. In case you’re not familiar with AdWords: businesses use it to advertise on google.com and partner websites. Advertising makes up majority of Google’s revenue, so when Google decides to completely redo the customer-facing front end to it, it’s a big deal. The Dart team is proud to say that this new front end is built with Dart and Angular 2. Whenever you asked us whether Google is ‘even using Dart for anything,’ this is what we had in mind but couldn’t say aloud. Until now. We asked Joshy Joseph, the primary technical lead on the project, some questions. Joshy is focusing on things like infrastructure, application latency and development velocity, so he’s the right person to ask about Dart.Q: What exactly did we launch on Monday?It’s a complete redesign of the AdWords customer experience that is rolling out slowly as a test to a small initial set of advertisers. The most noticeable thing is probably the Material Design look and f…