Hy!
I have language-primitives, and language-renderers. Some of the renderers has Renderable[A] to some type of primitives, but sadly other renderers has not. (For example Cube
is a primitive, and the OpenscadRenderer can render it, but it is possible that some other renderer can not.)
Now I have 2 interfaces:
trait Renderable[A] {
def render(s: A, indent: Int): String
}
trait RenderableForOps {
type INNER
val a: INNER
val fa: Renderable[INNER]
override def toString: String = a.toString
def render(indent: Int): String = fa.render(a, indent)
}
And ~2 types of primitives:
case class Sphere(radius: Length)
case class Union(objs: RenderableForOps*)
(Yes this will be a huge tree of RenderableForOps
in the memory.)
The problem:
If I want to describe a model with this language without defining the final Renderer
, my functions look like this:
def clipcut(layerheight: Double)(implicit ev1: Renderable[Cube], ev2: Renderable[Translate], ev3: Renderable[Union], ev4: Renderable[Rotate], ev5: Renderable[Polygon], ev6: Renderable[Extruded[Polygon]], ev7: Extrudable[Polygon]): RenderableForOps = {
Any idea how can I “automatically” generate the needed implicits to the function header? Or how can I cut off this huge boilerplate? Or move it to a new, less long syntax?
I thought about rewriting the evs to sth like def ... (implicit ev: Renderable[ClipCut]) = { import ev._
but for this I still need to write and manage a lot of implicits by hand, I want more implicit implicits
I have some code if you need it to understand the problem better (not cleaned mostly experimental):
Any idea about how I can move forward with this concept? The problem is that both the primitives and the renderers should be easily extendable. (My core problem came from the scadla repo, bcs I wanted to add new solids to the language, and for that, I needed to add the new solid to “random” places.)