Add exclusion/not type #17879
Replies: 0 comments 10 replies
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Edit. After small researches about implementing this feature. I think it should become an infix operator like intersection and union: traitAtraitBextendsAtraitC//A ! B -> A without B.//B ! A should throw an error because A is a superclass of B//A ! C should be treated as A by the compiler (maybe a compile-time warning ?)Reasons of this change
GoalThe goal is to implement an operator equivalent to the exclusive operator from the set theory in mathematics. Here the proposed model uses the ExampleNote: Gray means "excluded" |
BetaWas this translation helpful?Give feedback.
-
See also the discussion on the contributors forum: https://contributors.scala-lang.org/t/union-types-and-generalisations/3820/9 |
BetaWas this translation helpful?Give feedback.
-
A couple of summary points from the thread that @LPTK mentioned (because it was a while ago!):
|
BetaWas this translation helpful?Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Hello.
I think I understood but I would like to know how an example using your impl on 2.11 looks. |
BetaWas this translation helpful?Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
// this is only to verify the expected type.importscala.reflect.runtime.universe.{TypeTag, typeTag} traitSpookyFunction[-In, +Out]{defandThen[NextIn<:In, NextOut]( next: SpookyFunction[OutwithNextIn, NextOut] ):SpookyFunction[NextIn, OutwithNextOut] =newSpookyFunction[NextIn, OutwithNextOut]{} } traitA; traitB; traitC; traitD; traitEobjectFooextendsSpookyFunction[AwithB, C] objectBarextendsSpookyFunction[CwithD, E] objectExampleextendsApp{// to see what's inferreddefshowType[T:TypeTag](t: T):Unit= println(typeTag[T]) // Expected: TypeTag[SpookyFunction[A with B with D,C with E]]// Why? Because even though Bar requires C, it is provided by Foo and so it can be eliminated. showType(Foo andThen Bar) }This works in Scala 2.11, 2.12, 2.13, and 3. (The type inference part, not necessarily the syntax and |
BetaWas this translation helpful?Give feedback.
-
Note that it's very important in Scala 2.x to say: next:SpookyFunction[OutwithNextIn, NextOut]rather than next:SpookyFunction[NextInwithOut, NextOut](i.e. if you don't put the "thing to eliminate" first, it won't work.) Not sure if this caveat applies to Scala 3 or not. |
BetaWas this translation helpful?Give feedback.
-
Well it looks like we haven't read the same thread.
This was not well-agreed at all. A general negation type would in fact be a lot more tractable than smart matching in type inference. Currently, matching components in these types breaks in surprising ways if types are reordered (violating the commutativity property), because it's the problem of smartly matching unions and intersection during type inference that is intractable, not negation types. The potential soundness issue is more of a technicality in DOT as far as I can see. It's a safe initialization problem, and there are already many like it, so negation types don't meaningfully change anything here: #11716
Again, I think you have it backwards. Negation types do not any dramatic runtime implications; smarter type matching does, and it's necessary for a good library implementation of type subtraction. |
BetaWas this translation helpful?Give feedback.
-
@LPTK I agree with you that it would be useful (I suggested it on the thread, even). But a lot of folks smarter than me pointed out soundness issues with it. Apologies if I was mistaken about the level of consensus. |
BetaWas this translation helpful?Give feedback.
-
You say "a lot of folks" pointed out soundness issues, but only two people made concrete arguments regarding soundness issues AFAIK.
|
BetaWas this translation helpful?Give feedback.
-
The mentioned thread is a bit inactive so I will continue to write here. Icharan proposed a negation type x match{case~A=> doStuff() }This is readable but for the reasons talked above, I think an "exclusion type" should be more appropriate so I sent an example of pattern matching with this: x match{case _ \A=> doStuff() //Or Any \ A }This notation is the same like exclusion with Maths and it takes only one more character. I also find it more readable in more complex situations: traitAtraitBextendsA//Other child traits... x match{caseA&~B=> doStuff() }versus traitAtraitBextendsA//Other child traits... x match{caseA\B=> doStuff() } |
BetaWas this translation helpful?Give feedback.



Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Suggestion: add a way to exclude a type from an union. This could be caracterised by a "not" type to preserve the already used
-.Examples:
A & !B→ A and not B. This is equivalent toA - Bin mathematics.A | !B→ A or not B. This is equivalent to*!A | B→ Not A or B. Equals to* - (A - B)in mathematics. It forbids allAexceptBBetaWas this translation helpful?Give feedback.
All reactions