(Almost) everything is expression

Dmitry Soshnikov dmitry.soshnikov at gmail.com
Fri Nov 11 03:04:58 PST 2011


On 11.11.2011 14:37, David Bruant wrote:
> Hi,
>
> It reminds me of something I was thinking about recently.
> A very common pattern in JS is:
> ----
> (function(global){
>   var private1 = 'a';
>   // ...
>   global.something = 11;
> })(this)
> ----
>
> block-scoped variables allow a light-weigth version of this pattern:
> -----
> {
>   let private1 = 'a';
>
>   // |this| is the global object already, but if people feel 
> uncomfortable with
>   // reading code with |this|, they can always create an alias:
>   const global = this;
>
>   // ...
>   global.something = 11;
> }
> -----
>
>
> So I thought we could get rid of the (function(){...}()) pattern for 
> good.
> But there is also this pattern:
> -----
> var C = (function(global){
>     var something;
>
>     // ...
>
>     return something;
> })(this);
> -----
>
> which I thought could be turned into:
> -----
> var C = {
>     let something;
>
>     // |this| is the global object
>     // ...
> }
> -----
>
> But it does not have a return value and as noted in your second 
> message, there seems to be an ambiguity with object initializers (not 
> only visual but formal).
> The 'do expressions' solution sounds like a good idea, but visually 
> reminds of a do-while loop.
>
> I don't really have a better proposition yet, but i'm looking forward 
> to seeing any solution that will allow to replace all 
> "(function(global){...})(this);"
>

Yep, exactly. Block-expressions (w/ return values) are in many 
languages. And it's really often convenient. E.g. in the same Erlang 
(sorry for mentioning it too often), you may also use imminently applied 
function:

Foo = (fun() ->
   % do stuff
   100
end)(),

But nobody do this there, since e.g. there is a block-expression:

Foo = begin
   % do stuff
   100
end,

And the main thing also, that we can use internal variable there. It's 
of course can be achieved with `let` blocks as you show above, but such 
blocks don't allow to assign the result to the outside. Actually, it can 
be OK, we may assigned the value inside the block itself:

let foo;

{
   let x = 10;
   foo = x;
}

But if the block is long, it seems more convenient to see that the block 
assigns something in the head of the block, but not in its body:

let foo = {
   // do stuff
   100;
}

Anyway, the blocks are just "one of" the cases. The proposal is to have 
"all of them" as expressions as well, e.g. switch, if, try, perhaps 
`while` etc.

Dmitry.

> David
>
> Le 11/11/2011 08:07, Dmitry Soshnikov a écrit :
>> Hi,
>>
>> (unfortunately Twitter is again doesn't fit for a more than 140 ch 
>> discussion, so moving here)
>>
>> I'd like to still notice the possibility of accepting the "almost 
>> everything is expression" approach for JS. After Erlang I very often 
>> miss this possibility.
>>
>> The idea is to make most of current complex statements as expressions.
>>
>> Dave mentioned the proposal with `do { ... }` -- yeah, it's fine, but 
>> much nicer is to have "all of them" as expressions. CoffeeScript 
>> adopted this style as well.
>>
>> Besides, I'd like to note, that the thing is not just "interesting 
>> theoretical stuff", but really is very convenient and useful in 
>> practice.
>>
>> Examples:
>>
>> 1. Switch-expression (as addition, I eliminated `break`)
>>
>> let a = switch (foo) {
>>   case 10: 100;
>>   default: 200;
>> };
>>
>> 2. If-expression:
>>
>> let a = if (foo) {
>>   print('a is foo');
>>   foo;
>> } else {
>>   // do some longer stuff
>> };
>>
>> We of course already have for years the expression sugar for this -- 
>> ? : operator, but it doesn't allow to conveniently have longer bodies 
>> of consequent and alternative nodes of if-expression.
>>
>> 3. Try-expressions:
>>
>> let a = try {
>>   // do dangerous stuff
>>   "ok  value";
>> } catch (e) {
>>   "default value";
>> };
>>
>> Another note -- I also made `return` optional (if need to exit from 
>> the middle -- we can use it; BTW, it's a lack of Erlang -- we can't 
>> exit from the middle, but should build our blocks in the needed way).
>>
>> 4. What else? ... Perhaps some others.
>>
>> Brendan and Dave mention explicit semicolon. Yes, it's seems so by 
>> the grammar (though, have to check more precisely), but it can be 
>> acceptable price.
>>
>> P.S:
>>
>> Regarding Dave's `do { .. }` -- we may omit `do` and just evaluate 
>> the block.
>>
>> let a = {
>>   print('doing stuff');
>>   100;
>> };
>>
>> It's of course seems ambiguous with an object initialiser (at first 
>> glance), but it's only at first glance. Obviously there is a code 
>> inside to evaluate.
>>
>> Cheers,
>> Dmitry.
>> _______________________________________________
>> es-discuss mailing list
>> es-discuss at mozilla.org
>> https://mail.mozilla.org/listinfo/es-discuss
>



More information about the es-discuss mailing list