Valid code fail with "overloaded method ... with alternatives"

Hi everybody, i have been translate valid java code with example of using jenetic (java library for genetic programming) to scala.
java code:

import org.jenetics.BitChromosome;
import org.jenetics.BitGene;
import org.jenetics.Genotype;
import org.jenetics.engine.Engine;
import org.jenetics.util.Factory;

public class RunTestJava {
    public static void main(String[] args) {
        Factory<Genotype<BitGene>> gtf = Genotype.of(BitChromosome.of(10, 0.5));
        Engine<BitGene, Integer> engine = Engine.builder(RunTestJava::eval, gtf).build();
    }

    static private Integer eval(Genotype<BitGene> gt) {
        return gt.getChromosome().as(BitChromosome.class).bitCount();
    }
}

scala code:

import java.util.function.{Function => JFunction}
import org.jenetics.engine.Engine
import org.jenetics.util.Factory
import org.jenetics.{BitChromosome, BitGene, Genotype}

object RunTest extends App {
  val ff = new JFunction[Genotype[BitGene], Integer] {
    override def apply(t: Genotype[BitGene]): Integer =
      t.getChromosome.as(classOf[BitChromosome]).bitCount()
  }
  val gtf: Factory[Genotype[BitGene]] = Genotype.of(BitChromosome.of(10, 0.5))
  val engine: Engine[BitGene, Integer] = Engine.builder(ff, gtf).build
}

and i have this compile-time error (it’s point to builder method):

Error:(17, 49) overloaded method value builder with alternatives:
  [T, G <: org.jenetics.Gene[_, G], C <: Comparable[_ >: C]](x$1: java.util.function.Function[_ >: T, _ <: C], x$2: org.jenetics.engine.Codec[T,G])org.jenetics.engine.Engine.Builder[G,C] <and>
  [G <: org.jenetics.Gene[_, G], C <: Comparable[_ >: C]](x$1: java.util.function.Function[_ >: org.jenetics.Genotype[G], _ <: C], x$2: org.jenetics.Chromosome[G], x$3: org.jenetics.Chromosome[G]*)org.jenetics.engine.Engine.Builder[G,C] <and>
  [G <: org.jenetics.Gene[_, G], C <: Comparable[_ >: C]](x$1: java.util.function.Function[_ >: org.jenetics.Genotype[G], _ <: C], x$2: org.jenetics.util.Factory[org.jenetics.Genotype[G]])org.jenetics.engine.Engine.Builder[G,C] <and>
  [T, G <: org.jenetics.Gene[_, G], C <: Comparable[_ >: C]](x$1: org.jenetics.engine.Problem[T,G,C])org.jenetics.engine.Engine.Builder[G,C]
 cannot be applied to (java.util.function.Function[org.jenetics.Genotype[org.jenetics.BitGene],Integer], org.jenetics.util.Factory[org.jenetics.Genotype[org.jenetics.BitGene]])
  val engine: Engine[BitGene, Integer] = Engine.builder(ff, gtf).build

I know about problems with overloading in scala, but i annotate all types explicit.
How can i resolve this error?

I think you’re just missing parentheses on the call to build.

Scala is interpreting that as an attempt to assign the method “build” to the value “engine” rather than call the method and assign the result.

it’s point to build method

Sorry, i meant builder method, not build. But i add parentheses and error hasn’t gone.

Does anything change if you call it like Engine.builder[BitGene, Integer](ff, gtf).build?

1 Like

Thanks! Now it’s work.
I tried to change fitness function (ff) to

val ff: Genotype[BitGene] => Integer = {t =>
    t.getChromosome.as(classOf[BitChromosome]).bitCount()
  } 

and get similar error:

Error:(11, 56) overloaded method value builder with alternatives:
  (x$1: java.util.function.Function[_ >: org.jenetics.Genotype[org.jenetics.BitGene], _ <: Integer],x$2: org.jenetics.Chromosome[org.jenetics.BitGene],x$3: org.jenetics.Chromosome[org.jenetics.BitGene]*)org.jenetics.engine.Engine.Builder[org.jenetics.BitGene,Integer] <and>
  (x$1: java.util.function.Function[_ >: org.jenetics.Genotype[org.jenetics.BitGene], _ <: Integer],x$2: org.jenetics.util.Factory[org.jenetics.Genotype[org.jenetics.BitGene]])org.jenetics.engine.Engine.Builder[org.jenetics.BitGene,Integer]
 cannot be applied to (org.jenetics.Genotype[org.jenetics.BitGene] => Integer, org.jenetics.util.Factory[org.jenetics.Genotype[org.jenetics.BitGene]])
  val engine: Engine[BitGene, Integer] = Engine.builder[BitGene, Integer](ff, gtf).build

Can i use scala function signature Genotype[BitGene] => Integer or method def ff(t: Genotype[BitGene]): Integer instead of JFunction[Genotype[BitGene], Integer]? I use scala 2.12.2 and i thought scala lambda compile to java SAM interface java.util.function.Function. I have same problem with other java libraries and i’m interested how right resolve it.

In Scala 2.12.x you should be able to write

val ff: JFunction[Genotype[BitGene], Integer] = t => t.getChromosome.as(classOf[BitChromosome]).bitCount()

Or

def eval(t: Genotype[BitGene]): Integer =  t.getChromosome.as(classOf[BitChromosome]).bitCount()
val ff: JFunction[Genotype[BitGene], Integer] = eval

A Scala function (not method or lambda) however will not be automatically converted to a Java Function instance. There is a library that does that: https://github.com/scala/scala-java8-compat.

1 Like