IIAFEs?

# Jorge (11 years ago)

How would this:

(Function () {

  // ...

})();

now look like with arrow functions?

(()=>{

  // ...

})();

What can be left out, if anything?

# Jorge (11 years ago)
s/Function/function/g
# Axel Rauschmayer (11 years ago)

You'll rarely, if ever, need IIFEs with ES6, thanks to block-scoped function declarations and for-of (which creates a fresh copy of the iteration variable for each iteration).

Thus, instead of:

(function () {
    var tmp = ?;
}());

you can do:

{
    let tmp = ?;
}

I'd still love to have do-blocks, though.

# François REMY (11 years ago)

Arrow functions probably shouldn't be used for this, this is not very readable.

I think you should have a look at modules, this is what is expected to replace this pattern ;-)

# Jorge (11 years ago)

On 01/06/2013, at 23:49, Axel Rauschmayer wrote:

You'll rarely, if ever, need IIFEs with ES6, thanks to block-scoped function declarations and for-of (which creates a fresh copy of the iteration variable for each iteration).

Thus, instead of:

(function () {
    var tmp = ?;
}());

you can do:

{
    let tmp = ?;
}

I'd still love to have do-blocks, though.

But they're not fully interchangeable, for example I can exit a function at any point with a return, but can I exit a block at any point with a break or something? Also a function returns a value, does a block evaluate to something?

In any case, I would really like to know which parenthesis or curly braces can I leave out in an immediately invocated arrow function expression, for example this:

var x= (=>{
  //...
})();

Is it correct ES6? Is there anything else that I could rmv in that IIAFE?

# Axel Rauschmayer (11 years ago)

But they're not fully interchangeable,

No, they aren’t.

for example I can exit a function at any point with a return, but can I exit a block at any point with a break or something?

You can give the block a label, say, foo and then exit via break foo.

Also a function returns a value, does a block evaluate to something?

No it doesn’t. David Herman proposed a “do expression” that would be able to do so: strawman:do_expressions

# Brandon Benvie (11 years ago)

On 6/1/2013 3:44 PM, Jorge wrote:

But they're not fully interchangeable, for example I can exit a function at any point with a return, but can I exit a block at any point with a break or something?

block: {
  if (true) {
    break block;
  }
}

Also a function returns a value, does a block evaluate to something? In any case, I would really like to know which parenthesis or curly braces can I leave out in an immediately invocated arrow function expression, for example this: var x= (=>{ //... })(); Is it correct ES6? Is there anything else that I could rmv in that IIAFE? Thank you!

You can only get the return value of a block using eval. However you can accomplish the same task by assigning to some outside variable.

let x;
block: {
  x = 20;
  // do some stuff
  if (condition) {
    break block;
  }
  x = 30;
}

Some fun stuff you can do with eval:

console.log(eval("block: { 'a'; if (Math.random() > .5) break  block; 'b' }"))
# Jorge (11 years ago)

On 02/06/2013, at 01:12, Axel Rauschmayer wrote:

for example I can exit a function at any point with a return, but can I exit a block at any point with a break or something?

You can give the block a label, say, foo and then exit via break foo.

So should I break to a label outside the block? Like so?

{ //... while (condition) { //... if (something) break resume; //... } //... } resume:

Also a function returns a value, does a block evaluate to something?

No it doesn’t. David Herman proposed a “do expression” that would be able to do so: strawman:do_expressions

Do expressions are cool! Are they in for es6?

Thanks.

# Jorge (11 years ago)

On 02/06/2013, at 01:22, Brandon Benvie wrote:

On 6/1/2013 3:44 PM, Jorge wrote:

But they're not fully interchangeable, for example I can exit a function at any point with a return, but can I exit a block at any point with a break or something?

block: {
  if (true) {
    break block;
  }
}

What might happen with this is that if you concatenate a bunch of .js files that use this pattern, they might end redefining the same label (which would be an error, I guess). Wrapping it all in another block would solve that?

{
  block: {
    if (true) {
      break block;
    }
  }
}

But then... I'm not sure this is any better than an IIFE!

Also a function returns a value, does a block evaluate to something? In any case, I would really like to know which parenthesis or curly braces can I leave out in an immediately invocated arrow function expression, for example this: var x= (=>{ //... })(); Is it correct ES6? Is there anything else that I could rmv in that IIAFE? Thank you!

You can only get the return value of a block using eval.

I knew that ;-P

However you can accomplish the same task by assigning to some outside variable.

let x;
block: {
  x = 20;
  // do some stuff
  if (condition) {
    break block;
  }
  x = 30;
}

But that's a bit awful, isn't it? When it's wrapped in an IIFE the code inside the block needs to know nothing about the outside var.

Some fun stuff you can do with eval:

console.log(eval("block: { 'a'; if (Math.random() > .5) break block; 'b' }"))

Cool :-)

# Brandon Benvie (11 years ago)

On 6/1/2013 4:52 PM, Jorge wrote:

What might happen with this is that if you concatenate a bunch of .js files that use this pattern, they might end redefining the same label (which would be an error, I guess).

You can only break a block that you're currently in. So this is fine:

 block: {
   break block;
 }
 block : {
   // whatever
 }

There's no conflict; this is perfectly valid. You would only run into an issue if the code was being wrapped in some outer block that was named the same, and there's no reason that would happen.

But then... I'm not sure this is any better than an IIFE!

It's certainly more ugly. It can be more performant because a block scope is lighter than creating a new function and then executing it, but most IIFEs are only executed once so it doesn't matter. The option is there, though.

# David Bruant (11 years ago)

Le 01/06/2013 16:52, Jorge a ?crit :

But then... I'm not sure this is any better than an IIFE!

You can also use a less naive concatenator. Labels seem to be very static parts of a JS program. It sounds doable to find and rewrite them.

Given what people have been doing with esprima recently 1, I have the impression it would be even easy (?)

# Petter Envall (11 years ago)

2013/6/2 David Bruant <bruant.d at gmail.com>

Le 01/06/2013 16:52, Jorge a écrit :

On 02/06/2013, at 01:22, Brandon Benvie wrote:

On 6/1/2013 3:44 PM, Jorge wrote:

But they're not fully interchangeable, for example I can exit a function at any point with a return, but can I exit a block at any point with a break or something?

block: {
  if (true) {
    break block;
  }
}

What might happen with this is that if you concatenate a bunch of .js files that use this pattern, they might end redefining the same label (which would be an error, I guess). Wrapping it all in another block would solve that?

{ block: { if (true) { break block; } } }

But then... I'm not sure this is any better than an IIFE!

You can also use a less naive concatenator. Labels seem to be very static parts of a JS program. It sounds doable to find and rewrite them.

Given what people have been doing with esprima recently [1], I have the impression it would be even easy (?)

David

[1] olov/defs

Ouch?

It seems like a sorry path to take that makes one have to comfess "Yes. In this language we have made some improvements that make it unsafe to concatenate program files like before - without using a parser/rewriter". Or is there another way?

Otherwise it seems tom me like IIFEs still would do the best job defining "modules" (in the sense "parts of a program") in the outermost scope.

// P

# David Bruant (11 years ago)

Le 01/06/2013 21:10, Petter Envall a ?crit :

Ouch?

It seems like a sorry path to take that makes one have to comfess "Yes. In this language we have made some improvements that make it unsafe to concatenate program files like before - without using a parser/rewriter". Or is there another way?

I'm not too familiar with JS labels, but I learned from Brandon's message that it is actually safe to concatenate with repeating labels 1, so no need for rewritters in the end.

Re "In this language", I'm not aware of other languages where you need to concatenate code. It has become a good practice for perf on the web as a workaround of HTTP 1.x limitations. HTTP 2 promises that with multiplexing, script concats won't be necessary anymore (and may even become a bad practice); server push will also be possible [2] so that we can keep several <script> elements and ES6 modules as separate files without performance issues.

"make it unsafe to concatenate program files like before" => Heard of what happens when naively concatenating files using strict mode inconsistently? [3] :-) Even before strict mode, loading JS on one of several <script> elements has observable behavior (number of<script> elements) and can cause bugs in fragile code. Also, document.write has a different semantics if run in an inline script or a loaded script. In any case, it's not new that how JS is packaged and loaded can be observed at runtime and lead to bugs if the loaded code behavior depends on that. It's been fought with conventions and tools. I don't thing that'll stop with any version of the language. Maybe that'll stop when the majority of servers and clients support HTTP 2. 20 years from now? 30? The problem is concatenation, not the language.

Regardless, compile-to-JS tools are the future for large scale applications. Look at the current trend. CoffeeScript, Dart, TypeScript, etc. This isn't an isolated effort. HTML is generated from HTML template languages (handlebar, moustache, jade, etc.). CSS is generated from other languages (SASS, LESS, etc.). These preprocessor tools are necessary to abstract away what I call "regrets" [4], that is cruft and annoyances due to the course of history. Also you don't necessarily deploy your code to the browser the same way your organize it for maintainability purposes.

Otherwise it seems tom me like IIFEs still would do the best job defining "modules" (in the sense "parts of a program") in the outermost scope.

I feel this thread was more exploratory than trying to define a good practice. I believe ES6 modules are the way forward to replace top-level IIFEs.

[2] Slide 48-51 of www.igvita.com/slides/2013/fluent-perfcourse.pdf [3] bugzilla.mozilla.org/show_bug.cgi?id=579119, bugzilla.mozilla.org/show_bug.cgi?id=627531 [4]: DavidBruant/ECMAScript-regrets

# Petter Envall (11 years ago)

2013/6/2 David Bruant <bruant.d at gmail.com>

Good points, thanks!

I'm not too familiar with JS labels, but I learned from Brandon's message that it is actually safe to concatenate with repeating labels [1], so no need for rewritters in the end.

Good!

Re "In this language", I'm not aware of other languages where you need to concatenate code. It has become a good practice for perf on the web as a workaround of HTTP 1.x limitations. HTTP 2 promises that with multiplexing, script concats won't be necessary anymore (and may even become a bad practice); server push will also be possible [2] so that we can keep several <script> elements and ES6 modules as separate files without performance issues.

Yes, but concatenation may not be the only "need" (thinking of build systems to produce a single file for a widget script or something). Guess it is not unreasonable either to make a system for such ends work a little bit harder if it has to (or use a different approach altogether).

"make it unsafe to concatenate program files like before" => Heard of what happens when naively concatenating files using strict mode inconsistently? [3] :-)

:) But my impression is "strict" is to be implicit in es6 anyway, so that problem for concatenation would not be present by then? Happy to be corrected here.

Even before strict mode, loading JS on one of several <script> elements has observable behavior (number of <script> elements) and can cause bugs in fragile code. Also, document.write has a different semantics if run in an inline script or a loaded script. In any case, it's not new that how JS is packaged and loaded can be observed at runtime and lead to bugs if the loaded code behavior depends on that. It's been fought with conventions and tools. I don't thing that'll stop with any version of the language.

True, agree. I was just thinking.. a lot of the awesomeness of new the features would cause fragility, without one even having used any "weird" constructs - just the feature and "plain old concatenation".

Maybe that'll stop when the majority of servers and clients support HTTP 2. 20 years from now? 30? The problem is concatenation, not the language.

Yeah concatenation may be costly in the way that it can cause conflicts under various circumstances. Though, it has been part of the trade for quite a while, and "breaking" (which probably is too strong a word) what worked with it would be a little disappointing.

Regardless, compile-to-JS tools are the future for large scale applications. Look at the current trend. CoffeeScript, Dart, TypeScript, etc. This isn't an isolated effort. HTML is generated from HTML template languages (handlebar, moustache, jade, etc.). CSS is generated from other languages (SASS, LESS, etc.). These preprocessor tools are necessary to abstract away what I call "regrets" [4], that is cruft and annoyances due to the course of history. Also you don't necessarily deploy your code to the browser the same way your organize it for maintainability purposes.

Otherwise it seems tom me like IIFEs still would do the best job defining "modules" (in the sense "parts of a program") in the outermost scope.

I feel this thread was more exploratory than trying to define a good practice. I believe ES6 modules are the way forward to replace top-level IIFEs.

I'm sure they are. I just thought the concatenation problem that arose with ES5/"use strict"; would be gone by ES6, and that it would not be replaced by another quirk regarding this practice.

[1] esdiscuss/2013-June/030953 [2] Slide 48-51 of www.igvita.com/slides/2013/fluent-perfcourse.pdf [3] bugzilla.mozilla.org/show_bug.cgi?id=579119, bugzilla.mozilla.org/show_bug.cgi?id=627531 [4] DavidBruant/ECMAScript-regrets

Thanks for the links too,

# David Bruant (11 years ago)

Le 01/06/2013 23:14, Petter Envall a ?crit :

Yes, but concatenation may not be the only "need" (thinking of build systems to produce a single file for a widget script or something).

Do you have examples of such systems? In a world with multiplexing and server push, what is the benefit of a single-file widget?

:) But my impression is "strict" is to be implicit in es6 anyway, so that problem for concatenation would not be present by then? Happy to be corrected here.

Only within new syntax IIRC (modules, classes). Outside these new syntax constructs, non-strict will remain non-strict.

True, agree. I was just thinking.. a lot of the awesomeness of new the features would cause fragility, without one even having used any "weird" constructs - just the feature and "plain old concatenation".

What are you referring to? The example that triggered my answer then yours only used "let" as new feature. And even hacked around with old features (label+break), it wasn't fragile after all. What is fragile about new features?

I believe we're having a dogma issue. Concatenation is not an unconditionally good idea. It's only become a good practice because of HTTP 1.x and the inherent latency of the network. Improve HTTP and the good practice is ready to be questioned.

Yeah concatenation may be costly in the way that it can cause conflicts under various circumstances.

There is also a granularity problem. If you concat all the files together, it takes time to parse/run. If you can send all the files at once (server push), but have them run only when needed, you're saving a bit of CPU time.

Though, it has been part of the trade for quite a while, and "breaking" (which probably is too strong a word) what worked with it would be a little disappointing.

I don't get it. If by "it", you're referring to "concatenation", I highly recommend reading Ilya Grigorik talk (Slides 42-43 this time) www.igvita.com/slides/2013/fluent-perfcourse.pdf

HTTP 2 enables web devs to get rid of all the dirty hacks we've been forced to do because of HTTP 1.x limitations (like concatenation, sprites, asset sharding in multiple domains...). Having the opportunity to undo all of that is the opposite of disappointing.

I'm sure they are. I just thought the concatenation problem that arose with ES5/"use strict"; would be gone by ES6

I am under the impression that you don't fully understand how web standards work. The ES5/"use strict" problem will never go away. The very first rule of evolving something on the web platform is to break no website. ES6 only brings new feature and the hope is that people will use these new features which are safe by default and incidentally stop using unsafe features. Again, concatenation is a hack to work around an HTTP limitation; not an inherently good idea. I don't think "plain concatenation" is a worthwhile consideration for how the language works.

and that it would not be replaced by another quirk regarding this practice.

It is not... Modules will replace top-level IIFEs.

Hmm... All your answers are shaped as "yes, but..."

# Alan Schmitt (11 years ago)

Axel Rauschmayer writes:

Also a function returns a value, does a block evaluate to something?

No it doesn’t.

I thought they did evaluate to a "completion type": es5.github.io/#x8.9

One can see this using an Expression statement (es5.github.io/#x12.4) and `eval'. For instance, after running x = eval("{ 5; 4 }") x will be bound to 4.

Alan

# Quildreen Motta (11 years ago)

On 1 June 2013 20:52, Jorge <jorge at jorgechamorro.com> wrote:

On 02/06/2013, at 01:22, Brandon Benvie wrote:

On 6/1/2013 3:44 PM, Jorge wrote: { block: { if (true) { break block; } } }

But then... I'm not sure this is any better than an IIFE!

Anything is better than an "Immediately Invoked Function-silly-Expression", actually. The only reasonable use for that is to create a new scope in the context of a statement:

void function() { doSomething() }()

Block scoping/let makes this pattern completely unecessary. As for the other arguments, you do not wrap a function expression in parenthesis, they're already expressions so there's no need for that. At any rate, the problem here is JavaScript's usage of statements instead of Expressions, Expressions Everywhere.

e.g.:

var x = function(){ return foo }()

# Chris Ryan (11 years ago)

sorry if this is tangentially related to the conversation, however I've just got a simple question. How would you call eval() with the ThisBinding inside the evaluated code being a custom item? In ES5 we'd do something like the following:

(function () {

eval(foo);

}).call(bar);

Would this change significantly with the advent of arrow functions and hard lexical binding or am I not getting my head around how these are supposed to be applied?