I would guess that the mentioned deprecation stuff is the SIP-18 thing, according to which the compiler warns about types expressed with forSome (represented as ExistentialTypeTrees in the parser, dubbed "existential types" in SLS).As to macros, there was (and is) a bug in the tracker that is caused by an internal implementation detail of existentials. Inside the compiler we have a wider array of tools to deal with this kind of situations, but the reflection API isn't rich enough, therefore a macro didn't work. Other than that, I don't know of potential glitches caused by existentials w.r.t macros.
Only where enabled, existential types that cannot be expressed as wildcard types can be written and are allowed in inferred types of values or return types of methods. Existential types with wildcard type syntax such as List[_]
, or Map[String, _]
are not affected.
Why keep the feature? Existential types are needed to make sense of Java’s wildcard types and raw types and the erased types of run-time values.
Why control it? Having complex existential types in a code base usually makes application code very brittle, with a tendency to produce type errors with obscure error messages. Therefore, going overboard with existential types is generally perceived not to be a good idea. Also, complicated existential types might be no longer supported in a future simplification of the language.
On Thu, Oct 18, 2012 at 5:16 PM, martin odersky <martin....@epfl.ch> wrote:Are you saying that this is a syntactic level thing only?
> Only where enabled, existential types that cannot be expressed as wildcard
> types can be written and are allowed in inferred types of values or return
> types of methods. Existential types with wildcard type syntax such as
> List[_], or Map[String, _] are not affected.
Suppose we have an existential which isn't immediately in that form, eg.,
type Problematic = (List[T], Option[T]) forSome { type T }
we can rewrite this to an equivalent form which can be expressed using
a syntactic wildcard with the help of an alias,
type F[T] = (List[T], Option[T])
type Unproblematic = F[_]
Is that really all that's need to circumvent the warning?
I'll buy this. I can see why tree-rewriting would be annoying in this context. It doesn't strike me as something that is undecidable, but it would definitely require some machinery that is specific to existential types of the "forSome" form.
Good catch. We should provide the return type explicitly. Can you file a ticket?
The problematic return type "Option[(A, B[_$1])] forSome { type _$1 }" is not generated together withthe unapply method, but inferred by the compiler (when the generated method is type-checked).
trait Z { trait Lower trait Upper { val result: Z def inverse: result.Lower } val upper: Upper val pred: Lower => Unit def ok1 = Seq(upper) map { u => u.result.pred(u.inverse) } def ok2 = Seq(upper) map { u => u.result.pred match { case p => p(u.inverse) } } def ok3 = Seq(upper) map { u => u.inverse match { case x => u.result.pred(x) } } def ok4 = Seq(upper) map { u => (u.result.pred, u.inverse) match { case (p, x) => p(x) } } def ok5 = Seq(upper) map { u => (u.result.pred, u ) match { case (p, u1: u.type) => p(u1.inverse) } } def nok = Seq(upper) map { u => (u.result.pred, u ) match { case (p, u1) => p(u1.inverse) } } /** a.scala:15: error: type mismatch; found : u1.result.Lower required: u.result.Lower def nok = Seq(upper) map { u => (u.result.pred, u) match { case (p, u1) => p(u1.inverse) } } ^ **/ }
def ok5 = Seq(upper) map { u => (u.result.pred, u ) match { case (p, u1: u.type) => p(u1.inverse) } }
def nok = Seq(upper) map { u => (u.result.pred, u ) match { case (p, u1) => p(u1.inverse) } }
Rumor started here: https://www.precog.com/blog-precog-2/entry/existential-types-ftw#comment-11 Mike Slinn is under the impression (apparently from Martin and Josh) that existential types are incompatible with macros (??) and are going to be removed post 2.10 (!!). This doesn't really mesh with what I know of macros, and it doesn't make any sense to me in the context of the planned move toward a more DOT-based meta-calculus.
Can anyone shed some light on this?
Daniel
Good catch. We should provide the return type explicitly. Can you file a ticket?
Option[(A, B[_])], that is Option[(A, B[_$1] forSome { type _$1 })] (note that _$1 is bound right outside of B, though this might look confusing).andOption[(A, B[_$1])] forSome { type _$1 }
You don't even have to go that far. What you just illustrated is a general issue with the let-binding of type parameters on functions. Your solution is to use existential types (which sort of does the right thing), but the more correct solution would be to apply a higher-rank type and release the binding of T1 and T2 from the function def. In other words, what you really want here is an unbound universal, rather than an unbound existential.
scala> f[String,Int]res0: Map[String,Int]#Inner = Map$Inner@770440dd
Abstract types in the way that I used them are existential types, even though SLS and scalac may not refer to them as such.
DanielOn Fri, Oct 19, 2012 at 10:12 AM, iulian dragos <jagu...@gmail.com> wrote:
On Thu, Oct 18, 2012 at 5:58 PM, Daniel Spiewak <djsp...@gmail.com> wrote:
Rumor started here: https://www.precog.com/blog-precog-2/entry/existential-types-ftw#comment-11 Mike Slinn is under the impression (apparently from Martin and Josh) that existential types are incompatible with macros (??) and are going to be removed post 2.10 (!!). This doesn't really mesh with what I know of macros, and it doesn't make any sense to me in the context of the planned move toward a more DOT-based meta-calculus.
Just a quick note related to your blog post (that I thoroughly enjoyed, we need more of this!): you are using abstract types, not existentials. So unless I missed something, Mike's comment, while factually true, does not invalidate your approach.iulian
Can anyone shed some light on this?
Daniel
--
« Je déteste la montagne, ça cache le paysage »
Alphonse Allais