groostav
03/01/2023, 10:50 PMval domainRelevantKey = Root / HighDomainTerm / MediumDomainTerm / LowDomtainTerm("runtime value!") / OptionallyAFeature
which would be a kind of key for use in our application. As you can imagine by its pathy-ness this kind've imposes a hierarchy on my app, which is what im looking for.
I did get this... with a boatload of pretty strange code:
https://gist.github.com/Groostav/68234f5ab6d5582b182990c16b548db8
Some pros:
- use of static symbols like this means spelling mistakes become compiler errors (where if I'd used some more dynamic things involving strings, I'd likely see misbehaviors that given my usage would be difficult to find in tests)
- its likely going to be pretty readable; anybody reading val relevantSection = Root / Model / ...
is going to understand its usage.
- its reasonably extensible in as far as java-with-boilerplate is extensible, in that you can copy-paste-change and have it likely work for your purposes.
some cons:
- nobody will ever understand my inheritance scheme, I'm pretty sure I wont in 3 months.
- each new symbol/domain concept requires more code. A purely dynamic solution wouldn't have this problem --except of course at callsites.
- seems pretty overbuiltephemient
03/01/2023, 10:53 PMephemient
03/02/2023, 1:29 AMimport Level1.*
, import Level2.*
, etc. but if we had context-sensitive resolution, the compiler could pick those up without additional namespace pollution
interface PathSegment<Child>
sealed interface Path<Last : PathSegment<*>> {
val segments: List<PathSegment<*>>
}
data class Nested<Last : PathSegment<*>>(val parent: Path<*>, val child: Last) : Path<Last> {
override val segments: List<PathSegment<*>>
get() = parent.segments + child
}
object Root : Path<Root>, PathSegment<Level1> {
override val segments: List<Nothing>
get() = emptyList()
}
enum class Level1 : PathSegment<Level2> {
HighDomainTerm, // ...
}
enum class Level2 : PathSegment<Level3> {
MediumDomainTerm, // ...
}
sealed class Level3 : PathSegment<Level4> {
data class LowDomainTerm(val string: String) : Level3()
// ...
}
enum class Level4 : PathSegment<Nothing> {
OptionallyAFeature, // ...
}
operator fun <Last : PathSegment<Child>, Child : PathSegment<*>> Path<Last>.div(child: Child): Path<Child> = Nested(this, child)
(Root / HighDomainTerm / MediumDomainTerm / LowDomainTerm("runtime value!") / OptionallyAFeature).segments ==
listOf(Level1.HighDomainTerm, Level2.MediumDomainTerm, Level3.LowDomainTerm("runtime value!"), Level4.OptionallyAFeature)