Re: Can `new` be optional?
> Why does calling a class throw an exception instead of just creating a new instance backward compatibility and early "rushed" behavior is one of the reasons. `String() instanceof String` is false and it's just one example. Because of primitives and `typeof`, `new Symbol` throws too, you are not meant to do that. Array and Regexp though, have no primitive namespace, but that's old gotcha later specs tried to prevent. What about `new Date` ? Now that's an instance, while `Date()` is a string. Using `new` makes your intent unambiguous in a PL where functions can be used as constructors too. There is also the possibility to create functions that cannot be used as `new`: ```js const method = {method(){}}.method; new method; // throws ``` Accordingly, since you have Reflect for all procedural use cases, what is the benefit of not using `new` where it's an instance of that Class you are after? ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Can `new` be optional?
> I also don't see how decorators can solve it. Making to wrapper for class constructor to allow the constructor to callable would be fairly straightforward, e.g. ``` function callable(cls) { function Wrapper(...args) { return Reflect.construct(cls, args, new.target || cls); } Object.defineProperty(Wrapper, "name", { value: cls.name }); Object.setPrototypeOf(Wrapper, cls); Wrapper.prototype = cls.prototype; return Wrapper; } const Example = callable(class Example {}); Example(); ``` and thus potentially ``` @callable class Example {} ``` I know you said "At the cost of non-zero overhead." but it seems like this would be something engines could optimize more easily than proxies. > This seems like a really short sighted issue. Why can't calling a class just invoke it's constructor? I think the big question for me when discussing this with people is, is it more surprising to throw a clear error in these case, or to do something close but not quite the same as if it were an ES5-style constructor? ``` class Foo { constructor() { this.foo = 4; } } var obj = {}; var inst = Foo.call(obj); // what happens? // obj.foo => 4 or undefined // inst => obj, new object, or undefined // inst.foo => 4 or undefined ``` To be consistent with ES6 class semantics it has to be that a new instance is returned and `obj` is 100% ignored but that are very much not what you'd get if you replaced the class there with `function Foo(){ this.foo = 4; }`. Isn't that its own set of confusing changes? Specifically for "This seems like a really short sighted issue" I'd say this is the opposite of short-sighted. There's nothing preventing support for this in the future, but if it got added with a behavior that ended up confusing people _more_ than not having it at all, then we'd be stuck with it for good. On Sun, Nov 5, 2017 at 11:53 AM, J Deckerwrote: > > > On Sun, Nov 5, 2017 at 7:53 AM, Andrea Giammarchi < > andrea.giammar...@gmail.com> wrote: > >> oldie but goldie ? >> >> ```js >> Object.defineProperty( >> Function.prototype, >> 'new', >> { >> configurable: true, >> value(...args) { >> return new this(...args); >> } >> } >> ); >> ``` >> >> doesn't make new optional, just moves it, and doesn't apply to 'class'es > which the OP is saying. > > >> >> >> >> >> On Sun, Nov 5, 2017 at 11:28 AM, Oriol _ >> wrote: >> >>> > Why can't `new` be optional? >>> >>> When you call a function, you are using the internal [[Call]] method. >>> When you use the `new` operator, it's the internal [[Construct]] method. >>> >>> They are different things, so IMO avoiding `new` when you are >>> instantiating is bad practice. >>> >>> > Of course it is... with out new, classes throw an exception. > > This seems like a really short sighted issue. Why can't calling a class > just invoke it's constructor? > > I also don't see how decorators can solve it. > > Seems just as arbitrary as the underscore proposal not accepting > underscore trailing a number or before or after a decimal. > > Maybe, it would be better to ask 'Why does calling a class throw an > exception instead of just creating a new instance. > > >> But if you really want to avoid `new` when using ES6 `class` syntax, you >>> can use proxies, e.g. >>> >>> ```js >>> let MyClass = new Proxy(class MyClass { >>> constructor(arg) { this.arg = arg; } >>> }, { >>> apply: (target, thisArg, args) => Reflect.construct(target, args) >>> }); >>> MyClass(1); // { arg: 1 } >>> new MyClass(2); // { arg: 2 } >>> ``` >>> >> > At the cost of non-zero overhead. > > >> --Oriol >>> >>> ___ >>> es-discuss mailing list >>> es-discuss@mozilla.org >>> https://mail.mozilla.org/listinfo/es-discuss >>> >>> >> >> ___ >> es-discuss mailing list >> es-discuss@mozilla.org >> https://mail.mozilla.org/listinfo/es-discuss >> >> > > ___ > es-discuss mailing list > es-discuss@mozilla.org > https://mail.mozilla.org/listinfo/es-discuss > > ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Syntax is the Problem
This is projective editing. See for example https://www.jetbrains.com/mps/ On 5 November 2017 at 13:22, Michael Lewiswrote: > Raul-Sebastian Mihăilă just made a post here about some mixin syntax. I > didn't read it (sorry). > > But, it got me thinking about a concept I've been thinking for years: *syntax > is the problem*, and there's a better solution. > > If you define syntax as a human <--> computer language (a human-readable > and computer-readable form of text), you necessarily need a very strictly > defined syntax. One missing curly, and you're f'd. > > Duh, we all know this. Hang onto your pants for a second, let's explore > an alternative. > > What if we edited scripts more directly in AST form (abstract syntax > tree). Developers could implement their own UI to manipulate this AST. > There are many, many benefits to this, I'll get to in a second. > > First, let's remember what everyone in the JS community is doing right > now: running their code through transpilers. (I refuse to do this, that's > why I'm unemployed - I strongly dislike the concept). What is a > transpiler? It's an unofficial middleman that interprets the syntax, > converts it to an AST, performs transformations, and then returns the AST > to syntax form. > > Suddenly, scripting in AST form doesn't sound so crazy. > > Clearly, you wouldn't be writing JSON. We would be using a GUI to create > the AST. And this is the greatest benefit: moving away from *syntax*, > and moving to a GUI. > > Then, instead of babel plugins that provide alternative *syntax*, you > could have plugins that provide alternative *experiences.* > > What would designing a class look like, if using a GUI? > >1. Click [ create new class ] >2. Click [ add new method ] > > Or, click the [ extend ] button next to an existing class... > > This is the future. I have to go eat breakfast, but I'd love to discuss > this future if anyone is interested... > > ___ > es-discuss mailing list > es-discuss@mozilla.org > https://mail.mozilla.org/listinfo/es-discuss > > ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Can `new` be optional?
On Sun, Nov 5, 2017 at 7:53 AM, Andrea Giammarchi < andrea.giammar...@gmail.com> wrote: > oldie but goldie ? > > ```js > Object.defineProperty( > Function.prototype, > 'new', > { > configurable: true, > value(...args) { > return new this(...args); > } > } > ); > ``` > > doesn't make new optional, just moves it, and doesn't apply to 'class'es which the OP is saying. > > > > > On Sun, Nov 5, 2017 at 11:28 AM, Oriol _> wrote: > >> > Why can't `new` be optional? >> >> When you call a function, you are using the internal [[Call]] method. >> When you use the `new` operator, it's the internal [[Construct]] method. >> >> They are different things, so IMO avoiding `new` when you are >> instantiating is bad practice. >> >> Of course it is... with out new, classes throw an exception. This seems like a really short sighted issue. Why can't calling a class just invoke it's constructor? I also don't see how decorators can solve it. Seems just as arbitrary as the underscore proposal not accepting underscore trailing a number or before or after a decimal. Maybe, it would be better to ask 'Why does calling a class throw an exception instead of just creating a new instance. > But if you really want to avoid `new` when using ES6 `class` syntax, you >> can use proxies, e.g. >> >> ```js >> let MyClass = new Proxy(class MyClass { >> constructor(arg) { this.arg = arg; } >> }, { >> apply: (target, thisArg, args) => Reflect.construct(target, args) >> }); >> MyClass(1); // { arg: 1 } >> new MyClass(2); // { arg: 2 } >> ``` >> > At the cost of non-zero overhead. > --Oriol >> >> ___ >> es-discuss mailing list >> es-discuss@mozilla.org >> https://mail.mozilla.org/listinfo/es-discuss >> >> > > ___ > es-discuss mailing list > es-discuss@mozilla.org > https://mail.mozilla.org/listinfo/es-discuss > > ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Syntax is the Problem
You may be interested in [this][1]. It's actually not that uncommon in childrens' programming, animation, and other less technical needs for scripting. Also, consider [Node-RED][2], which is also a visual platform for the Internet of Things (with a JS core, but you rarely need to actually dive into JS for most things). [1]: https://en.wikipedia.org/wiki/Visual_programming_language [2]: https://nodered.org/ - Isiah Meadows m...@isiahmeadows.com Looking for web consulting? Or a new website? Send me an email and we can get started. www.isiahmeadows.com On Sun, Nov 5, 2017 at 8:22 AM, Michael Lewiswrote: > Raul-Sebastian Mihăilă just made a post here about some mixin syntax. I > didn't read it (sorry). > > But, it got me thinking about a concept I've been thinking for years: > syntax is the problem, and there's a better solution. > > If you define syntax as a human <--> computer language (a human-readable and > computer-readable form of text), you necessarily need a very strictly > defined syntax. One missing curly, and you're f'd. > > Duh, we all know this. Hang onto your pants for a second, let's explore an > alternative. > > What if we edited scripts more directly in AST form (abstract syntax tree). > Developers could implement their own UI to manipulate this AST. There are > many, many benefits to this, I'll get to in a second. > > First, let's remember what everyone in the JS community is doing right now: > running their code through transpilers. (I refuse to do this, that's why > I'm unemployed - I strongly dislike the concept). What is a transpiler? > It's an unofficial middleman that interprets the syntax, converts it to an > AST, performs transformations, and then returns the AST to syntax form. > > Suddenly, scripting in AST form doesn't sound so crazy. > > Clearly, you wouldn't be writing JSON. We would be using a GUI to create > the AST. And this is the greatest benefit: moving away from syntax, and > moving to a GUI. > > Then, instead of babel plugins that provide alternative syntax, you could > have plugins that provide alternative experiences. > > What would designing a class look like, if using a GUI? > > Click [ create new class ] > Click [ add new method ] > > Or, click the [ extend ] button next to an existing class... > > This is the future. I have to go eat breakfast, but I'd love to discuss > this future if anyone is interested... > > ___ > es-discuss mailing list > es-discuss@mozilla.org > https://mail.mozilla.org/listinfo/es-discuss > ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Web Docs
Not on the committee, but IMHO that should be up to MDN rather than TC39. Also, you *could* look at the [meeting notes][1], specifically the summaries of each meeting, to see what happened. Alternatively, someone *could* create a centralized resource of what each meeting decided. (I'd personally do it if I got a Patreon set up and got some funding to do it, to make up for the lost productivity elsewhere.) [1]: https://esdiscuss.org/notes - Isiah Meadows m...@isiahmeadows.com Looking for web consulting? Or a new website? Send me an email and we can get started. www.isiahmeadows.com On Sun, Nov 5, 2017 at 7:29 AM, Michael Lewiswrote: > tl;dr Maybe there needs to be an official blog? And/or summarize decisions > on MDN? > > With the advent of transpiling, the state of the ES language is in greater > flux than ever before. This group guides the development of the language > itself. Then there are the implementers of your specifications. I won't > pretend to know how it works, but it's safe to say, "it's like trying to hit > a moving target." While standing on a moving platform. > > When Andrea Giammarchi just wrote a post here showing an example of > extending the native Array "class", I wasn't aware that was even > possible/recommended. > > I found an article from 2015 the other day, and scoured at it's age. "This > is worthless! Nothing from 2015 is still valid today." It's very common to > discover some new syntax, and not really know what it is. Is it a babel > plugin? TypeScript? ES9000? Where can I use it? When should I use it? > > If this is the "official" JavaScript Steering Committee, then it would make > sense that you should produce the authoritative documentation, and publish > the authoritative announcements/reasoning. > > For example, when TC39 decided to remove properties from classes, there > should have been an announcement. It seems like many people disagree with > this decision (myself included). > > The MDN web docs are trying to be the go to place for all things web. Yet, > I still google, "can i use es6 classes" to find browser compatibility info. > Because MDN has already dissected "all the things" (they have navigation and > pages for all the topics you might discuss), documenting certain design > decisions on their site might make the most sense. Maybe you just start > with a TC39 Design Notes sub page that can be added in various places. > > We should condense, summarize, and publish the enormously complex work that > is going on in these back channels. Basically, extract the most important > stuff. Extract the signal from the noise, and share it in an official > place. > > What is this community's stance on documentation? > > > ___ > es-discuss mailing list > es-discuss@mozilla.org > https://mail.mozilla.org/listinfo/es-discuss > ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Definition mixins
Saying "you don't need this if you follow my personal way of doing things" isn't helpful at all. Especially when these views are *controversial*. On 5 Nov 2017 4:27 pm, "kai zhu"wrote: the problem is that you chose to write the chess program in javascript, instead of say, python or c#. why did you choose javascript? probably because you intend the chess program to be an online webapp. mixins, like classes, are inferior to plain json-objects for webapps. how do you intend to serialize the mixin board-state so you can sync it with a friend in an online match? the i/o part of a webapp is typically as challenging as the business-logic of the game itself. it would be more efficient if you represented the board-state as a json-object, so it can be easily serailized and shared with other online players, and use static functions to manipulate the json-data. here's a functional web-demo of a simple connect4 game using only json-objects and static functions (in 400 lines of code). -kai https://github.com/kaizhu256/node-connect4 ```js /* * test.js * * this file contains the standalone connect-4 game * * setup instructions * 1. save this file as test.js * 2. install nodejs * 3. run the shell command *$ PORT=8081 node test.js * 4. open browser to url http://localhost:8081 * 5. play the connect4 game! */ /*jslint bitwise: true, browser: true, maxerr: 8, maxlen: 96, node: true, nomen: true, regexp: true, stupid: true */ (function () { 'use strict'; var local; // run shared js-env code - pre-init (function () { // init local local = {}; // init modeJs local.modeJs = (function () { try { return typeof navigator.userAgent === 'string' && typeof document.querySelector('body') === 'object' && typeof XMLHttpRequest.prototype.open === 'function' && 'browser'; } catch (errorCaughtBrowser) { return module.exports && typeof process.versions.node === 'string' && typeof require('http').createServer === 'function' && 'node'; } }()); // init global local.global = local.modeJs === 'browser' ? window : global; local.nop = function () { /* * this function will do nothing */ return; }; // export local local.global.local = local; }()); // run shared js-env code - function (function () { local.gameStateCreate = function () { /* * this function will create a new game state */ var state; state = {}; state.board = [ // -> rows [0, 0, 0, 0, 0, 0], // | [0, 0, 0, 0, 0, 0], // v [0, 0, 0, 0, 0, 0], // [0, 0, 0, 0, 0, 0], // c [0, 0, 0, 0, 0, 0], // o [0, 0, 0, 0, 0, 0], // l [0, 0, 0, 0, 0, 0] // s ]; state.playerCurrent = 1; state.streakToWin = 4; return state; }; local.playerMove = function (state, positionCol) { /* * this function will perform a move * by dropping the state.playerCurrent's disc in the given positionCol, * and then checks to see if it wins the game */ var colList, ii, positionRow, streak; if (state.ended) { state.error = new Error('game ended'); } if (state.error) { // debug error console.error(state.error.stack); return; } if (positionCol === 'random') { while (true) { positionCol = Math.floor(Math.random() * state.board.length); colList = state.board[positionCol] || []; if (colList[colList.length - 1] === 0) { break; } } } state.positionCol = positionCol; colList = state.board[positionCol] || []; // naive algorithm to deposit disc in the last unfilled positionRow in colList for (ii = 0; ii < colList.length; ii += 1) { if (colList[ii] === 0) { positionRow = ii; colList[positionRow] = state.playerCurrent; // debug board console.log(state.board.join('\n')); break; } } if (positionRow === undefined) { state.error = new Error('invalid move'); // debug error console.error(state.error.stack); return; } // naive
Re: Definition mixins
On Sun, Nov 5, 2017 at 5:27 PM, kai zhuwrote: > the problem is that you chose to write the chess program in > javascript, instead of say, python or c#. > Kai, you're off-topic. The topic is mixins, not chess games. Please refrain from disrupting this thread. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Can `new` be optional?
oldie but goldie ? ```js Object.defineProperty( Function.prototype, 'new', { configurable: true, value(...args) { return new this(...args); } } ); ``` On Sun, Nov 5, 2017 at 11:28 AM, Oriol _wrote: > > Why can't `new` be optional? > > When you call a function, you are using the internal [[Call]] method. When > you use the `new` operator, it's the internal [[Construct]] method. > > They are different things, so IMO avoiding `new` when you are > instantiating is bad practice. > > But if you really want to avoid `new` when using ES6 `class` syntax, you > can use proxies, e.g. > > ```js > let MyClass = new Proxy(class MyClass { > constructor(arg) { this.arg = arg; } > }, { > apply: (target, thisArg, args) => Reflect.construct(target, args) > }); > MyClass(1); // { arg: 1 } > new MyClass(2); // { arg: 2 } > ``` > > --Oriol > > ___ > es-discuss mailing list > es-discuss@mozilla.org > https://mail.mozilla.org/listinfo/es-discuss > > ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Definition mixins
Actually the mix obj must be extensible but must be an exotic object so that it's extended only through the mixin mechanism. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Definition mixins
the problem is that you chose to write the chess program in javascript, instead of say, python or c#. why did you choose javascript? probably because you intend the chess program to be an online webapp. mixins, like classes, are inferior to plain json-objects for webapps. how do you intend to serialize the mixin board-state so you can sync it with a friend in an online match? the i/o part of a webapp is typically as challenging as the business-logic of the game itself. it would be more efficient if you represented the board-state as a json-object, so it can be easily serailized and shared with other online players, and use static functions to manipulate the json-data. here's a functional web-demo of a simple connect4 game using only json-objects and static functions (in 400 lines of code). -kai https://github.com/kaizhu256/node-connect4 ```js /* * test.js * * this file contains the standalone connect-4 game * * setup instructions * 1. save this file as test.js * 2. install nodejs * 3. run the shell command *$ PORT=8081 node test.js * 4. open browser to url http://localhost:8081 * 5. play the connect4 game! */ /*jslint bitwise: true, browser: true, maxerr: 8, maxlen: 96, node: true, nomen: true, regexp: true, stupid: true */ (function () { 'use strict'; var local; // run shared js-env code - pre-init (function () { // init local local = {}; // init modeJs local.modeJs = (function () { try { return typeof navigator.userAgent === 'string' && typeof document.querySelector('body') === 'object' && typeof XMLHttpRequest.prototype.open === 'function' && 'browser'; } catch (errorCaughtBrowser) { return module.exports && typeof process.versions.node === 'string' && typeof require('http').createServer === 'function' && 'node'; } }()); // init global local.global = local.modeJs === 'browser' ? window : global; local.nop = function () { /* * this function will do nothing */ return; }; // export local local.global.local = local; }()); // run shared js-env code - function (function () { local.gameStateCreate = function () { /* * this function will create a new game state */ var state; state = {}; state.board = [ // -> rows [0, 0, 0, 0, 0, 0], // | [0, 0, 0, 0, 0, 0], // v [0, 0, 0, 0, 0, 0], // [0, 0, 0, 0, 0, 0], // c [0, 0, 0, 0, 0, 0], // o [0, 0, 0, 0, 0, 0], // l [0, 0, 0, 0, 0, 0] // s ]; state.playerCurrent = 1; state.streakToWin = 4; return state; }; local.playerMove = function (state, positionCol) { /* * this function will perform a move * by dropping the state.playerCurrent's disc in the given positionCol, * and then checks to see if it wins the game */ var colList, ii, positionRow, streak; if (state.ended) { state.error = new Error('game ended'); } if (state.error) { // debug error console.error(state.error.stack); return; } if (positionCol === 'random') { while (true) { positionCol = Math.floor(Math.random() * state.board.length); colList = state.board[positionCol] || []; if (colList[colList.length - 1] === 0) { break; } } } state.positionCol = positionCol; colList = state.board[positionCol] || []; // naive algorithm to deposit disc in the last unfilled positionRow in colList for (ii = 0; ii < colList.length; ii += 1) { if (colList[ii] === 0) { positionRow = ii; colList[positionRow] = state.playerCurrent; // debug board console.log(state.board.join('\n')); break; } } if (positionRow === undefined) { state.error = new Error('invalid move'); // debug error console.error(state.error.stack); return; } // naive algorithm to check for win condition in the column // e.g. // [ // -> rows // [1, 1, 1, 1, 0, 0], // | // [2, 2, 2, 0, 0, 0], // v // [0, 0,
Definition mixins
Also, in the same context, for different mixin associated objects there will be different mix objects: ```js function F() { const obj = {}; const obj2 = {}; mixin obj, mixin1; mixin obj2, mixin2; } function mixin1() { return (obj, mix) => {}; } function mixin2() { return (obj, mix) => {}; } ``` The mix argument that the mixin function created by mixin2 receives will be different from the one received by the mixin function created by mixin1 because obj1 !== obj2. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Can `new` be optional?
> Why can't `new` be optional? When you call a function, you are using the internal [[Call]] method. When you use the `new` operator, it's the internal [[Construct]] method. They are different things, so IMO avoiding `new` when you are instantiating is bad practice. But if you really want to avoid `new` when using ES6 `class` syntax, you can use proxies, e.g. ```js let MyClass = new Proxy(class MyClass { constructor(arg) { this.arg = arg; } }, { apply: (target, thisArg, args) => Reflect.construct(target, args) }); MyClass(1); // { arg: 1 } new MyClass(2); // { arg: 2 } ``` --Oriol ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Definition mixins
One issue that just occurred to me is that we want different families of mixin functions to have access to different mix objects, so that one family doesn't have access to mixin functions from another family (since they're private and the constructor must decide what private data shares with the mixin functions). So different mix object could be created for different families based on the reference's base value (by reference I mean the reference that is used to specify the mixin function). ```js mixin obj, mixinModule.func1; mixin obj, mixinModule.func2; mixin obj, func3; ``` Here func1 and func2 will use the same mix object and func3 will have another mix object. Another solution would be, since normally mixin functions are imported from other modules, to have the source module of the mixin function as the grouping key for the mixin functions, even if the base value of the reference is an environment record (like in func3's case). If the mixin functions belong to the current module it's fine for them to share the private state. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Syntax is the Problem
Raul-Sebastian Mihăilă just made a post here about some mixin syntax. I didn't read it (sorry). But, it got me thinking about a concept I've been thinking for years: *syntax is the problem*, and there's a better solution. If you define syntax as a human <--> computer language (a human-readable and computer-readable form of text), you necessarily need a very strictly defined syntax. One missing curly, and you're f'd. Duh, we all know this. Hang onto your pants for a second, let's explore an alternative. What if we edited scripts more directly in AST form (abstract syntax tree). Developers could implement their own UI to manipulate this AST. There are many, many benefits to this, I'll get to in a second. First, let's remember what everyone in the JS community is doing right now: running their code through transpilers. (I refuse to do this, that's why I'm unemployed - I strongly dislike the concept). What is a transpiler? It's an unofficial middleman that interprets the syntax, converts it to an AST, performs transformations, and then returns the AST to syntax form. Suddenly, scripting in AST form doesn't sound so crazy. Clearly, you wouldn't be writing JSON. We would be using a GUI to create the AST. And this is the greatest benefit: moving away from *syntax*, and moving to a GUI. Then, instead of babel plugins that provide alternative *syntax*, you could have plugins that provide alternative *experiences.* What would designing a class look like, if using a GUI? 1. Click [ create new class ] 2. Click [ add new method ] Or, click the [ extend ] button next to an existing class... This is the future. I have to go eat breakfast, but I'd love to discuss this future if anyone is interested... ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Definition mixins
I've been successfully experimenting with a kind of mixins which is different from the naive mixin solution (for instance based on Object.assign) and from functional mixins ( https://medium.com/javascript-scene/functional-mixins-composing-software-ffb66d5e731c). I call them definition mixins. The reason I'm bringing this up is that the definition mixins solution is verbose and custom syntax would be useful to simplify things. Using traditional functions we can create constructors that hold private state. The main difference between definition mixins and the other ones is that the mixins share private state with the context where they are used. In this way, they are intimately connected to the context where the object is created. It's important to note that the constructor will choose what private state to share with the mixins. Other differences: - you don't get the gorilla-banana problem - you don't get property collisions at all (unlike the other mixins where the last object always wins) - beside sharing private state, another advantage is that you explicitly pick the functions that you want to mix in, so it's clear what the object's structure is by simply looking at its definition (which can be useful in a dynamic language like js). Beside sharing private state, the other issues with the other kinds of mixins can be solved by using specific APIs with which you explicitly list the functions you're interested in. Example: Let's say we have a game of chess. We have a game board that is used to play the game and a building board that is used to create specific positions and then start a game from those positions. The game board and the building board are similar because they have similar state and logic to update that state (for instance whether the position is checkmate, stalemate etc.) because we want to create a game board from a building board and vice versa. They are also different because a simple board will have a move function that moves a piece and updates the state of the board. A possible move is en passant. You can not perform en passant in a building board, because the building board is not used for playing the game. The building board has a deletePiece function that is used to remove any number of pieces from the board anytime. The game board doesn't have such a function because the only way a piece can be removed during a game is by following the rules of chess. The game board also handles promoting pawns, while the building board doesn't. ```js // board file import * as boardMixin from '...'; function Board({board: fromBoard}) { const mix = { kings: {}, currentMove }; let promotingPawn = null; const board = boardMixin.create(); board.currentSide = null; board.isPromoting = false; board.isCheckmate = false; board.isStalemate = false; board.isDraw = false; const isSafeMove = mix.isSafeMove = boardMixin.isSafeMove(mix); const setBoardResolution = mix.setBoardResolution = boardMixin.setBoardResolution(board, mix); board.isSquareAttacked = boardMixin.isSquareAttacked(board); board.getPiece = boardMixin.getPiece(board); board.move = (piece, x, y) => { // ... if (!isSafeMove(piece, x, y)) { return false; } setBoardResolution(); }; // ... } ``` --- ```js // building-board file import * as boardMixin from '...'; function BuildingBoard({board: fromBoard}) { const mix = { kings: {}, currentMove: null }; const board = boardMixin.create(); board.currentSide = null; board.isCheckmate = false; board.isStalemate = false; board.isDraw = false; const setBoardResolution = mix.setBoardResolution = boardMixin.setBoardResolution(board, mix); board.getPiece = boardMixin.getPiece(board); board.isBoardPlayable = () => { // ... }; board.deletePiece = (piece) => { // ... setBoardResolution(); }; } ``` --- ```js // board-mixin file // mixin functions: const isSafeMove = (mix) => (piece, x, y) => { // ... }; const setBoardResolution = (board, mix) => () => { // ... board.isCheckmate = true; }; // ... ``` In this example we're creating mixin functions that become public or private methods in the constructor. The mix object is used to hold the mixin functions as a mixin function might want to use another mixin function. Also, in our example we're also holding in the mix object the private state that we wish to share with the mixin functions. The board object is an array of arrays and because we use it in the mixin functions we need to make sure that it's created before the mixin functions are mixed into the constructor. Mixin functions such as isSafeMove are also assigned to consts because we want to easily call them in the constructor, without having to use the mix object. This is verbose. It would be niced if we could: - create bindings for the mixin functions in the constructor more easily - add the mixin functions to the mix object more easily - create the board
Re: Can `new` be optional?
Is there a technical limitation, or just an opinion? If I call an ES6 `class MyClass {}` without new: `MyClass()`, it throws. Just change this bit to do whatever `new` was supposed to do. Problem solved? On Sun, Nov 5, 2017 at 6:01 AM, Michał Wadaswrote: > This was covered by "call constructor" proposal, but unfortunately, it was > withdrawn. > > https://github.com/tc39/ecma262/blob/master/workingdocs/callconstructor.md > > Status: "Withdrawn: can be solved with decorators" - > https://github.com/tc39/proposals/blob/master/inactive-proposals.md > > On 5 Nov 2017 12:55 pm, "Michael Lewis" wrote: > >> Why can't `new` be optional? >> >> I found this thread, https://esdiscuss.org/topic/ob >> soleting-the-new-keyword, but it's so long (and 9 years old), I didn't >> read much of it. Can someone summarize the current status of this decision? >> >> On a side note, it seems the ES Steering Committee needs a wiki - a place >> to document important decisions. I feel like the MDN web docs would be a >> good place to put all levels of documentation. I'm going to make a new >> thread about docs, it's so important... >> >> >> Anyway, in my ES5 "classes", I use an `if (!(this instanceof Class)) >> return new Class()` (similar to what jQuery does) to avoid having to use >> `new`. I feel like there should be a way to build this into the language. >> >> I have a `View()` class that is invoked a lot: >> >> ``` >> View().append({ >> one: View(...), >> two: View(View(...), View(...)) >> }); >> ``` >> >> And, being forced to write `new View()` every time is actually the only >> reason why I won't switch to native classes, at the moment. >> >> >> ___ >> es-discuss mailing list >> es-discuss@mozilla.org >> https://mail.mozilla.org/listinfo/es-discuss >> >> ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Web Docs
tl;dr Maybe there needs to be *an official blog*? And/or summarize decisions on MDN? With the advent of transpiling, the state of the ES language is in greater flux than ever before. This group guides the development of the language itself. Then there are the implementers of your specifications. I won't pretend to know how it works, but it's safe to say, "it's like trying to hit a moving target." While standing on a moving platform. When Andrea Giammarchi just wrote a post here showing an example of extending the native Array "class", I wasn't aware that was even possible/recommended. I found an article from 2015 the other day, and scoured at it's age. "This is worthless! Nothing from 2015 is still valid today." It's very common to discover some new syntax, and not really know what it is. Is it a babel plugin? TypeScript? ES9000? Where can I use it? When should I use it? If this is the "official" JavaScript Steering Committee, then it would make sense that you should produce the authoritative documentation, and publish the authoritative announcements/reasoning. For example, when TC39 decided to remove properties from classes, there should have been an announcement. It seems like many people disagree with this decision (myself included). The MDN web docs are trying to be the go to place for all things web. Yet, I still google, "can i use es6 classes" to find browser compatibility info. Because MDN has already dissected "all the things" (they have navigation and pages for all the topics you might discuss), documenting certain design decisions on their site might make the most sense. Maybe you just start with a TC39 Design Notes sub page that can be added in various places. We should condense, summarize, and publish the enormously complex work that is going on in these back channels. Basically, extract the most important stuff. Extract the signal from the noise, and share it in an official place. What is this community's stance on documentation? ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Can `new` be optional?
This was covered by "call constructor" proposal, but unfortunately, it was withdrawn. https://github.com/tc39/ecma262/blob/master/workingdocs/callconstructor.md Status: "Withdrawn: can be solved with decorators" - https://github.com/tc39/proposals/blob/master/inactive-proposals.md On 5 Nov 2017 12:55 pm, "Michael Lewis"wrote: > Why can't `new` be optional? > > I found this thread, https://esdiscuss.org/topic/ > obsoleting-the-new-keyword, but it's so long (and 9 years old), I didn't > read much of it. Can someone summarize the current status of this decision? > > On a side note, it seems the ES Steering Committee needs a wiki - a place > to document important decisions. I feel like the MDN web docs would be a > good place to put all levels of documentation. I'm going to make a new > thread about docs, it's so important... > > > Anyway, in my ES5 "classes", I use an `if (!(this instanceof Class)) > return new Class()` (similar to what jQuery does) to avoid having to use > `new`. I feel like there should be a way to build this into the language. > > I have a `View()` class that is invoked a lot: > > ``` > View().append({ > one: View(...), > two: View(View(...), View(...)) > }); > ``` > > And, being forced to write `new View()` every time is actually the only > reason why I won't switch to native classes, at the moment. > > > ___ > es-discuss mailing list > es-discuss@mozilla.org > https://mail.mozilla.org/listinfo/es-discuss > > ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Can `new` be optional?
Why can't `new` be optional? I found this thread, https://esdiscuss.org/topic/obsoleting-the-new-keyword, but it's so long (and 9 years old), I didn't read much of it. Can someone summarize the current status of this decision? On a side note, it seems the ES Steering Committee needs a wiki - a place to document important decisions. I feel like the MDN web docs would be a good place to put all levels of documentation. I'm going to make a new thread about docs, it's so important... Anyway, in my ES5 "classes", I use an `if (!(this instanceof Class)) return new Class()` (similar to what jQuery does) to avoid having to use `new`. I feel like there should be a way to build this into the language. I have a `View()` class that is invoked a lot: ``` View().append({ one: View(...), two: View(View(...), View(...)) }); ``` And, being forced to write `new View()` every time is actually the only reason why I won't switch to native classes, at the moment. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss