What optimizations? On Thursday, 17 December 2015, Isiah Meadows <[email protected]> wrote:
> @Alex Those languages have this thing called static types, which enable > many of those optimizations. > > On Thu, Dec 17, 2015, 04:09 Alexander Jones <[email protected] > <javascript:_e(%7B%7D,'cvml','[email protected]');>> wrote: > >> I think we can do better than to follow C#'s lead, if that's the case. I >> don't see what the point in `Color.Red - Color.Green` is. Languages like >> Rust, Swift, OCaml are providing full Algebraic Data Types that approach >> this whole domain from a better level. Also, I don't like the idea of >> overloading enum for both sets of combineable flags and sets of distinct >> values - that seems like a lack of a good abstraction. Look to Qt for IMO a >> pretty good one: http://doc.qt.io/qt-4.8/qflags.html >> >> Alex >> >> >> On Wednesday, 16 December 2015, Ron Buckton <[email protected] >> <javascript:_e(%7B%7D,'cvml','[email protected]');>> wrote: >> >>> In C#, an enum is a declaration that defines a distinct type consisting >>> of a set of named constant values of that type. The distinct type of the >>> enum has an underlying numeric base type, such as byte, int, long, etc. By >>> default, each constant value is assigned an incrementing integer value >>> starting from 0, although this sequence can be interrupted by assigning an >>> explicit integer value: >>> >>> ```cs >>> enum Colors { Red, Green, Blue } >>> Colors.Red // 0 >>> Colors.Green // 1 >>> Colors.Blue // 2 >>> >>> enum Days: byte { Sat = 1, Sun, Mon, Tue, Wed, Thu, Fri } >>> Days.Sat // 1 >>> Days.Sun // 2 >>> ``` >>> >>> C# enum values can be used with many standard numeric operations, and >>> are often heavily used with bitwise operators. A C# enum value is a >>> constant value, and is internally treated as a numeric literal by the >>> compiler. In any C# enum declaration, only constant numeric values can be >>> explicitly assigned to an enum member, although constant reduction is >>> permitted: >>> >>> ```cs >>> enum UriComponents { >>> Scheme = 0x1, >>> UserInfo = 0x2, >>> Host = 0x4, >>> Port = 0x8, >>> Path = 0x10, >>> Query = 0x20, >>> Fragment = 0x40, >>> AbsoluteUri = Scheme | UserInfo | Host | Port | Path | Query | Fragment >>> } >>> ``` >>> >>> Although C# enum values are converted to numeric literals by the >>> compiler, their type information is preserved. This allows for an enum type >>> to have different behavior from a literal numeric type. One example of this >>> behavior is how ToString is handled on an enum value: >>> >>> ```cs >>> enum Numbers { Zero, One, Two } >>> (int)Numers.Zero // 0 >>> Numbers.Zero.ToString() // Zero >>> ``` >>> >>> The enum type itself has a number of static methods to make it easier to >>> program against, including: GetName, GetNames, GetUnderlyingType, >>> IsDefined, Parse, and ToObject. Instance members of an enum type include >>> HasFlag and CompareTo. >>> >>> In TypeScript we treat an enum declaration in a fashion similar to a C# >>> enum, with respect to how we handle incremental integer values and >>> explicitly assigned values. We effectively emit an enum as an object >>> literal: >>> >>> ```ts >>> // TypeScript >>> enum Colors { Red, Green, Blue } >>> >>> Colors.Red // 0 >>> >>> // JavaScript >>> var Colors; >>> (function (Colors) { >>> Colors[Colors[0] = "Red"] = 0; >>> Colors[Colors[1] = "Green"] = 1; >>> Colors[Colors[2] = "Blue"] = 2; >>> })(Colors || (Colors = {})); >>> >>> Colors.Red // 0 >>> ``` >>> >>> In this way, you can use `Colors.Red` to get the value 0, and >>> `Colors[0]` to get the value "Red". As a performance optimization we also >>> have what we call "const enums". A const enum can be completely erased by >>> the compiler: >>> >>> ```ts >>> // TypeScript >>> const enum Colors { Red, Green, Blue } >>> >>> Colors.Red // 0 >>> >>> // JavaScript >>> 0 /*Colors.Red*/ // 0 >>> ``` >>> >>> I think a general proposal for ES enums would be a combination of the >>> above approaches, with some additions: >>> >>> * An enum can be a declaration or an expression. >>> * The body of an enum consists of a new lexical scope. >>> * Enum members are standard JavaScript identifiers. >>> * Enum members are automatically assigned an incrementing integer value, >>> starting at zero. >>> * Enum members can be explicitly assigned to an integer value, or >>> another enum value. >>> * Within the body of an enum, Enum members can be accessed in the >>> initializer without qualification. >>> * Within the body of an enum, Enum members are lexically declared names >>> and cannot be accessed before they are defined (TDZ). >>> * An enum declaration can be called as a function to convert a string or >>> numeric value into the enum value, making enum types distinct from numbers >>> and from each other. [1] >>> * The result of `typeof` on an enum value is `enum`. >>> * Enum values support (at least) the following operators, returning an >>> enum value of the same type: + (unary), - (unary), ~, + (binary), - >>> (binary), | (binary), & (binary), ^ (binary). >>> * Any binary operation between two enums of different types is a >>> TypeError. [1] >>> * Any binary operation between an enum and a number first converts the >>> number to the enum type. If the number is not an integer it is a TypeError. >>> * Any binary operation between an enum and a string first converts the >>> enum into the string value for that enum based on the enum member's >>> JavaScript identifier (if present), or the string representation of its >>> integer numeric value. [2] >>> * Calling Number() with an enum value as its first argument returns its >>> underlying number value. >>> * Calling String() with an enum value as its first argument returns the >>> string value for the enum member that defines the number (if present), or >>> the string representation of its integer numeric value. [2] >>> * Calling the valueOf() instance method on an enum value has the same >>> effect as Number() above. >>> * Calling the toString() instance method on an enum value has the same >>> effect as String() above. [2] >>> * Two enum members on the same enum or differing enum types with the >>> same underlying integer value are equivalent (==) but not >>> strictly/reference equivalent (===). [1] >>> >>> I think these rules could satisfy both anyone who needs enum values to >>> be numeric (to support bitwise operations, bitmasks, ordinal indices, etc.) >>> and those that would like enum values to be unique in a fashion similar to >>> using Symbol(). >>> >>> [1] We have noticed in TypeScript some issues with Symbol-like >>> equivalence with enums if you have two versions of the same module in >>> NodeJS due to specific version dependencies, where you could have >>> a.Color.Red !== b.Color.Red if *a* and *b* are different versions of the >>> same module. Generally I think having enum values just really be numbers >>> and not differing between == and === is less of a footgun. >>> >>> [2] If enum values of different types should be === to each other, you >>> should not be able to get a different result when you call .ToString(). In >>> that case, we could add a static `getName` method to the enum type to get >>> the string value for an enum. >>> >>> Ron >>> >>> > -----Original Message----- >>> > From: es-discuss [mailto:[email protected]] On Behalf Of >>> > Brendan Eich >>> > Sent: Wednesday, December 16, 2015 10:04 AM >>> > To: Alican Çubukçuoğlu <[email protected]>; es- >>> > [email protected] >>> > Subject: Re: Re: Propose simpler string constant >>> > >>> > On Wed, Dec 16, 2015 at 9:41 AM Alican Çubukçuoğlu >>> > <[email protected] <mailto:[email protected]> > >>> > wrote: >>> > >>> > >>> > How are enums declared? >>> > ```javascript >>> > let myVar = 13; >>> > enum myEnum = {Red, Green, Blue}; >>> > >>> > >>> > No `=` between name and `{`. >>> > >>> > Enumerator scope is a good question. Clearly we do not want global >>> scope. >>> > Rather, as a declaration immedicately contained by a block or top >>> > level, we want lexical scope for the enum name -- and (I think) for >>> the enumerators' >>> > individual names. >>> > >>> > What about enumerator name scope for enum in class, without `static`? >>> > I'm not sure, but precedent says that the enumerator names define >>> > prototype properties. >>> > >>> > Expression as well as declaration `enum` form follows class and >>> > function precedent. Expression form requires a reserved identifier >>> > (not sym or sum or whatever), which `enum` has been forever, >>> fortunately. >>> > >>> > I agree symbol values by default, with ` = 0` or some other number >>> > than >>> > 0 after the first enumerator name, looks confusing. Recall the first >>> > use-case in the o.p. was (implicit, should rather be explicit) >>> > reflection on the string value that spells the enumerator name. >>> > >>> > /be >>> _______________________________________________ >>> es-discuss mailing list >>> [email protected] >>> https://mail.mozilla.org/listinfo/es-discuss >>> >> _______________________________________________ >> es-discuss mailing list >> [email protected] >> <javascript:_e(%7B%7D,'cvml','[email protected]');> >> https://mail.mozilla.org/listinfo/es-discuss >> >
_______________________________________________ es-discuss mailing list [email protected] https://mail.mozilla.org/listinfo/es-discuss

