Proposal for new floating point and integer data types

# Brandon Andrews (5 years ago)

I've seen posts asking for optional strong typing (often relating to typescript), but not many asking for data types. I think since the process takes a while it would be a good idea to consider adding extra data types on top of the already existing dynamic ones. I'll keep each comment short since everyone here is probably familiar with how Actionscript did their type specs. I'd like to discuss proposing these data types to start:

  • int,int8/16/32/64
  • uint,uint8/16/32/64
  • single (32-bit IEEE 754)
  • double (64-bit IEEE 754 as an alias for Number)

These correspond to most computer hardware and have fairly standard instruction set operations on them. The goal here is mostly to bring ECMAScript closer to a generic bit based computer. These types are fairly standard across hardware and are well understood in other languages.

var foo: uint16 = 100;
var bar: uint64 = foo;
var baz = bar >> 58;

This would in turn expand things that JavaScript was never able to do, which is to work with 64-bit types. (The idea being this could be expanded later for higher bit types).

This would translate to functions:

function Foo(a: int32, b: int32): int32
{
    return a + b;
}
var foo = new function(): void { }

Then expanding more, users would be allowed to type functions making function parameters easy to understand:

function Foo(a: function(a: int32, b: int32): int32): void
{
}

Other type specifications allowed would be bool, string, and object with the concept that classes would fit seamlessly into the typing when added later.

Some specific rules would be applied. Integer data types would not throw exceptions when overflowing keeping them simple. Any binary operation would immediately convert a single and double type to corresponding uint32 and uint64 data types.

The untyped Number data type would convert to any of the other types if possible. It would be up to the programmer to ensure a Number variable fits into the required data type.

var foo = 1000;
var bar: uint8 = foo; // 232

However a programmer could explicitly convert the type with the following syntax:

var foo = (10 * 100): uint8;

This proposal would also include changes to Array, Map, and Set with a generic type syntax found in C#:

var foo = new Array<int8>(100); // Identical to Int8Array

var foo = new Array<string, int8>();

var foo = new Map<int32,object>();

var foo = new Set<object>();

It would work as one would expect only accepting a specifically defined type.

int and uint would correspond to big integer data types which would remove any current limitation with integer based math. they would support syntax for typed array like views.

var foo: uint = 9999999999999999999999999999999999999;
var bar: Array<uint8> = foo;

var baz: uint8 = bar[0];

These views would also work with the non-big integer types. So:

var foo: uint32 = 42;
var bar: Array<uint16> = foo;

var baz: uint16 = foo[0];

They would also be the only way to go from an uint32/64 and int32/64 to a single or double like:

var foo: uint32 = 42;

var bar: single = (foo: Array<single>)[0];

While more verbose than other possible proposals it keeps with one syntax for all bitwise conversions.

The last edge case I'd like to cover is making the changes work with Math:

var foo: uint32 = 42;
var bar: single = Math.cos((foo * 42):double);

By default the return type would be inferred by the input type or storage type (in this case single) and the function would be overloaded for different inputs. As another example Math.min and Math.max would return their input data type rather than Number when the types are specified.

Benefits to this proposal would be easier optimization to map to hardware and operators. It would also help to alleviate the issues that caused the need for the TypeArray spec. That is allowing the user to work with types that map to native hardware on the CPU and GPU.

For developers who work with binary formats this simplifies the usage of integer and floats along with their respective binary operators.

The main issue I see is that big integers are niche so it might be a bit naive to include them, but it's something I'd prefer was included as it makes the language flexible for the future. The other issue is defining any type of generic syntax using <> would need serious discussion if there are any issues making the system compatible.

Future additions this would allow would be function overloading, but I left that out as it complicates the proposal.

I've been looking through the archive for similar discussions as I assume something like this has been proposed before. If anyone has any related links that would be appreciated along with a discussion of issues or compatibility conflicts. (Or general feelings toward adding types in general as ECMAscript has been fairly unchanged over the years with to types).

# Rick Waldron (5 years ago)

Sorry for the top post, but I recommend reading this: strawman:value_types

# Domenic Denicola (5 years ago)
# Brandon Andrews (5 years ago)

On Sun, 10/27/13, Domenic Denicola <domenic at domenicdenicola.com> wrote:

Also www.slideshare.net/BrendanEich/js-resp/5, presented in convenient video form at www.youtube.com/watch?v=IXIkTrq3Rgg.

(I'm not sure how to replay to these. I see people bottom posting usually. Not overly familiar with mailing lists, so I hope this works).

Woah, I didn't see that video when I was searching. (Finding a bunch searching for ECMAscript 7 and 8 and simd now). That's exactly the direction I was hoping JS would go. I was actually typing up SIMD types, but removed it as it seemed too much to request. If they're willing to add all the types and the operators with swizzling support that would probably make JS nearly perfect for computing. (I have a few projects I did in the past which could have used it). I found a gist where someone wrote of a proposal apparently gist.github.com/jensnockert/7a0f6a99a0f3bde2facb , looks very well thought out, even including prefetch operations which would be amazing.

Looking at his direction and slides, then single and double in my proposal would be float32, float64 which is more aesthetically similar to the other types. I'm impressed at how well thought out everything is for the future of JS.

I see the slide with the types he's suggesting. Are there types for the int8/16/32, and uint8/16/32?

var foo = 0: float32;

On slide 14 he has float32(0) indicating something like the following (or using the literal syntax):

var foo = float32(42);

I was worried about suggesting something like that for compatibility with old code, but if that's the direction and has no issues, then it's perfect. I just realized that Brendan Eich created JS so I assume he fully knows about any compatability issues. His solution is cleaner for conversions.

With what he's proposing how do you perform a bitwise conversion from uint64 to a float64? I think the norm right now is to use the typed array spec with views for 32-bit conversions. (It comes up in a few problems). I assume they're adding Uint64Array and Int64Array with his proposed changes which would provide a solution for the bitwise conversion.

I think strong typing would be a really good idea with all of these types flying around. Found a few posts Brendan Eich made about strong typing. Can't figure out how he feels about that. Would static typing ever work for JS? Kind of like a "use static"; with proper all or nothing compilation?

# Brendan Eich (5 years ago)

Brandon Andrews <mailto:warcraftthreeft at sbcglobal.net> October 27, 2013 5:45 AM

(I'm not sure how to replay to these. I see people bottom posting usually. Not overly familiar with mailing lists, so I hope this works).

USENET norm applies (bottom posting, AKA top-citing -- and gmail will trick people into not trimming their citations, but please do).

Woah, I didn't see that video when I was searching. (Finding a bunch searching for ECMAscript 7 and 8 and simd now). That's exactly the direction I was hoping JS would go. I was actually typing up SIMD types, but removed it as it seemed too much to request. If they're willing to add all the types and the operators with swizzling support that would probably make JS nearly perfect for computing. (I have a few projects I did in the past which could have used it). I found a gist where someone wrote of a proposal apparently gist.github.com/jensnockert/7a0f6a99a0f3bde2facb , looks very well thought out, even including prefetch operations which would be amazing.

Looking at his direction and slides, then single and double in my proposal would be float32, float64 which is more aesthetically similar to the other types. I'm impressed at how well thought out everything is for the future of JS.

strawman:value_objects is the place where I will be editing ES7 value objects (shortly; in time for the November meeting, I hope). Please excuse the out-of-date material.

John McCutchan's SIMD polyfill, as my slides showed, is at johnmccutchan/ecmascript_simd. Emscripten now has a branch targeting SIMD intrinsics. Here's what Alon wrote recently:


I've implemented some SIMD support in emscripten, in a branch called 'simd'. Status is:

  1. There is a SIMD header, system/include/emscripten/vector.h, which defines float32x4 and uint32x4. They can be used for basic vector operations - load/store, add/subtract/multiple/divide - which LLVM translates into the proper LLVM vector instructions.

  2. Emscripten translates LLVM vector instructions into SIMD JS API calls, compatible with the polyfill.

  3. Currently some basic tests work, both using the explicit vector types from that new header, and LLVM's autovectorization (which generates the same LLVM vector instructions). (Supporting the vector types in emscripten turned out to be easier than I had anticipated, at least for basic usage.)

  4. This does not relate to asm.js yet, I am not sure what the status of SIMD in the type system there is. But for smaller benchmarks that should not prevent us from measuring useful numbers.

  5. The emscripten branch does not include the SIMD polyfill code yet (just waiting on a license for me to be able to merge it into emscripten), so the tests don't run out of the box yet, but you can just paste the polyfill at the top of the emscripten output and it should work. (To run the tests, do EM_SAVE_DIR=1 ./tests/runner.py other.test_simd or the same with simd2 at the end, output file will be in /tmp/emscripten_temp/a.out.js)

  6. The largest testcase I've tried on so far is autovectorization on the Linpack benchmark. I've been in touch with Heidi who has provided some more benchmarks, I think they would need to be converted from the SSE SIMD API into the more generic one, but I am not sure if all those benchmarks need fits in the JS API. Also not sure if we can't 'polyfill' the SSE API (or a part of it) using the simpler JS-compatible one somehow, if that were possible, we could perhaps avoid manually converting benchmarks?

  7. Using the explicit float32x4/uint32x4 types in C does not require any special compiler settings. The LLVM autovectorizer on the other hand is off by default, to enable it you need

    --llvm-opts "['-O3', '-vectorize', '-vectorize-loops', '-bb-vectorize-vector-bits=128', '-force-vector-width=4']"

    , see test_simd in tests/test_other.py for an example. I am considering adding an option to emcc such as --autovectorize which would add those 4 instructions, thoughts? (Perhaps it should always be on, once this is stable?)

So overall this is basically at the point where we can start to test compiled C code using the polyfill and/or JS engine support, when ready.

- Alon


I see the slide with the types he's suggesting.

("he" => me; hello.)

Are there types for the int8/16/32, and uint8/16/32?

var foo = 0: float32;

No one is proposing type annotations a la ES4 or TypeScript, note well.

Indeed although I call out float32 and int32/uint32, it makes sense to have value objects for all the sized int and IEEE-754 floating types.

On slide 14 he has float32(0) indicating something like the following (or using the literal syntax):

var foo = float32(42);

I was worried about suggesting something like that for compatibility with old code, but if that's the direction and has no issues, then it's perfect. I just realized that Brendan Eich created JS so I assume he fully knows about any compatability issues. His solution is cleaner for conversions.

Thanks :-). You're right that extant code on the Web might use float32 as a function name, but that's ok. As usual, JS's bindings in the global object are writable or otherwise replaceable, to allow user definitions to trump emergent built-ins. Object detection, e.g., something like

if (!this.float32)
   var float32 = function (x) {...};

may fail, but anything object detecting float32 should want what we aim to provide here -- if that name were used for a function with a different signature and semantics, I'd be sad but we would probably try to evangelize such object-detecting content.

It's extremely unlikely that anyone wrote a detection pattern for the name 'float32' without anticipating what I've been talking about lately, anyway.

Still, I've learned the hard way to never say never on the Web. I've seen almost every common name used in the global object's scope, and not always as one might expect. If we do run into a hard compatibility problem of the object-detection-for-mismatching-signature/semantics kind, we can use a built-in module. Indeed it may be better to do that anyway, although the typed arrays, Int8Array, etc., are all in global scope and require no import. If we do use a built-in module, then you'd have to say something like

import {int8, int16, int32, int64} from "@valueobjects";

where the "@valueobjects" name is a place-holder that may or may not be spelled anything like that.

With what he's proposing how do you perform a bitwise conversion from uint64 to a float64? I think the norm right now is to use the typed array spec with views for 32-bit conversions. (It comes up in a few problems).

See dherman/float.js.

I assume they're adding Uint64Array and Int64Array with his proposed changes which would provide a solution for the bitwise conversion.

Yes, we want 64-bit scalar and typed-array objects, both.

I think strong typing would be a really good idea with all of these types flying around. Found a few posts Brendan Eich made about strong typing. Can't figure out how he feels about that. Would static typing ever work for JS? Kind of like a "use static"; with proper all or nothing compilation?

I've written quite a bit about the problems adding static typing to JS ("strong typing" is ill-defined, it was used by marketeers in the past and that hurt). A fairly recent es-discuss thread:

esdiscuss.org/topic/optional-strong-typing

Quoting myself:

"ES4 failed in part because of AS3 namespaces (from original JS2/ES4 namespaces in 1999, also in JScript.NET in 2000, IIRC; inspired by Common Lisp symbol packages), but also because on the Web it's very hard to know /when/ to typecheck. Code loads all the time. Judgments may be invalidated down the road. The "any" type requires runtime checking."

# Brendan Eich (5 years ago)

Brendan Eich wrote:

Here's what Alon wrote recently:

Alon Zakai, creator of Emscripten, first among discoverers of asm.js.

# Tristan Zajonc (5 years ago)

I apologize for jumping in here with an incomplete understanding what's being proposed, but perhaps somebody can help clarify it for me. I've been following value types and operator overloading discussion with great interest. From the slides and video, it appears that operator overloading is only being discussed in the context of immutable value objects. Is this right? Or is it just what the examples use? If operator overloading only applies to value objects, what's the motivation?

I've implemented a large part of MATLAB/R like functionality in JavaScript. The biggest hurdle is a tolerable API for the core matrix and dataframe types. While perhaps silly, it's a deal breaker for some people coming from other environments. Otherwise, JS is an amazing platform, particularly with ES6 features.

A secondary issue, and probably a bigger can of worms, is whether the proposal will allow for additional operators. For matrices, there is a well-defined and established set of operators that operate elementwise and objectwise (MATLABs dot-operators vs. operators). The API Function.defineOperator(symbol, type1, type2) would be perfect to support this. However I assume this is not the intention? Is there any openness to supporting user defined infix operators or at least an extended set similar to Python's PEP 225 proposal (www.python.org/dev/peps/pep-0225)?

Sorry if my comments are based on not understanding the proposal.

# Brendan Eich (5 years ago)

Tristan Zajonc <mailto:tristan at senseplatform.com> October 27, 2013 5:47 PM

I apologize for jumping in here with an incomplete understanding what's being proposed, but perhaps somebody can help clarify it for me. I've been following value types and operator overloading discussion with great interest. From the slides and video, it appears that operator overloading is only being discussed in the context of immutable value objects. Is this right? Or is it just what the examples use? If operator overloading only applies to value objects, what's the motivation?

Do you mean "what's the motivation for not applying operators to mutable objects too?"

I've implemented a large part of MATLAB/R like functionality in JavaScript. The biggest hurdle is a tolerable API for the core matrix and dataframe types. While perhaps silly, it's a deal breaker for some people coming from other environments. Otherwise, JS is an amazing platform, particularly with ES6 features.

Mutable objects may want certain operators for convenience, but for mutable objects in JS, === must be reference (not transient value) identity, and == would be pretty bug-inducing if transient value comparing. Same comment for < and <=.

A secondary issue, and probably a bigger can of worms, is whether the proposal will allow for additional operators. For matrices, there is a well-defined and established set of operators that operate elementwise and objectwise (MATLABs dot-operators vs. operators).

What punctuators or (non-ASCII?) lexemes would you want for these operators?

The API Function.defineOperator(symbol, type1, type2) would be perfect to support this. However I assume this is not the intention? Is there any openness to supporting user defined infix operators or at least an extended set similar to Python's PEP 225 proposal (www.python.org/dev/peps/pep-0225)?

I'm not proposing syntactically novel operator extension. That is hard in a C-like language, but doable with enough work. It would be a separate proposal on top.

Sorry if my comments are based on not understanding the proposal.

No worries,

# Brendan Eich (5 years ago)

Brendan Eich wrote:

I'm not proposing syntactically novel operator extension. That is hard in a C-like language, but doable with enough work. It would be a separate proposal on top.

Just to set expectations, this won't be done quickly. As I understand it, sweetjs.org (macros for JS, Tim Disney's baby) needs to come along farther, and tackle "enforestation", before new infix operators support is anywhere near a strawman for an ECMA-262 future edition.

# Tristan Zajonc (5 years ago)

On Mon, Oct 28, 2013 at 8:14 AM, Brendan Eich <brendan at mozilla.com> wrote:

Do you mean "what's the motivation for not applying operators to mutable objects too?"

Yes. My question was why not mutable objects too? I definitely agree with the overall motivation.

Mutable objects may want certain operators for convenience, but for mutable objects in JS, === must be reference (not transient value) identity, and == would be pretty bug-inducing if transient value comparing. Same comment for < and <=.

Having === be reference equality is fine if that's a hard JS requirement. For a matrix API, there is some flexibility on comparison operators, but transient value comparison returning a single boolean is the most natural, other issues aside. I'm not sure I fully understand the bug you're worried about though.

What punctuators or (non-ASCII?) lexemes would you want for these operators?

I'd want every operator prefixed by something (dot, tilde, colon). You'd call these dot-operators, colon-operators, or extended-operators. One can go round-and-round on whether all these are necessary, but for matrices strictly separating objectwise/algebraic operators from elementwise/broadcasting operators has many advantages. The Julia and Mata languages have both adopted this approach. In this scheme, matrix + 1 is an error (they are not conformable for addition) and matrix .+ 1 is a matrix. Combining these tends to lead to bugs. These details would be up to the library though.

I'm not proposing syntactically novel operator extension. That is hard in a C-like language, but doable with enough work. It would be a separate proposal on top.

Complete flexibility is not necessary in the technical computing domain. Plenty of people have proposed more operators, but most are speculative and there's definitely a valid concern of introducing too many esoteric symbols.

# Brendan Eich (5 years ago)

Tristan Zajonc wrote:

Having === be reference equality is fine if that's a hard JS requirement. For a matrix API, there is some flexibility on comparison operators, but transient value comparison returning a single boolean is the most natural, other issues aside. I'm not sure I fully understand the bug you're worried about though.

if (mutMatA == mutMatB) {
     accidentallyMutate(mutMatA);
     assumeStillEqual(mutMatA, mutMatB, data);
}

It's true that in JS today, comparing an object to a non-object, valueOf or toString on the object can be used to make == results vary.

However, I'm proposing value objects with declarative syntax to solve several problems:

  1. Backward compatibility, so == uses cannot change unexpectedly on extant code, or grow performance hair in existing engines facing existing code.

  2. Solve the cross-frame problem where loading the same value class declaration results in the same typeof and other results for operations on values instantiated from equivalent declarations (details still being worked out).

  3. Facilitate functional programming, both for user benefit and for engines, which can better optimize based on immutable values (including stack allocation).

