Skip to content

Explicit operator #257

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
listepo opened this issue Mar 7, 2019 · 10 comments
Closed

Explicit operator #257

listepo opened this issue Mar 7, 2019 · 10 comments

Comments

@listepo
Copy link

listepo commented Mar 7, 2019

I would like to have something like this or alternative

@munificent
Copy link
Member

Dart does not have cast operators at all, so I'm not sure what you're asking to be able to mark explicit.

@listepo
Copy link
Author

listepo commented Mar 7, 2019

@munificent but will there be an alternative so that we can simply convert one object into another?

@Hixie
Copy link

Hixie commented Mar 7, 2019

You can do this today. Just declare a method on your class that converts to the other class.

class Foo {
  Foo(this.value);
  final int value;
  Bar toBar() => Bar(value);
}

class Bar {
  Bar(this.value);
  final int value;
  Foo toFoo() => Foo(value);
}

void main() {
  Foo myFoo = Foo(1);
  Bar myBar = myFoo.toBar();
  print(myBar.value); // 1
}

@listepo
Copy link
Author

listepo commented Mar 9, 2019

@Hixie thanks, but it would be nice to have syntax sugar for this.

class Bar {
  Bar(this.value);
  final int value;
  operator as(Foo foo) {
   //extra logic here...
  }
}

Bar myBar = myFoo;

var myBar = myFoo as Bar;

@leafpetersen
Copy link
Member

Note that there is a related issue here: #107 , and in the other issue and pull request referenced from that issue.

@Hixie
Copy link

Hixie commented Mar 18, 2019

@listepo The sugar you suggest is longer than the current code... can you elaborate on what problem you want to solve?

@eernstg
Copy link
Member

eernstg commented Mar 19, 2019

Yes, for example: null is int is false, null as int succeeds. This has always been so, but it will change with non-null types (where e as int will be a dynamic error in the case where e evaluates to null; presumably this will even be the case when e is null because any type of expression is allowed as the left operand of as, so even that won't be a compile-time error).

@eernstg
Copy link
Member

eernstg commented Mar 19, 2019

Assuming that T denotes a type, the expression null as T evaluates to null for all T, but that's because the null object is an acceptable value for a variable (or parameter, or returned value, etc) whose type is T. So there is no conversion here, it is just a matter of checking whether a given object is included in the specified type.

(In terms of types, T as a type annotation currently means T | Null, so null is always included; with non-null types that will change, as I mentioned).

A conversion from Type to Function would be a completely different concept. If it is taken to be a notation for constructor tear-offs (including some support for passing actual type arguments) then we could certainly define it, but I would expect a more explicit constructor tear-off mechanism to be more readable and maintainable (like List<int>.new).

@listepo
Copy link
Author

listepo commented Mar 19, 2019

@Hixie I would like to avoid calling the method to convert.

class Builder {
  static run(Foo foo) {
    print(foo);
  }
}

void main() {
  Builder.run(Bar(23).toFoo());
  Builder.run(Bar(23)); // call as operator or alternative
}

@eernstg
Copy link
Member

eernstg commented Mar 20, 2019

@listepo wrote:

  ...
  Builder.run(Bar(23)); // call as operator or alternative
  ...

If you allow this kind of conversion to take place implicitly then we're basically talking about the same thing as Scala implicit conversions.

For that, I'd like to mention that we have comments like the following:

The only widely misunderstood/abused mechanic for implicits
is implicit conversions and they are already deprecated

It may seem very convenient to get things converted from any type to any type that we have taken the effort to declare an implicit conversion for, just because the type checker can say "ah, that A thing won't fit here, but I know which code to run in order to create a B from an A, so I'll just do that, silently".

Another example is that we have the subsection title 'Restricting implicit conversions' in the Medium article about 'What's new in Scala 3' (where it's mentioned that they will now enforce some changes that make it a bit less implicit what is going on).

A third hint is that Martin Odersky singled out implicit conversions at his ECOOP/PLDI 2017 keynote as one of the few mechanisms that they actually don't really like any more.

I'm not convinced that it will make programs more maintainable in the long run to have this kind of implicit conversions, and it seems that the Scala community has had similar considerations, after a while where they tried it out.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants