07:59
<Jesse (🇪🇸)>
the decimal continuatin will be this afternoon (early, not late)
08:42
<Jesse (🇪🇸)>
here are the continuation topics:
08:48
<Jesse (🇪🇸)>
not sure what WH has in mind with pi to 72 significant digits; this isn't one of the (many, many) Number values that are exactly representable in base-2 and having > 34 significant (decimal) digits
08:49
<Jesse (🇪🇸)>
I'd love to hear more about use cases for equals for amounts
08:50
<Jesse (🇪🇸)>
it got removed not because of any opposition to it, just ignorance of any concrete need
08:50
<Jesse (🇪🇸)>
(I added it in the latest version of the Decimal polyfil, fwiw)
08:52
<sffc>
It confounds me how any value type wouldn't have an equals function. As the most basic use case, I would like the ability to store these in a hash set.
08:52
<Jesse (🇪🇸)>
MM's question at the top ("Why is amount tied to decimal?") might have been answered by N-ic's email
08:53
<Jesse (🇪🇸)>
but it might also be another form of "why a monomorphic decimal-backed amount instead of a polymorphic one"
08:53
<nicolo-ribaudo>
I still have to answer again to Mark
08:53
<Jesse (🇪🇸)>
sgtm -- that's convincing enough
08:54
<Jesse (🇪🇸)>
for the exponential notation question, I'm not sure if there's any issue. All the examples we listed use decimal digit strings but we intend to support exponential notation, too
08:55
<sffc>
The Equals function gets a bit more fraught with Polymorphic Amount (are numerically-equal Number, BigInt, and Decimal Amounts .equals to each other?)
08:55
<Jesse (🇪🇸)>
right
08:56
<sffc>
I think that instead of Polymorphic Amount, I like your idea of String Amount. Many of the Polymorphic Amount problems go away.
08:56
<sffc>
So the question should be Decimal Amount or String Amount.
08:56
<Jesse (🇪🇸)>
a String-backed amount definitely aligns with the main use cases for amount
08:57
<Jesse (🇪🇸)>
conversion functions (toDecimal, toBigInt, toNumber etc.) might throw but maybe that's not so bad
08:58
<sffc>
We can discuss that in an issue but I feel like toDecimal could have an options argument that tells it whether to round or throw
09:00
<nicolo-ribaudo>
If we do string amount, I'd prefer conversions to be cast-like operations, e.g. Decimal(amount) and BigInt(amount) rather than amount.toDecimal() and amount.toBigInt()
09:04
<Jesse (🇪🇸)>
I think E-emli suggested this approach, too?
09:04
<eemeli>
I would also prefer something like a "string amount". Provided that its .toString() was a numeric string, then new Decimal(amount), BigInt(amount), and Number(amount) would all work.
09:05
<Jesse (🇪🇸)>
a String-backed amount also leaves open the possibility of adding new numeric types
09:05
<sffc>
I don't want to get ahead of ourselves on .toString(); I want it to be able to hold a unit annotation
09:06
<sffc>
Or some other syntax for rationals
09:06
<sffc>
"4/3" or "1.50[meter]" might be valid string outputs
09:06
<sffc>
But not as part of the Decimal proposal
09:07
<sffc>
We should make it future-proof though
09:08
<Jesse (🇪🇸)>
the decimal continuation might happen after this talk (!)
09:09
<eemeli>
As in, before lunch?
09:09
<Jesse (🇪🇸)>
yes
09:09
<sffc>
As long as Waldemar and Mark Miller are on the call
09:10
<Jesse (🇪🇸)>
WH is here but MM isn't (and he might not be here in the early afternoon, either)
09:10
<Jesse (🇪🇸)>
but there are too many contraints for the late afternoon
09:10
<Jesse (🇪🇸)>
(that's my understanding from the chairs)
09:10
<sffc>
We could do a WH continuation now and a MM continuation later (both shorter and therefore easier to fit in)
09:11
<ryzokuken>
neither expressed a constraint fwiw
09:11
<ryzokuken>
we have enough constraints explicitly laid out that it feels a bit harder accommodating implicit constraints
09:12
<sffc>
Based on the queue, it looks like the WH items are most of what's left
09:17
<sffc>
In preparing my slides for the meetup talk this evening, I'm reminded that I still don't recall us getting an answer on whether "redefine BigInt" is feasible
09:18
<Jesse (🇪🇸)>
redefine bigint? was that the idea of extending bigint with a new property indicating a decimal point index?
09:19
<Jesse (🇪🇸)>
IIRC this was an alternative path towards getting "decimal" as a primitive
09:21
<sffc>
Yes. If we did that, then that would also be the [numeric portion of the] Amount type, since it is a superset of the others.
09:22
<eemeli>
Re "the Amount type", do you mean the type of the numerical value within Amount?
09:22
<sffc>
yes
09:22
<eemeli>
If so, I agree.
09:24
<Jesse (🇪🇸)>
one question would be the data model -- BigInt is an unlimited data type but Decimal128 has bounds
09:25
<Jesse (🇪🇸)>
I guess Decimal128 wouldn't be the way to go
09:25
<Jesse (🇪🇸)>
(for this approach)
09:25
<eemeli>
Yah.
09:26
<sffc>
"Modified BigInt" is more like "BigDecimal" which is closer to String than Decimal
09:27
<Jesse (🇪🇸)>
thinking about arithmetic on these values, it's a sort of back-door rational number (but restricted to values that have finite decimal representations)
09:28
<Jesse (🇪🇸)>
(btw that is definitley doable, and not slow; I'm not raising a performance concern)
09:28
<eemeli>
Is there any way in which a string-backed Amount could be distinguished from a bigdecimal-backed Amount by a JS user?
09:29
<eemeli>
(I don't think there is or should be any difference)
09:30
<Jesse (🇪🇸)>
to my mind nothing sticks out; they seem basically interchangeable
09:32
<sffc>
That's mostly correct, yes, except that it may prevent us from supporting rationals where a string like "4/3" could be a thing we support
10:01
<Jesse (🇪🇸)>
it seems that we're converging toward a String-backed Amount that would support all "numerics" via cast-like operations suggested by Eemeli and Nic
10:01
<nicolo-ribaudo>
Note that string amount is not a solution to all problems, as we might need to redefine that for example 1e+1 and 1e1 are the same number but different strings
10:02
<Jesse (🇪🇸)>
right we'd need to settle on normalization here too
10:02
<Jesse (🇪🇸)>
decimal does that kind of normalization in the sense that it accepts both of those but outputs only the 1st
10:05
<Richard Gibson>
I can say with extremely high confidence that redefining bigint is not feasible. It is a primitive type with existing well-defined integer-only semantics, e.g. 4n / 3n === 1n.
10:05
<sffc>
No, I would say that we're converging on this being a feasible alternative, not necessarily converging on the preferred approach
10:07
<sffc>
Just add a new operator and define / as integer division. I see this as a papercut to be weighed with other pros and cons but not a fatal flaw
10:09
<Jesse (🇪🇸)>
for storage, it might be a bit odd to have bigints be either an integer or a decimal
10:09
<Jesse (🇪🇸)>
even if we could smooth out the ergonomics and surface area
10:10
<sffc>
bigints already require a heap, so I don't think it's much cost
10:10
<sffc>
In other words, they are already not particularly efficient in their storage. We're making a slightly-inefficient-and-not-widely-used type into a slightly-more-inefficient-but-more-widely-used type
10:15
<Richard Gibson>
oh, "just" add a new operator? And it's not only that anyway, there's also existing ecosystem use of bigint for alignment with interoperable data models such as Syrup and CBOR, in which arbitrarily-sized integers constitute a distinct type from arbitrary decimal and/or binary fractions
10:17
<sffc>
Yes, the data model concerns are something worth discussing, the nature of the issues involved there
10:17
<Richard Gibson>
to be clear: not only do I have high confidence that redefining bigint is not feasible, but furthermore I am personally inclined to oppose any such attempt
11:43
<sffc>
Jesse (🇪🇸): Should we steer the conversation to one of the questions we need answers from MM
11:43
<sffc>
Better use of time than NaN
12:18
<eemeli>
I don't really understand the relevance of the rounding discussions, given that AFAIK the only place where rounding might happen with Amount is when going from a high-precision numeric string to Decimal (if that's what's used as its internal representation). Any Amount-internal fraction/significant digit rounding will presumably happen with respect to the value's internal representation, so all of it will happen consistently.
12:20
<Jesse (🇪🇸)>
yes, I also didn't quite detect the substantive issue that we were trying to get at in the rounding discussion
12:20
<Jesse (🇪🇸)>
surely, such things would be a stage 2 concern
12:22
<Jesse (🇪🇸)>
even Intl, with its huge limits, surely has to handle rounding, when given massive digit strings
12:22
<eemeli>
I do think that unless we use something like a numeric strings as the internal representation, then a constructor needs to be able to define the rounding mode. Would the currently-proposed .from static method allow for a second argument setting that?
12:23
<Jesse (🇪🇸)>
we could add a 2nd argument
12:23
<eemeli>
Do any of the prior-art Temporal .from methods allow for a second argument?
12:24
<Jesse (🇪🇸)>
IIRC those are all single-argument methods
12:25
<Jesse (🇪🇸)>
this reminds me of the discussion of whether we should also have a constructor, not just .from
12:25
<Jesse (🇪🇸)>
the constructor would be like Temporal's, where every argument is needed
12:25
<Jesse (🇪🇸)>
to totally specify everything, without fallbacks
12:50
<eemeli>
I would think that the Intl.NumberFormat model of value+options bag matches much better, esp. considering future extension for unit/currency support.
12:54
<Jesse (🇪🇸)>
procedurally, how should we think about presenting a String-backed Amount? would it continue to be part of the decimal proposal?
12:59
<eemeli>
I would think that'd be easier done as a separate refactored proposal-measure.
12:59
<Jesse (🇪🇸)>
(not saying we've totally switched to that approach; at this point, it's an interesting potential alternative. just asking hypothetically)
13:02
<Jesse (🇪🇸)>
otoh in our current discussions of (Decimal.)Amount, we've had the luxury of not yet worrying about units, the thinking being that Measure will round out the picture
13:03
<Jesse (🇪🇸)>
iow even a String-based Amount could make sense in the Decimal proposal, because it is indeed a kind of numeric value
13:03
<Jesse (🇪🇸)>
and it works
13:03
<Jesse (🇪🇸)>
it's like part 1 of a 2-part movie
13:04
<Jesse (🇪🇸)>
it does make sense on its own
13:04
<eemeli>
A minimal non-Decimal Amount could start out with unit and currency as string-valued optional properties, and include special handling in Intl.NumberFormat when an Amount used is used in a .format() call.
13:04
<Jesse (🇪🇸)>
ah, interesting, good point -- I like the idea of pointing to those bits of Intl as prior art
13:06
<eemeli>
As we're proposing a single class for handling both currency and unit formatting, we're going to have the potential for .format(amount) throwing no matter what, so gating the supported units at that point rather than in the Amount constructor also makes sense.
13:06
<eemeli>
And doesn't introduce a dependency in ECMA-262 on the ECMA-402 list of supported units.
14:04
<sffc>
Procedurally, I wonder if we could get Stage 2 on Decimal and Decimal.Amount, followed by the proposal to extend Decimal.Amount to support dimensions and higher precision
14:04
<sffc>
(in which case we would rename it from Decimal.Amount to something else, perhaps in a Numerics namespace)
14:06
<Jesse (🇪🇸)>
this sounds like a reasonable path -- I think the committee understands decimal and decimal.amount fairly well at this point. the motivation for increased limits comes more naturally from a discussion of measurements
14:10
<eemeli>
Or we could just leave out Decimal.Amount from the Decimal proposal, and introduce Amount separately under the measure proposal.
14:10
<sffc>
My long-standing position is that I don't support the Decimal proposal without the i18n solution
14:11
<eemeli>
Would those concerns be potentially resolved if we were to propose a non-Decimal Amount for Stage 2 before proposing Decimal for Stage 2?
14:11
<sffc>
I could be reasonably happy with String Amount to Stage 2 and Decimal to Stage 2 later
14:12
<eemeli>
That sounds like a thing that could be done relatively easily from where we are now.
14:13
<sffc>
except for the fact that we haven't presented String Amount to committee before and don't have a temperature check on it :)
14:13
<Jesse (🇪🇸)>
if so then I wonder if we need to pivot to measure amount for now
14:15
<eemeli>
I think the most vocal objections to Decimal.Amount as currently proposed have been from Mark and me, regarding the value limits that Decimal imposes. A string-based Amount would resolve those concerns, so I could well believe it getting through unless wholly new concerns are raised.
14:16
<eemeli>
And as I discovered with Intl.MessageFormat, asking for Stage 2 might be the only way to surface those.
14:16
<Jesse (🇪🇸)>
I think it makes some sense to do a String-based amount in decimal (called Amount, not Decimal.Amount)
14:16
<sffc>
(I think it should be Numerics.Amount and Numerics.Decimal but that can be resolved pre-2.7)
14:17
<Jesse (🇪🇸)>
it makes sense because the use cases for decimal, especially the i18n ones, need (Numerics.)Amount
14:18
<eemeli>
I would prefer bare Amount over Numerics.Amount, but I agree that this should not be a stage 2 blocker.
14:19
<eemeli>
To clarify, I don't dislike Numerics.Amount, but prefer the non-namespaced one.
14:20
<sffc>
It's not dissimilar to SeededPRNG being better as Random.Seeded but probably only if there are other things in the Random namespace
14:22
<ljharb>
imo we've made lots of mistakes by not optimistically namespacing things
14:23
<ljharb>
eventually everything gets something else related to it added
14:29
<eemeli>
On a separate note, have we considered/discussed whether Amount.p.valueOf() should explicitly throw like Decimal.p.valueOf() does? For the latter I gather it's primarily done to prevent something like d1 + d2 from appearing to work, but I'm not sure that the argument made for Decimal wholly applies to Amount. The ergonomics cost of casts like BigInt(amount) and Number(amount) not working is kinda high.
14:30
<Jesse (🇪🇸)>
my initial gut reaction would be for valueOf to return a serialized number
14:30
<Jesse (🇪🇸)>
(without units/currency)
14:31
<sffc>
we should do what Temporal does, which is to throw on valueOf
14:31
<eemeli>
That would work for me, certainly.
14:31
<eemeli>
(my response was to Jesse's suggestion)
14:31
<sffc>
I'm not in favor of valueOf or toString returning something that is equal if the corresponding Amounts are not equal
14:31
<eemeli>
Why does Temporal's behaviour here matter for Amount?
14:32
<Jesse (🇪🇸)>
ah, I meant not exactly the number but the number + precision
14:32
<Jesse (🇪🇸)>
digit string iow
14:32
<Jesse (🇪🇸)>
this should satisfy the constraint you have in mind sffc
14:33
<Jesse (🇪🇸)>
how important are casts in comparison to explicit method calls?
14:34
<sffc>
Temporal decided to throw on valueOf for a number of well-motivated reasons, which I think also apply here. If valueOf returns a string, then people are going to take amt1 + amt2 and get garbage
14:34
<Jesse (🇪🇸)>
Number(amount) vs. amount.toNumber()
14:39
<Jesse (🇪🇸)>
I'm inclined to make valueOf throw, to avoid mixing, following the logic of decimal
14:40
<Jesse (🇪🇸)>
(I wonder if this thinking was one of the "stop casting things" series of talks by KG?)
14:42
<Jesse (🇪🇸)>
sorry "stop coercing things"
14:47
<Jesse (🇪🇸)>
btw I realize this is getting into the weeds but what should we do about (1) NaN, (2) -0, and (3) +/infinity?
14:47
<Jesse (🇪🇸)>
one argument is that we should support all of them because decimal does, and so does intl
14:48
<Jesse (🇪🇸)>
another approach would be to ban them, the thinking being that an "amount" is always a finite amount
14:48
<ljharb>
-0 is a finite amount
14:48
<Jesse (🇪🇸)>
true
14:48
<ljharb>
banning nan and infinity tho seems fine to me, as long as it throws for them
14:49
<Jesse (🇪🇸)>
should we normalize -0 to 0?
14:49
<ljharb>
i strongly dislike doing that overall (as i'll be talking about in the clamp continuation)
14:49
<ljharb>
but, tbf, that's probably what most people will want done
14:49
<Jesse (🇪🇸)>
yeah
14:50
<Jesse (🇪🇸)>
I'd like us to have Amount(0).equals(Amount(-0)) to be true
14:50
<Jesse (🇪🇸)>
at a minimum
14:50
<ljharb>
i also dislike that but i think it's much more defensible given === and the concept of an amount
14:50
<Jesse (🇪🇸)>
ah ok interesting
14:51
<ljharb>
like, in general i think IEEE's -0 behavior is confusing and bad and we shouldn't constrain ourselves to something whose importance and impact we've long since surpassed
14:51
<ljharb>
but waldemar for sure, and others possibly, would not be happy with deviating from ieee 754
14:51
<Jesse (🇪🇸)>
right
14:54
<Jesse (🇪🇸)>
the same line of thinking -- "don't deviate from IEEE 754" -- could also be an argument for supporting NaN and infinity
14:55
<ljharb>
well, supporting a subset isn't necessarily "deviation"
14:55
<Jesse (🇪🇸)>
we do have things like Infinity.toPrecision(5) --> "Infinity"
14:55
<Jesse (🇪🇸)>
(rather than throwing)
14:55
<eemeli>
I think ensuring that the Amount value was guaranteed to be finite would be a good idea.
14:55
<ljharb>
sure but that's from the olden days when coercing was the thing
14:56
<Jesse (🇪🇸)>
the golden olden days
14:56
<ljharb>
having to account for the special Infinity and NaN strings is gross
14:56
<Jesse (🇪🇸)>
agree
14:56
<Jesse (🇪🇸)>
ok it sounds like we have consensus on supporting finite values only, as well as -0
14:57
<eemeli>
For the interoperability story, an Amount that was able to represent any finite value would be probably the most valuable approach.
14:58
<eemeli>
I think -0 should absolutely work as an input value, but normalising it to 0 has precedent in String(-0) === '0'.
14:58
<Jesse (🇪🇸)>
sgtm
14:59
<Jesse (🇪🇸)>
seems like a stage 2 concern to me
17:08
<sffc>
Is it already the case that for two Number-s x and y, that x === y implies String(x) === String(y) ?
17:28
<eemeli>
Yes.
17:29
<sffc>
That would align with my expectation, and it's also the case for Temporal types, and it's a large part of why I would like to have that property for Amount, too.
17:29
<sffc>
(including an Amount containing units.)
17:33
<eemeli>
Equality of amounts implying equality of their string representations is quite straightforward, but inequality of amounts implying inequality of string representations is not quite so straightforward.
21:40
<Richard Gibson>
yes, but note that === returns true for distinct values 0 and -0, so that implication only holds because Number::toString also treats those values the same (2. If _x_ is either *+0*𝔽 or *-0*𝔽, return *"0"*.)