How to design abstract classes if methods don't have the exact same signature? - scala

This is a "real life" OO design question. I am working with Scala, and interested in specific Scala solutions, but I'm definitely open to hear generic thoughts.
I am implementing a branch-and-bound combinatorial optimization program. The algorithm itself is pretty easy to implement. For each different problem we just need to implement a class that contains information about what are the allowed neighbor states for the search, how to calculate the cost, and then potentially what is the lower bound, etc...
I also want to be able to experiment with different data structures. For instance, one way to store a logic formula is using a simple list of lists of integers. This represents a set of clauses, each integer a literal. We can have a much better performance though if we do something like a "two-literal watch list", and store some extra information about the formula in general.
That all would mean something like this
object BnBSolver[S<:BnBState]{
def solve(states: Seq[S], best_state:Option[S]): Option[S] = if (states.isEmpty) best_state else
val next_state = states.head
/* compare to best state, etc... */
val new_states = new_branches ++ states.tail
solve(new_states, new_best_state)
}
class BnBState[F<:Formula](clauses:F, assigned_variables) {
def cost: Int
def branches: Seq[BnBState] = {
val ll = clauses.pick_variable
List(
BnBState(clauses.assign(ll), ll :: assigned_variables),
BnBState(clauses.assign(-ll), -ll :: assigned_variables)
)
}
}
case class Formula[F<:Formula[F]](clauses:List[List[Int]]) {
def assign(ll: Int) :F =
Formula(clauses.filterNot(_ contains ll)
.map(_.filterNot(_==-ll))))
}
Hopefully this is not too crazy, wrong or confusing. The whole issue here is that this assign method from a formula would usually take just the current literal that is going to be assigned. In the case of two-literal watch lists, though, you are doing some lazy thing that requires you to know later what literals have been previously assigned.
One way to fix this is you just keep this list of previously assigned literals in the data structure, maybe as a private thing. Make it a self-standing lazy data structure. But this list of the previous assignments is actually something that may be naturally available by whoever is using the Formula class. So it makes sense to allow whoever is using it to just provide the list every time you assign, if necessary.
The problem here is that we cannot now have an abstract Formula class that just declares a assign(ll:Int):Formula. In the normal case this is OK, but if this is a two-literal watch list Formula, it is actually an assign(literal: Int, previous_assignments: Seq[Int]).
From the point of view of the classes using it, it is kind of OK. But then how do we write generic code that can take all these different versions of Formula? Because of the drastic signature change, it cannot simply be an abstract method. We could maybe force the user to always provide the full assigned variables, but then this is a kind of a lie too. What to do?
The idea is the watch list class just becomes a kind of regular assign(Int) class if I write down some kind of adapter method that knows where to take the previous assignments from... I am thinking maybe with implicit we can cook something up.

I'll try to make my answer a bit general, since I'm not convinced I'm completely following what you are trying to do. Anyway...
Generally, the first thought should be to accept a common super-class as a parameter. Obviously that won't work with Int and Seq[Int].
You could just have two methods; have one call the other. For instance just wrap an Int into a Seq[Int] with one element and pass that to the other method.
You can also wrap the parameter in some custom class, e.g.
class Assignment {
...
}
def int2Assignment(n: Int): Assignment = ...
def seq2Assignment(s: Seq[Int]): Assignment = ...
case class Formula[F<:Formula[F]](clauses:List[List[Int]]) {
def assign(ll: Assignment) :F = ...
}
And of course you would have the option to make those conversion methods implicit so that callers just have to import them, not call them explicitly.
Lastly, you could do this with a typeclass:
trait Assigner[A] {
...
}
implicit val intAssigner = new Assigner[Int] {
...
}
implicit val seqAssigner = new Assigner[Seq[Int]] {
...
}
case class Formula[F<:Formula[F]](clauses:List[List[Int]]) {
def assign[A : Assigner](ll: A) :F = ...
}
You could also make that type parameter at the class level:
case class Formula[A:Assigner,F<:Formula[A,F]](clauses:List[List[Int]]) {
def assign(ll: A) :F = ...
}
Which one of these paths is best is up to preference and how it might fit in with the rest of the code.

Related

How to create a Scala function that can parametrically create instances of sub-types of some type

