Re: const VS features detection

2013-12-19 Thread Andrea Giammarchi
as side note: in node.js using --harmony flag ... what a developer should
do there to understand that a partially non standard version of Proxy is
there instead of the real one?

Let's imagine I am a client/server library author ... just for a second,
I'd like to grant one behaviour across platforms ... I'd love V8 to flag
experimental features as v8Proxy instead, at least I know what I am dealing
with!!! Don't care about multiple checks, as long as I can grant
consistency.

This is a concern of mine that keeps coming up ... off topic here


On Thu, Dec 19, 2013 at 10:47 PM, Andrea Giammarchi <
andrea.giammar...@gmail.com> wrote:

> thanks for the exhaustive answer, useful and more than appreciated.
>
> The example was addressing one problem, the need for an extra variable,
> and was not meant to represent the best way to detect if the Proxy was the
> meant one.
>
> About this, since you pointed that out, I'll come back on vendor prefixes,
> and the fact that to know if Proxy is the old one, and MDN has even a
> specific page for it, or "the real/standard one", a developer should go
> down the [native] check on the constructor and the inevitable try/catch
> since both old and new Proxy functions have that create method as public
> static.
>
> Proxy is a very good example of those hard to detect features since the
> vendor/engine decided that prefixes were not a good option ... well,
> if(typeof Proxy === 'undefined') brings you nowhere in current node.js, as
> example, neither in any Chrome with experiments enabled ... and about that,
> there is no exposed flag anyone can feature detect to understand if the
> current constructor is out of an experimental feature or it's the real one
> spec'd and supported.
>
> Best Regards
>
>
>
>
>
>
> On Thu, Dec 19, 2013 at 7:05 PM, Brendan Eich  wrote:
>
>> Andrea Giammarchi wrote:
>>
>>> why is this not possible, giving the ability to understand through
>>> typeof if there is a value or not?
>>>
>>> ```javascript
>>> // defined as const
>>> // reserved in this scope
>>> // but not assigned yet
>>> const WHATEVER;
>>> if (condition) {
>>>   // first come, first serves
>>>   WHATEVER = 123;
>>>   // that's it! const defined for the whole scope
>>>   // immutable from now on
>>> } else {
>>>   WHATEVER = 456;
>>> }
>>>
>>
>> Past JS2/ES4 designs have allowed this, but it requires definite
>> assignment analysis and use-before-defining-assignment error checking.
>>
>> In general, such checks can't be static in JS, so the language and VM
>> complexity blow up a bit with runtime checking for an "uninitialized" (not
>> same as undefined) sentinel value that must be guarded against by a read
>> barrier where it can't be proven unnecessary.
>>
>> This is pretty obnoxious for implementors, not great for users either
>> (did I declare const IMPORTANT; and forget to assign IMPORTANT= in some
>> branch of control flow that my tests miss?).
>>
>> It's not in Harmony. We require an initialiser as part of the const
>> declaration syntax. What you are doing here, by many measures, is varying a
>> variable from its default (undefined) value to a new value.
>>
>> If you want that variable to stop varying after, and you need it as a
>> global (window) object property anyway, use Object.defineProperty to make
>> it non-writable.
>>
>> BTW, the last version your head post gave,
>>
>> const ES6_PROXY = function(){
>>
>>   try {
>> new Proxy({},{});
>> return true;
>>   } catch(o_O) {
>> return false;
>>   }
>> }();
>>
>> isn't bad at all, but are you really concerned about false-positive
>> (typeof Proxy != "undefined") test results? Some other Proxy could easily
>> be a function that does not throw when called with two objects as
>> arguments. The standard object detection pattern:
>>
>> if (typeof Proxy == "undefined")
>>   this.Proxy = (/* polyfill Proxy here somehow... */);
>>
>> often has a leading
>>
>> var Proxy;
>> if (typeof Proxy == "undefined")
>>   this.Proxy = (/* polyfill Proxy here somehow... */);
>>
>> precisely to avoid errors from static analyzers looking for bare Proxy
>> uses without a declared var in scope.
>>
>> In any event, these patterns want *variables*, not constants, because
>> they must work when there's already a binding. And you cannot redeclare
>> with const (or let or class), as Rick points out.
>>
>> /be
>>
>
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: const VS features detection

2013-12-19 Thread Andrea Giammarchi
thanks for the exhaustive answer, useful and more than appreciated.

The example was addressing one problem, the need for an extra variable, and
was not meant to represent the best way to detect if the Proxy was the
meant one.

About this, since you pointed that out, I'll come back on vendor prefixes,
and the fact that to know if Proxy is the old one, and MDN has even a
specific page for it, or "the real/standard one", a developer should go
down the [native] check on the constructor and the inevitable try/catch
since both old and new Proxy functions have that create method as public
static.

Proxy is a very good example of those hard to detect features since the
vendor/engine decided that prefixes were not a good option ... well,
if(typeof Proxy === 'undefined') brings you nowhere in current node.js, as
example, neither in any Chrome with experiments enabled ... and about that,
there is no exposed flag anyone can feature detect to understand if the
current constructor is out of an experimental feature or it's the real one
spec'd and supported.

Best Regards






On Thu, Dec 19, 2013 at 7:05 PM, Brendan Eich  wrote:

> Andrea Giammarchi wrote:
>
>> why is this not possible, giving the ability to understand through typeof
>> if there is a value or not?
>>
>> ```javascript
>> // defined as const
>> // reserved in this scope
>> // but not assigned yet
>> const WHATEVER;
>> if (condition) {
>>   // first come, first serves
>>   WHATEVER = 123;
>>   // that's it! const defined for the whole scope
>>   // immutable from now on
>> } else {
>>   WHATEVER = 456;
>> }
>>
>
> Past JS2/ES4 designs have allowed this, but it requires definite
> assignment analysis and use-before-defining-assignment error checking.
>
> In general, such checks can't be static in JS, so the language and VM
> complexity blow up a bit with runtime checking for an "uninitialized" (not
> same as undefined) sentinel value that must be guarded against by a read
> barrier where it can't be proven unnecessary.
>
> This is pretty obnoxious for implementors, not great for users either (did
> I declare const IMPORTANT; and forget to assign IMPORTANT= in some branch
> of control flow that my tests miss?).
>
> It's not in Harmony. We require an initialiser as part of the const
> declaration syntax. What you are doing here, by many measures, is varying a
> variable from its default (undefined) value to a new value.
>
> If you want that variable to stop varying after, and you need it as a
> global (window) object property anyway, use Object.defineProperty to make
> it non-writable.
>
> BTW, the last version your head post gave,
>
> const ES6_PROXY = function(){
>
>   try {
> new Proxy({},{});
> return true;
>   } catch(o_O) {
> return false;
>   }
> }();
>
> isn't bad at all, but are you really concerned about false-positive
> (typeof Proxy != "undefined") test results? Some other Proxy could easily
> be a function that does not throw when called with two objects as
> arguments. The standard object detection pattern:
>
> if (typeof Proxy == "undefined")
>   this.Proxy = (/* polyfill Proxy here somehow... */);
>
> often has a leading
>
> var Proxy;
> if (typeof Proxy == "undefined")
>   this.Proxy = (/* polyfill Proxy here somehow... */);
>
> precisely to avoid errors from static analyzers looking for bare Proxy
> uses without a declared var in scope.
>
> In any event, these patterns want *variables*, not constants, because they
> must work when there's already a binding. And you cannot redeclare with
> const (or let or class), as Rick points out.
>
> /be
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: const VS features detection

2013-12-19 Thread Brendan Eich

Andrea Giammarchi wrote:
why is this not possible, giving the ability to understand through 
typeof if there is a value or not?


```javascript
// defined as const
// reserved in this scope
// but not assigned yet
const WHATEVER;
if (condition) {
  // first come, first serves
  WHATEVER = 123;
  // that's it! const defined for the whole scope
  // immutable from now on
} else {
  WHATEVER = 456;
}


Past JS2/ES4 designs have allowed this, but it requires definite 
assignment analysis and use-before-defining-assignment error checking.


In general, such checks can't be static in JS, so the language and VM 
complexity blow up a bit with runtime checking for an "uninitialized" 
(not same as undefined) sentinel value that must be guarded against by a 
read barrier where it can't be proven unnecessary.


This is pretty obnoxious for implementors, not great for users either 
(did I declare const IMPORTANT; and forget to assign IMPORTANT= in some 
branch of control flow that my tests miss?).


It's not in Harmony. We require an initialiser as part of the const 
declaration syntax. What you are doing here, by many measures, is 
varying a variable from its default (undefined) value to a new value.


If you want that variable to stop varying after, and you need it as a 
global (window) object property anyway, use Object.defineProperty to 
make it non-writable.


BTW, the last version your head post gave,

const ES6_PROXY = function(){
  try {
new Proxy({},{});
return true;
  } catch(o_O) {
return false;
  }
}();

isn't bad at all, but are you really concerned about false-positive 
(typeof Proxy != "undefined") test results? Some other Proxy could 
easily be a function that does not throw when called with two objects as 
arguments. The standard object detection pattern:


if (typeof Proxy == "undefined")
  this.Proxy = (/* polyfill Proxy here somehow... */);

often has a leading

var Proxy;
if (typeof Proxy == "undefined")
  this.Proxy = (/* polyfill Proxy here somehow... */);

precisely to avoid errors from static analyzers looking for bare Proxy 
uses without a declared var in scope.


In any event, these patterns want *variables*, not constants, because 
they must work when there's already a binding. And you cannot redeclare 
with const (or let or class), as Rick points out.


/be
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: const VS features detection

2013-12-19 Thread Andrea Giammarchi
quick recap:

why is this not possible, giving the ability to understand through typeof
if there is a value or not?

```javascript
// defined as const
// reserved in this scope
// but not assigned yet
const WHATEVER;
if (condition) {
  // first come, first serves
  WHATEVER = 123;
  // that's it! const defined for the whole scope
  // immutable from now on
} else {
  WHATEVER = 456;
}

