koinos / koinos-types

The Rosetta Stone of the Koinos ecosystem. Allows for the interpretation of Koinos data structures in a multitude of languages. Useful in the development of microservices, clients, and smart contracts.
MIT License
12 stars 3 forks source link

Golang Opaque Problems #128

Closed mvandeberg closed 3 years ago

mvandeberg commented 3 years ago

I recently added a method, SetBlob() to Opaques that allows setting the blob of an opaque type (as the name suggests).

During the review of this PR, I was asked if C++ had a similar method to keep the interfaces identical. C++ does allow setting an opaque to a variable blob via a constructor overload. Golang does not support constructors nor overloads.

However, while the methods are named similarly between C++ and Golang, the semantics are critically different due to language differences.

Opaque have three states, boxed, unboxed, and mutable. In C++, when the opaque is boxed, only the variable blob is accessible, when unboxed, a const reference to the native type is accessible, and when mutable, a non const reference.

The problem with the golang implementation is that there is no concept as const pointers, so the unboxed state is more or less useless. Returning a pointer to the underlying native type cannot prevent modification.

The opaque was designed to wrap a type that may be updated later, allowing it to be passed around as a blob. However, there is still code designed to create/read opaques that are annoying to write with the wrapping. The two scenarios we need to address are:

  1. Read the opaque as a native type
  2. Create an opaque as a native type

Golang currently only supports the first mode of operation and half of the second. Via GetNative individual fields can be set, but there is no way of creating an opaque wrapping an existing native object.

I reject matching the C++ interface as a reason to have pointless code in Golang's opaque since the semantics of the interface is already different because of the language.

I propose simplifying the implementation of Golang Opaques with the following changes:

  1. Remove the "Unboxed" state and rename "Mutable" -> "Unboxed".
  2. Remove SetBlob
  3. Add New*FromBlob, New*FromNative factories.