scala / pickling

Fast, customizable, boilerplate-free pickling support for Scala
lampwww.epfl.ch/~hmiller/pickling
BSD 3-Clause "New" or "Revised" License
831 stars 79 forks source link

Force generation to create (un)picklers together #412

Closed jvican closed 8 years ago

jvican commented 8 years ago
jvican commented 8 years ago

Also, it's worth mentioning the fact that we reduce considerably the sourcegen code (by 2/3), which is good for future maintainability of the project.

jvican commented 8 years ago

I've discovered some issues with this PR, don't merge (yet) please.

jsuereth commented 8 years ago

Yeah, the sourgen reduction is nice. I like where we're going. a few notes:

  1. Either in this PR (or open a ticket so we remember): We should update the runtime registry of picklers/unpicklers so that it works on PicklerUnpicklers rather than the individual ones. This includes generating both when we need runtime creation of picklers.
  2. we should get a name for PicklerUnpickler

In any case, great work! Really awesome to see all these cleanups!!

jvican commented 8 years ago

This can already be merged, but there's no way to share/reuse already generated picklers/unpicklers so far and I don't know if it's going to be possible either. Implicits never get out of the scope. The only way to reuse them is this one:

implicit val pu = PicklerUnpickler.generate[T]

Note the implicit keyword in the definition of pu. This only can be done in concrete cases. Currently, the way the algorithm proceeds is super inefficient, since it's creating (un)picklers for every call site, and repeating the generation of a LOT of picklers/unpicklers (including the nested ones). However, it's not sure if there's another alternative.

My last commit explains how exposing an AnyPickler speeds up the compilation time by 40% in my computer (the generation of a pickler for any is crazily requested when compiling the test suite). However, there's room for improvement, and we should try something to reuse the generated picklers/unpicklers.

jsuereth commented 8 years ago

Agree on having AnyPickler be there by default. I think because we DON'T have contravariant picklers and covariant unpicklers (by necessity) this is fine.

Relating to avoiding generating the code, for PicklerUnpickler.generate, the implicit bit is the best we can do.

At some point I'd love to be able to have something like:


sealed trait Bar
@Autopicklers object Bar

@Autopicklers
final case class Foo....

Where we can autogenerate the implicit val for the type. Right now though, I think having implicit-val in companion obejcts isn't the worst.

jsuereth commented 8 years ago

If you think you're ready on this PR, it's good t merge. Looks good!

jvican commented 8 years ago

Yes, that's exactly what I thought, the only way AnyPickler could be chosen is if it we explicitly pickle something which is Any. And it that's the case, it's the user's fault.

Yes, let's merge this, I'll move this conversation to a ticket so that we can make a serious/formal proposal.

jvican commented 8 years ago

BTW, I was also thinking about that macro annotation. It's a great idea although it changes the design and the API. But we would really get good improvements. Right now, the code size is bloated of unnecessary repetitive picklers/unpicklers.