Subject: [Cbor] Money amounts

From: Changaco <[email-masked]>
Date: Mon, 25 Feb 2019 10:28:21 +0100

Hello everyone,

I've started using tags 77111 and 77112 for money amounts and written a spec for them: https://liberapay.github.io/specs/cbor-money.html

I hadn't seen the previous proposal <https://j-richter.github.io/CBOR/currency.html> but it's different from mine so I think the two are complementary. That said tags 165 and 77111 do represent the same thing so 77111 could be abandoned if 165 is extended to support more use cases.

P.S. The form to register new tags is the one in <https://www.iana.org/form/protocol-assignment>, right?

---
Charly C. / @Changaco

---

From: Carsten Bormann <[email-masked]>
Date: Mon, 25 Feb 2019 10:41:14 +0100

Hi Charly,

What is the difference between a 77112 basket with just one currency in it and a 77111 money?

(I’m not a big fan of having to parse the string version of 77111, but if that string style is important to your application, that’s not relevant.)

You never have the use case of an alternative (like 77112, but “either pay USD 25 or EUR 20 or CAD 30 or AUD 35”)?

Grüße, Carsten

> On Feb 25, 2019, at 10:28, Changaco <changaco=[email-masked]> wrote:
> 
> Hello everyone,
> 
> _______________________________________________
> CBOR mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/cbor
>

---

From: Changaco <[email-masked]>
Date: Mon, 25 Feb 2019 11:44:18 +0100

> What is the difference between a 77112 basket with just one currency in it and a 77111 money?

We use baskets when summing amounts that *can* be in different currencies, but in fact there may only be one currency, or none at all, so the basket can end up containing only one currency or be completely empty.

I put an example of a basket with only one currency to show that it is valid.

> (I’m not a big fan of having to parse the string version of 77111, but if that string style is important to your application, that’s not relevant.)

It's not really important, I added it mostly because for some "small" amounts it can actually be shorter than other formats.

For example `"EUR10.00"` takes up 9 bytes whereas `["EUR", 10.00]` uses 11 bytes when the number is encoded as a decimal fraction (tag 4).

> You never have the use case of an alternative (like 77112, but “either pay USD 25 or EUR 20 or CAD 30 or AUD 35”)?

No.

---

From: Richter, Jörg <[email-masked]>
Date: Mon, 25 Feb 2019 11:06:57 +0000

> > (I’m not a big fan of having to parse the string version of 77111, but
> if that string style is important to your application, that’s not
> relevant.)
> 
> It's not really important, I added it mostly because for some "small"
> amounts it can actually be shorter than other formats.
> 
> For example `"EUR10.00"` takes up 9 bytes whereas `["EUR", 10.00]` uses 11
> bytes when the number is encoded as a decimal fraction (tag 4).

And I'm not a big fan of encoding additional information in the number of 
decimal places.  So "EUR10.00" should be transmitted as "EUR10", or ["EUR",10].
But for other decimal fractions you are right that the string might be shorter.

Isn't this a use case for the additional attributes map?  To encode the 
number of decimal places that should be used (e.g. for display).  What
other applications do you have in mind for the attribute map?
Can some common attributes be included in the proposal?

If there is consensus I can include your extensions into my proposal for tag 165.

- Jörg

---

From: Changaco <[email-masked]>
Date: Wed, 27 Feb 2019 13:41:13 +0100

> But for other decimal fractions you are right that the string might be shorter.

I think it's best to be lossless by default. If an encoder receives a `10.00`, for example a `Decimal('10.00')` object in Python, then it should encode the trailing zeroes unless it has been explicitly configured to drop them.

> Can some common attributes be included in the proposal?

So far I've only used the attributes map to store a `fuzzy` flag, like the example I put in the spec. When that flag is on the messages we display to users mention that the amount is approximate.

---

From: Carsten Bormann <[email-masked]>
Date: Wed, 27 Feb 2019 13:49:12 +0100

> I think it's best to be lossless by default. If an encoder receives a `10.00`, for example a `Decimal('10.00')` object in Python, then it should encode the trailing zeroes unless it has been explic…

But that presumes there is a semantic difference between “EUR10” and “EUR10.00”.  Is there is there not?

Assuming there is no semantic difference, we could still make it so that an encoder can output both, and a decoder is required to be able to process both, presumably with an identical result.  Or we could use the concept of “preferred encoding” with that, with making the shortest encoding the preferred one, but not placing the onus on the encoder to always generate preferred encoding (outside instances of canonicalization), but continuing to place the onus on the decoder to handle both, but *not* placing the onus on it to keep the distinction available to the application.

Interoperably handling equivalent representations of the same information has turned out to be more laden with consequences than one would initially think…

If there *is* a semantic difference, it should be clearly explained, or even better, made more explicit in the encoding.

Grüße, Carsten

---

From: Richter, Jörg <[email-masked]>
Date: Wed, 27 Feb 2019 14:01:00 +0000

> I think it's best to be lossless by default. If an encoder receives a
> `10.00`, for example a `Decimal('10.00')` object in Python, then it should
> encode the trailing zeroes unless it has been explicitly configured to
> drop them.

Then this problem is independent of money amounts.  But I am not sure if
CBOR allows 4([-2,100]) and 4([-1,10]) and 1 to have different semantics.

If this should be the case for money amounts than we should use the map
to store the number of digits (or the exponent).

- Jörg