[idea] One more call operator

# Andrew Fedoniouk (12 years ago)

In typical JS code we can see things like these:

el.on("click", function() {....}); el.myplugin({....});

The syntax noise above is obvious I think.

In principle nothing prevents us to modify JS grammar so statements above can be rewritten as:

el.on :: "click", function() {....}; el.myplugin :: {....};

Or even this: (one token lookahead required)

el.on : "click", function() {....}; el.myplugin : {....};

So formal rule for CallExpression may look like as

CallExpression : MemberExpression Arguments or MemberExpression '::' ArgumentList

Not that much but can make it more readable.

-- Andrew Fedoniouk.

terrainformatica.com

# Michael Haufe (12 years ago)

Looks more like an architecture problem to me than a language one. There is plenty of sugar available already

el.on("click", function(e) {....});

using the existing arrow syntax:

el.on("click", e => ...)

using a constant instead of a string (it is a flag after all...):

el.on(click, e => ...)

And for your object:

el.myplugin({....});

you can use a setter:

el.myplugin = {...}

# Andrew Fedoniouk (12 years ago)

On Sat, Jul 20, 2013 at 2:21 PM, Michael Haufe <tno at thenewobjective.com> wrote:

Looks more like an architecture problem to me than a language one. There is plenty of sugar available already

el.on("click", function(e) {....});

using the existing arrow syntax:

el.on("click", e => ...)

using a constant instead of a string (it is a flag after all...):

el.on(click, e => ...)

That, indeed, may reduce noise but with proposed change all this will look even cleaner:

el.on : click, e => $(this).addClass("clicked");

And for your object:

el.myplugin({....});

you can use a setter:

el.myplugin = {...}

Unfortunately setters do not work with jQuery where chained calls are used frequently:

el.myplugin({....}) .addClass("myplugin");

that with new syntax may look like as:

el.myplugin: { params } .addClass: "myplugin";

-- Andrew Fedoniouk.

terrainformatica.com

# Till Schneidereit (12 years ago)

On Sun, Jul 21, 2013 at 12:17 AM, Andrew Fedoniouk < news at terrainformatica.com> wrote:

Unfortunately setters do not work with jQuery where chained calls are used frequently:

el.myplugin({....}) .addClass("myplugin");

that with new syntax may look like as:

el.myplugin: { params } .addClass: "myplugin";

This is ambiguous. Is addClass a method on the { params } object, or is it a chained method call, as you want it to be? That is, the example could just as well translate to this:

el.myplugin({ params }.addClass("myplugin"));

# Rick Waldron (12 years ago)

On Sat, Jul 20, 2013 at 6:27 PM, Till Schneidereit < till at tillschneidereit.net> wrote:

On Sun, Jul 21, 2013 at 12:17 AM, Andrew Fedoniouk < news at terrainformatica.com> wrote:

Unfortunately setters do not work with jQuery where chained calls are used frequently:

el.myplugin({....}) .addClass("myplugin");

that with new syntax may look like as:

el.myplugin: { params } .addClass: "myplugin";

This is ambiguous. Is addClass a method on the { params } object,

No it's not, {}.addClass throws a syntax error exception:

{foo:1}.foo; // SyntaxError at the "."

({foo:1}).foo; // 1

# Till Schneidereit (12 years ago)

On Sun, Jul 21, 2013 at 12:44 AM, Rick Waldron <waldron.rick at gmail.com>wrote:

On Sat, Jul 20, 2013 at 6:27 PM, Till Schneidereit < till at tillschneidereit.net> wrote:

On Sun, Jul 21, 2013 at 12:17 AM, Andrew Fedoniouk < news at terrainformatica.com> wrote:

Unfortunately setters do not work with jQuery where chained calls are used frequently:

el.myplugin({....}) .addClass("myplugin");

that with new syntax may look like as:

el.myplugin: { params } .addClass: "myplugin";

This is ambiguous. Is addClass a method on the { params } object,

No it's not, {}.addClass throws a syntax error exception:

{foo:1}.foo; // SyntaxError at the "."

({foo:1}).foo; // 1

Oh, right, thanks.

@Andrew, is the idea to use this syntax only when passing either object or function literals? For those, it wouldn't be ambiguous, indeed. For everything else, though, it would be:

el.myplugin: objectwithparams .addClass: "myplugin";

# Andrew Fedoniouk (12 years ago)

