-
Notifications
You must be signed in to change notification settings - Fork 0
Generics and type information
Jonathan edited this page Mar 13, 2018
·
1 revision
In Firefly, generics are always kept, the way this information is stored depends on the target. For the JVM, generics must be provided as function arguments (or constructor arguments).
Generic classes/interfaces/enums/types...
interface List<T> {
}
class LinkedListImpl<T> : List<T> {
}
enum Option<T> {
Some(val value: T),
None
}
type Container<T> {
val value: T
}
Firefly does not allow you to operate on generic values directly such as:
fun <T> add(f: T, s: T): T { f + s }
Note: This fails with generic type T does not implement + function
.
Instead you should explicitly specify that the type T
implements +
or make it dynamic:
fun <T: dynamic> add(f: T, s: T): T { f + s } // + invoked dynamically at runtime
fun <T: AddOp> add(f: T, s: T): T { f + s } // + invoked statically, but may also be invoked dynamically depending on the case
Sometimes you want to invoke the constructor of the generic type, to do this you should declare a Type with the constructor and specify that the generic implements the type:
type Example {
fun new(name: String, count: Int): Example
}
fun <T: Example> factory(): T { T.new("x", count++) }
fun <T> info(): FireflyType = type<T>()
fun <E> gens() {
info<List<String>>() // FireflyType.concrete(List).of(String)
info<Map<String, Int>>() // FireflyType.concrete(Map).of(String).and(Int)
info<Map<String, Map<Int, E>>>() // FireflyType.concrete(Map).of(String).and(FireflyType.concrete(Map).of(Int).and("E"))
info<E>() // FireflyType.type(type<E>())
// From firefly classes:
val map = HashMap<String, Int>()
typeOf(map) // FireflyType.concrete(HashMap).of(String).and(Int)
// For Java Types
val javaMap = java.util.HashMap<String, Int>()
typeOf(map) // FireflyType.java(HashMap).of(FireflyType.javaVariable("K")).and(FireflyType.javaVariable("V"))
}