Allow specify numbers with suffixes

# Andrey Muzalevsky (6 years ago)

Idea is simple, also is simple to implement and do not conflicting with existing standard

Readability of javascript can be improved in certain cases like:

  • populationSize = 100000000
  • maxMessageSize = 4194304
  • setTimeout(foo, 30000)
  • if(timeElapsed > 100) {...}

This can be changed to following:

  • populationSize = 100M
  • maxMessageSize = 4MB
  • setTimeout(foo, 30s)
  • if(timeElapsed > 0.1s) {...}

Also it will be great to support floating number, most convinient way to do this is tract suffix just like a multipler, so

1.5MB == 1.5 * 1MB

Supported suffixes, as I see them:

  • Metric prefixes group
    • follow SI Prefixes www.npl.co.uk/reference/measurement-units/si-prefixes scheme, to decrease entrance level
    • allowing to use short and full form
    • it is case sensetive (bad, but everyone knows it)
    • not sure about μ, it either:
    • (my preference) supported as UTF-8 sumbol, always can be replaced with 'full' form when needed(is it recommended to use?)
      • has a replace symbol which can be easily typed
      • allowed only in full form
    • samples:
      • 4M == 4mega == 4 000 000
      • 5n == 5nano == 0.000 000 005
      • 1micro == 0.000 001
    • Bytes prefixes group
    • Metric prefixes turned into bytes prefixes by adding either 'B' to short form, or 'byte[s]' to full form
    • Byte suffix is written in upper-case 'B', e.g. 'kB', 'MB', 'GB'
      • This is done to remove inconsistency with widely used bit/byte differentiation, e.g. kb and KB usually mean different things
    • Samples:
      • 1kB = 1kilobyte = 1024
      • 1MB = 1megabyte = 1024*1024
    • Time group, counted in milliseconds
  • s, sec = 1000
    • min = 60 * 1000
    • h, hr = 60 * 60 * 1000
    • d, day[s] = 24 * 60 * 60 * 1000
    • w, week[s] = 7 * 24 * 60 * 60 * 1000
  • Also it will be good to allow compound number definitions, samples
  • 1h 30min = 1h + 30min
    • 1mB 200kB = 1mB + 200kB

What do you think?

# Isiah Meadows (6 years ago)

Check out the various unit-related proposals that have spawned on this list, and note that IIRC the BigInt proposal 1 also notes that as a possible future expansion.

# kdex (6 years ago)

Please see [1].

[1] littledan/proposal

# Jerry Schulteis (6 years ago)

I see the BigInt proposal at the moment uses a suffix 'n' for BigInt literals.That would conflict with Andrey's desire to have it mean metric nano (* 10**-9).Maybe tagged template literals would do?     populationSize = SI100M;    setTimeout(foo, millis30s);

On Thursday, November 23, 2017, 7:22:41 AM CST, Isiah Meadows <isiahmeadows at gmail.com> wrote:  

Check out the various unit-related proposals that have spawned on this list, and note that IIRC the BigInt proposal 1 also notes that as a possible future expansion.

On Thu, Nov 23, 2017, 08:17 Andrey Muzalevsky <face2world at gmail.com> wrote:

Idea is simple, also is simple to implement and do not conflicting with existing standard Readability of javascript can be improved in certain cases like:

  • populationSize = 100000000

  • maxMessageSize = 4194304

  • setTimeout(foo, 30000)

  • if(timeElapsed > 100) {...}

This can be changed to following:

  • populationSize = 100M

  • maxMessageSize = 4MB

  • setTimeout(foo, 30s)

  • if(timeElapsed > 0.1s) {...}

