(a few days ago there was some lively discussion about relaxing type requirements for array indices which the forums seem to have lost, so this is my attempt to restart that discussion.)
it’s well known that swift is opinionated about standardizing on
Int as an index type, which is why we cannot directly subscript
UInt8, etc. i don’t really disagree with this idea in general; i’ve always hated how C brackets all the integer types.
but there is one downside to
Int, compared to say,
Int32, in that
Int has a huge stride: 8 bytes!
obviously, there are a lot of situations where this is not a problem at all:
Intuses more memory that
Int32, but it’s highly uncommon for
Intitself to be your memory bottleneck, so using
Intfields for in-memory structures is usually okay.
Intcan use a lot more storage than
Int32when serialized to a text-based format like JSON, but it almost never does, because JSON is a variable-length encoding:
uses the same amount of storage regardless of original bit width. so serializing
Intto JSON is usually okay.
Int is good for in-memory stuff, and
Int is good for JSON-encoded stuff.
Int is not good for binary-serialized stuff, like BSON, because BSON is a fixed-length encoding, and always uses 8 bytes to encode
Int, which is twice as much storage as it uses to encode
i suppose one thing we can do is to use
Int exclusively from the swift side, and narrow the
Int32 when encoding to BSON. but now we’ve lost the compile-time guarantee of not trapping/throwing on encode, and (unlike decoders), encoders are not supposed to trap, or really, fail at all.
another approach could be to implement a more intelligent encoding + decoding strategy for these
Int-typed fields, that encodes
Int32 if it fits, and
Int64 otherwise. but this adds a lot of complexity to the encoding + decoding logic just to serialize a simple
Int field. MongoDB is totally cool with this (it brackets
Int32 when executing queries), but it’s a nightmare to handle in the strongly-typed swift world, because you have taken something that was a scalar type in your database schema, and turned it into a sum type with two cases.
i could also use a property wrapper to make the
Int32 “look like an
Int”, but this presents some challenges for algorithms that mutate the field, and if we really think about it, making the
Int32 behave like an
Int is a non-goal, the only reason we are pretending it is an
Int is to be able to subscript an
Array with it.
what are we to do about