-
-
Notifications
You must be signed in to change notification settings - Fork 34
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
A case in spec/functions/string.json
is implementation dependent
#998
Comments
The smallest fix here would be to change the input to a string It's true that we don't specify any minimum for values "for which conversion to a string is supported", but it would be quite unfortunate if an implementation did not allow for an integer value to be serialized. |
@eemeli It is kind of weird to have a test of the |
There is already a
Then it will fail for some languages. On fixing the spec, I don't think that Otherwise we will have to specify exactly what that serialization looks like, how is going to treat extreme values (many decimals, 3.14E-12, and so on). Already And if we allow SOME programming languages to do type coercion from number to string, then this is not portable anymore. Options to make this portable:
Option 2 is way messier to define and to implement. We already have "magical conversions" hidden in some places that I am unhappy with. String to number We have it, and there is no way around that if we want to support something like `{|2| :number} for the price of one" Number to string We also have it for the selection on But we in fact have it, only refuse to admit it... |
That is done by something like This is the same argument that was used to reject the idea that selection keys are can be numeric. Why can't my implementation deserialize a It looks like we pick and choose when to do type coercion and we have no consistency. |
@mihnita wrote:
No. You have to keep the different levels of implementation concern apart. In the syntax, keys are always literals. The interpretation of keys as "values" is defined first by the selector function's specification and then by the implementation of that selector function. The literal But by the same token, the function My point is that it is wrong to talk at the MF syntax level about keys being anything except literals. What your implementation's functions do with those literals are up to you (and the function spec, of course). Your implementation is free to interpret the key
It can. We explicitly say:
We allow it for operands too. You'll recall that there is no WG consensus on how to support floating point number selection.
Type coercion is left to implementations. We go out of our way to put type coercion into the implementers hands. We do not pick and choose in MF2, because we are specifically typeless. In short, you're right that the test was faulty... as a generic test. But users should expect that native number types work for formatting and selection (or what's the point?) |
I should add... I was wrong to say:
The type coercion to a string would be inside the
It doesn't belong in the |
I agree with Addison. A key of An implementation of MF (including the default functions) is free to pre-parse an MF message, and convert the keys in an internal data structure into real datatypes for all the functions has control over. (If that weren't true, it would be a problem in the spec.) So an implementation in Rust could, for example, support BigRational in |
Then we can't say "the
This answer from Addison is not about the keys, it is about the
Everything is a string in a syntax, because we store the sources (for code, for mf2, etc) in text files. Even in JavaScript (in the browser console): var na = 1
var nb = 1.00
var nc = 0x01
var sa = '1'
var sb = '1.00'
var sc = '0x01'
typeof na
// < 'number'
typeof nb
// < 'number'
typeof nc
// < 'number'
typeof sa
// < 'string'
typeof sb
// < 'string'
typeof sc
// < 'string'
na == nb
// < true
na == nc
// < true
na === nb
// < true
na === nc
// < true
sa == sb
// < false
sa == sc
// < false
sa === sb
// < false
sa === sc
// < false
// type coercion done by JS
na == sa
// < true
// no type coercion, stricter equal
na === sa
// < false
That is not how any programming language works. If we take a Java example:
This is not about keys, not directly. What Addison / Eemeli are arguing here is that You have to define two different functions, and one would do explicit conversion:
Or do some ugly stuff like
No, implementations are not free to do that. Because the spec overreaches and dictates how this works internally, and what types are acceptable (nothing but strings). In fact, I did that (I had a real numeric type in the data model, and a number literal). But that is a big cause of friction now, when the spec went on to define how to do function chaining, resolved values (mentioned by Eemeli in an email as "small changes" since LDML 46). I had function chaining (and still have it), and worked. By going in to specify how chaining works the spec forces all implementations to throw away a type system and accept strings everywhere. And (right now) (for
But in reality that is not legal "by the spec", because the data model (which is part of the spec) only has Even JS does not do that. |
I do not understand what you mean. In https://cldr-smoke.unicode.org/spec/main/ldml/tr35-messageFormat.html#messageformat-2-0-data-model it says specifically:
Now, I think the wording could have been clearer, but it doesn't require that all internal data types are strings. For clarity, it should be:
And we can consider having this remain Final Candidate, since it isn't in the main section of the spec, and is optional. Can you point to some other place in the spec: aside from functions, and data model section that disallow an implementation from using a numeric type internally? |
In the
spec/functions/string.json
file one test is implementation dependent:The expected result seem to indicate that the numeric value 1 (from params) is somehow converted to a number.
Why I think that is the case?
The test file is a JSON file, and in most cases a number in a json file will be parsed into some sort of numeric type in the target programming language.
So the 1 in
params[0].value
will become some kind of numeric value.This is true in Java using gson, and even in JavaScript:
The spec for the
:string
function (string.md
) says this:So for the test to pass it means that this case is true:
"or for which conversion to a string is supported"
(it is not an "implementation-defined type that is a string" and it is not a literal value)
It is unclear what "conversion to a string is supported" means exactly in the above description
(happens automatically, like in JS, or one calling a
itoa
in C orfoo.toString()
is Java means "it is supported")We already agreed (in the discussions about fallbacks) that we don't want to do something like the Java
.toString()
, because it risks disclosing private information (think SSN or employee ID in aPerson
object).So in Java / C / C++ / others a "conversion to a string is " NOT "supported"
In fact, the spec text itself says "any implementation-defined type
that is a string or for which conversion to a string is supported"
Note "implementation-defined"
TLDR: the test is implementation dependent.
So it does not belong in an implementation independent test suite.
The fix should be as easy as removing the test case.
The text was updated successfully, but these errors were encountered: