-
Notifications
You must be signed in to change notification settings - Fork 347
Add cross-build for Scala 2.12 #600
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
Conversation
|
Whelp, looks like just killing those overrides breaks |
|
@ianoc we are willing to break binary compatibility here so maybe we can clean up. As I recall, you made this change to make the hashCode lazy, is that right? Did you look up some alternate syntax that would work here? We could always just manually implement a hashCode for these types (also not using lazy is probably worth it, and just checking if the hashCode is 0 or something and recomputing if it is). |
|
Yeah i made the change, it has a pretty big performance impact. I don't really care how it gets done, I'd probably keep it using lazy unless it makes a visible change to a benchmark, just that its obvious what it does to anyone driving past and doesn't seem necessary for the fix. Upstream just up and deleted these functions iirc, since the code generation in case classes doesn't call them anymore, i believe they inject the hash code function now directly into the generated class. the method in 2.11 is just which still exists in 2.12, so the minimal change is to just use |
|
This excludes algebird-spark, since spark isn't ready for 2.12 primetime yet. Also fixes deprecation warnings from the SBT upgrade (there's still one left that I'm not sure how to fix) |
|
Legit failures now: [info] IntervalLaws:
[info] - [x, x + 1) contains x *** FAILED ***
[info] GeneratorDrivenPropertyCheckFailedException was thrown during property evaluation.
[info] (CheckProperties.scala:12)
[info] Falsified after 0 successful property evaluations.
[info] Location: (CheckProperties.scala:12)
[info] Occurred when passed generated values (
[info] arg0 = 0 // 32 shrinks
[info] )
[info] - (x, x + 1] contains x + 1 *** FAILED ***
[info] GeneratorDrivenPropertyCheckFailedException was thrown during property evaluation.
[info] (CheckProperties.scala:12)
[info] Falsified after 0 successful property evaluations.
[info] Location: (CheckProperties.scala:12)
[info] Occurred when passed generated values (
[info] arg0 = 0 // 32 shrinks
[info] )And this serialization error: |
|
Here's the bug for interval, it's legit: scala> Interval.leftClosedRightOpen(0, 1).contains(0)
<console>:15: warning: a type was inferred to be `Any`; this may indicate a programming error.
Interval.leftClosedRightOpen(0, 1).contains(0)
res8: Boolean = false |
438ae0a to
8cdf22e
Compare
|
This bug too for 2.12 |
|
The Any being inferred looks like an issue to me. The second issue is probably a change due to how scalacheck changed, I would think. |
|
The serialization test seems to say (didn't look in detail yet) that it should not serialize but does? Maybe that is just a weird test or testing some detail that changes with java 8. |
|
yeah, looks like this change for scalacheck typelevel/scalacheck@a2100f6 |
|
calling it quits for now. The build works, so we can iterate on the three issues:
Otherwise all the build BS is cleaned up! |
|
Ah yeah we ran into typelevel/scalacheck@a2100f6 too internally - though it's overall a good thing. It's surfacing mistakes that were quietly being ignored before. |
|
Can you explain some of the Interval changes? Why was Either replaced w/ MaybeEmpty? Why does the implicit Ordering move from being a class member of Interval to a method param on each method? Having the Ordering bound at construction time instead of separately (possibly differently) at each call sight seems like a big change. |
|
The |
|
OK -- I wasn't saying it should be one way or another. I don't really understand this enough to have an opinion so that's why I was asking for some clarification for my own understanding. The Either part makes sense. Can you clarify why an object should have its ordering provided to each of its methods instead of once to its constructor? That means an instance will behave differently depending on where it's called from which surprised me. |
|
@isnotinvain by capturing the typeclass, we have two issues:
Generally, taking typeclasses where they are used is usually considered the better design these days (Haskell always does this, but it also requires typeclass uniqueness). |
|
OK. That goes counter to some "encapsulation" type intuitions I have, like if I construct an Interval, that's probably the point in time where I know what the right ordering is, and then I hand it over to some other code, I'd sort of expect it to "keep" its ordering. The case you mentioned "if you have two different Interval[T], they can have the same type T but different inner Ordering[T] instances" is more in line with what I'd expect. But I guess as you said, if you're going the route of Interval is just a data container, and the type class contains all the behavior, then whenever you want to "do" something with an interval you have to bring your own ordering for that. So I think I get it, it's sort of like how a List() doesn't contain an ordering, but List().sort() will ask you for one. Thanks for the explanation. |
|
I like the way you put it, @isnotinvain. I think this is the way to go, and cleans up the code - as I keep pushing on documentation I'll highlight this distinction so that it's clear that we're taking a stance, and folks can respond / we can change if this introduces problems anywhere. Does that work for you? |
|
Yeah SGTM! |
|
Looks like the scala 2.12 wasn't respecting the |
| val bytesAfterSizeCalled = new String(serialize(bf)) | ||
| assert(bytesBeforeSizeCalled == bytesAfterSizeCalled) | ||
| val bytesAfterSizeCalled = Bytes(serialize(bf)) | ||
| assert(bytesBeforeSizeCalled.size == bytesAfterSizeCalled.size) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
so, this started as a legit bug with @transient lazy val. I fixed that by upgrading to scala 2.12. I can see now that this does NOT serialize the dense instance... but a single byte is different in the serialized version, so equality won't work for the test. Nothing's corrupt as far as I can tell.
I changed the test to just check for size. Is this legit?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the confusing thing is that contains should be read-only. How does calling contains change the binary representation?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It instantiates the dense representation in the lazy Val. I wonder if some but gets flipped? If so seems like a regression in 2.12, but one that doesn't affect the behavior. Maybe we should make a minimal test case to see if this is true for all classes with a transient lazyval.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is worrisome in that the transient lazy val trick is VERY commonly used to sidestep scalding serialization issues. We should probably chase it a bit or we will see massive pains on trying to merge this at scale.
| class CmsSmallFrequencyProperty[K: CMSHasher: Gen] extends CmsFrequencyProperty[K] { | ||
| def exactGenerator: Gen[Vector[K]] = Gen.containerOf[Vector, K](implicitly[Gen[K]]) | ||
| def exactGenerator: Gen[Vector[K]] = | ||
| Gen.nonEmptyListOf[K](implicitly[Gen[K]]).map(_.toVector) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
easy fix here for the empty generators.
d47ab9f to
cb4092e
Compare
6f04583 to
7bebc41
Compare
Current coverage is 80.33% (diff: 54.54%)@@ develop #600 diff @@
==========================================
Files 113 110 -3
Lines 4932 4928 -4
Methods 4491 4493 +2
Messages 0 0
Branches 440 435 -5
==========================================
- Hits 3960 3959 -1
+ Misses 972 969 -3
Partials 0 0
|
|
sorry to be a pain @sritchie, and it is totally my fault too, but can we actually break the interval changes out into a separate PR. I don't want to mess up history by atomically merging those. I think we should just do the minimal in this PR to get 2.12 working (since we have some risk of introducing bugs here and we want to have a clear version to see that happen). |
|
@johnynek sure, I can do that tomorrow before we pair. |
|
okay @johnynek, backed out those changes for |
johnynek
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess we can merge and see about dealing with the bloomfilter issue as things come up.
@isnotinvain note this transient lazy val may bite scalding pretty hard at Twitter. I imagine you should look into it.
| }, | ||
|
|
||
| scalacOptions ++= { | ||
| if (scalaVersion.value startsWith "2.12") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not so sure we should be turning on optimization, actually. I have heard that this is best for end projects, not libraries, but I guess we can leave it as is for now.
Various plugin and SBT upgrades. I managed to get rid of all deprecation warnings in the build.sbt, which is a nice start to this new era.
The three issues we found were
Interval(Eithergained acontainsmethod, screwing up our implicit conversion trick)Gen.nonEmptyListWe also did some work to remove the
Orderinginstance from theIntervaltrait, since we're going binary-incompatible on this release.The only library excluded is
algebird-spark, since spark isn't on 2.12 yet. Turns out they're waiting on our chill release!