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

Drop `forSome`, restrict existentials to wildcards #443

Open
adriaanm opened this Issue Nov 21, 2017 · 8 comments

Comments

Projects
None yet
4 participants
@adriaanm
Copy link
Member

adriaanm commented Nov 21, 2017

See: dotty

@adriaanm adriaanm added this to the 2.14 milestone Nov 21, 2017

@dwijnand

This comment has been minimized.

Copy link
Member

dwijnand commented Nov 28, 2017

How do you rewrite these?

  • Parser[Seq[ScopedKey[T]] forSome { type T }]
  • Initialize[Task[T]] forSome { type T }
  • Seq[Initialize[M[T]] forSome { type T }]
@Sciss

This comment has been minimized.

Copy link

Sciss commented Nov 28, 2017

Just

  • Parser[Seq[ScopedKey[_]]]
  • Initialize[Task[_]]
  • Seq[Initialize[M[_]]]

?

@dwijnand

This comment has been minimized.

Copy link
Member

dwijnand commented Nov 28, 2017

No Parser[Seq[ScopedKey[_]]] is "a parser of a sequence of any type of scoped keys".

Parser[Seq[ScopedKey[T]] forSome { type T }] is "a parser of a sequence of scoped keys of the same type".

@Sciss

This comment has been minimized.

Copy link

Sciss commented Nov 28, 2017

I don't think there is any semantic difference. These types are the same to Scala:

// Scala 2.12
trait ScopedKey[A]

trait Foo {
  def bar: ScopedKey[Seq[_]]
  
  def baz(x: ScopedKey[Seq[T] forSome { type T }]): Unit
  
  def test() = baz(bar)  // no prob
}
@dwijnand

This comment has been minimized.

Copy link
Member

dwijnand commented Nov 28, 2017

Seq[T] forSome { type T } is equivalent to Seq[_]

Seq[ScopedKey[T]] forSome { type T } is not equivalent to Seq[ScopedKey[_]], it's a subtype:

Welcome to Scala 2.12.3 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_144).
Type in expressions for evaluation. Or try :help.

scala> trait ScopedKey[A]
defined trait ScopedKey

scala> (null: Seq[ScopedKey[_]]): (Seq[ScopedKey[T]] forSome { type T })
<console>:13: error: type mismatch;
 found   : Seq[ScopedKey[_]]
 required: Seq[ScopedKey[T]] forSome { type T }

       (null: Seq[ScopedKey[_]]): (Seq[ScopedKey[T]] forSome { type T })
            ^

scala> (null: Seq[ScopedKey[T]] forSome { type T }): Seq[ScopedKey[_]]
res1: Seq[ScopedKey[_]] = null
@adriaanm

This comment has been minimized.

Copy link
Member Author

adriaanm commented Nov 29, 2017

Yes, you lose some precision or concision if all you have is wildcards. Given type SeqWithKeysOfType[T] = Seq[ScopedKey[T]], you recover the type you lost as SeqWithKeysOfType[_]

@dwijnand

This comment has been minimized.

Copy link
Member

dwijnand commented Nov 29, 2017

Nice, thanks.

Also expressible as the type lambda ({ type SeqWithKeysOfType[T] = Seq[ScopedKey[T]] })#SeqWithKeysOfType[_].

@smarter

This comment has been minimized.

Copy link

smarter commented Dec 1, 2017

Yes, you lose some precision or concision if all you have is wildcards. Given type SeqWithKeysOfType[T] = Seq[ScopedKey[T]], you recover the type you lost as SeqWithKeysOfType[_]

Dotty disallows this exactly because it would require the type system to support full existential types to work:

scala> type ScopedKey[T] 
scala> type SeqWithKeysOfType[T] = Seq[ScopedKey[T]] 
// defined alias type SeqWithKeysOfType = [T] => Seq[ScopedKey[T]]
scala> val x: SeqWithKeysOfType[_] = null 
1 |val x: SeqWithKeysOfType[_] = null
  |       ^^^^^^^^^^^^^^^^^^^^
  |unreducible application of higher-kinded type [T] => Seq[ScopedKey[T]] to wildcard arguments

@adriaanm adriaanm added the dotty label Jan 14, 2019

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment