Skip to content
About
Main content

Type promotion versus coercion

Which type changes are provable widenings, and which are lossy parsers dressed as casts?

These two are often confused. They are not the same kind of thing.

Promotion is a widening that is total and value-preserving over the old domain. Examples: int32 to int64, float32 to float64, date to timestamp, fixed-length string to variable-length string. It is legal exactly when it is and total. It can be checked by a machine, and it is safe to automate.

Coercion is a read-time conversion applied when the types do not match. It may lose information, and what happens on failure is a policy choice: return , raise an error, or truncate. This is "masking moves failure to a channel with no schema" in a small form: a type error is converted into a value, and a value carries no error channel. Automating means choosing silence.

Edges worth knowing

  • Decimal precision can widen safely. A change of scale (digits after the decimal point) rescales every existing value. A value stored as 1234 with scale 2 means 12.34. Read with scale 3 and no rescale, it means 1.234.
  • Float and decimal are not injective in either direction. The round trip through the other type is not the identity.
  • String to numeric is a locale-dependent parser, not a cast. ("1,234" is one thousand two hundred thirty-four in one locale and a number with a decimal comma in another.) Calling it a cast is how you get nulls in a revenue .
  • Timestamp milliseconds to microseconds is a widening. Microseconds to milliseconds truncates data that you already wrote.
  • Signed and unsigned integers of the same width (for example int32 and uint32) have disjoint domains: each has values the other lacks. Neither direction is a promotion.

Promotion is a provable widening; . Only one of them belongs in an automatic path.