Skip to content

Histogram methods should be sensitive to implied variance #2845

Description

@moradology

The methods on Histograms should be written to take into account the variance implied by the histogram hierarchy. Otherwise, asInstanceOf calls become necessary (not nice)

// StreamingHistogram *is* Histogram[Double], and should be treated like it
val someTile: Tile = ???
val otherTile: Tile = ???
val h1 = StreamingHistogram.fromTile(someTile)
val h2 = StreamingHistogram.fromTile(otherTile)

The compiler is not satisfied that h1 and h2 (Histogram[Double] subtypes) can be merged

val mergeFail = h1 merge h2

This works, is ugly:

val mergeSucc = h1 merge h2.asInstanceOf[Histogram[Double]]

Activity

  1. added
    technical debthttps://en.wikipedia.org/wiki/Technical_debt
    and removed
    technical debthttps://en.wikipedia.org/wiki/Technical_debt
    on Dec 7, 2018
  2. pomadchin commented on Dec 12, 2018

    @pomadchin
    Member

    I've checked it an everything works; are you sure that there is a problem in this API?

        val sourceHistogram = {
          val h = StreamingHistogram(42)
          h.countItem(1, 1)
          h.countItem(2, 2)
          h.countItem(4, 3)
          h.countItem(8, 4)
          h.countItem(16, 5)
          h
        }
    
        val targetHistogram = {
          val h = StreamingHistogram(42)
          h.countItem(1, 1)
          h.countItem(2, 2)
          h.countItem(3, 3)
          h.countItem(4, 4)
          h.countItem(5, 5)
          h
        }
    
        sourceHistogram merge targetHistogram

    Works good for me.

  3. moradology commented on Dec 12, 2018

    @moradology
    ContributorAuthor

    You're right, in the single case (which I foolishly provided without further investigation) this is not a problem but by not keeping type information around (i.e. without handling the implied variance) folds will be problematic (this is the context I encountered it in):

    val t: Tile = ???
    val s1 = StreamingHistogram.fromTile(t)
    val s2 = StreamingHistogram.fromTile(t)
    val s3 = StreamingHistogram.fromTile(t)
    val s4 = StreamingHistogram.fromTile(t)
    List(s1, s2, s3).foldLeft(s4)(_ merge _)

    The above won't compile without this change:

    List(s1, s2, s3).foldLeft(s4.asInstanceOf[Histogram[Double]])(_ merge _)

    Happy to close if this is desirable behavior

  4. pomadchin commented on Dec 12, 2018

    @pomadchin
    Member

    Talked a lil bit in private about it, so it makes sense to walk through all the Histogram[Double] functions and to check that all functions return the most specific types. For instance, this would resolve the signature of the fold above from being verbose:

    List(s1, s2, s3).foldLeft[Histogram[Double]](s4)(_ merge _)

    To just

    List(s1, s2, s3).foldLeft(s4)(_ merge _)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions