Closed octalsrc closed 7 years ago
As mentioned before, we can further use simulacrum
, in the style of the cats
library, to eliminate some of the boilerplate required for defining these abstractions. Specifically, the companion objects for Lattice
, Semilattice
, and Abstraction
which enable the typeclass-like usage of the traits can be macro-generated with the @typeclass
annotation.
Just a note: I changed some of the scaladoc since Intellij was complaining about broken references.
When using the [[Foo]] Syntax it tries to find a class. I changed the method references in there to [[Foo.method]] which removed the error. I am not sure how to specifically make it link to the methods though since when I build the scala-doc the links seem broken. If anyone has an idea on this it would be good to hear.
To view scaladoc in intellij: ctrl j (on Mac)
@octalsrc I believe we should have a discussion on the following points. I had some trouble implementing extra unit tests but I think it may be my understanding of implicits. I will try to spend some time tonight going through the documentation and understand them better. Perhaps we can spend some time looking at this together next time we meet?
Notes on interface: -The methods in the tests which "adapt" implicits to be used locally seem redundant and it would be nice if we didn't need such things. Is there a better way to do this? Also I had trouble replicating this when I attempted to add a test for "isBottom" but I think that is my own lack of experience with implicits in scala.
def checkmeet[C,A : Lattice](
c1: C, c2: C
)(
implicit inst: Abstraction[C,A]
): A = {
meet(beta(c1),beta(c2))
}
@ftc Sorry, those methods you cited (checkmeet
, checkjoin
) are actually not needed; they were sort of testing that writing polymorphic methods for typeclasses works (since all the typeclass uses otherwise in the suites were concrete).
The apply
methods are used to take a step out of using the instances. It's described in this document: http://typelevel.org/cats/typeclasses.html
Providing this apply
for a typeclass Monoid
, for example,
object Monoid {
def apply[A : Monoid]: Monoid[A] = implicitly[Monoid[A]]
}
lets you use this:
def combineAll[A : Monoid](list: List[A]): A =
list.foldRight(Monoid[A].empty)(Monoid[A].combine)
instead of this:
def combineAll[A : Monoid](list: List[A]): A =
list.foldRight(implicitly[Monoid[A]].empty)(implicitly[Monoid[A]].combine)
As for method names, represent
and beta
are the same; I've changed it to just beta
now. It's up to bikeshedding which one we end up with.
The reason there are both represent
and beta
is that either of them could be clearer depending on the context and what your background is.
Nick and I discussed this and believe that the next reasonable step is to implement an abstract interpreter on top of this. I am going to start by extending the interval domain with a few things and making a domain for static variables.
@ftc But this is a new task. Could you finish the review? For the review, critique what you think is relevant to this feature. Is the code being committed connected with tests? Can you add an additional (likely somewhat redundant) test case?
I added unit tests for the "isBottom" method and it appears to be something I can work with (Although I am still learning how it is organized). I think I would be satisfied to merge this and start working on extensions after we figure out how to write unit tests that exercise a few things:
For a general todo: I can't figure out how to make code coverage work on the domains package, it seems to not list them in a meaningful way. Manual inspection makes me think they are reasonably covered beyond the bullets above though.
I have redefined the abstractions for abstract domains using the pattern of Scala-style typeclasses and implemented two abstract domains as examples,
Interval
andVote
.To use these abstractions for your new abstract domain datatype
Foo
(which abstracts concrete datatypeInt
), you implement instances ofAbstraction[Int,Foo]
andSemilattice[Foo]
(or, optionally,Lattice[Foo]
) as implicit values in the objectFoo.implicits
.Having provided these implementations, you can use the semilattice and abstraction operations wherever you like. (
beta
, as used in this example, is an alias forrepresent
)You can also define generic operations over abstract domain values
and use them for
Foo
.