I'd want every operator prefixed by something (dot, tilde, colon).

JS uses dot, tilde and colon. But let's not get stuck here. I suggest that novel operator syntax needs a fresh thread, and that it should be informed by the SweetJS experience so far.

# Tristan Zajonc (5 years ago)

On Mon, Oct 28, 2013 at 4:03 PM, Brendan Eich <brendan at mozilla.com> wrote:

if (mutMatA == mutMatB) {
    accidentallyMutate(mutMatA);
    assumeStillEqual(mutMatA, mutMatB, data);
}

Is this bug related to operator overloading? It seems just the nature of the beast with mutable reference types. Pretty much all JS matrix libraries today use:

if (mutMatA.equals(mutMatB)) {
    accidentallyMutate(mutMatA);
    assumeStillEqual(mutMatA, mutMatB, data);
}

which I assume would suffer from the same bug?

It's true that in JS today, comparing an object to a non-object, valueOf or toString on the object can be used to make == results vary.

However, I'm proposing value objects with declarative syntax to solve several problems:

  1. Backward compatibility, so == uses cannot change unexpectedly on extant code, or grow performance hair in existing engines facing existing code.

  2. Solve the cross-frame problem where loading the same value class declaration results in the same typeof and other results for operations on values instantiated from equivalent declarations (details still being worked out).

  3. Facilitate functional programming, both for user benefit and for engines, which can better optimize based on immutable values (including stack allocation).

On 3, I think mutability is a required option for matrix libraries. While immutable matrix APIs are interesting, I do not believe anybody has successfully implemented a flexible high performance immutable matrix library in any language. I think the key user demand is porting basic MATLAB like numeric code to JS, which wouldn't be possible with an immutable library.

Can value objects / immutability be separated from operator overloading?

JS uses dot, tilde and colon. But let's not get stuck here. I suggest that novel operator syntax needs a fresh thread, and that it should be informed by the SweetJS experience so far.

Will do.

# Brendan Eich (5 years ago)

Tristan Zajonc wrote:

Is this bug related to operator overloading? It seems just the nature of the beast with mutable reference types. Pretty much all JS matrix libraries today use:

if (mutMatA.equals(mutMatB)) {
    accidentallyMutate(mutMatA);
    assumeStillEqual(mutMatA, mutMatB, data);
}

which I assume would suffer from the same bug?

You bet, but special forms exist to have primitive semantics, which can be meta-programmed only in certain ways (we try to preserve certain invariants). With .equals, anything goes. With == where both operands are object references, there has been an invariant. Allowing operator customization to break that invariant might be worth the downside, but it deserves discussion.

# Brendan Eich (5 years ago)

Tristan Zajonc wrote:

On 3, I think mutability is a required option for matrix libraries. While immutable matrix APIs are interesting, I do not believe anybody has successfully implemented a flexible high performance immutable matrix library in any language. I think the key user demand is porting basic MATLAB like numeric code to JS, which wouldn't be possible with an immutable library.

The Haskell folks will disagree with you, but I'll let them speak for themselves.

Item 2 is important but hard to get right in the face of mutable objects and prototype chains.

Can value objects / immutability be separated from operator overloading?

Almost certainly. I'm starting with value objects because in design, leaving things out (without necessarily being future-hostile to extension) is generally better than trying to do include too much.

The value class syntax (operator multimethods) that I showed at JSConf.eu could easily be class syntax, as you surmised.

# Tristan Zajonc (5 years ago)

On Tue, Oct 29, 2013 at 10:04 AM, Brendan Eich <brendan at mozilla.com> wrote:

You bet, but special forms exist to have primitive semantics, which can be meta-programmed only in certain ways (we try to preserve certain invariants). With .equals, anything goes. With == where both operands are object references, there has been an invariant. Allowing operator customization to break that invariant might be worth the downside, but it deserves discussion.

Got it, worthy of discussion. My user data point is that I've never assumed == has that invariant. Overloading equals is a bigger deal, but it's not clear users should expect invariance given existing toString/valueOf issues. So +1 for this not being a blocker to extending your operator proposal more broadly.

# Tristan Zajonc (5 years ago)

On Tue, Oct 29, 2013 at 10:08 AM, Brendan Eich <brendan at mozilla.com> wrote:

The Haskell folks will disagree with you, but I'll let them speak for themselves.

My point here is only that I don't think JS should adjudicate this debate in the context of operators. It seems like this discussion should happen if a Matrix type is added to the core of JS. Having operators would encourage the development of cow paths.

Item 2 is important but hard to get right in the face of mutable objects and prototype chains.

I don't understand this issue well enough to comment.

Almost certainly. I'm starting with value objects because in design, leaving things out (without necessarily being future-hostile to extension) is generally better than trying to do include too much.

The value class syntax (operator multimethods) that I showed at JSConf.eu could easily be class syntax, as you surmised.

Got it. I'm a fan of the syntax and dispatch mechanism.

# Tristan Zajonc (5 years ago)

One clarification on the value objects proposal... The JSConf slides say that immutability is implemented as an implicit Object.freeze(this) on return in the constructor. Is this meant as shorthand for a deep freeze?

# Brendan Eich (5 years ago)

Tristan Zajonc wrote:

One clarification on the value objects proposal... The JSConf slides say that immutability is implemented as an implicit Object.freeze(this) on return in the constructor. Is this meant as shorthand for a deep freeze?

Yes, although depth may be hard to generalize. A deepFreeze can be self-hosted in ES6 using Object.freeze and weak maps. But I'm still considering using only typed objects for state, which have the advantage of being flat.

More in the strawman when I update it (next week or the week after).

# Brandon Andrews (4 years ago)

Took a break while I worked on some Javascript projects for the past year to see if they'd give me more perspective on types. I'll keep this short though.

Brendan Eich wrote:

No one is proposing type annotations a la ES4 or TypeScript, note well.

I'm thinking the discussion needs to start up again for the sake of JS's future. Basically building a base for other languages and also making JS a more complete language by itself. Before I get into that though I have a few comments and questions.

Starting with this video from Brendan Eich that was linked: www.youtube.com/watch?v=IXIkTrq3Rgg

Regarding Literal Syntax ( www.slideshare.net/BrendanEich/js-resp/14 ) used in other languages I think Javascript could handle it cleaner without arbitrary suffixes like L, UL, f, n, and m. I'm not totally against the idea, but would constructors always work as an alternative? bignum(1234567890). If so it seems fine. (I just want to make sure the literal syntax is optional for all proposed types).

The proposed operator overloading syntax ( www.slideshare.net/BrendanEich/js-resp/15 ) has the right idea, but I think partial classes might be a cleaner approach. Basically being able to define the same class multiple times and having their implementations merged ignoring duplicates.

value class vector2d
{
    x: float32;
    y: float32;
    get Length():float32
    {
        return Math.sqrt(x * x + y * y); // uses Math.sqrt(v:float32):float32 due to input and return type
    }
    constructor(x:float32 = 0, y:float32 = 0)
    {
        this.x = x;
        this.y = y;
    }
    operator +(v:vector2d)
    {
        return vector2d(this.x + v.x, this.y + v.y); // return value type
    }
    operator ==(v:vector2d)
    {
        // equality check between this and v
    }
}
// In MyClass.js defined extensions to vector2d
class vector2d
{
    operator ==(v:MyClass)
    {
        // equality check between this and MyClass
    }
}

The implementation would then just need to update the current class definition as Javascript files are loaded. The other advantage with this is it allows for organization of operators which can be convenient for math objects that are required to work with many objects or third party code.

For value type classes are they always passed by reference? I didn't see anything regarding pass by reference syntax. Do value classes have a copy constructor or something for cloning objects in that case?

Okay onto typing. Ultimately what I'd like to happen is for an ECMA member to understand the value of static typing for JS and help turn this into a rough draft proposal that can be expanded on with critiques.

What I keep seeing from years of conversation are comments like in this thread: esdiscuss.org/topic/optional-argument-types

Brendan Eich wrote:

Types are hard. This doesn't mean "no, never". But big brains are still researching the general topic, and btw what Dart has can't be called types according to the researchers and literature I trust.

