I have an interface:
interface TileSet {
fun contains(x: Int, y: Int) : Boolean
}
I want to be able to create unions of sets of tiles (tile is a pair of x and y integer coordinates):
fun TileSet.union(another: TileSet) : TileSet =
// ..
In Java 8, I could do it like this:
#FunctionalInterface
public interface TileSet {
boolean contains(int x, int y);
public default TileSet unite(TileSet another) {
return (x, y) -> TileSet.this.contains(x, y) && another.contains(x, y);
}
}
So an interface is implemented with a lambda in TileSet#unite(). Or it could be implemented with the old anonymous class approach:
public default TileSet unite(TileSet another) {
return new TileSet() {
#Override
public boolean contains(int x, int y) {
return TileSet.this.contains(x, y) && another.contains(x, y);
}
}
}
How can I create an anonymous implementation of a single-method interface in Kotlin?
I know how to do it if I use (Int, Int) -> Boolean instead of TileSet, but I want the type to have a descriptive name rather than just a function signature.
There are examples in the documentation for anonymous classes, but not for interfaces.
This is how I created an instance of an interface:
fun TileSet.union(another: TileSet) : TileSet =
object : TileSet {
override fun contains(x: Int, y: Int) : Boolean =
this#union.contains(x, y) || another.contains(x, y)
}
Notice that, unlike in the example from documentation, there are no parentheses after object : TileSet.
I was experimenting a little bit, and I was surprised to find that you can implement Java functional interfaces using Kotlin lambdas:
// Implementing Java functional interfaces using lambdas
val greeter = Consumer<String> { println("Hi $it") }
val dice = Supplier { ThreadLocalRandom.current().nextInt(1, 7) }
But when you implement Kotlin functional interfaces, you need the full ceremony:
// Implementing a Kotlin functional inteface with lambdas is not possible
val greeter = object : MyConsumer<String> {
override fun accept(x: String) {
println("Hi $x")
}
}
#FunctionalInterface
interface MyConsumer<T> {
fun accept(x:T)
}
I wonder why the full anonymous class syntax is needed when implementing Kotlin intefaces from the very Kotlin!
Maybe they want you to use functions instead? That could be done like this.
// If you want to use lambdas, define a function instead of an interface
val greeter: MyConsumerFunction<String> = { println("Hi $it") }
typealias MyConsumerFunction<T> = (T) -> Unit
Anyway, if anyone knows anything about this, please let me know! :)
it's possible with kotlin, it's just you have to add fun before the interface so would be like fun interface xx, it's called a functional interface, basically what it means is an interface with ONE function, which is what we usually want
https://kotlinlang.org/docs/fun-interfaces.html
Related
Overview
I have a Kotlin-based project that defines a DSL, but for reasons given below I'm now investigating whether it would be better to write my project in Scala. As Scala doesn't seem to lend itself to creating DSLs with as much ease as in Kotlin, I'm not entirely sure how I'd recreate the same DSL in Scala.
Before this gets flagged as a duplicate of this question, I've looked at that but my DSL requirements are somewhat different and I haven't been able to figure out a solution from that.
Details
I'm trying to create a flow-based programming system for developing automated vehicle part test procedures, and for the past couple of weeks I've been testing out an implementation of this in Kotlin, since it seems to support a lot of features that are really nice for creating FBP systems (native coroutine support, easy creation of DSLs using type-safe builders, etc.).
As awesome as Kotlin is though, I'm starting to realise that it would help a lot if the implementation language for the FBP was more functional, since FBP's seem to share a lot in common with functional languages. In particular, being able to define and consume typeclasses would be really useful for a project like this.
In Kotlin, I've created a DSL representing the "glue" language between nodes in a flow-based system. For example, given the existence of two blackbox processes Add and Square, I can define a "composite" node that squares the sum of two numbers:
#CompositeNode
private fun CompositeOutputtingScalar<Int>.addAndSquare(x: Int, y: Int) {
val add = create<Add>()
val square = create<Square>()
connect {
input(x) to add.x
input(y) to add.y
add.output to square.input
square.output to output
}
}
The idea is that connect is a function that takes a lambda of form ConnectionContext.() -> Unit, where ConnectionContext defines various overloads of an infix function to (shadowing the built-in to function in the Kotlin stdlib) allowing me to define the connections between these processes (or nodes).
This is my attempt to do something similar in Scala:
class OutputPort[-A] {
def connectTo(inputPort: InputPort[A]) {}
}
class InputPort[+A]
object connect {
val connections = new ListBuffer[Connection[_]]()
case class Connection[A](outputPort: OutputPort[A], inputPort: InputPort[A])
class ConnectionTracker() {
def track[A](connection: Connection[A]) {}
}
// Cannot make `OutputPort.connectTo` directly return a `Connection[A]`
// without sacrificing covariance, so make an implicit wrapper class
// that does this instead
implicit class ExtendedPort[A](outputPort: OutputPort[A]) {
def |>(inputPort: InputPort[A]): Unit = {
outputPort connectTo inputPort
connections += Connection(outputPort, inputPort)
}
}
}
def someCompositeFunction() {
val output = new OutputPort[Int]
val input = new InputPort[Int]
output |> input // Should not be valid here
connect {
output |> input // Should be valid here
}
}
Right now this won't compile because ConnectablePort isn't in scope. I can bring it into scope by doing:
import connect._
connect {
output |> input // Should be valid here
}
However, it's undesirable to have to do this within the node definition.
To summarise, how can I recreate the DSL I've made in Kotlin within Scala? For reference, this is how I've defined my Kotlin DSL:
interface Composite {
fun <U : ExecutableNode> create(id: String? = null): U
fun connect(apply: ConnectionContext.() -> Unit)
class ConnectionContext {
val constants = mutableListOf<Constant<*>>()
fun <T> input(parameter: T): OutputPort<T> = error("Should not actually be invoked after annotation processing")
fun <T> input(parameterPort: OutputPort<T>) = parameterPort
fun <T> constant(value: T) = Constant(value.toString(), value)
infix fun <U, V> U.to(input: InputPort<V>): Nothing = error("Cannot connect value to specified input")
infix fun <U> OutputPort<U>.to(input: InputPort<U>) = this join input
infix fun <T, U> T.to(other: U): Nothing = error("Invalid connection")
}
}
interface CompositeOutputtingScalar<T> : Composite {
val output: InputPort<T>
}
interface CompositeOutputtingCluster<T : Cluster> : Composite {
fun <TProperty> output(output: T.() -> TProperty): InputPort<TProperty>
}
Just turning on the |> is pretty straightforward in Scala if you use a companion object, and is something always available with the output port
class OutputPort[-A] {
def connectTo(inputPort: InputPort[A]):Unit = {}
}
class InputPort[+A]
object OutputPort{
implicit class ConnectablePort[A](outputPort: OutputPort[A]) {
def |>(inputPort: InputPort[A]): Unit = outputPort connectTo inputPort
}
}
def someCompositeFunction() {
val output = new OutputPort[Int]
val input = new InputPort[Int]
output |> input // Should be valid here
}
Judiciously deciding where to do imports is a core Scala concept. It is how we turn on implicit in our code, like the following, is very common, since that is the way we turn on our type classes.
class OutputPort[-A] {
def connectTo(inputPort: InputPort[A]): Unit = {}
}
class InputPort[+A]
object Converter {
implicit class ConnectablePort[A](outputPort: OutputPort[A]) {
def |>(inputPort: InputPort[A]): Unit = outputPort connectTo inputPort
}
}
def someCompositeFunction() {
val output = new OutputPort[Int]
val input = new InputPort[Int]
import Converter._
output |> input // Should be valid here
}
Now, I think this is what you are looking for, but there are still some import and implicit that needs to be setup, but this would enclose the implicit behavior:
class OutputPort[-A] {
def connectTo(inputPort: InputPort[A]): Unit = {}
}
class InputPort[+A]
object Converter {
private class ConnectablePort[A](outputPort: OutputPort[A]) {
def |>(inputPort: InputPort[A]): Unit = outputPort connectTo
inputPort
}
def convert[A](f: (OutputPort[A] => ConnectablePort[A]) => Unit): Unit = {
def connectablePortWrapper(x: OutputPort[A]): ConnectablePort[A] = new ConnectablePort[A](x)
f(connectablePortWrapper _)
}
}
object MyRunner extends App {
val output = new OutputPort[Int]
val input = new InputPort[Int]
import Converter.convert
//output |> input won't work
convert[Int] { implicit wrapper =>
output |> input // Should be valid here
}
}
I want to do something like this:
interface Serializable<FromType, ToType> {
fun serialize(): ToType
companion object {
abstract fun deserialize(serialized: ToType): FromType
}
}
or even this would work for me:
interface Serializable<ToType> {
fun serialize(): ToType
constructor(serialized: ToType)
}
but neither compiles. Is there a syntax for this, or will I be forced to use make this an interface for a factory? Or is there another answer? 😮 That'd be neat!
Basically, nothing in a companion object can be abstract or open (and thus be overridden), and there's no way to require the implementations' companion objects to have a method or to define/require a constructor in an interface.
A possible solution for you is to separate these two functions into two interfaces:
interface Serializable<ToType> {
fun serialize(): ToType
}
interface Deserializer<FromType, ToType> {
fun deserialize(serialized: ToType): FromType
}
This way, you will be able to implement the first interface in a class and make its companion object implement the other one:
class C: Serializable<String> {
override fun serialize(): String = "..."
companion object : Deserializer<C, String> {
override fun deserialize(serialized: String): C = C()
}
}
Also, there's a severe limitation that only a single generic specialization of a type can be used as a supertype, so this model of serializing through the interface implementation may turn out not scalable enough, not allowing multiple implementations with different ToTypes.
For future uses, it's also possible to give the child class to a function as a receiver parameter:
val encodableClass = EncodableClass("Some Value")
//The encode function is accessed like a member function on an instance
val stringRepresentation = encodableClass.encode()
//The decode function is accessed statically
val decodedClass = EncodableClass.decode(stringRepresentation)
interface Encodable<T> {
fun T.encode(): String
fun decode(stringRepresentation: String): T
}
class EncodableClass(private val someValue: String) {
// This is the remaining awkwardness,
// you have to give the containing class as a Type Parameter
// to its own Companion Object
companion object : Encodable<EncodableClass> {
override fun EncodableClass.encode(): String {
//You can access (private) fields here
return "This is a string representation of the class with value: $someValue"
}
override fun decode(stringRepresentation: String): EncodableClass {
return EncodableClass(stringRepresentation)
}
}
}
//You also have to import the encode function separately:
// import codingProtocol.EncodableClass.Companion.encode
This is the more optimal use case for me. Instead of one function in the instanced object and the other in the companion object like your example, we move both functions to the companion object and extend the instance.
Search results so far have led me to believe this is impossible without either a non-primary constructor
class Foo { // NOT OK: 2 extra lines--doesn't leverage Scala's conciseness
private var _x = 0
def this(x: Int) { this(); _x = x }
def x = _x
}
val f = new Foo(x = 123) // OK: named parameter is 'x'
or sacrificing the name of the parameter in the primary constructor (making calls using named parameters ugly)
class Foo(private var _x: Int) { // OK: concise
def x = _x
}
val f = new Foo(_x = 123) // NOT OK: named parameter should be 'x' not '_x'
ideally, one could do something like this:
class Foo(private var x: Int) { // OK: concise
// make just the getter public
public x
}
val f = new Foo(x = 123) // OK: named parameter is 'x'
I know named parameters are a new thing in the Java world, so it's probably not that important to most, but coming from a language where named parameters are more popular (Python), this issue immediately pops up.
So my question is: is this possible? (probably not), and if not, why is such an (in my opinion) important use case left uncovered by the language design? By that, I mean that the code either has to sacrifice clean naming or concise definitions, which is a hallmark of Scala.
P.S. Consider the case where a public field needs suddenly to be made private, while keeping the getter public, in which case the developer has to change 1 line and add 3 lines to achieve the effect while keeping the interface identical:
class Foo(var x: Int) {} // no boilerplate
->
class Foo { // lots of boilerplate
private var _x: Int = 0
def this(x: Int) { this(); _x = x }
def x = _x
}
Whether this is indeed a design flaw is rather debatable. One would consider that complicating the syntax to allow this particular use case is not worthwhile.
Also, Scala is after all a predominantly functional language, so the presence of vars in your program should not be that frequent, again raising the question if this particular use case needs to be handled in a special way.
However, it seems that a simple solution to your problem would be to use an apply method in the companion object:
class Foo private(private var _x: Int) {
def x = _x
}
object Foo {
def apply(x: Int): Foo = new Foo(x)
}
Usage:
val f = Foo(x = 3)
println(f.x)
LATER EDIT:
Here is a solution similar to what you originally requested, but that changes the naming a bit:
class Foo(initialX: Int) {
private var _x = initialX
def x = _x
}
Usage:
val f = new Foo(initialX = 3)
The concept you are trying to express, which is an object whose state is mutable from within the object and yet immutable from the perspective of other objects ... that would probably be expressed as an Akka actor within the context of an actor system. Outside the context of an actor system, it would seem to be a Java conception of what it means to be an object, transplanted to Scala.
import akka.actor.Actor
class Foo(var x: Int) extends Actor {
import Foo._
def receive = {
case WhatIsX => sender ! x
}
}
object Foo {
object WhatIsX
}
Not sure about earlier versions, but In Scala 3 it can easily be implemented like follows:
// class with no argument constructor
class Foo {
// prive field
private var _x: Int = 0
// public getter
def x: Int = _x
// public setter
def x_=(newValue: Int): Unit =
_x = newValue
//auxiliary constructor
def this(value: Int) =
this()
_x = value
}
Note
Any definition within the primary constructor makes the definition public, unless you prepend it with private modifier
Append _= after a method name with Unit return type to make it a setter
Prepending a constructor parameter neither with val nor with var, makes it private
Then it follows:
val noArgFoo = Foo() // no argument case
println(noArgFoo.x) // the public getter prints 0
val withArgFoo = Foo(5) // with argument case
println(withArgFoo.x) // the public getter prints 5
noArgFoo.x = 100 // use the public setter to update x value
println(noArgFoo.x) // the public getter prints 100
withArgFoo.x = 1000 // use the public setter to update x value
println(withArgFoo.x) // the public getter prints 1000
This solution is exactly what you asked; in a principled way and without any ad hoc workaround e.g. using companion objects and the apply method.
If function accepts structural type, it can be defined as:
def doTheThings(duck: { def walk; def quack }) { duck.quack }
or
type DuckType = { def walk; def quack }
def doTheThings(duck: DuckType) { duck.quack }
Then, you can use that function in following way:
class Dog {
def walk { println("Dog walk") }
def quack { println("Dog quacks") }
}
def main(args: Array[String]) {
doTheThings(new Dog);
}
If you decompile (to Java) the classes generated by scalac for my example, you can see that argument of doTheThings is of type Object and the implementation uses reflection to call methods on the argument (i.e.duck.quack)
My question is why reflection? Isn't it possible just to use anonymous and invokevirtual instead of reflection?
Here is way to translate(implement) the structural type calls for my example (Java syntax, but the point is the bytecode):
class DuckyDogTest {
interface DuckType {
void walk();
void quack();
}
static void doTheThing(DuckType d) {
d.quack();
}
static class Dog {
public void walk() { System.out.println("Dog walk"); }
public void quack() { System.out.println("Dog quack"); }
}
public static void main(String[] args) {
final Dog d = new Dog();
doTheThing(new DuckType() {
public final void walk() { d.walk(); }
public final void quack() { d.quack();}
});
}
}
Consider a simple proposition:
type T = { def quack(): Unit; def walk(): Unit }
def f(a: T, b: T) =
if (a eq b) println("They are the same duck!")
else println("Different ducks")
f(x, x) // x is a duck
It would print Different ducks under your proposal. You could further refine it, but you just cannot keep referential equality intact using a proxy.
A possible solution would be to use the type class pattern, but that would require passing another parameter (even if implicit). Still, it's faster. But that's mostly because of the lameness of Java's reflection speed. Hopefully, method handles will get around the speed problem. Unfortunately, Scala is not scheduled to give up on Java 5, 6 and 7 (which do not have method handles) for some time...
In addition to your proxy object implementing methods on the structural type, it would also need to have appropriate pass-through implementations of all of the methods on Any (equals, hashCode, toString, isInstanceOf, asInstanceOf) and AnyRef(getClass, wait, notify, notifyAll, and synchronized). While some of these would be straightforward, some would be almost impossible to get right. In particular, all of the methods listed are "final" on AnyRef (for Java compatability and security) and so couldn't be properly implemented by your proxy object.
In C# you can write:
using System.Numerics;
namespace ExtensionTest {
public static class MyExtensions {
public static BigInteger Square(this BigInteger n) {
return n * n;
}
static void Main(string[] args) {
BigInteger two = new BigInteger(2);
System.Console.WriteLine("The square of 2 is " + two.Square());
}
}}
How would this simple extension method look like in Scala?
The Pimp My Library pattern is the analogous construction:
object MyExtensions {
implicit def richInt(i: Int) = new {
def square = i * i
}
}
object App extends Application {
import MyExtensions._
val two = 2
println("The square of 2 is " + two.square)
}
Per #Daniel Spiewak's comments, this will avoid reflection on method invocation, aiding performance:
object MyExtensions {
class RichInt(i: Int) {
def square = i * i
}
implicit def richInt(i: Int) = new RichInt(i)
}
Since version 2.10 of Scala, it is possible to make an entire class eligible for implicit conversion
implicit class RichInt(i: Int) {
def square = i * i
}
In addition, it is possible to avoid creating an instance of the extension type by having it extend AnyVal
implicit class RichInt(val i: Int) extends AnyVal {
def square = i * i
}
For more information on implicit classes and AnyVal, limitations and quirks, consult the official documentation:
http://docs.scala-lang.org/overviews/core/implicit-classes.html
http://docs.scala-lang.org/overviews/core/value-classes.html
This would be the code after Daniel's comment.
object MyExtensions {
class RichInt( i: Int ) {
def square = i * i
}
implicit def richInt( i: Int ) = new RichInt( i )
def main( args: Array[String] ) {
println("The square of 2 is: " + 2.square )
}
}
In Scala we use the so-called (by the inventor of the language) Pimp My Library pattern, which is much discussed and pretty easy to find on the Web, if you use a string (not keyword) search.
Scala 3 now has extension methods. Functionally it seems similar as expected to C# and Kotlin.
https://dotty.epfl.ch/docs/reference/contextual/extension-methods.html
https://github.com/scala/scala
https://github.com/lampepfl/dotty
A recent (as of this post) pull shows the syntax being simplified. Stable version as of this post is still 2.x. But there is a 3.xRC, and I noticed Jetbrains already supports it in Idea, partially I assume.