Also it will be great to support floating number, most convinient way to do this is tract suffix just like a multipler, so 1.5MB == 1.5 * 1MB Supported suffixes, as I see them:

  • Metric prefixes group

  • follow SI Prefixes scheme, to decrease entrance level

  • allowing to use short and full form

  • it is case sensetive (bad, but everyone knows it)

  • not sure about μ, it either:

  • (my preference) supported as UTF-8 sumbol, always can be replaced with 'full' form when needed(is it recommended to use?)

  • has a replace symbol which can be easily typed

  • allowed only in full form

  • samples:

  • 4M == 4mega == 4 000 000

  • 5n == 5nano == 0.000 000 005

  • 1micro == 0.000 001

  • Bytes prefixes group

  • Metric prefixes turned into bytes prefixes by adding either 'B' to short form, or 'byte[s]' to full form

  • Byte suffix is written in upper-case 'B', e.g. 'kB', 'MB', 'GB'

  • This is done to remove inconsistency with widely used bit/byte differentiation, e.g. kb and KB usually mean different things

  • Samples:

  • 1kB = 1kilobyte = 1024

  • 1MB = 1megabyte = 1024*1024

  • Time group, counted in milliseconds

  • s, sec = 1000

  • min = 60 * 1000

  • h, hr = 60 * 60 * 1000

  • d, day[s] = 24 * 60 * 60 * 1000

  • w, week[s] = 7 * 24 * 60 * 60 * 1000

  • Also it will be good to allow compound number definitions, samples

  • 1h 30min = 1h + 30min

  • 1mB 200kB = 1mB + 200kB

What do you think?_______________________________________________ es-discuss mailing list es-discuss at mozilla.org, mail.mozilla.org/listinfo/es

# Andrey Muzalevsky (6 years ago)

Thank for your answers

Jerry, I think that in tagged template literals form it won't be widely used e.g. setTimeout(foo, millis30s); is much harder to read than setTimeout(foo, 30000);


Regarding littledan/proposal-extensible-numeric-literals:

Doesn't conflict with this idea.

Also looks great at first sight. BTW - In my personal opinion - in most cases number suffixes/literals/syntaxes are just sugar, and must be processed at compile-time (0xFF000000 syntax is also just sugar). Also to make this proposal useful - JS also need to support operators overloading, without operator overloading do something useful while writing 10px + 1em is impossible, so it decreases usability of this innovation to just another way of calling function(for now).

So in my personal opinion, for now it is better to stay with fixed list of built-in compile-time executed number suffixes/literals


Regarding tc39/proposal-bigint

The only problem between proposals is the suffix n which specifies 10^-9. Few thoughts:

  • milli, nano, etc. suffixes won't be widely used
  • they always can be replaced with expotential notation 1e-3, 1e-6, ...

So they are removed from this idea, Also removed full form, as it doesn't look semantically valid

Updated list of sugar suffixes:

  • Usable list analogues of 1e3, 1e6, 1e9:
    • 1K = 1000 = 1e3
    • 1M = 1000*1000 = 1e6
    • 1G = 100010001000 = 1e9
    • ... (T,P,E,Z,Y)
  • The same with bytes, nobody will count nanobytes... Isn't it? Usable list:
    • 1KB = 1024
    • 1MB = 1024*1024
    • 1GB = 102410241024
    • ... (TB,PB,EB,ZB,YB)
  • Updated time group, this can make life easier for each novice...
    • 1s = 1000
    • 1m = 60s
    • 1h = 60m
    • 1d = 24h
    • 1w = 7d

How it looks for you with updates?

Best ,

Andrey

2017-11-25 1:22 GMT+02:00 Jerry Schulteis <jdschulteis at yahoo.com>:

# Sam Goto (6 years ago)

Ha, that's quite interesting.

Somewhat related to the proposal of tc39/proposal-numeric-separator that we moved forward earlier this year.

Are you thinking that the suffixes are purely ignored by VMs or that the conversation is effectively done? That is, is "populationSize = 1M" equivalent to "populationSize = 1" or does it make a translation somewhere to "populationSize = 1_000_000"?

# Sam Goto (6 years ago)
  • rick that co-authored numeric separators too and may have thoughts on this. my first impression is that this (if kept purely as something that gets ignored by the VMs) shares a lot of the sentiments with numeric separators ....
# kai zhu (6 years ago)

On Dec 13, 2017, at 2:15 AM, Sam Goto <goto at chromium.org> wrote:

  • rick that co-authored numeric separators too and may have thoughts on this. my first impression is that this (if kept purely as something that gets ignored by the VMs) shares a lot of the sentiments with numeric separators ….

