proposal-Declarations-in-Conditionals icon indicating copy to clipboard operation
proposal-Declarations-in-Conditionals copied to clipboard

Why just conditionals?

Open zloirock opened this issue 6 years ago • 7 comments

Declarations could be useful in many other places, for example

foo(let bar = buz());

Why not just equate variable declarations to expression statements in the scope of this proposal?

zloirock avatar Sep 12 '19 02:09 zloirock

What is the point of allowing declarations in these other places? A big difference with conditionals is that they create a new (nested) scope, whereas most other code does not.

foo(let bar = buz());

Why not just foo(buz)? What does allowing let/const add?

dcrousso avatar Sep 12 '19 03:09 dcrousso

It could be used after, for example

foo((let bar = buz()) && bar.x && bar.y);

One more time - it's just an example. It can be useful in many other cases. For example, switch - here also block scoping like in if and while.

zloirock avatar Sep 12 '19 03:09 zloirock

I'm not opposed to "extending" this proposal to switch as well, but I personally don't see it being as useful there as if/while, given that it's already necessary to provide some other value to compare against for each case (not including default, which I think would benefit the most from this, as then you could actually get the value out of the switch for further use inside a default), meaning that you have the equivalent value written as part of case and could use that instead. I do see value in reusing the same identifier in each case, though, so I'll keep this in mind.

As far as your example (which I understand is just an example), I personally find reading that to be extremely confusing and not immediately/obviously clear as to how it would work. One question that immediately pop into my head when seeing that is whether bar is scoped to foo (is it only visible until foo returns, but at the same time isn't actually visible to the body of foo)? Since there are no { ... }, my mind thinks that bar would be visible outside foo (but in the same scope as foo), which I don't think you are suggesting. The extra parenthesis around let bar = buz() (which I'm guessing is to distinguish it as a variable declaration, and wouldn't actually be required) just adds to that confusion.

I'd rather keep this proposal simple, as it's a fairly well established concept in some other languages as well. I'd like to discuss what I have proposed first, and once that has been decided (assuming it is accepted) then perhaps we can extend it to support your suggestion (see the Future Work section for other ideas).

dcrousso avatar Sep 12 '19 10:09 dcrousso

One question that immediately pop into my head when seeing that is whether bar is scoped to foo (is it only visible until foo returns, but at the same time isn't actually visible to the body of foo)?

It's not principal for me - it can be visible outside of foo for don't extend the scoping model.

The extra parenthesis around let bar = buz() (which I'm guessing is to distinguish it as a variable declaration, and wouldn't actually be required)

Without those parentheses, the order of the operators will be broken - && executed before =.

zloirock avatar Sep 13 '19 07:09 zloirock

As I understand, case like foo((let bar = buz()) && bar.x && bar.y) could (should) be solved by do expression proposal.

hax avatar Sep 22 '19 19:09 hax

switch would be useful to have.

function foo(bar) {
  switch (const type = typeof bar) {
    case "string":
    case "number":
      return `This is a ${type} value!`;
    default:
      throw new TypeError(`I do not support ${type}!`);
  }
}

I brought it up in the IRC at one point, https://freenode.logbot.info/tc39/20190903#c2616001

puppy0cam avatar Oct 07 '19 01:10 puppy0cam