There's not even a proposal for people to begin discussing the grammar and implications on JS though. It was given mild interest years ago, but it's past the time for putting off the discussion. (Also it doesn't look like anyone is against adding this. I've read a large part of the mailing list so far which discusses typing a lot).

So what a static typing proposal should have at the minimal are the following types (lowercase seems to look best I think):

bool
string
uint8/16/32/64
int8/16/32/64
float32/64
bignum
decimal
int32x4, int32x8
uint32x4, uint32x8
float32x4, float32x8

I saw the following mentioned in Brendan's slides and they'd probably be nice if a standardized interface and implementation is found:

rational
complex

The ability to type any variable including lambdas. I'd go with the already proposed syntax that's been around for years. I've read the old guard and trademarks type proposals, but they seem unneeded for now.

var foo:uint8 = 0;
var foo = uint8(0); // cast

var foo:(int32, string):string; // hold reference to a signature of this type
var foo = (s:string, x:int32) => s + x; // implicit return type of string

var foo = (x:uint8, y:uint8):uint16 => x + y; // explicit return type

Support for typed arrays.

var foo:uint8[] = [1, 2, 3, 4];

Support for nullable types.

var foo:uint8? = null;

Function signatures with constraints.

function Foo(a:int32, b:string, c:bignum[], callback:(string, bool)):int32 { }

Function overloading:

function Foo(x:int32[]) { return "int32"; }
function Foo(s:string[]) { return "string"; }

Foo(["test"]); // "string"

So by default Number would convert implicitly with precedence given to decimal, float64, float32, uint64/32/16/8, int64/32/16/8. (Or whichever order makes the most sense).

Then lastly, support within the currently proposed class syntax to support multiple constructors and fixed size classes.

// 4 byte object
value class myType
{
    x:float32; // be able to define members outside of the constructor
    constructor(x:float32)
    {
        this.x = x;
    }
    constructor(y:uint32)
    {
        this.x = float32(y) * 2;
    }
}
var t:myType = 1; // float32 implicit constructor call

Implicit constructors could also be added to the proposed SIMD classes to go from a scalar to a vector.

var v:float32x4 = 1; // would be equivalent to var v = float32(1, 1, 1, 1);

These static typing rules expand the language greatly. They allow for other features to be added later like arrays of POD types:

var t:myType[] = [1, 2, 3, uint32(1)];

That's not necessary though, but it's nice to keep that in mind.

Judging from previous conversations the idea of static typing for ECMAScript is over 10 years old, so any discussion would probably last for a few years. It would be nice to see a proposal written by someone familiar with the current issues along with the plans for the future to make an optional typing system seamless. Also I'm not proposing any form of a strict "using static"; or something since it's expected static and dynamic typing would be mixed a lot. Even in my examples with variadic functions it can be nice having untyped arguments. Having a single proposal for bringing up issues and more examples would be nice also.

# Florian Bösch (4 years ago)

On Mon, Nov 24, 2014 at 9:00 AM, Brandon Andrews < warcraftthreeft at sbcglobal.net> wrote:

float32/64

  • float16: common name: half, IEEE 754-2008: binary16, often used on GPUs
  • float32: common name: float, IEEE 754-2008: binary32
  • float64: common name: double, IEEE 754-2008: binary64
  • float128: common name: quad, IEEE 754-2008: binary 128, often used in scientific computing
  • float80: common name: x86 extended precision, IEEE 754-2008 permissible extended percision format, often used instead of float128 because speed on x86

decimal

  • decimal32: IEEE 754-2008: decimal32
  • decimal64: IEEE 754-2008: decimal64
  • decimal128: IEEE 754-2008: decimal128

FTFY

# Brandon Andrews (4 years ago)

float16/80

decimal32/64/128

Those are reasonable additions also. Wasn't sure with decimal was going to assume 128 bit for financial type applications. Having it vary with 32, 64, and 128 bit thought is much closer to the other suggestions. (I updated my original post on esdiscuss to include them.)

I saw your esdiscuss post