Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create the Money type. #116

Merged
merged 13 commits into from
Jun 7, 2023
Merged

Create the Money type. #116

merged 13 commits into from
Jun 7, 2023

Conversation

rofrankel
Copy link
Contributor

(Note: this PR is for review purposes only; the contents of this PR should ultimately live in the common-components repo which does not yet exist.)

@rofrankel rofrankel requested a review from a team as a code owner May 5, 2023 19:58
Copy link
Contributor

@toumorokoshi toumorokoshi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks! primary concern is package naming at this point. meta-concern about redundant content.

option go_package = "aip.dev/type/money;money";
option java_multiple_files = true;
option java_outer_classname = "MoneyProto";
option java_package = "dev.aip.type";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel like it's an issue that the java and go package have a different type prefix.

why not aip-dev as the package name? or maybe just aip?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know enough about Java or Go to know what the right package names are. So I was following the google.type precedent:

option cc_enable_arenas = true;
option go_package = "google.golang.org/genproto/googleapis/type/money;money";
option java_multiple_files = true;
option java_outer_classname = "MoneyProto";
option java_package = "com.google.type";
option objc_class_prefix = "GTP";

I don't really have an opinion about what these should be, though if we should do something different from google.type it should probably be deliberate (i.e. we actively believe google.type got it wrong).

Copy link
Contributor

@lukesneeringer lukesneeringer May 8, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Java uses reverse domain syntax, so what you did is correct.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@toumorokoshi do you have further comments on this? I updated the proto package already.


## Schema

A `Money` has two fields:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel like we should have some way to define this in a programmatically consumable format, and have that be the source of truth. This content is largely redundant with the content in the proto.

That format can translate itself into the proto, as well as the .md file.

I primarily worry about the drift in different representations if we don't have some tooling to help here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that's a fair point. A couple counter-points:

  • We don't expect the number of common components to be large enough that manual maintenance is intractable, right? Especially since we don't expect common components to change over time?
  • I actually quite deliberately made the canonical definitions IDL-agnostic, treating formal IDL definitions as implementation details.

But those aside, sure - I don't actually feel too strongly about this. How would you recommend we canonically define common components, if not prose + bullet points? If you know of some appropriate formal syntax/DSL for defining such things, great.

Or we could just say that protos are canonical, and other IDLs are secondary?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was thinking we could have our own yaml format, or use JSONSchema and translate it.

But I'm fine with merging these first couple as a reference point, and then we can write a script to do the translation and generation. I think it's pretty straightforward, so I'd be happy to pick that up once we have an example.

We don't expect the number of common components to be large enough that manual maintenance is intractable, right? Especially since we don't expect common components to change over time?

Sure, but I think any manual cost we can reduce would be great. it is low-hanging fruit since the content is roughly the same.

I actually quite deliberately made the canonical definitions IDL-agnostic, treating formal IDL definitions as implementation details.

I think this further emphasizes that code-genning these would be better.

Copy link
Contributor Author

@rofrankel rofrankel May 10, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately JSON isn't sufficient because it doesn't have a way to specify e.g. int32 and int64; it just has number. My first thought was to use TypeScript interfaces like some of the AIPs do, but the lack of distinct numeric types made it a non-starter.

And sure, we could come up with our own DSL for this. It's a principled approach, but also seems a bit yak-shavey. And how different will it really end up looking than protobuf?

Copy link
Contributor

@toumorokoshi toumorokoshi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removing the concern about package naming since we'll revisit this later.

just a couple fixes that should be down re examples, and I think it LGTM.

Comment on lines 24 to 25
- The `amount` field is a field of type [`Decimal`][], representing the amount
of currency.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This conflicts with prior art such as Agoric's Amount, which is composed of a brand (generalizing currency code to arbitrary distinguishable kinds) and a value (which is either a fungible nonnegative integer or a non-fungible unique asset). It would be unfortunate for some software to use "amount" for the composite type and other software to use it for just the component of a composite type upon which arithmetic can be performed. Is there an alternative that would work here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, I hadn't seen that before, interesting.

I think value is generally a bad field name, unless the schema itself is specifically wrapping just that one field (e.g. google.protobuf.BoolValue), because the whole schema represents the value.

We could go with something like quantity (or count, but that seems much worse). But I'd rather do that because we think quantity is a better field name than amount in the API context, rather than because some crypto startup has dibs on the word "amount".

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

True, but representing currency is certainly more germane to that space than it is to generic API guidelines. I'm not proposing an outright adoption of that data model, just something that avoids "amount" referring to the composite in some domains and to a field of the composite in others. But even in common English, financial "amount" seems to correspond better with the former—consider e.g. "amount due: $123.45".

I could see using quantity—although it also seems to represent the composite in at least some scientific discourse, that is further removed from this purpose.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But even in common English, financial "amount" seems to correspond better with the former—consider e.g. "amount due: $123.45".

I think that's a good point. Hmm. I also think you're right that quantity implies a unit as well as a number.

google.type.Money uses two integer fields, units and nanos, in place of this field. I don't think that really helps.

I am still pretty against value. Any other ideas for what to call this field?

Copy link
Contributor Author

@rofrankel rofrankel May 31, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Discussed in the steering meeting today:

  • This field should be named "quantity".
  • If/when we do a Measurement type, we should also call the corresponding field "quantity".

Rationale:

  • Why not value? Because "the value of money" or "the value of a dollar" means a different thing.
  • Why not amount? As @gibson042 said above, "amount due" refers to the whole value.
  • No one ever says "quantity of money" or "quantity of dollars" in English, so "quantity" is probably safe regarding misunderstandings/confusion.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lukesneeringer https://google.aip.dev/141 specifies that "quantities" are discrete. Any problem with using "quantity" to refer to a decimal value here? Should AIP-141 be updated to "support" decimal values (e.g. 0.5 miles)?

Base automatically changed from decimal-type to main May 24, 2023 17:54
rofrankel added 4 commits May 31, 2023 14:33
* Specify required fields
* Disallow additional properties
* Add trailing newline.
Also, fix the "One and a half Bitcoin" example.
@rofrankel
Copy link
Contributor Author

I've updated this PR to reflect the renaming of amount to quantity.

Copy link
Contributor

@gibson042 gibson042 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM after typo fixes.

Comment on lines +18 to +20
// Five US dollars === `{currency_code: "USD" quantity: {significand: 5}}`
// One and a half Bitcoin ===
// `{currency_code: "X-BTC" quantity: {significand: 15 exponent: -1}}`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// Five US dollars === `{currency_code: "USD" quantity: {significand: 5}}`
// One and a half Bitcoin ===
// `{currency_code: "X-BTC" quantity: {significand: 15 exponent: -1}}`
// Five US dollars === `{"currency_code": "USD", "quantity": {"significand": 5}}`
// One and a half Bitcoin ===
// `{"currency_code": "X-BTC", "quantity": {"significand": 15, "exponent": -1}}`

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this suggestion is right, because these examples are written as text format protos.

Comment on lines +29 to +31
- Five US dollars === `{currency_code: "USD", quantity: {significand: 5}}`
- One and a half Bitcoin ===
`{currency_code: "X-BTC", quantity: {significand: 15, exponent: -1}}`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- Five US dollars === `{currency_code: "USD", quantity: {significand: 5}}`
- One and a half Bitcoin ===
`{currency_code: "X-BTC", quantity: {significand: 15, exponent: -1}}`
- Five US dollars === `{"currency_code": "USD", "quantity": {"significand": 5}}`
- One and a half Bitcoin ===
`{"currency_code": "X-BTC", "quantity": {"significand": 15, "exponent": -1}}`

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn't really JSON or proto...admittedly, it's not any specific thing, and maybe it should be. But since this is the primary schema definition (as opposed to implementations in proto or JSON schema), I kind of deliberately made it neither of the two in order to avoid any implication that one of the two IDLs was privileged.

Co-authored-by: Richard Gibson <richard.gibson@gmail.com>
@rofrankel rofrankel merged commit bb610fd into main Jun 7, 2023
@rofrankel rofrankel deleted the money-type branch June 7, 2023 17:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants