Skip to content

Instantly share code, notes, and snippets.

@rlmark
Last active December 19, 2018 22:47
Show Gist options
  • Save rlmark/d5ae3c4897cd6b58133f4fa945333734 to your computer and use it in GitHub Desktop.
Save rlmark/d5ae3c4897cd6b58133f4fa945333734 to your computer and use it in GitHub Desktop.
Updates/NeedAdvice

Updates / Seeking advice! Dec 18

Hi Muniverse, apologies for the delay, yesterday was our Seattle office party and I didn’t have as much time to try out the Traverse solution that Juan Pedro suggested. I’ve implemented a traverse function for ProtobufF and still run into the stack overflow error. (I also tried the @deriveTraverse annotation, which is way cool! But it also resulted in the stack overflow.) I’m analyzing the difference between the code that Juan Pedro suggested in my minimal repro app and the actual code and 1 big thing sticks out as a problem.

In the Skeuomorph code, TRepeated is constructed with a value of type A. This makes sense, TRepeated should contain some type which repeats, which could be another Message or just a primitive type, like a String.

Here’s a loose representation of the structure we have:

`BaseDescriptor`  ==========(Coalgebra)==========> `ProtobufF[A]` 

           ||
           ||
      (is parent of)
           ||
           \/
     
`FieldDescriptor` ====(Branch of match statement)===> `TRepeated[A](value: A)` AND Some primitive like `TString[A]()`

So in effect we have one source type, FieldDescriptor that needs to be used to generate a TRepeated(fieldDescriptor) and the primitive corresponding to its type, i.e. TString()

I’m fairly confident this is the source of the non terminating loop in my code, and I’m not sure how to fix this.

Why is TRepeated important (Aka why I am I spending so much time on this):

  • This is what would represent a List[SomeType] in Scala code generation, so we probably can’t leave the code as is, downgrading everything to a non-list type.

Several (bad but creative) ideas:

  • Remove TRepeated as a class altogether and instead represent whether a field can be repeated on the primitive (leaf) nodes of the ProtobufF ADT. This would, however, push the responsibility of printing whether a type is a scala List to all the corresponding leaf nodes in the MuF ADT.
  • Remove TRepeated as a class and represent whether a field can be repeated as a boolean on the Field class. This would also change MuF’s Field class and the printing syntax, which might break our existing Avro implementation.
  • Some sort of depth counter for the transformation from a BaseDescriptor to a ProtobufF so we can conditionally decide which class to transform our FieldDescriptor into.
  • Some other thing?

Slightly better ideas (a post-lunch edit):

  • Let's say we can't directly read a FieldDescriptor into two types: TRepeated and the primtive types like TString. Maybe that's not how our domain can be modeled given the constraints, but that is ok, because we do have the ability to provide micro-optimizations when operating in MuF (or ProtobufF for that matter.) Perhaps we can provide a natural transformation from MuF ~> MuF or ProtobuF ~> ProtobufF such that we can still get the desired String representation of the repeated field.

Anyways, sorry for the novel. Thanks for reading!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment