Proposal: expression mode (=)
potentially, this syntax can be extended to functions
function f() ={stat}
// is equivalent to
function f() {return stat}
let f = () => ={stat}
// are equivalent to
let f = () => stat
it can also be applied to try...catch
.... and more, such as
// pattern matching
match(expr) {
pattern1:={
//block
}
pattern2:={
//block
}
pattern3:={
//block
}
}
Sounds like the "do expressions" proposal. strawman:do_expressions
Yes, it does the exact same thing. I think using = and operators is a bit cleaner than 'do'. However, The biggest advantage for this feature is you can write functional code without extra syntax. Allowing block to return value will allow you to write concise code like in ocaml Haskell or scala.
OMG sweet! I love it. then how it’ll be formed when mixed with labeled statement?
ambiguous case
let x = {
// statements here?
label: ’value'
};
I think label: ’value'
is not a legal statement I think, so you actually
can distinguish them.
On Oct 30, 2016, at 10:45 AM, Yad Smood <y.s.inside at gmail.com> wrote:
I think
label: ’value'
is not a legal statement I think, so you actually can distinguish them.
"use strict"; is a valid Statement, so why not?
My read of this was that it uses := instead of = to work around this ambiguity.
I think the do-expressions idea is more powerful, though, since it's a valid RHS operand to any binary op, whereas this looks limited to assignment.
Ah, nevermind, I guess := was just used in the pattern matching example. So, there is a grammar ambiguity here.
For supporting label, yes that is kinda a problem. However, IMO jumping around labels is an anti-pattern in functional programming, I don't think it needs to be supported. Syntax error might be the most reasonable way in this case.
for 'match', while it is just some thought. I wasn't intended to proposal
it but just showing potential of extending = expression
.
Personally I do not think label would be a problem for implementing this pattern.
here are two possible solutions I can think of:
-
If
[name]:
exist inside the block, just parse it as object and throw error if the structure doesn't match. -
If
[label]:
does exist inside the block, only allow in scope jump. (label not accessible outside the scope)
For what it's worth, if the =
requires a space before it (I disagree that
the semantic ambiguity must exist at assignment - it could simply require
whitespace), that alone would create sufficient context to differentiate.
Compare these two:
a == {} // loose equals, almost always false
a = = {} // a = undefined
Labels would already be unambiguous, because it can only parse statements.
Here's my concern about ambiguity, though:
var b = 1
var a = b
= { c }
What's a
? ASI makes this much less obvious to resolve, and resolving this
by changing assignment to require no line terminator before the =
is
technically a breaking change. (Oh, and the Closure Compiler can and will
spit out that.)
Isiah,
The reason for =
instead of the do expression
is to write functional
code without extra syntax. I do not think there are any indistinguishable
or 'very confusing' case, though I am aware the *Object Property Shorthand`
that been introduced in ES6 might cause some problems.
Here is what I think that may resolve this problem for your concern,
var b = 1
var a = b
= { c }
the solution is to make Object literals
to have higher parsing priority.
if c
is a variable, it will be parsed as object literal
, otherwise it
is considered as scope and been parsed as expression block.
ex.
var x = { a }
will be parsed as var x = { a: a }
var x = { a() }
will be parsed as var x = a()
, under current specs it
would be syntax error.
In this case, this proposal should not cause any confusion IMO.
Not quite. I did some later thinking, and hage found probably a simpler solution.
On Mon, Oct 31, 2016, 16:10 Yongxu Ren <renyongxu at gmail.com> wrote:
Isiah, The reason for
=
instead of thedo expression
is to write functional code without extra syntax. I do not think there are any indistinguishable or 'very confusing' case, though I am aware the *Object Property Shorthand` that been introduced in ES6 might cause some problems.Here is what I think that may resolve this problem for your concern,
var b = 1 var a = b = { c }
the solution is to make
Object literals
to have higher parsing priority.
Actually, the above example should read as this:
a
= { b }
First, most linters will complain, anyways.
Second, it could be resolved by requiring no line terminator appears
between the assignee and =
operator. The Closure Compiler is okay with
emitting such code normally, but no other minifier does by default. And
those can be fixed.
if
c
is a variable, it will be parsed asobject literal
, otherwise it is considered as scope and been parsed as expression block.ex.
var x = { a }
will be parsed asvar x = { a: a }
var x = { a() }
will be parsed asvar x = a()
, under current specs it would be syntax error.
You missed the original proposal here. Your examples should be this (with
the preceding =
):
var x = = { a }
var x = = { a() }
In this case, this proposal should not cause any confusion IMO.
To clarify, I'm mentioning parser ambiguity, not visual (which does exist to some extent).
Isiah, In your case, if we do
var x = = { a }
there isn't much difference from the do expression
, actually, it might be
worse since it looks confusing. if it can not be omitted, I'd rather stay
with do
.
The intent for this proposal is to allow writing better functional code in
javascript. IMO, the do expression
is a good start, but I think using =
(and other operators) is a more elegant since it can be omitted.
Actually, I think I have a better idea to put it together:
1. besides defining a function, if the block can be legally be replaced by an expression, while otherwise it would cause parsing error, convert it to expression block
2. if the case is ambiguous or it is been used in function declaration,
adding =
(actually, using do
here isn't a bad idea either, but can be
quite ugly for defining function) will enforce block to be parsed as
expression
The goal is to make javascript more functional friendly.
I like the idea of expressions over statements (it's actually my preference), but not at the cost of breaking everything (feel free to fork Acorn/Escodegen and create your own transpiled JS variant - their licenses permit it), so my support of your particular idea is pretty much nil, at least in the JavaScript standards.
there isn't much difference from the
do expression
, actually, it might be worse since it looks confusing. if it can not be omitted, I'd rather stay withdo
.
I thought omitting additional brackets(var foo = = if (cond) { bar } else { baz }
) was most sweet spot in this proposal than do expressions.
what do you think about var foo = do if (cond) { bar } else { baz };
?
Beat you to it by about a year ;-)
esdiscuss.org/topic/generalize-do-expressions-to-statements-in-general
And to be quite honest, I did find it got some interest from TC39, but it
was one of them IIRC that pointed out the ambiguity with do { ... } while (...)
, in which the fix would require no line terminator between the }
and while
, but it wasn't particularly elegant. Keep in mind they are
interested (V8 implements the original proposal behind a flag FWIW), but
it's the parsing difficulty that's the blocker. I'm currently writing up an
alternative strawman right now that would probably end up a little more
intuitive. (Loops will trip up way too many people with the current
semantics, for example.)
On Tue, Nov 1, 2016, 09:21 JongChan Choi <jong at chan.moe> wrote:
there isn't much difference from the
do expression
, actually, it might
be worse since it looks confusing. if it can not be omitted, I'd rather
stay with do
.
I thought omitting additional brackets(var foo = = if (cond) { bar } else { baz }
) was most sweet spot in this proposal than do expressions.
what do you think about var foo = do if (cond) { bar } else { baz };
?
- 1., 오후 4:10, Yongxu Ren <renyongxu at gmail.com> 작성:
Isiah, In your case, if we do
var x = = { a }
there isn't much difference from the
do expression
, actually, it might
be worse since it looks confusing. if it can not be omitted, I'd rather
stay with do
.
The intent for this proposal is to allow writing better functional code
in javascript. IMO, the do expression
is a good start, but I think using
=
(and other operators) is a more elegant since it can be omitted.
Actually, I think I have a better idea to put it together:
*1. besides defining a function, if the block can be legally be replaced
by an expression, while otherwise it would cause parsing error, convert it to expression block*
*2. if the case is ambiguous or it is been used in function declaration,
adding =
(actually, using do
here isn't a bad idea either, but can be
quite ugly for defining function) will enforce block to be parsed as
expression*
Do expressions seems like another thing like => ({ })
to fix the mess with curly braces (used for expressions or objects litterals)
var f = x => ({ foo: 1}); // need () there, but we get used to it.
var f = { x: {foo: 1} }; // no need for ()
But do expressions seems the less bad way (= would be confusing), to solve things like format1 below
format1({
html() { // unecessary function to wrap expressions
doSomething(...);
res.send('..')
},
json() {
//...
},
})
format2({
html: (()=>{ // bit ugly with iifes
doSomething(...);
res.send('..')
})()
})
format2({
html: do { // do expressions proposal
doSomething(...);
res.send('..')
}
})
format2({ // if you have just one statement, is it stricly equivalent to do { res.send('...') } ?
html: res.send('..')
})
2016-11-01 16:46 GMT+01:00 Isiah Meadows <isiahmeadows at gmail.com>:
This proposal makes it easier to write functional code, you can convert statements block into expressions producing a useful result and plugging that back into an expression context.
This proposal is an alternative to the 'do expressions'.
Prepending
=
will automatically convertif...else
,switch...
,block
into statement that returns last inner statements value by default.examples:
If the left hand side is an expression or operator, '=' can be omitted
examples: