Use SAM syntax for typeclass instances where possible#4279
Use SAM syntax for typeclass instances where possible#4279johnynek merged 13 commits intotypelevel:mainfrom
Conversation
e10b935 to
9d0d5f4
Compare
| def empty: A = self.zero | ||
| def combine(x: A, y: A): A = join(x, y) | ||
| } | ||
| BoundedSemilattice.instance(zero, join) |
There was a problem hiding this comment.
This isn't really a SAM, so isn't it subject to my same concern from #3871 (comment)?
There was a problem hiding this comment.
I think the concern was when there are more than one lambda
There was a problem hiding this comment.
Hmm, not sure why this is different. I think it is storing two references (zero and join) where it previously stored one (a reference to self)
There was a problem hiding this comment.
Right, but is that really a problem when before we used to have an entire new class instead of an additional reference?
There was a problem hiding this comment.
Except, you have one class per JVM vs an extra reference per instance :) FTR I don't particularly care about this, I'm just unconvinced whether we are really optimizing anything here. See my comment in #3871 (comment).
Additionally, isn't this de-optimizing the current implementations? By replacing dedicated classes with lambdas and thus adding a level of indirection and a larger per-instance footprint. Like, these are micro-optimizations, but isn't saving a few megabytes? :)
There was a problem hiding this comment.
Well if it's not worth it then we can also close this PR and the related issue.
One minor advantage is that the definitions get a bit more concise.
9d0d5f4 to
43a2226
Compare
|
I'm all for using the sam syntax for things like However, this is doing something different since we are not taking a function literal and returning a trait value, we are passing a literal to a function so it must have the indirection. It may be inlined by the JIT, but my understanding is that Function1 being megamorphic that will not happen. So I'm concerned this is a performance degradation for a slight benefit (perhaps) in jar size and in lines of code. |
Do you think we should do that instead? I would be in favour of that change. |
|
yeah, I think that change would be fine. Another idea, we could add a macro that we could write on 2.12/2.13 and 3.0 that would work like some of these constructor methods except we know that it will inline. So this could be useful for a more concise Monoid implementation for instance (since it isn't a SAM). But honestly, that sounds like a lot of work for some pretty minor syntax wins. |
Yes, I believe it is equivalent in performance, but IIUC it still generates an anonymous class in Scala 2 due to the compiler bug described in #3871 (comment).
Yup, my concern too, which I raised in #3871 (comment). There at least there were significant decreases in jar size. |
43a2226 to
132b4c3
Compare
|
Ok I made the changes to use SAM syntax |
|
nice to see so many net lines removed! |
Definitions are shorter and don't generate anonymous classes in some cases.
Instances:
ShowEqPartialOrderOrderSemigroup,CommutativeSemigroupMonoid,CommutativeMonoidBandSemilattice,BoundedSemilatticeCloses #3870