On Sat, Jul 20, 2013 at 3:27 PM, Till Schneidereit <till at tillschneidereit.net> wrote:

On Sun, Jul 21, 2013 at 12:17 AM, Andrew Fedoniouk <news at terrainformatica.com> wrote:

Unfortunately setters do not work with jQuery where chained calls are used frequently:

el.myplugin({....}) .addClass("myplugin");

that with new syntax may look like as:

el.myplugin: { params } .addClass: "myplugin";

This is ambiguous. Is addClass a method on the { params } object, or is it a chained method call, as you want it to be? That is, the example could just as well translate to this:

el.myplugin({ params }.addClass("myplugin"));

Yep, my bad, wrong example.

-- Andrew Fedoniouk.

terrainformatica.com

# Rick Waldron (12 years ago)

On Sat, Jul 20, 2013 at 4:05 PM, Andrew Fedoniouk <news at terrainformatica.com

wrote:

In typical JS code we can see things like these:

el.on("click", function() {....}); el.myplugin({....});

The syntax noise above is obvious I think.

In principle nothing prevents us to modify JS grammar so statements above can be rewritten as:

el.on :: "click", function() {....}; el.myplugin :: {....};

I disagree with the implication that this is a good use for "::" as new syntax.

Or even this: (one token lookahead required)

More then that, a whole new language that doesn't yet have existing grammar rules...

el.on : "click", function() {....}; el.myplugin : {....};

If the function at the call site isn't the method of an object, both examples above turn into code that is already completely valid JavaScript in the existing grammar

Given:

function foo(o) { return o; }

The first turns into a labelled statement, followed by a comma operator expression:

foo: "click", function() {}; // function() {}

The second turns into a label statement, followed by an empty block body:

foo: {}; // undefined

# Andrew Fedoniouk (12 years ago)

On Sat, Jul 20, 2013 at 3:55 PM, Till Schneidereit <till at tillschneidereit.net> wrote:

On Sun, Jul 21, 2013 at 12:44 AM, Rick Waldron <waldron.rick at gmail.com> wrote: ...

No it's not, {}.addClass throws a syntax error exception:

{foo:1}.foo; // SyntaxError at the "."

({foo:1}).foo; // 1

Oh, right, thanks.

@Andrew, is the idea to use this syntax only when passing either object or function literals? For those, it wouldn't be ambiguous, indeed. For everything else, though, it would be:

el.myplugin: objectwithparams .addClass: "myplugin";

Yeah, that's kind of weak moment.

-- Andrew Fedoniouk.

terrainformatica.com

# Rick Waldron (12 years ago)

On Sat, Jul 20, 2013 at 7:37 PM, Rick Waldron <waldron.rick at gmail.com>wrote:

On Sat, Jul 20, 2013 at 4:05 PM, Andrew Fedoniouk < news at terrainformatica.com> wrote:

In typical JS code we can see things like these:

el.on("click", function() {....}); el.myplugin({....});

The syntax noise above is obvious I think.

In principle nothing prevents us to modify JS grammar so statements above can be rewritten as:

el.on :: "click", function() {....}; el.myplugin :: {....};

I disagree with the implication that this is a good use for "::" as new syntax.

Or even this: (one token lookahead required)

More then that, a whole new language that doesn't yet have existing grammar rules...

el.on : "click", function() {....}; el.myplugin : {....};

If the function at the call site isn't the method of an object, both examples above turn into code that is already completely valid JavaScript in the existing grammar

Given:

function foo(o) { return o; }

The first turns into a labelled statement, followed by a comma operator expression:

foo: "click", function() {}; // function() {}

The second turns into a label statement, followed by an empty block body:

Sorry, typo—this should say "labelled statement" (it is the same as the previous example)

# Rick Waldron (12 years ago)

On Sat, Jul 20, 2013 at 6:55 PM, Till Schneidereit < till at tillschneidereit.net> wrote:

On Sun, Jul 21, 2013 at 12:44 AM, Rick Waldron <waldron.rick at gmail.com>wrote:

On Sat, Jul 20, 2013 at 6:27 PM, Till Schneidereit < till at tillschneidereit.net> wrote:

On Sun, Jul 21, 2013 at 12:17 AM, Andrew Fedoniouk < news at terrainformatica.com> wrote:

Unfortunately setters do not work with jQuery where chained calls are used frequently:

el.myplugin({....}) .addClass("myplugin");

that with new syntax may look like as:

el.myplugin: { params } .addClass: "myplugin";

This is ambiguous. Is addClass a method on the { params } object,

No it's not, {}.addClass throws a syntax error exception:

{foo:1}.foo; // SyntaxError at the "."

({foo:1}).foo; // 1

Oh, right, thanks.

@Andrew, is the idea to use this syntax only when passing either object or function literals? For those, it wouldn't be ambiguous, indeed.

Except that it would be:

function foo(o) {o}

foo: { label: 1; }; // 1

This is a labelled statement, followed by a block body (not an object literal—note the semi-colon inside, following the 1). The block body then has a labelled statement the contains the identifier "label" and its statement is the expression statement "1;". The number 1 is returned because it is the last expression statement in the block's statement list that returns a value.

# Andrew Fedoniouk (12 years ago)

On Sat, Jul 20, 2013 at 4:37 PM, Rick Waldron <waldron.rick at gmail.com> wrote:

On Sat, Jul 20, 2013 at 4:05 PM, Andrew Fedoniouk <news at terrainformatica.com> wrote:

...

Or even this: (one token lookahead required)

More then that, a whole new language that doesn't yet have existing grammar rules...

It is far less complex than that "fat arrow" syntax.

el.on : "click", function() {....}; el.myplugin : {....};

If the function at the call site isn't the method of an object, both examples above turn into code that is already completely valid JavaScript in the existing grammar

Given:

function foo(o) { return o; }

The first turns into a labelled statement, followed by a comma operator expression:

foo: "click", function() {}; // function() {}

The second turns into a label statement, followed by an empty block body:

foo: {}; // undefined

As I said that requires one token lookahead:

name ':' while|for|do -> labeled statement, else

name ':' ArgumentList -> function call

The main problem may arise with '?' operator though.

var r = cond ? name1 : name2;

Such function call has to have less precedence than the '?' to keep existing code correct.

-- Andrew Fedoniouk.

terrainformatica.com

# Rick Waldron (12 years ago)

On Sat, Jul 20, 2013 at 7:53 PM, Andrew Fedoniouk <news at terrainformatica.com

wrote:

On Sat, Jul 20, 2013 at 4:37 PM, Rick Waldron <waldron.rick at gmail.com> wrote:

On Sat, Jul 20, 2013 at 4:05 PM, Andrew Fedoniouk <news at terrainformatica.com> wrote:

...

Or even this: (one token lookahead required)

More then that, a whole new language that doesn't yet have existing grammar rules...

It is far less complex than that "fat arrow" syntax.

Fat arrow isn't ambiguous with existing grammar, which implies that it is indeed less complex.

el.on : "click", function() {....}; el.myplugin : {....};

If the function at the call site isn't the method of an object, both examples above turn into code that is already completely valid JavaScript in the existing grammar

Given:

function foo(o) { return o; }

The first turns into a labelled statement, followed by a comma operator expression:

foo: "click", function() {}; // function() {}

The second turns into a label statement, followed by an empty block body:

foo: {}; // undefined

As I said that requires one token lookahead:

name ':' while|for|do -> labeled statement, else

This is incomplete.

The following is a syntactically valid ES program, that never mentions "while|for|do"

label: "click", function() {};

label: "click", function() {};

function label(o) { return o; } label: {};

label: {};

label: var a = "hi!";

label: var a = "hi!";

label: function foo() {}

label: function foo() {}

label: (a = 1);

label: (a = 1);

label: [1, 2, 3, 4];

label: [1, 2, 3, 4];

label:;

name ':' ArgumentList -> function call

See above.

The main problem may arise with '?' operator though.

var r = cond ? name1 : name2;

Such function call has to have less precedence than the '?' to keep existing code correct.

Sure, this can be the "main" problem if you want.

# Brendan Eich (12 years ago)

Andrew Fedoniouk wrote:

As I said that requires one token lookahead:

name ':' while|for|do -> labeled statement, else name ':' ArgumentList -> function call

In fact there's no restriction in LabelledStatement that only loops come after the label and colon. For one think, break to label can occur in an 'if' or block statement. Another point: on the web, accidental javascript: labels creep from URLs into code. These have been observed. They generally label expression statements, which may be parenthesized at the start.

The main problem may arise with '?' operator though.

var r = cond ? name1 : name2;

Such function call has to have less precedence than the '?' to keep existing code correct.

Write the grammar in full, then argue it's simpler than alternatives. For now you seem to be tilting at windmills still.