console.log(WHATEVER);

// should throw as it is now
var WHATEVER;
let WHATEVER;
function WHATEVER(){}

```

It seems to me this might be a desired behavior. Any chance this will
happen? NO is a valid answer, thanks.


On Thu, Dec 19, 2013 at 4:31 PM, Andrea Giammarchi <
andrea.giammar...@gmail.com> wrote:

> it's not invalind, it's what I am talking about.
>
> There is no way to conditionally define constants if not through an inline
> ternary or a returned value from a closure otherwise, by design, a second
> variable (garbage, pointless hoisting pollution) is mandatory.
>
> The only way to avoid this is to evaluate ... it looks dirty, it works "as
> I would like to" ... as any other C like language I know would do with
> constants without the old var hoisting problem.
>
> ```javascript
> try {
>   new Proxy({},{});
>   eval('const ES6_PROXY=true');
> } catch(nope) {
>   eval('const ES6_PROXY=false');
> }
>
> console.log(ES6_PROXY);
> ```
>
> Does this make sense?
>
>
>
> On Thu, Dec 19, 2013 at 3:50 PM, Rick Waldron wrote:
>
>>
>>
>>
>> On Thu, Dec 19, 2013 at 6:18 PM, Andrea Giammarchi <
>> andrea.giammar...@gmail.com> wrote:
>>
>>> Rick thanks but I wasn't strictly asking for solutions because I have
>>> one, I was rather pointing at the fact that there is no solution and by
>>> design we need to create garbage.
>>>
>>> Your last example talks itself ... why do we need to define another
>>> variable in that scope? That is annoying, imho ... I don't want define a
>>> `tmp` like variable per each const type I'd like to address down the road,
>>> you know what I mean?
>>>
>>> I cannot even drop that var, so that's a potential leak in the global
>>> scope/context if not loeaded through modules while I might want to define
>>> that constant globally (and maybe name-spaced, but that's not the issue
>>> here)
>>>
>>> IE11 ... I don't have it with me now, would this work nicely ? I think
>>> no :-(
>>>
>>> ```javascript
>>> let ES6_PROXY = true;
>>>  try {
>>>   new Proxy({},{});
>>> } catch(o_O) {
>>>   ES6_PROXY = false;
>>> }
>>> const ES6_PROXY = ES6_PROXY;
>>> ```
>>>
>>
>> It doesn't matter if I ran this in IE11 today or Firefox/Chrome/whatever
>> when those implementations are updated: let and const bindings don't allow
>> _redeclaration_ of bindings that already exist in that scope.
>>
>>
>>
>>>
>>>  So const are not as simple and straight forward to be defined as it is
>>> in C or others and because these have been defined on top of `var` hoisting
>>> behavior.
>>>
>>> ```C
>>>
>>> #ifdef WHATEVER
>>>   static int const NAME = 1;#else
>>>   static int const NAME = 0;
>>>
>>>
>>>
>>> #endif
>>>
>>> ```
>>>
>>> Thoughts?
>>>
>>
>> It's an invalid comparison, unless you're saying you want ifdefs in JS.
>> This is an apples-to-apples comparison:
>>
>> C:
>>
>>   if (1) {
>> static int const A_VAL = 1;
>>   }
>>   printf("%d", A_VAL);
>>
>>   // error: use of undeclared identifier 'A_VAL'
>>
>> JS:
>>
>>   if (1) {
>>  const A_VAL = 1;
>>   }
>>   console.log(A_VAL);
>>
>>   //  'A_VAL' is undefined
>>
>>
>> Rick
>>
>>
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: const VS features detection

2013-12-19 Thread Andrea Giammarchi
it's not invalind, it's what I am talking about.

There is no way to conditionally define constants if not through an inline
ternary or a returned value from a closure otherwise, by design, a second
variable (garbage, pointless hoisting pollution) is mandatory.

The only way to avoid this is to evaluate ... it looks dirty, it works "as
I would like to" ... as any other C like language I know would do with
constants without the old var hoisting problem.

```javascript
try {
  new Proxy({},{});
  eval('const ES6_PROXY=true');
} catch(nope) {
  eval('const ES6_PROXY=false');
}

console.log(ES6_PROXY);
```

Does this make sense?



On Thu, Dec 19, 2013 at 3:50 PM, Rick Waldron wrote:

>
>
>
> On Thu, Dec 19, 2013 at 6:18 PM, Andrea Giammarchi <
> andrea.giammar...@gmail.com> wrote:
>
>> Rick thanks but I wasn't strictly asking for solutions because I have
>> one, I was rather pointing at the fact that there is no solution and by
>> design we need to create garbage.
>>
>> Your last example talks itself ... why do we need to define another
>> variable in that scope? That is annoying, imho ... I don't want define a
>> `tmp` like variable per each const type I'd like to address down the road,
>> you know what I mean?
>>
>> I cannot even drop that var, so that's a potential leak in the global
>> scope/context if not loeaded through modules while I might want to define
>> that constant globally (and maybe name-spaced, but that's not the issue
>> here)
>>
>> IE11 ... I don't have it with me now, would this work nicely ? I think no
>> :-(
>>
>> ```javascript
>> let ES6_PROXY = true;
>>  try {
>>   new Proxy({},{});
>> } catch(o_O) {
>>   ES6_PROXY = false;
>> }
>> const ES6_PROXY = ES6_PROXY;
>> ```
>>
>
> It doesn't matter if I ran this in IE11 today or Firefox/Chrome/whatever
> when those implementations are updated: let and const bindings don't allow
> _redeclaration_ of bindings that already exist in that scope.
>
>
>
>>
>>  So const are not as simple and straight forward to be defined as it is
>> in C or others and because these have been defined on top of `var` hoisting
>> behavior.
>>
>> ```C
>>
>> #ifdef WHATEVER
>>   static int const NAME = 1;#else
>>   static int const NAME = 0;
>>
>>
>> #endif
>>
>> ```
>>
>> Thoughts?
>>
>
> It's an invalid comparison, unless you're saying you want ifdefs in JS.
> This is an apples-to-apples comparison:
>
> C:
>
>   if (1) {
> static int const A_VAL = 1;
>   }
>   printf("%d", A_VAL);
>
>   // error: use of undeclared identifier 'A_VAL'
>
> JS:
>
>   if (1) {
>  const A_VAL = 1;
>   }
>   console.log(A_VAL);
>
>   //  'A_VAL' is undefined
>
>
> Rick
>
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: const VS features detection

2013-12-19 Thread Rick Waldron
On Thu, Dec 19, 2013 at 6:18 PM, Andrea Giammarchi <
andrea.giammar...@gmail.com> wrote:

> Rick thanks but I wasn't strictly asking for solutions because I have one,
> I was rather pointing at the fact that there is no solution and by design
> we need to create garbage.
>
> Your last example talks itself ... why do we need to define another
> variable in that scope? That is annoying, imho ... I don't want define a
> `tmp` like variable per each const type I'd like to address down the road,
> you know what I mean?
>
> I cannot even drop that var, so that's a potential leak in the global
> scope/context if not loeaded through modules while I might want to define
> that constant globally (and maybe name-spaced, but that's not the issue
> here)
>
> IE11 ... I don't have it with me now, would this work nicely ? I think no
> :-(
>
> ```javascript
> let ES6_PROXY = true;
>  try {
>   new Proxy({},{});
> } catch(o_O) {
>   ES6_PROXY = false;
> }
> const ES6_PROXY = ES6_PROXY;
> ```
>

It doesn't matter if I ran this in IE11 today or Firefox/Chrome/whatever
when those implementations are updated: let and const bindings don't allow
_redeclaration_ of bindings that already exist in that scope.



>
> So const are not as simple and straight forward to be defined as it is in
> C or others and because these have been defined on top of `var` hoisting
> behavior.
>
> ```C
>
> #ifdef WHATEVER
>   static int const NAME = 1;#else
>   static int const NAME = 0;
>
> #endif
>
> ```
>
> Thoughts?
>

It's an invalid comparison, unless you're saying you want ifdefs in JS.
This is an apples-to-apples comparison:

C:

  if (1) {
static int const A_VAL = 1;
  }
  printf("%d", A_VAL);

  // error: use of undeclared identifier 'A_VAL'

JS:

  if (1) {
const A_VAL = 1;
  }
  console.log(A_VAL);

  //  'A_VAL' is undefined


Rick
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: const VS features detection

2013-12-19 Thread Andrea Giammarchi
Rick thanks but I wasn't strictly asking for solutions because I have one,
I was rather pointing at the fact that there is no solution and by design
we need to create garbage.

Your last example talks itself ... why do we need to define another
variable in that scope? That is annoying, imho ... I don't want define a
`tmp` like variable per each const type I'd like to address down the road,
you know what I mean?

I cannot even drop that var, so that's a potential leak in the global
scope/context if not loeaded through modules while I might want to define
that constant globally (and maybe name-spaced, but that's not the issue
here)

IE11 ... I don't have it with me now, would this work nicely ? I think no
:-(

```javascript
let ES6_PROXY = true;
try {
  new Proxy({},{});
} catch(o_O) {
  ES6_PROXY = false;
}
const ES6_PROXY = ES6_PROXY;
```

So const are not as simple and straight forward to be defined as it is in C
or others and because these have been defined on top of `var` hoisting
behavior.

```C

#ifdef WHATEVER
  static int const NAME = 1;#else
  static int const NAME = 0;
#endif

```

Thoughts?




On Thu, Dec 19, 2013 at 2:34 PM, Rick Waldron wrote:

>
>
>
> On Thu, Dec 19, 2013 at 3:03 PM, Andrea Giammarchi <
> andrea.giammar...@gmail.com> wrote:
>
>> It seems that I need to create N amount of garbage by design.
>>
>> This does not work, the const has already been defined:
>>
>> ```javascript
>> try {
>>   new Proxy({},{});
>>   const ES6_PROXY = true;
>> } catch(o_O) {
>>   const ES6_PROXY = false;
>> }
>> ```
>>
>
> That doesn't work anyway, not because the const has already been defined,
> but because ES6_PROXY is defined within block bodies. Same as:
>
> {
>   const IS_BOUND_TO_THE_BLOCK = true;
> }
>
>
>
>>
>> This does not work neither
>>
>> ```javascript
>> try {
>>   new Proxy({},{});
>>   var ES6_PROXY = true;
>> } catch(o_O) {
>>   var ES6_PROXY = false;
>> }
>> const ES6_PROXY = false;
>>
>> // var 'ES6_PROXY' has already been declared
>> ```
>>
>
> Because the var was hoisted up to the const's scope and const can't be
> used to redeclare an existing binding of the same name. Is ES6_PROXY meant
> to be bound in the global scope?
>
>
>
>>
>>  neither does the following
>>
>> ```javascript
>> try {
>>   new Proxy({},{});
>>   let ES6_PROXY = true;
>> } catch(o_O) {
>>   let ES6_PROXY = false;
>> }
>>
>> // Illegal let declaration outside extended mode
>>
>
> That's a Canary-specific error, but the code wouldn't do what you want
> anyway, for the same reason as the first example.
>
>
>> ```
>>
>> As summary, there is no way to feature detect and define a const in the
>> same scope, a closure without the possibility to define such constant as
>> well is mandatory.
>>
>> ```javascript
>> const ES6_PROXY = function(){
>>   try {
>> new Proxy({},{});
>> return true;
>>   } catch(o_O) {
>> return false;
>>   }
>> }();
>> ```
>>
>
> This works fine:
>
>   var result = true;
>   try {
> new Proxy({},{});
>   } catch(o_O) {
> result = false;
>   }
>   const ES6_PROXY = result;
>
>
>
>
> Rick
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: const VS features detection

2013-12-19 Thread Rick Waldron
On Thu, Dec 19, 2013 at 5:34 PM, Rick Waldron wrote:

>
>
>
> On Thu, Dec 19, 2013 at 3:03 PM, Andrea Giammarchi <
> andrea.giammar...@gmail.com> wrote:
>
>> It seems that I need to create N amount of garbage by design.
>>
>> This does not work, the const has already been defined:
>>
>> ```javascript
>> try {
>>   new Proxy({},{});
>>   const ES6_PROXY = true;
>> } catch(o_O) {
>>   const ES6_PROXY = false;
>> }
>> ```
>>
>
> That doesn't work anyway, not because the const has already been defined,
> but because ES6_PROXY is defined within block bodies. Same as:
>
> {
>   const IS_BOUND_TO_THE_BLOCK = true;
> }
>
>
>
>>
>> This does not work neither
>>
>> ```javascript
>> try {
>>   new Proxy({},{});
>>   var ES6_PROXY = true;
>> } catch(o_O) {
>>   var ES6_PROXY = false;
>> }
>> const ES6_PROXY = false;
>>
>> // var 'ES6_PROXY' has already been declared
>> ```
>>
>
> Because the var was hoisted up to the const's scope and const can't be
> used to redeclare an existing binding of the same name. Is ES6_PROXY meant
> to be bound in the global scope?
>
>
>
>>
>>  neither does the following
>>
>> ```javascript
>> try {
>>   new Proxy({},{});
>>   let ES6_PROXY = true;
>> } catch(o_O) {
>>   let ES6_PROXY = false;
>> }
>>
>> // Illegal let declaration outside extended mode
>>
>
> That's a Canary-specific error, but the code wouldn't do what you want
> anyway, for the same reason as the first example.
>

Also, if you want to experiment with the closest-to-spec-so-far let/const
behavior, use IE11.


Rick
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: const VS features detection

2013-12-19 Thread Rick Waldron
On Thu, Dec 19, 2013 at 3:03 PM, Andrea Giammarchi <
andrea.giammar...@gmail.com> wrote:

> It seems that I need to create N amount of garbage by design.
>
> This does not work, the const has already been defined:
>
> ```javascript
> try {
>   new Proxy({},{});
>   const ES6_PROXY = true;
> } catch(o_O) {
>   const ES6_PROXY = false;
> }
> ```
>

That doesn't work anyway, not because the const has already been defined,
but because ES6_PROXY is defined within block bodies. Same as:

{
  const IS_BOUND_TO_THE_BLOCK = true;
}



>
> This does not work neither
>
> ```javascript
> try {
>   new Proxy({},{});
>   var ES6_PROXY = true;
> } catch(o_O) {
>   var ES6_PROXY = false;
> }
> const ES6_PROXY = false;
>
> // var 'ES6_PROXY' has already been declared
> ```
>

Because the var was hoisted up to the const's scope and const can't be used
to redeclare an existing binding of the same name. Is ES6_PROXY meant to be
bound in the global scope?



>
> neither does the following
>
> ```javascript
> try {
>   new Proxy({},{});
>   let ES6_PROXY = true;
> } catch(o_O) {
>   let ES6_PROXY = false;
> }
>
> // Illegal let declaration outside extended mode
>

That's a Canary-specific error, but the code wouldn't do what you want
anyway, for the same reason as the first example.


> ```
>
> As summary, there is no way to feature detect and define a const in the
> same scope, a closure without the possibility to define such constant as
> well is mandatory.
>
> ```javascript
> const ES6_PROXY = function(){
>   try {
> new Proxy({},{});
> return true;
>   } catch(o_O) {
> return false;
>   }
> }();
> ```
>

This works fine:

  var result = true;
  try {
new Proxy({},{});
  } catch(o_O) {
result = false;
  }
  const ES6_PROXY = result;




Rick
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Why thenables?

2013-12-19 Thread Alex Russell
Right, but number of objects you have to guard with anti-branding is much,
much larger. That argues against thenables pretty strongly, but again, I
don't think we need to change anything for ES6. We can repair this in ES7
if it's a problem in practice.


On Thu, Dec 19, 2013 at 2:21 PM, Gorgi Kosev  wrote:

>
> ...but only in an unpolyfillable, ES6-only world.
>>
>>
> Right, they don't help existing libraries, but it would still pave a path
> towards branded-only promises in the (unfortunately very, very far) future
> (with ES5 all but gone)
>
> Only "ghetto anti-branding" will help existing libraries (and make it
> possible to check if flipping the switch is okay much earlier).
>
> Its not like combining ghetto .then with ghetto `__notPromise__` is worse
> than just ghetto `then`. One thing that can be done is to make it less
> ugly. Since it would always be checked in tandem with `then`, it could
> simply be `notConvertableToPromise`.  Without the double underscores,
> people will be slightly less likely to ask "what the hell were they smoking"
>
>
> ___
> es-discuss mailing list
> es-discuss@mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
>
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Why thenables?

2013-12-19 Thread Gorgi Kosev
> ...but only in an unpolyfillable, ES6-only world.
>
>
Right, they don't help existing libraries, but it would still pave a path
towards branded-only promises in the (unfortunately very, very far) future
(with ES5 all but gone)

Only "ghetto anti-branding" will help existing libraries (and make it
possible to check if flipping the switch is okay much earlier).

Its not like combining ghetto .then with ghetto `__notPromise__` is worse
than just ghetto `then`. One thing that can be done is to make it less
ugly. Since it would always be checked in tandem with `then`, it could
simply be `notConvertableToPromise`.  Without the double underscores,
people will be slightly less likely to ask "what the hell were they smoking"
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Why thenables?

2013-12-19 Thread Alex Russell
On Thu, Dec 19, 2013 at 9:24 AM, Mark S. Miller  wrote:

> I think this anti-branding idea is worth considering, but using a symbol
> or weakmap for the anti-branding rather than a magic double-underbar
> property name. Unlike prior positive thenable branding proposals, this one
> doesn't break existing code but still provides systems that use "then" in
> contrary ways an ability to cope.
>

...but only in an unpolyfillable, ES6-only world.

What in the heck are we smoking if we decided that thenables were the right
thing to do but we should lean on unavailable tech to do the contra? How
could we POSSIBLY talk ourselves into that in good faith?

This has ventured into farce. I pray it stops.


> It also doesn't break anything premised on the promise-unwrapping
> consensus that we've agreed on and specced. I see only two questions:
>
> * Whether the benefit is worth the additional complexity?
> * If we do decide to do this, does it make sense to postpone it to ES7?
>
> Unless there is significant demonstrated need, I am leaning away from the
> paying the additional complexity. OTOH, since this would mainly be about
> mitigating the pain of fixing contrary uses of "then", if we're going to do
> it at all, we should do it in ES6. If we don't, then these contrary uses of
> "then" will probably already be fixed by the time ES7 rolls out.
>
>
>
> On Thu, Dec 19, 2013 at 9:03 AM, Ѓорѓи Ќосев wrote:
>
>> On Thu 19 Dec 2013 07:42:31 AM CET, Andrea Giammarchi wrote:
>>
>> > The only thing that does is having *one*, *standard* contract -- and we
>> are past due on that.
>>
>> Perhaps the right path would be to try and discuss this for
>> Promises/A++, and maybe if it happens there, ES7 afterwards :)
>>
>> > Devs also complain about mistakes though .. not sure how to win here :-(
>>
>> No worries. I think I understand now. Still I felt it was worth a shot,
>> although I guess I picked the wrong path (and time) to go about it.
>>
>> Thanks for your time -- and sorry for creating a stir.
>>
>> ___
>> es-discuss mailing list
>> es-discuss@mozilla.org
>> https://mail.mozilla.org/listinfo/es-discuss
>>
>
>
>
> --
> Cheers,
> --MarkM
>
> ___
> es-discuss mailing list
> es-discuss@mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
>
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


const VS features detection

2013-12-19 Thread Andrea Giammarchi
It seems that I need to create N amount of garbage by design.

This does not work, the const has already been defined:

```javascript
try {
  new Proxy({},{});
  const ES6_PROXY = true;
} catch(o_O) {
  const ES6_PROXY = false;
}
```

This does not work neither

```javascript
try {
  new Proxy({},{});
  var ES6_PROXY = true;
} catch(o_O) {
  var ES6_PROXY = false;
}
const ES6_PROXY = false;

// var 'ES6_PROXY' has already been declared
```

neither does the following

```javascript
try {
  new Proxy({},{});
  let ES6_PROXY = true;
} catch(o_O) {
  let ES6_PROXY = false;
}

// Illegal let declaration outside extended mode
```

As summary, there is no way to feature detect and define a const in the
same scope, a closure without the possibility to define such constant as
well is mandatory.

```javascript
const ES6_PROXY = function(){
  try {
new Proxy({},{});
return true;
  } catch(o_O) {
return false;
  }
}();
```

This is not such a huge deal, but it does not feel/look right with bigger
amount of features detection and a growing adoption of constants.

Thoughts?

Cheers
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Why thenables?

2013-12-19 Thread Ѓорѓи Ќосев
On Thu 19 Dec 2013 06:24:50 PM CET, Mark S. Miller wrote:
> I think this anti-branding idea is worth considering, but using a
> symbol or weakmap for the anti-branding rather than a magic
> double-underbar property name. Unlike prior positive thenable branding
> proposals, this one doesn't break existing code but still provides
> systems that use "then" in contrary ways an ability to cope. It also
> doesn't break anything premised on the promise-unwrapping consensus
> that we've agreed on and specced.

Thanks :)

> I see only two questions:
>
> * Whether the benefit is worth the additional complexity?
> * If we do decide to do this, does it make sense to postpone it to ES7?
>
> Unless there is significant demonstrated need, I am leaning away from
> the paying the additional complexity.

This anti-branding proposal is not just about making the
immediate future smoother. My hope is that it could potentially provide
a path for the far future where research can be done to determine
whether compatibility issues are still there. If they aren't, Promises
could start assuming that object[notPromiseSymbol] === true, (unless
explicitly stated otherwise). This practically means completely
removing the wart from the language except for promise authors that
don't extend the built-in Promise (or for those that actually *want*
automatic thenable assimilation of their non-promises)

I feel that right now the `then` method is a bit worse than a keyword. 
Unlike
keywords, it may cause random hard to find bugs and unpredictable 
behaviour
(instead of syntax errors) for unsuspecting users. That makes any path 
that can
potentially make it unreserved worth pursuing, at any time (now or in 
the future).

The complexity cost is not much greater than regular branding for
implementers. The complexity cost is not much greater for end-users
either - in both cases they will still have to know that `.then` is
special (albiet in the latter case case, still available, and
potentially not special at all in the future).

And in the latter case, cognitive load can potentially be reduced for 
users.
Its easier to make a static analysis tool that warns them to explicitly 
set
this[notPromiseSymbol] to either true or false when a then method is 
detected.

Whereas without the anti-brand, the tool would have no idea whether the 
user
really wants automatic assimilation, or they're just unaware of the 
special
behaviour.

> OTOH, since this would mainly be
> about mitigating the pain of fixing contrary uses of "then", if we're
> going to do it at all, we should do it in ES6.

Right - thats why I tried suggesting it now... But still, I think that 
there are
enough reasons to do this even if after the ES6 ship sails.

> If we don't, then these contrary uses of "then" will probably already be
> fixed by the time ES7 rolls out.

I'm sorry, but I cannot accept the claim that there is such a thing as
"contrary use of then". Libraries are not at fault here - ES6 is the 
one trampling
on their use of a perfectly valid, very generic method name.


___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Why thenables?

2013-12-19 Thread Mark S. Miller
I think this anti-branding idea is worth considering, but using a symbol or
weakmap for the anti-branding rather than a magic double-underbar property
name. Unlike prior positive thenable branding proposals, this one doesn't
break existing code but still provides systems that use "then" in contrary
ways an ability to cope. It also doesn't break anything premised on the
promise-unwrapping consensus that we've agreed on and specced. I see only
two questions:

* Whether the benefit is worth the additional complexity?
* If we do decide to do this, does it make sense to postpone it to ES7?

Unless there is significant demonstrated need, I am leaning away from the
paying the additional complexity. OTOH, since this would mainly be about
mitigating the pain of fixing contrary uses of "then", if we're going to do
it at all, we should do it in ES6. If we don't, then these contrary uses of
"then" will probably already be fixed by the time ES7 rolls out.



On Thu, Dec 19, 2013 at 9:03 AM, Ѓорѓи Ќосев  wrote:

> On Thu 19 Dec 2013 07:42:31 AM CET, Andrea Giammarchi wrote:
>
> > The only thing that does is having *one*, *standard* contract -- and we
> are past due on that.
>
> Perhaps the right path would be to try and discuss this for
> Promises/A++, and maybe if it happens there, ES7 afterwards :)
>
> > Devs also complain about mistakes though .. not sure how to win here :-(
>
> No worries. I think I understand now. Still I felt it was worth a shot,
> although I guess I picked the wrong path (and time) to go about it.
>
> Thanks for your time -- and sorry for creating a stir.
>
> ___
> es-discuss mailing list
> es-discuss@mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
>



-- 
Cheers,
--MarkM
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Why thenables?

2013-12-19 Thread Ѓорѓи Ќосев
On Thu 19 Dec 2013 07:42:31 AM CET, Andrea Giammarchi wrote:

> The only thing that does is having *one*, *standard* contract -- and we are 
> past due on that.

Perhaps the right path would be to try and discuss this for 
Promises/A++, and maybe if it happens there, ES7 afterwards :)

> Devs also complain about mistakes though .. not sure how to win here :-(

No worries. I think I understand now. Still I felt it was worth a shot, 
although I guess I picked the wrong path (and time) to go about it.

Thanks for your time -- and sorry for creating a stir.

___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss