e.g. with Kotlin - its close but I want to be able to define ONLY an interface and then 'derive' data classes from it withouth having to re-specify all the members
you cant quite do that with either class or property delegation.
So I cheated
I have code using 'byte buddy' that generates an instance of a concrete class given an interface -- very close to java's Proxy implemenation, except it generates an actual class
with properties, and works given non-interfaces (abstract or other) classes as well.
In fact it works with simply a map of name/type
which allows me to convert a jdbc ResultSet into a sequence of concrete classes without having pre-defined the class
which in turn I give to vaadin -- where it can make Grid and forms etc using its default data binding
without ever having to have pre-defined an interface or a class at runtime.
Which means I just re-invented Groovy :(* :(
A differnt motivation -- it seriously pains me (becuase its 'SO CLOSE' ) that to implement certian types of APIs -- at minimum any class structure that uses an interface or abstract class --
that one has to manually re-implement the exact same code over and over -- 'boilerplate' -- the sort of thing Kotlin strives to avoid -- yet doesnt quite ...
interface A {
val b : String
}
now if I want to every have an "A" I MUST re-implement every member one by one.
class aA : A {
override val b : String /// ARRRG -- DOUBLE ARG because I now need an initializer too !!!!
}
EVEN IF all I am doing is using a data binding library like Jackson
val aaa : A = objectMapper.readValue<aA>( file)
IF one has a very flat or simple set of classes its not bad -- data classes are great --
data class A( val b: String )
that even works with no initializer with jackson ( val a = objectMapper.read<A>(file) )
But the second one needs variants or extensions ( particularly if in seperately compiled projects -- like a api impl + interface)
as soon as you need any kind of class derivation the problem explodes --
Even the wonderful class delegation -- REQUIRES BOTH an interface and a concrete class just to delegate yet a third class ...
class X(a : A ) : A by a // Beautiful !!! EXCEPT
you need now at minimum 2 classes fully and redundantly implemented, often more.
interface A { ... blah }
class aA : A { override every member AND at least 1 constructor AND provide all initializers }
then usuually
class bA: A { otherwise why are you using derivation ? unless you have atleast 1 variant }
So now the beautiful 1 liner 'poster child' for all thats wonderful about Kotlin --
is totally shattered into a mess and tossed on the floor (metaphorically )
That is just so philosophically painful I cannot help but try to find a remedy -- something OTHER then 'spring' which brings too much its own pain :)
So .. as a 'fascinating puzzle' -- I can now write code like this ( not quite perfect yet -- but satisfying even if I dont actually do it :)
interface A { any number of members defined ONCE }
....
val a : A = configure {
from( systemDefaults )
from( userProvidedConfigFile )
with( optionalyProvidedMapOrObjectToFillInMissingBits )
}
done.
or with the proper 'conventions' (i.e. vast amount of code ELSEWHERE :)
val a = configure<A>{ with( appDefaults ) }
editableForm<A>( a ) {
title("Awesome Dynamicaly generated Form from Only an Inteface" )
}
.
The NEXT STep -- get the interface definition dynamically from some outside source -- like a openAPI spec, json/xml schema, introspection of a CSV file's headers --
Or simply from a manually created interface
At development time -- with IDE support.
that boils down to some form of source (or .class ) generation in realtime as you author.
A simple but painfuly illusive variant of this -- when you want a class that expoes val or var differently to differnt consumers. A common case is to AVOID the above magic configure( ) function and allow 'constructor like' syntax in source but on a immutable class.
Essentially what the copy() method does -- but not limited to data classes or initial constructor calls -- taking a partially created object and adapting or completing it.
Or simply where an internal /private class could make use of a 'var' in a type safe encapusualted way but only expose 'val' -- without having to implement parallel/redundant classes and a bunch of boilerplate copy code
Hi,
I got here by following a link on Karibu's GitHub page (https://github.com/mvysny/karibu-testing). Is this room also for Karibu testing?
Overload resolution ambiguity:
public inline fun HorizontalLayout.content(block: HorizontalLayoutContent.() -> Unit): Unit defined in com.github.mvysny.karibudsl.v10
public inline fun HorizontalLayout.content(block: HorizontalLayoutContent.() -> Unit): Unit defined in com.github.mvysny.karibudsl.v10.