စံကား

01The language

Conversions

Turn a value of one kind into another - the conversion expression, which pairs convert, what happens to the value, and the widening that needs no words.

A value of one kind can take the place of another kind through two means. A conversion is written out: the program names the kind it wants and the value is changed to fit. A widening happens with no words, but just where the new kind holds each value of the old one. Each other change of kind is an error.

The Learn chapter shows conversions with gentle examples. This page gives the rules.

The conversion expression

<value>  ကို  <kind>  အဖြစ်  ပြောင်းလဲသော ရလဒ်
 operand      target kind        the verb

It reads "the result of changing the value into the kind". The verb ပြောင်းလဲသော ရလဒ် closes a clause: the value takes ကို and the kind takes အဖြစ်. The result has the target kind, and it can take a particle of its own, so a conversion can be the first part of a longer phrase.

စံကား

Expected output

၂.၀
၄.၅
၀.၅

A conversion is a clause, so inside a sum written with signs it needs parentheses, as the third line shows. A conversion to the kind that the value has changes nothing. The compiler works out a conversion of a constant.

Which pairs convert

A conversion is allowed between the pairs below, and in no other pair (ZK0408):

From \ Tointegerdecimal numberစာလုံးမှန်မှားတန်ဖိုး
integerallowedallowedallowedrefused
decimal numberallowedallowedrefusedrefused
စာလုံးallowedrefusedallowedrefused
မှန်မှားတန်ဖိုးallowedrefusedrefusedallowed

An integer is never turned into a true/false value. Test it with a comparison instead: n != ၀. Conversions between addresses and integers, and between pointer kinds, have rules of their own, in Pointers. A list never converts.

စံကားZK0408

Expected error

error[ZK0408]: cannot convert isize to bool

What happens to the value

A conversion is the one place where Zaka changes a value without an error, even if the new kind cannot hold the old value. Each pair has one fixed rule.

FromToRule
integerintegerthe low bits are kept; the sign is read again in the new kind
integerdecimal numberthe nearest value; big integers lose their low digits
decimal numberintegerthe fraction is dropped toward zero; a value outside the range becomes the smallest or the largest of the kind; NaN becomes ၀
decimal numberdecimal numberthe nearest value; one too large becomes inf
စာလုံးintegerthe code point, cut to the width as an integer is
integerစာလုံးthe character with that code point; a value that is no Unicode scalar value (negative, a surrogate, above 10FFFF) gives U+FFFD
မှန်မှားတန်ဖိုးinteger၁ for မှန် and ၀ for မမှန်
စံကား

Expected output

၄၄
၂၅၅
-၅၆
၄၂၉၄၉၆၇၂၉၅
၃
-၃
၀
၉၂၂၃၃၇၂၀၃၆၈၅၄၇၇၅၈၀၇

Going from an integer to a wider kind keeps the value: a signed integer is extended with its sign, an unsigned one with zeros. Going to a narrower kind cuts the high bits, which gives ၃၀၀ the result ၄၄ (300 - 256) in a လက္ခဏာမဲ့ ၈ ဘစ် ကိန်းပြည့်.

Characters, true/false values and decimal numbers of other widths:

စံကား

Expected output

A
၄၀၉၆
၀
၀
၁၆၇၇၇၂၁၆.၀
၁.၀၉၉၆

Widening: the change that needs no words

A value goes into a place of another kind with no conversion just when the place's kind holds each value of the value's kind. The places are the initial value of a declaration, the new value of an assignment, an argument, a returned value, and the operands of an operator (the next section). The cases:

FromToWhen
integerintegerthe target is wider and no sign is lost: signed to wider signed, unsigned to wider unsigned, unsigned to wider signed
integerdecimal numberthe integer's width is at most the bits of the float's significand: 11 for f16, 24 for f32, 53 for f64, 113 for f128
decimal numberdecimal numberthe target is wider

So u8 goes into i16, i16 into f32, i32 into f64, and f32 into f64. These do not widen: signed to unsigned, a narrower target, isize or usize (64 bits) into f64, i32 into f32, and isize into i64 (the two kinds are the same width but differ). A စာလုံး and a မှန်မှားတန်ဖိုး never widen. An address widens to the address kinds described in Pointers and to nothing else.

စံကား

Expected output

၂၀၀
၂၀၀.၀
၂၀၀.၀

A widening that is missing is ZK0401, which names both kinds and suggests the conversion:

စံကားZK0401

Expected error

error[ZK0401]: expected f64, found isize
 = help: convert the value with "ကို <kind> အဖြစ် ပြောင်းလဲသော ရလဒ်"

Mixing kinds in an operation

An operator with two operands joins them as follows (see Expressions).

  • If both have one kind, the result has that kind.
  • If one kind widens to the other, the narrower operand is widened first and the result has the wider kind: u8 + i16 is an i16.
  • If neither widens to the other, there is no common kind and the program does not compile (ZK0404). A signed and an unsigned integer of one width are such a pair.

A literal without a kind prefix takes the kind of the other operand, so က + ၁ with a u8 named က adds a u8. When both sides are literals, a fraction or an exponent in either makes both of them decimal numbers: ၃ + ၀.၅ is ၃.၅. A literal that does not fit the kind it must take is ZK0406.

စံကားZK0404

Expected error

error[ZK0404]: cannot combine i8 and u8 without a conversion
စံကားZK0406

Expected error

error[ZK0406]: the literal 300 does not fit i8

Convert one side to join two kinds that do not widen:

စံကား

Expected output

၂၀၅

Errors in one table

CodeRaised when
ZK0401a value of the wrong kind goes into a variable, parameter or result
ZK0403an operator gets an operand it does not take, such as မှန် + ၁
ZK0404the two operands of an operator have no common kind
ZK0406a literal does not fit the kind that its place gives it
ZK0408a conversion between two kinds that cannot convert