-1 the difference is that numeric-separators are well-defined and hopefully a one-time language-change that never has to be re-visited again. these proposed numbers-with-suffixes are arbitrary and nobody is naive enough to believe they won’t be revisited repeatedly in the future. they open a can-of-worms to never-ending future language-feature requests (like destructuring and import-statements did), which harms tooling and language stability.

# J Decker (6 years ago)

On Tue, Dec 12, 2017 at 1:24 PM, kai zhu <kaizhu256 at gmail.com> wrote:

On Dec 13, 2017, at 2:15 AM, Sam Goto <goto at chromium.org> wrote:

  • rick that co-authored numeric separators too and may have thoughts on this. my first impression is that this (if kept purely as something that gets ignored by the VMs) shares a lot of the sentiments with numeric separators ….

-1 the difference is that numeric-separators are well-defined and hopefully a one-time language-change that never has to be re-visited again. these proposed numbers-with-suffixes are arbitrary and nobody is naive enough to believe they won’t be revisited repeatedly in the future. they open a can-of-worms to never-ending future language-feature requests (like destructuring and import-statements did), which harms tooling and language stability.

My concern would be the non-symmetry/irreversability of this.... (can't get out what you put in) Factorio uses such suffixes in their mods but that's a total one-off. I've not seen real standards anywhere for this sort of thing in any language generally.

B as an additional suffix to say base 2 is actually fairly arbitrary... (although this page suggests such a thiing) people.csail.mit.edu/jaffer/MIXF/MIXF-08 says only languages could be extended, but has no examples of any language with support.

There's also no NPM for such a thing (if there is it's called something I wouldn't think of)

www.npmjs.com/package/convert-units (converts a value to another value, and uses such metric suffixes, but only as strings to .from() and .to() )

And these two that convert from a number to text, but not the other way around... www.npmjs.com/package/metric-suffix, www.npmjs.com/package/number-suffix

Even math heavy lanauages (mathematica/Wolfram, R, FORTRAN ); human friendly lanaguages (BASIC, COBOL); and kid friendly Scratch, et al. son't have such support.

So I think someone should first implement it as a library/package (maybe even going as far as to overload Number()/new Number() when converting numbers...

# Darien Valentine (6 years ago)

[...] in most cases number suffixes/literals/syntaxes are just sugar, and must be processed at compile-time (0xFF000000 syntax is also just sugar).

Probably everybody has a different idea of what "sugar" is, but to me something is sugar when it can be desugared to some more complex thing underlying it. I’d just call dec/hex/oct/bin "notations" — even though the choice of numeric notation doesn’t contribute to runtime semantics, "0xFF" doesn’t desugar to "255" (or 0XFF, or 255.0, or 0o377, etc).

[...] to make this proposal useful - JS also need to support operators overloading, without operator overloading do something useful while writing 10px + 1em is impossible, so it decreases usability of this innovation to just another way of calling function(for now).

If it were just a static multiplier value (e.g., 1s evaluating to 1000), then I’d imagine the suffix data wouldn’t be available at runtime; it would occur during parsing and just be an (alternative notation / sugar). However if you’re envisioning it as something that interacts with operators at runtime, that would seem to be a very different thing; the type in question could no longer be "number".

The static-only version doesn’t look good to me because it sits on a lot of syntactic space and miscommunicates the nature of the values. For example, many APIs accept seconds, not milliseconds. So say somebody reads that in the docs for something, "maxAge accepts a value in seconds". How surprising then that when they dutifully provide { maxAge: 30s }, it sets it to a bit over eight hours :D

The runtime version seems likely to create more confusion than not, too. The example you gave — 10px + 1em — demonstrates how that might go. One might expect that to work because css’s calc can do it. But the browser knows what the current value of em for the node in question is. Even if it somehow knew what the contextual relationship between px and em was, it’s not clear to me what that’s actually supposed to evaluate to.

# Andreas Rossberg (6 years ago)

On 13 December 2017 at 02:26, J Decker <d3ck0r at gmail.com> wrote:

My concern would be the non-symmetry/irreversability of this.... (can't get out what you put in) Factorio uses such suffixes in their mods but that's a total one-off. I've not seen real standards anywhere for this sort of thing in any language generally.

F# includes a system of user-definable units of measure, based on Andrew Kennedy's pioneering work. The type system checks that they are used consistently and it can infer that e.g. acceleration (m/s^2) multiplied by time (s) yields velocity (m/s).

However, the main benefit of all this is the type checking, so I doubt there is much value for JavaScript. If you just want dynamic checking you can build respective classes yourself.

# Tab Atkins Jr. (6 years ago)

On Tue, Dec 12, 2017 at 6:38 PM, Darien Valentine <valentinium at gmail.com> wrote:

The runtime version seems likely to create more confusion than not, too. The example you gave — 10px + 1em — demonstrates how that might go. One might expect that to work because css’s calc can do it. But the browser knows what the current value of em for the node in question is. Even if it somehow knew what the contextual relationship between px and em was, it’s not clear to me what that’s actually supposed to evaluate to.

Right. It turns out that we have an answer to that now! (drafts.css-houdini.org/css-typed-om) But any solution that didn't allow us to write that sort of thing and get a CSSNumericValue out of it would be pretty incomplete.

# Jerry Schulteis (6 years ago)

Unless I badly misunderstood Andrey's post he does not want something like numeric separators, that get ignored by the VM; he wants 1M to translate (I presume at compile time) to 1_000_000 (here's hoping numeric separators makes it into the spec) and 3min to translate to 18_000. While I see some merit to the idea, I think adding such things to the language ad hoc leads to PHP--not the direction I'd like to see JavaScript take. I think any proposed addition to a language should be reviewed as to whether it constitutes a specific case of some more general principle.

Moreover, the BigInt proposal is at Stage 3 and would use an "n" suffix to indicate a BigInt literal; the Extensible Numeric Literals proposal is at Stage 1 and would make further use of the same syntactic space ("i" for imaginary numbers, "m" for decimals); Brendan Eich's Int64 slide deck (www.slideshare.net/BrendanEich/int64) uses "L" as suffix for Int64, "uL" for Uint64, and considers extending the concept to user-defined value types. If such user-defined value types ever make it into JavaScript, it might give Andrey something close to what he wants.

On Tuesday, December 12, 2017, 1:16:02 PM CST, Sam Goto <goto at chromium.org> wrote:

  • rick that co-authored numeric separators too and may have thoughts on this. my first impression is that this (if kept purely as something that gets ignored by the VMs) shares a lot of the sentiments with numeric separators ....
# Andrey Muzalevsky (6 years ago)

Jerry Schulteis: Unless I badly misunderstood Andrey's post he does not

want something like numeric separators, that get ignored by the VM; he wants 1M to translate (I presume at compile time) to 1_000_000 (here's hoping numeric separators makes it into the spec) and 3min to translate to 18_000.

You are correct.


Intresting that cpp implements user literals as operators en.cppreference.com/w/cpp/language/user_literal

I stuck with the idea that number "notation" and number "literals/postpositions" are the different things...

So basicly if it is possible to say than number "literal/postposition"("user literal" or "user postposition" or whatever) SHOULD BE separated from the number by space - it resolves questions and allows to write e.g.:

1 min
1 sec
1n min
1uL whatever

Moreover this also may work (it doesn't look good for me, but why not...):

let minutesLeft = 5;
let minutesLeftInMs = minutesLeft min; // or (minutesLeft)min

This case preserves number suffix for number types and other goals and adding kind of generic syntax for "literals/postpositions" (which basicly are not required to be used with numbers, or return numbers)

So the "literal/postposition" definition is just a simple function with single argument, which works with any type, e.g.

function __literal_min(x) {
      // or __postposition_min
    return x * 60 * 1000;
}

Best ,

Andrey

2017-12-14 0:36 GMT+02:00 Jerry Schulteis <jdschulteis at yahoo.com>: