When compiling to Michelson, LIGO must choose a "layout" for record
and variant data types. Unfortunately, Michelson only has binary
pair
/or
types, for esoteric theoretical reasons.
This means that for each record or variant type, LIGO must pick one of the many isomorphic binary tree structures which can represent it in Michelson. This choice needs to be consistent (else we will get type errors) and ideally it should be flexible (so that users can interoperate with Michelson types defined in standards or emitted by other compilers.)
Background
In early versions of LIGO, two layouts were supported: tree
and
comb
.
Layout tree
was made the default, primarily because this layout
supports record field access and update with cost O(log n), where n is
the number of fields in the record type. This layout also sorted
fields alphabetically by name, which made it compatible with LIGO's
structural handling of record and variant types at the time, where
order doesn't matter.
The tree
layout was also used for tuple types, and originally this
could not be changed.
The comb
layout was also supported because it was expected that it
would show up in standards and in interop with Michelson generated by
other compilers (and indeed it did.) At some point, LIGO was modified
to preserve the order of comb layout record fields and variant cases,
since this is useful for interop. (The order now also matters for
these types; two comb-layout record types are equal in LIGO only if
their fields are in the same order.)
Originally, the comb layout had worse performance, with cost O(n) for record field access and updates.
Why change the default?
Since then, Michelson has added native O(log n) record field accesses
and updates with the comb
layout. Additionally, there is an n-ary
pair x y z ...
notation for comb layout, which makes large comb pair
types cheaper and more readable.
Thus, current best practice is for LIGO developers to almost always
mark record and tuple types as @layout comb
. This generally leads to
smaller code size, and so less gas and storage burn.
It would be more convenient if this were the default. Unfortunately, changing the default is a breaking change. But with 1.0, we are taking the chance to finally make this breaking change...
Variant types still do not have any special comb support in Michelson
(again, for esoteric theoretical reasons.) However, for consistency
and simplicity, we are making comb layout the default always. We
believe that in most cases, the difference will not be
significant. Users can explicitly mark variants as @layout tree
if
desired.
What do I do?
See the How to deal with the change of the default datatype layout to @layout comb
? doc for advice on how to deal
with this breaking change.