Skip to content

[F] syntactic sugar for dynamic dispatch involving union types #6090

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
robstoll opened this issue Mar 14, 2019 · 5 comments
Closed

[F] syntactic sugar for dynamic dispatch involving union types #6090

robstoll opened this issue Mar 14, 2019 · 5 comments

Comments

@robstoll
Copy link
Contributor

I am not using dotty yet and merely read the doc about union types. Might be this is already supported. The idea is that the compiler does the dynamic dispatch if a method is called on a union type. For instance:

trait A { def foo(){} }
trait B { def foo(){} }
object Test {
  def test(fooable: A | B) {
    fooable.foo()
  }
}

Would expand to:

object Test {
  def test(fooable: A | B) {
    fooable match {
      case a: A => a.foo()
      case b: B => b.foo()
    }
  }
}

This would also go well in combination with structural types:

def test(fooable: A | B | { def foo(): Unit }) {
  fooable.foo()
}

Would expand to something like:

object Test {
  def test(fooable: A | B | { def foo(): Unit }): Unit = {
    fooable match {
      case a: A                   => a.foo()
      case b: B                   => b.foo()
      case x => x.asInstanceOf[{ def foo(): Unit }].foo() 
    }
  }
@smarter
Copy link
Member

smarter commented Mar 14, 2019

We used to have this two and a half years ago but removed it, see the discussion in #1550 (comment). Assuming no one's mind has changed since then, I'm afraid I'll have to close this (you can still try to gather popular support for it on http://contributors.scala-lang.org/).

@smarter smarter closed this as completed Mar 14, 2019
@robstoll
Copy link
Contributor Author

Fair enough, this is surely only a nice to have as one can easily write the boiler-plate code. Thanks for the quick reply

@robstoll
Copy link
Contributor Author

An afterthought: If I get it right you can now only use members which are found in a common super type. I guess you do this so that you can pass the member around as any other member of a "regular" type.
What about approaching this problem differently?

I see two steps. Firstly you could do the expansion shown above only if the member is used directly and fail otherwise. If this is done in a phase of the compiler where finding the method has not yet taken place, then you don't have to do anything in addition (kind of like a macro, the error reporting wouldn't be so neat, but well...). That would already be an improvement which probably covers most cases.

Secondly, for the use case where a member is passed around (e.g. to a higher-order function): instead of trying to find a member which you can directly pass around you could always create a syntactic type which comprises the above sugar. Finding a member is then reduced to the problem to find member foo for A and B which is already implemented. Again the error reporting could be confusing in such a case but well..
What do you think?

@smarter
Copy link
Member

smarter commented Mar 14, 2019

In the discussion I linked to,people objected to this on the principle that it wasn't a good idea to do this in the first place, no specific implementation mechanism changes that.

@robstoll
Copy link
Contributor Author

I see, thanks for your time

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

2 participants