0

During my involvement of an project that heavily relies on type-checked binding with Schematic data. I found many of the existing code share the following pattern:

case class Datum1(
  col1: String = "default",
  col2: Double = 0
  ... (over 40 columns)
)

case class Datum2(
  col1: String = "default",
  col2: Double = 0
  ... (over 40 columns)
)

case class Datum3
...

Obviously I would regard most of it as boilerplate, and ideally they should be rewritten to facilitate fast evolution of database schema. The closest implementation I could think of is:

case class SharedSchema(
  col1: String = "default",
  col2: Double = 0
  ... (over 40 columns)
)

case class Datum1(
  schema: SharedSchema
)

case class Datum2(
  schema: SharedSchema
)

case class Datum3
...

When the same call-site function Datum1(col2 = 1) is used, it should be rewritten into Datum1(SharedSchema(col2 = 1)) by the compiler.

I haven't seen any compiler feature or extension capable of doing this. What's the minimal work required to implement it?

Dmytro Mitin
  • 48,194
  • 3
  • 28
  • 66
tribbloid
  • 4,026
  • 14
  • 64
  • 103
  • 1
    https://www.optics.dev/Monocle/ – Dmytro Mitin Feb 08 '23 at 23:37
  • Thanks a lot professor, I assume you are referring to Iso specifically: https://www.optics.dev/Monocle/docs/optics/iso – tribbloid Feb 09 '23 at 02:29
  • ... wait, I searched across all document pages and none mentioned "default argument", may I ask for elaboration? – tribbloid Feb 09 '23 at 02:49
  • 1
    Well, I was thinking just about lenses. I understood your question so that you're looking how to simplify access to nested fields. That's what lenses (and their composition) do. Lenses should work in absence or presence of default values. I can't see that you're doing anything specific to default values. You seem just to transfer all the fields (with their default values) to a different case class. Did I misunderstand your question? – Dmytro Mitin Feb 09 '23 at 06:28
  • I am: the `Datum1(col2=1)` should already use the default value (col1="default") – tribbloid Feb 09 '23 at 17:44
  • 1
    Besides lenses, maybe also `Dynamic` can help https://scala-lang.org/api/3.x/scala/Dynamic.html https://docs.scala-lang.org/scala3/reference/changed-features/structural-types.html#relation-with-scaladynamic https://stackoverflow.com/questions/74549477/scala3-crafting-types-through-metaprogramming – Dmytro Mitin Feb 09 '23 at 18:35
  • Yes that would be my solution a long time ago. But using dynamic effectively reduce it to schemaless which makes binding at compile-time almost impossible – tribbloid Feb 09 '23 at 18:53
  • I guess I'm just looking for something in-between, like this feature added into typescript: https://github.com/Microsoft/TypeScript/pull/24897. Wondering if a Scala macro would allow me to do it – tribbloid Feb 09 '23 at 18:57
  • 1
    *"using dynamic effectively reduce it to schemaless which makes binding at compile-time almost impossible"* Well, if you implement `applyDynamic`/`selectDynamic` with runtime reflection then surely it does but if you implement them with macros this was ok at least in Scala 2 https://github.com/milessabin/shapeless/blob/v2.3.10/core/src/main/scala/shapeless/hlists.scala#L102-L116 https://github.com/milessabin/shapeless/blob/v2.3.10/core/src/main/scala/shapeless/hlists.scala#L187-L282 https://github.com/milessabin/shapeless/blob/v2.3.10/core/src/main/scala/shapeless/singletons.scala#L63 – Dmytro Mitin Feb 10 '23 at 01:59
  • 1
    I guess you're also aware of Scala 3 `Selectable` – Dmytro Mitin Feb 10 '23 at 02:01
  • https://stackoverflow.com/questions/73624815/how-to-validate-field-path-in-compile-time-in-scala-2 – Dmytro Mitin Feb 21 '23 at 16:49

0 Answers0