- Notifications
You must be signed in to change notification settings - Fork3.8k
Open
Description
Up to this point weve been using a lot of datastructures without an explicit schema. For example, look at the following event.
typedstructenforce:true,module:ResultEventdofield(:tx_id,binary())field(:vm_result,Mempool.vm_result())end
The fields have a type, but that it is. If the shape of a vm_result changes at any point we will have to find all the types of these things in the codebase. This means:
- Functions that pattern match on
{:ok, noun}
or have{:ok, Noun.t()}
in their typespec. - Functions that craft these values manually
- Structs that use these types
What I propose is to use structs whenever it makes sense. This makes it easier to use protocols/implementations for any value like this.
For example, we could haveVmResult
struct.
typedstructVmResultdofield(:noun,Noun.t())field(:status,:error|:in_progress)end
This has several advantages.
%VmResult{}
will always be enforced to have all the values, if wanted.inspect(vm_result)
can be implemented to print the noun truncated, or something.- Adding fields to the VmResult is trivial and does not require changes in the codebase that the compiler will not catch.
- There are no duplicate typespecs in the codebase saying that a vm_result is
{:ok, Noun.t() | :error | :in_progress
. This is very much the case forvm_result
andtx_result
right now.
I don't want to refactor the whole codebase, but I do want to start of a discussion, or at least make everyone aware of technical debt that this approach can introduce.
Metadata
Metadata
Assignees
Type
Projects
Status
TODO