Subject: [Cbor] Explicitly define the CBOR data model

From: Carsten Bormann <[email-masked]>
Date: Wed, 27 Sep 2017 16:39:20 +0200

Jeffrey Yasskin has proposed to write some text for CBORbis that explicitly defines CBOR's data model:

https://github.com/cbor-wg/CBORbis/issues/2

I have now written a draft for such a section, available at:

https://github.com/cbor-wg/CBORbis/blob/master/datamodels.md

* Do we want to have such a section?
* Is the proposed text the right one?

Grüße, Carsten

---

From: Jeffrey Yasskin <[email-masked]>
Date: Wed, 27 Sep 2017 09:58:55 -0700

Thanks! Your text looks good except for one inconsistency:

"Note that integer and floating-point values are distinct in this model,
even if they have the same numeric value." is inconsistent with "For the
purposes of this specification, all number representations for the same
numeric value are equivalent." in
https://cbor-wg.github.io/CBORbis/#rfc.section.3.6. This will interact with
canonicalization: If 0 is equivalent to 0.0, then canonicalization has to
map integral floating point values to their integer representations, to
preserve the fact that canonicalization makes duplicate map keys easy to
identify. This also leads to a question of whether small BigInt,
BigDecimal, and BigFloat values are equivalent to integer and floating
values.

Jeffrey

On Wed, Sep 27, 2017 at 7:39 AM, Carsten Bormann <[email-masked]> wrote:

> _______________________________________________
> CBOR mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/cbor
>

---

From: Brian E Carpenter <[email-masked]>
Date: Thu, 28 Sep 2017 08:13:17 +1300

On 28/09/2017 05:58, Jeffrey Yasskin wrote:
> canonicalization: If 0 is equivalent to 0.0, 

It seems wrong to implicitly cast floats into ints. I think the fix is to delete
"even if they have the same numeric value" and to state that a FP number is
*never* canonically mapped to an integer representation.

Being picky, I think some mathematicians would tell you that a FP number
represents a real number, which is always an approximation whereas an integer
is exact. But in any case, even in a sloppy typing language like Python,
0 and 0.0 have distinct types. 0==0.0 is True, but I believe that's
because it's evaluated as 0==int(0.0) .

    Brian

> then canonicalization has to

---

From: Carsten Bormann <[email-masked]>
Date: Wed, 27 Sep 2017 22:11:46 +0200

> On Sep 27, 2017, at 21:13, Brian E Carpenter <[email-masked]> wrote:
> 
> "even if they have the same numeric value”

I think you are arguing for keeping “even if they have the same numeric value” — the sentence is trying to say that at the data model level, integers and floating point values are distinct, as they are in most programming languages (JavaScript being a notable exception).

> and to state that a FP number is

Right, this is what will happen in an environment (language + libraries) that already distinguishes them.
You cannot keep integers and integral floating point values separate in JavaScript, as it *only* has floating point values.  So something here has to go, and I think after four years of CBOR we have pretty good evidence that people want floating point to be separate from integer, JavaScript notwithstanding.

> represents a real number,

Yes.  Actually a number from the subset of the rational numbers, or a non-finite (± Infinity, NaNs).

> which is always an approximation

You cannot represent π in a floating point value except for an approximation, but all finite floating point numbers are exact representations of their actual (rational) values.  Binary64 has an exact representation of 0.5, but needs to approximate 0.1 (binary numbers need to approximate 1/10 just as decimal numbers need to approximate 1/3).
(Programming languages like Scheme actually make a difference between exact and inexact numbers; that is an innovation that is unfortunately rarely found elsewhere.)

> whereas an integer

(Actually, the 0 is coerced into a 0.0, not the other way around, or 0 == 0.1 would hold.)

Grüße, Carsten

---

From: Carsten Bormann <[email-masked]>
Date: Wed, 27 Sep 2017 22:29:55 +0200

> On Sep 27, 2017, at 18:58, Jeffrey Yasskin <[email-masked]> wrote:
> 
> "Note that integer and floating-point values are distinct in this model, even if they have the same numeric value." is inconsistent with "For the purposes of this specification, all number representations for the same numeric value are equivalent." in https://cbor-wg.github.io/CBORbis/#rfc.section.3.6. This will interact with canonicalization: If 0 is equivalent to 0.0, then canonicalization has to map integral floating point values to their integer representations, to preserve the fact that canonicalization makes duplicate map keys easy to identify. This also leads to a question of whether small BigInt, BigDecimal, and BigFloat values are equivalent to integer and floating values.

Good point.  These are not easy questions, and I think we have collected some implementation experience that argues for a cleaner separation of integer and floating point values.  We may want to separate implementation from data model questions here.  E.g., -2**64 is a bignum on most platforms, but should be represented as a basic “negative integer” canonically; this is the kind of consideration that 3.6 was trying to address.  Representing a floating point 0.0 by integer 0 may still make sense in a specific data model, but it should not be part of the generic data model.

At this point, I’m quite happy about the new "data models" text, because it already has helped clarify some issues (if not their desirable resolutions).  Numeric systems are freakily hard, and we couldn’t expect to get all nooks and crannies right in the initial RFC.

It may be worthwhile to collect some more information about implementation considerations posed by specific environments (int vs. float in JavaScript, “object" vs. map in JavaScript, map vs. array in Lua, etc.) in a document that helps designers of specific data models to make them as widely applicable as possible.

Grüße, Carsten