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
Support number types #816
Comments
In fact, use of explicitly typed numbers in Elvish code for purposes other than interoperability with serialization formats is not only optional, but should maybe even be discouraged; as such, the relatively clumsy syntax of |
As a starter, let's simply borrow Go's type names. For instance, the double-precision floating number type is |
I would suggest different semantics -- everything stays stringly upfront, but behind the scenes every value gets converted to the type most suited to the current operation and stays that way until a different type is needed. Since basically every value has a canonical string representation anyways. That is what TCL wound up having to do to get good performance in their everything-is-a-string world |
This is how Elvish behaves now. It doesn't solve the problem of JSON interoperability. I have researched Tcl's solution, and the answer is that Tcl does not have a solution: writing JSON from Tcl-native values requires a schema specifying the type of each field. |
Float64 values are printed like (float64 42). However, the float64 builtin does not actually exist yet, and builtin math functions do not accept float64 arguments either. However, after this CL, from-json | to-json is now an identity operator. Previously: ~> echo '[1]' | from-json | to-json ["1"] Now: ~> echo '[1]' | from-json | to-json [1] It is also possible to use from-json to construct float64 values before the float64 builtin is actually implemented.
I'm new to elvish and have some concerns. Correct me if I'm wrong. Supported types
My options for 1. support using big.Int/big.Float and for 2. not for now Convert between types
I prefer implicit convert numbers between different representation, (i.e. float64, int64 in golang, and big.Int, big.Float for large numbers), just like python. We could automatically choose appropriate types for result types.
And convert from/to string should be explicitly.
Strongly typedCould a function claims it only accept number like object? |
@clouds56 Thanks for your comment. Indeed, the topics you have touched upon are very interesting:
|
After some more thoughts, I've come up with some design changes and clarifications. A: Builtin functions that previously output numbers as strings will be outputting typed numbers. So previously The reason for this change is that, when we restrict ourselves to arithmetic functions, the original design makes much sense, as the user can very conviniently switch between the two output modes by deciding what types the arguments are. However, there are functions that do not take number arguments, but output numbers. Notably, I think that it is worthwhile to re-orientate a bit and treat typed numbers slightly more seriously. Previously my idea was that "typed numbers are only necessary when dealing with serialization formats, and you can forget about it if you are not dealing with them"; but now it seems simpler to embrace typed numbers, but still support the use of plain strings as numbers as a convinience. What does not change though, is that all the arithmetic functions will continue to accept string arguments. You will never have to write With this change, however, it is important that typed numbers interoperates well with strings. Hence points B and C: B: Typed numbers only have the clumsy-looking syntax in its representation, not stringification. Like Python and some other languages, Elvish values can be converted to a string in 2 ways: representation (resembling Python
C: Typed numbers can be concatenated with strings, in which case they stringify implicitly. Example:
|
To whomever comes around here with an older (v0.12 as f.ex. in Debian buster) elvish version: one of the problems mentioned in the OP, namely piping JSON number values:
... actually is resolved and works correctly in v0.13 (as in Debian bullseye):
Similarily piping a |
Numbers in Elvish, like
42
,-4
,3.14159
,0xcafe
,1e100
,Inf
etc., are just strings. This is a compromise; the basic idea is to support writing filenames and flags such as42
and-4
without requiring the use of quotes, without making them "sometimes strings, sometimes numbers". So, for the sake of avoiding sloppiness, they are always strings. The math functions in Elvish all expect strings as a result, just that such strings should contain well-formed numbers.This approach actually works pretty well in Elvish, and causes few problems or surprises, as long as the programmer stays within Elvish land.
However, there is one area that this approach falls short: interoperability with serialization formats that do have number types - that is to say, most of them. As a result, it is not possible to convert JSON to Elvish value and back to JSON and get exactly the same thing, because JSON numbers are converted to Elvish strings. A simple example:
To solve this problem, the best approach so far would be to introduce explicit number types for the sake of interoperability. Let's say that we introduce a
number
builtin for constructing such explicitly typed numbers. Now the JSON array[1,42]
will be converted into the Elvish list[(number 1) (number 42)]
, and it will be converted back to the JSON array[1,42]
- no information loss.Because it is common to manipulate the data and JSON and then output back, all the builtin math functions should also output explicitly typed numbers, when at least one of their arguments are explicitly typed numbers. Yet, to retain the old behavior, when all of the arguments are strings, the output should still be a string. Examples:
It is worth stressing that the use of the explicit number type is entirely optional for code that stays within the "Elvish value universe". This is because all of the math functions will continue to accept string arguments, and output strings when all arguments are strings. One does not need to even know the existence of explicit number types.
Another interesting potential in future is to introduce perhaps not only one number type, but many number types, in order to interoperate with formats that distinguish (for instance) integers and floating-point numbers. All of those types will still be entirely optional, however.
The text was updated successfully, but these errors were encountered: