Simpler Preserves Binary Syntax

I’ve just updated the Preserves spec to version 0.990.0. I feel like a 1.0-rc is approaching!

The main change since spec version 0.7.1 has been to simplify the binary syntax for Preserves Values:

  • Both “short” and “medium” SignedInteger representations (starting with tags 0x9x/0xAx) were removed. They weren’t pulling their weight. Every SignedInteger now has tag 0xB0.

  • Float and Double are now encoded with tag 0x87 and a length, rather than with fixed tags 0x82 and 0x83, opening the door to other IEEE754 formats in future.


Here’s the 0.990.0 syntax in “reference card” format, where we write «V» for the binary encoding of some value V:

                      «#f» = [0x80]
                      «#t» = [0x81]

                    «@W V» = [0x85] ++ «W» ++ «V»
                     «#!V» = [0x86] ++ «V»

  «V» if V ∈ Float         = [0x87, 0x04] ++ binary32(V)
  «V» if V ∈ Double        = [0x87, 0x08] ++ binary64(V)

  «V» if V ∈ SignedInteger = [0xB0] ++ varint(|intbytes(V)|) ++ intbytes(V)
  «V» if V ∈ String        = [0xB1] ++ varint(|utf8(V)|) ++ utf8(V)
  «V» if V ∈ ByteString    = [0xB2] ++ varint(|V|) ++ V
  «V» if V ∈ Symbol        = [0xB3] ++ varint(|utf8(V)|) ++ utf8(V)

           «<L F_1...F_m>» = [0xB4] ++ «L» ++ «F_1» ++...++ «F_m» ++ [0x84]
             «[X_1...X_m]» = [0xB5] ++ «X_1» ++...++ «X_m» ++ [0x84]
            «#{E_1...E_m}» = [0xB6] ++ «E_1» ++...++ «E_m» ++ [0x84]
     «{K_1:V_1...K_m:V_m}» = [0xB7] ++ «K_1» ++ «V_1» ++...++ «K_m» ++ «V_m» ++ [0x84]

                 varint(v) = [v] if v < 128
                             [(v & 0x7F) + 128] ++ varint(v >> 7) if v ≥ 128