Sorry I'm not very familiar with Scala, but I'm curious if this is possible and haven't been able to figure out how.
Basically, I want to create some convenience initializers that can generate a random sample of data (in this case a grid). The grid will always be filled with instances of a particular type (in this case a Location). But in different cases I might want grids filled with different subtypes of Location, e.g. Farm or City.
In Python, this would be trivial:
def fillCollection(klass, size):
return [klass() for _ in range(size)]
class City: pass
cities = fillCollection(City, 10)
I tried to do something similar in Scala but it does not work:
def fillGrid[T <: Location](size): Vector[T] = {
Vector.fill[T](size, size) {
T()
}
}
The compiler just says "not found: value T"
So, it it possible to approximate the above Python code in Scala? If not, what's the recommended way to handle this kind of situation? I could write an initializer for each subtype, but in my real code there's a decent amount of boilerplate overlap between them so I'd like to share code if possible.
The best workaround I've come up with so far is to pass a closure into the initializer (which seems to be how the fill method on Vectors already works), e.g.:
def fillGrid[T <: Location](withElem: => T, size: Int = 100): Vector[T] = {
Vector.fill[T](n1 = size, n2 = size)(withElem)
}
That's not a huge inconvenience, but it makes me curious why Scala doesn't support the "simpler" Python-style construct (if it in fact doesn't). I sort of get why having a "fully generic" initializer could cause trouble, but in this case I can't see what the harm would be generically initializing instances that are all known to be subtypes of a given parent type.
You are correct, in that what you have is probably the simplest option. The reason Scala can't do things the pythonic way is because the type system is much stronger, and it has to contend with type erasure. Scala can not guarantee at compile time that any subclass of Location has a particular constructor, and it will only allow you to do things that it can guarantee will conform to the types (unless you do tricky things with reflection).
If you want to clean it up a little bit, you can make it work more like python by using implicits.
implicit def emptyFarm(): Farm = new Farm
implicit def emptyCity(): City = new City
def fillGrid[T <: Location](size: Int = 100)(implicit withElem: () => T): Vector[Vector[T]] = {
Vector.fill[T](n1 = size, n2 = size)(withElem())
}
fillGrid[farm](3)
To make this more usable in a library, it's common to put the implicits in a companion object of Location, so they can all be brought into scope where appropriate.
sealed trait Location
...
object Location
{
implicit def emptyFarm...
implicit def emptyCity...
}
...
import Location._
fillGrid[Farm](3)
You can use reflection to accomplish what you want...
This is a simple example that will only work if all your subclasses have a zero args constructor.
sealed trait Location
class Farm extends Location
class City extends Location
def fillGrid[T <: Location](size: Int)(implicit TTag: scala.reflect.ClassTag[T]): Vector[Vector[T]] = {
val TClass = TTag.runtimeClass
Vector.fill[T](size, size) { TClass.newInstance().asInstanceOf[T] }
}
However, I have never been a fan of runtime reflection, and I hope there could be another way.
Scala cannot do this kind of thing directly because it's not type safe. It will not work if you pass a class without a zero-argument constructor. The Python version throws an error at runtime if you try to do this.
The closure is probably the best way to go.

Check for acceptance of type, rather than value, with isDefinedAt

I have a case where I want use isDefinedAt to check if a partial function accepts a type, rather than a specific value.
val test: PartialFunction[Any, Unit] = {
case y: Int => ???
case ComplexThing(x, y, z) => ???
}
Here you could do something like test isDefinedAt 1 to check for acceptance of that value, however, what I really want to do is check for acceptance of all Ints (more specifically, in my case the type I want to check is awkward to initialize (it has a lot of dependencies), so I would really like to avoid creating an instance if possible - for the moment I'm just using nulls, which feels ugly). Unfortunately, there is no test.isDefinedAt[Int].
I'm not worried about it only accepting some instances of that type - I would just like to know if it's completely impossible that type is accepted.
There is no way to make PartialFunction do this. In fact, because of type erasure, it can be difficult to operate on types at runtime. If you want to be able to verify types at compile-time you can use typeclasses instead:
class AllowType[-T] {
def allowed = true
}
object AllowType {
implicit object DontAllowAnyType extends AllowType[Any] {
override def allowed = false
}
}
implicit object AllowInt extends AllowType[Int]
implicit object AllowString extends AllowType[String]
def isTypeAllowed[T](implicit at: AllowType[T]) = at.allowed
isTypeAllowed[Int] // true
isTypeAllowed[Double] // false
The answer appears to be that this simply isn't possible - there are other ways to do this (as in wingedsubmariner's answer), but that requires either duplicating the information (which renders it pointless, as the reason for doing this was to avoid that), or changing not to use partial functions (which is dictated by an outside API).
The best solution is just to use nulls to fill the dependencies to create instances to check with. It's ugly, and has it's own issues, but it appears to be the best possible without substantial change.
test.isDefinedAt(ComplexThing(null, null, null))

Scala: compare type of generic class

There have been many questions on that issue, but sadly none seems to solve my problem.
I've written a generic scala class, let's call it
class MyClass[A]() { ... }
As well as the according object:
object MyClass() { ... }
Inside MyClass I want to define a function whichs behaviour depends on the given type A. For instance, let's just assume I want to define a 'smaller' function of type (A, A) => Boolean, that by default returns 'true' no matter what the elements are, but is meant to return the correct results for certain types such as Int, Float etc.
My idea was to define 'smaller' as member of the class in the following way:
class MyClass[A]() {
val someArray = new Array[A](1) // will be referred to later on
var smaller:(A,A) => Boolean = MyClass.getSmallerFunction(this)
...some Stuff...
}
object MyClass {
def getSmallerFunction[A](m:MyClass[A]):(A,A) => Boolean = {
var func = (a:Boolean, b:Boolean) => true
// This doesn't compile, since the compiler doesn't know what 'A' is
if(A == Int) func = ((a:Int, b:Int) => (a<b)).asInstanceOf[(A,A) => Boolean)]
// This compiles, but always returns true (due to type erasure I guess?)
if(m.isInstanceOf[MyClass[Float]]) func = ((a:Float, b:Float) => (a<b)).asInstanceOf[(A,A) => Boolean)]
// This compiles but always returns true as well due to the newly created array only containing null-elements
if(m.someArray(0).isInstanceOf[Long]) func = ((a:Long, b:Long) => (a<b)).asInstanceOf[(A,A) => Boolean)]
}
...some more stuff...
}
The getSmallerFunction method contains a few of the implementations I experimented with, but none of them works.
After a while of researching the topic it at first seemed as if manifests are the way to go, but unfortunately they don't seem to work here due to the fact that object MyClass also contains some constructor calls of the class - which, no matter how I change the code - always results in the compiler getting angry about the lack of information required to use manifests. Maybe there is a manifest-based solution, but I certainly haven't found it yet.
Note: The usage of a 'smaller' function is just an example, there are several functions of this kind I want to implement. I know that for this specific case I could simply allow only those types A that are Comparable, but that's really not what I'm trying to achieve.
Sorry for the wall of text - I hope it's possible to comprehend my problem.
Thanks in advance for your answers.
Edit:
Maybe I should go a bit more into detail: What I was trying to do was the implementation of a library for image programming (mostly for my personal use). 'MyClass' is actually a class 'Pixelmap' that contains an array of "pixels" of type A as well as certain methods for pixel manipulation. Those Pixelmaps can be of any type, although I mostly use Float and Color datatypes, and sometimes Boolean for masks.
One of the datatype dependent functions I need is 'blend' (although 'smaller' is used too), which interpolates between two values of type A and can for instance be used for smooth resizing of such a Pixelmap. By default, this blend function (which is of type (A,A,Float) => A) simply returns the first given value, but for Pixelmaps of type Float, Color etc. a proper interpolation is meant to be defined.
So every Pixelmap-instance should get one pointer to the appropriate 'blend' function right after its creation.
Edit 2:
Seems like I found a suitable way to solve the problem, at least for my specific case. It really is more of a work around though.
I simply added an implicit parameter of type A to MyClass:
class MyClass[A]()(implicit dummy:A) { ... }
When I want to find out whether the type A of an instance m:MyClass is "Float" for instance, I can just use "m.dummy.isInstanceOf[Float]".
To make this actually work I added a bunch of predefined implicit values for all datatypes I needed to the MyClass object:
object MyClass {
implicit val floatDummy:Float = 0.0f
implicit val intDummy:Int = 0
...
}
Although this really doesn't feel like a proper solution, it seems to get me around the problem pretty well.
I've omitted a whole bunch of stuff because, if I'm honest, I'm still not entirely sure what you're trying to do. But here is a solution that may help you.
trait MyClass[A] {
def smaller: (A,A) => Boolean
}
object MyClass {
implicit object intMyClass extends MyClass[Int] {
def smaller = (a:Int, b:Int) => (a < b)
}
implicit object floatMyClass extends MyClass[Float] {
def smaller = (a:Float, b:Float) => (a < b)
}
implicit object longMyClass extends MyClass[Long] {
def smaller = (a:Long, b:Long) => (a < b)
}
def getSmallerFunction[T : MyClass](a: T, b: T) = implicitly[MyClass[T]].smaller(a, b)
}
The idea is that you define your smaller methods as implicit objects under your MyClass, object, with a getSmallerFunction method. This method is special in the sense that it looks for a type-class instance that satisfies it's type bounds. We can then go:
println(MyClass.getSmallerFunction(1, 2))
And it automagically knows the correct method to use. You could extend this technique to handle your Array example. This is a great tutorial/presentation on what type-classes are.
Edit: I've just realise you are wanting an actual function returned. In my case, like yours the type parameter is lost. But if at the end of the day you just want to be able to selectively call methods depending on their type, the approach I've detailed should help you.

Should I use implicit conversions to enforce preconditions?

It occurs to me that I could use use implicit conversions to both announce and enforce preconditions. Consider this:
object NonNegativeDouble {
implicit def int2nnd(d : Double) : NonNegativeDouble = new NonNegativeDouble(d)
implicit def nnd2int(d : NonNegativeDouble) : Double = d.v
def sqrt(n : NonNegativeDouble) : NonNegativeDouble = scala.math.sqrt(n)
}
class NonNegativeDouble(val v : Double ) {
if (v < 0) {
throw new IllegalArgumentException("negative value")
}
}
object Test {
def t1 = {
val d : Double = NonNegativeDouble.sqrt(3.0);
printf("%f\n", d);
val n : Double = NonNegativeDouble.sqrt(-3.0);
}
}
Ignore for the moment the actual vacuity of the example: my point is, the subclass NonNegativeDouble expresses the notion that a function only takes a subset of the entire range of the class's values.
First is this:
A good idea,
a bad idea, or
an obvious idea everybody else already knows about
Second, this would be most useful with basic types, like Int and String. Those classes are final, of course, so is there a good way to not only use the restricted type in functions (that's what the second implicit is for) but also delegate to all methods on the underlying value (short of hand-implementing every delegation)?
This is an extremely cool idea, but unfortunately its true potential can't be realized in Scala's type system. What you really want here is dependent types, which allow you to impose a proof obligation on the caller of your method to verify that the argument is in range, such that the method can't even be invoked with an invalid argument.
But without dependent types and the ability to verify specifications at compile-time, I think this has questionable value, even leaving aside performance considerations. Consider, how is it any better than using the require function to state the initial conditions required by your method, like so:
def foo(i:Int) = {
require (i >= 0)
i * 9 + 4
}
In both cases, a negative value will cause an exception to be thrown at runtime, either in the require function or when constructing your NonNegativeDouble. Both techniques state the contract of the method clearly, but I would argue that there is a large overhead in building all these specialized types whose only purpose is to encapsulate a particular expression to be asserted at runtime. For instance, what if you wanted to enforce a slightly different precondition; say, that i > 45? Will you build an IntGreaterThan45 type just for that method?
The only argument I can see for building e.g. a NonNegativeFoo type is if you have many methods which consume and return positive numbers only. Even then, I think the payoff is dubious.
Incidentally, this is similar to the question How far to go with a strongly typed language?, to which I gave a similar answer.
Quite a neat idea actually, though I wouldn't use it in any performance sensitive loops.
#specialisation could also help out by a fair amount here to help make the code more efficient...
This would usually be called "unsigned int" in C. I don't think it's very useful, because you wouldn't be able to define operators properly. Consider this:
val a = UnsignedInt(5)
val b = a - 3 // now, b should be an UnsignedInt(2)
val c = b - 3 // now, c must be an Int, because it's negative!
Therefore, how would you define the minus operator? Like this maybe:
def -(i:Int):Either[UnsignedInt,Int]
That would make arithmetics with UnsignedInt practically unusable.
Or you define a superclass, MaybeSignedInt, that has two subclasses, SignedInt and UnsignedInt. Then you could define subtraction in UnsignedInt like this:
def -(i:Int):MaybeSignedInt
Seems totally awful, doesn't it? Actually, the sign of the number should not conceptually be a property of the number's type, but of it's value.

Pros and Cons of choosing def over val

I'm asking a slight different question than this one. Suppose I have a code snippet:
def foo(i : Int) : List[String] = {
val s = i.toString + "!" //using val
s :: Nil
}
This is functionally equivalent to the following:
def foo(i : Int) : List[String] = {
def s = i.toString + "!" //using def
s :: Nil
}
Why would I choose one over the other? Obviously I would assume the second has a slight disadvantages in:
creating more bytecode (the inner def is lifted to a method in the class)
a runtime performance overhead of invoking a method over accessing a value
non-strict evaluation means I could easily access s twice (i.e. unnecesasarily redo a calculation)
The only advantage I can think of is:
non-strict evaluation of s means it is only called if it is used (but then I could just use a lazy val)
What are peoples' thoughts here? Is there a significant dis-benefit to me making all inner vals defs?
1)
One answer I didn't see mentioned is that the stack frame for the method you're describing could actually be smaller. Each val you declare will occupy a slot on the JVM stack, however, the whenever you use a def obtained value it will get consumed in the first expression you use it in. Even if the def references something from the environment, the compiler will pass .
The HotSpot should optimize both these things, or so some people claim. See:
http://www.ibm.com/developerworks/library/j-jtp12214/
Since the inner method gets compiled into a regular private method behind the scene and it is usually very small, the JIT compiler might choose to inline it and then optimize it. This could save time allocating smaller stack frames (?), or, by having fewer elements on the stack, make local variables access quicker.
But, take this with a (big) grain of salt - I haven't actually made extensive benchmarks to backup this claim.
2)
In addition, to expand on Kevin's valid reply, the stable val provides also means that you can use it with path dependent types - something you can't do with a def, since the compiler doesn't check its purity.
3)
For another reason you might want to use a def, see a related question asked not so long ago:
Functional processing of Scala streams without OutOfMemory errors
Essentially, using defs to produce Streams ensures that there do not exist additional references to these objects, which is important for the GC. Since Streams are lazy anyway, the overhead of creating them is probably negligible even if you have multiple defs.
The val is strict, it's given a value as soon as you define the thing.
Internally, the compiler will mark it as STABLE, equivalent to final in Java. This should allow the JVM to make all sorts of optimisations - I just don't know what they are :)
I can see an advantage in the fact that you are less bound to a location when using a def than when using a val.
This is not a technical advantage but allows for better structuring in some cases.
So, stupid example (please edit this answer, if you’ve got a better one), this is not possible with val:
def foo(i : Int) : List[String] = {
def ret = s :: Nil
def s = i.toString + "!"
ret
}
There may be cases where this is important or just convenient.
(So, basically, you can achieve the same with lazy val but, if only called at most once, it will probably be faster than a lazy val.)
For a local declaration like this (with no arguments, evaluated precisely once and with no code evaluated between the point of declaration and the point of evaluation) there is no semantic difference. I wouldn't be surprised if the "val" version compiled to simpler and more efficient code than the "def" version, but you would have to examine the bytecode and possibly profile to be sure.
In your example I would use a val. I think the val/def choice is more meaningful when declaring class members:
class A { def a0 = "a"; def a1 = "a" }
class B extends A {
var c = 0
override def a0 = { c += 1; "a" + c }
override val a1 = "b"
}
In the base class using def allows the sub class to override with possibly a def that does not return a constant. Or it could override with a val. So that gives more flexibility than a val.
Edit: one more use case of using def over val is when an abstract class has a "val" for which the value should be provided by a subclass.
abstract class C { def f: SomeObject }
new C { val f = new SomeObject(...) }