Pure functions in EcmaScript

2012-11-28 Thread Marius Gundersen
Has there been any work done on pure functions in EcmaScript? The way I
imagine it, there would be a way to indicate that a function should be pure
(by using a symbol or a new keyword, although I understand new keywords
aren't terribly popular). The pure function is not allowed to access any
variable outside its own scope. Any access to a variable outside the scope
of the function would result in a Reference Error, with an indication that
the reference attempt was made from a pure function. This also applies to
any function called from within the pure function. The entire stack of a
pure function must be pure. This also means the pure function cannot access
the [this] object. Only the parameters  passed to the function can be used
in the calculation.

The syntax could be something like this (the @ indicates that it is pure):

function sum@(a, b){
  return a+b;
}

var sum = function@(a, b){
  return a+b;
}

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


Re: Pure functions in EcmaScript

2012-11-28 Thread Andreas Rossberg
On 28 November 2012 12:50, Marius Gundersen gunder...@gmail.com wrote:
 Has there been any work done on pure functions in EcmaScript? The way I
 imagine it, there would be a way to indicate that a function should be pure
 (by using a symbol or a new keyword, although I understand new keywords
 aren't terribly popular). The pure function is not allowed to access any
 variable outside its own scope. Any access to a variable outside the scope
 of the function would result in a Reference Error, with an indication that
 the reference attempt was made from a pure function. This also applies to
 any function called from within the pure function. The entire stack of a
 pure function must be pure. This also means the pure function cannot access
 the [this] object. Only the parameters  passed to the function can be used
 in the calculation.

 The syntax could be something like this (the @ indicates that it is pure):

 function sum@(a, b){
   return a+b;
 }

 var sum = function@(a, b){
   return a+b;
 }

A couple of comments.

First, your definition of pure is not quite correct. Any function
that even _returns_ locally created state in some form (i.e., a new
object), is impure.

Second, due to the extremely impure nature of JavaScript, there aren't
many useful pure functions you could even write. For example, your
'sum' function is not pure, because the implicit conversions required
by + can cause arbitrary side effects.

Last, short of a static type-and-effect system, I don't see how the
necessary checks could be implemented without imposing significant
overhead on almost every primitive operation -- because every
function, and hence almost any piece of code, might potentially end up
with a pure function in its call chain, and would need to check for
that.

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


Re: Pure functions in EcmaScript

2012-11-28 Thread David Bruant

Hi Marius,

I won't say the idea is bad, but what would be the benefit of this new 
type of function?


From experience on this list, if a new idea cannot prove to make a 
major difference with what currently exists, it is not considered to be 
added to the ES6 spec.
The major difference can be in performance, security, language 
extensibility, programming idioms/conveniences, etc.
Do you have reasons to think pure functions as you propose them make 
that big of an improvement as opposed to JS as it is?


David

Le 28/11/2012 12:50, Marius Gundersen a écrit :
Has there been any work done on pure functions in EcmaScript? The way 
I imagine it, there would be a way to indicate that a function should 
be pure (by using a symbol or a new keyword, although I understand new 
keywords aren't terribly popular). The pure function is not allowed to 
access any variable outside its own scope. Any access to a variable 
outside the scope of the function would result in a Reference Error, 
with an indication that the reference attempt was made from a pure 
function. This also applies to any function called from within the 
pure function. The entire stack of a pure function must be pure. This 
also means the pure function cannot access the [this] object. Only the 
parameters  passed to the function can be used in the calculation.


The syntax could be something like this (the @ indicates that it is pure):

function sum@(a, b){
  return a+b;
}

var sum = function@(a, b){
  return a+b;
}

Marius Gundersen


___
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: Pure functions in EcmaScript

2012-11-28 Thread Marius Gundersen
On Wed, Nov 28, 2012 at 1:20 PM, Andreas Rossberg rossb...@google.comwrote:

 On 28 November 2012 12:50, Marius Gundersen gunder...@gmail.com wrote:
  Has there been any work done on pure functions in EcmaScript? The way I
  imagine it, there would be a way to indicate that a function should be
 pure
  (by using a symbol or a new keyword, although I understand new keywords
  aren't terribly popular). The pure function is not allowed to access any
  variable outside its own scope. Any access to a variable outside the
 scope
  of the function would result in a Reference Error, with an indication
 that
  the reference attempt was made from a pure function. This also applies to
  any function called from within the pure function. The entire stack of a
  pure function must be pure. This also means the pure function cannot
 access
  the [this] object. Only the parameters  passed to the function can be
 used
  in the calculation.
 
  The syntax could be something like this (the @ indicates that it is
 pure):
 
  function sum@(a, b){
return a+b;
  }
 
  var sum = function@(a, b){
return a+b;
  }

 A couple of comments.

 First, your definition of pure is not quite correct. Any function
 that even _returns_ locally created state in some form (i.e., a new
 object), is impure.


Fair enough. A better name would probably be side effect free functions.

Second, due to the extremely impure nature of JavaScript, there aren't
 many useful pure functions you could even write. For example, your
 'sum' function is not pure, because the implicit conversions required
 by + can cause arbitrary side effects.


Functions passed to the array methods map, reduce, filter, etc would be
good candidates for pure/side-effect-free functions. These functions
shouldn't alter any state; they should only return a new value based on the
parameter they were sent.

Last, short of a static type-and-effect system, I don't see how the
 necessary checks could be implemented without imposing significant
 overhead on almost every primitive operation -- because every
 function, and hence almost any piece of code, might potentially end up
 with a pure function in its call chain, and would need to check for
 that.


I'm not an implementer of EcmaScript, so I don't have deep knowledge of how
this could be implemented. I would imagine that a subset of a true pure
function, where the only restriction would be that only variables passed as
arguments to the function exist in the scope, would be relatively easy to
implement. Wouldn't this be a faster implementation than todays functions,
which have to keep track of scope? These side-effect-free functions would
only need to contain the variables passed as parameters in their scope.
Accessing anything outside the scope would result in a reference error.

As you see this is obviously a subset of the pure function as it usually is
defined. The function is allowed to modify any object passed to is an
argument (since, as you point out, it would be difficult to protect against
this), and it is allowed to return new state.


 /Andreas

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


Re: Pure functions in EcmaScript

2012-11-28 Thread Marius Gundersen
On Wed, Nov 28, 2012 at 1:21 PM, David Bruant bruan...@gmail.com wrote:

  Hi Marius,

 I won't say the idea is bad, but what would be the benefit of this new
 type of function?

 From experience on this list, if a new idea cannot prove to make a major
 difference with what currently exists, it is not considered to be added to
 the ES6 spec.
 The major difference can be in performance, security, language
 extensibility, programming idioms/conveniences, etc.
 Do you have reasons to think pure functions as you propose them make that
 big of an improvement as opposed to JS as it is?


With many new functional programming possibilities (like map, reduce,
filter, lambdas) there are many scenarios where the implementer should use
pure (or as I renamed it in another reply, side-effect-free) functions.
Library implementers are likely interested in making functions that can
take lambdas as parameters, and these lambdas (in many cases) should not
alter any outside state, they should only return a value. A function with
this restriction could run faster and take up less memory since it only
needs the values passed to it as arguments in its own scope.

Mostly I feel this would introduce better coding practises with a focus on
functional programming rather than object oriented programming. Using
functions with limited scope would reduce the number of variables written
to the global scope, and would reduce the amount of state in an
application. Seeing as FP is a bit of a trend today (due, in part, to the
popularity of JavaScript), it seems to me like a good idea to implementing
features which help promote good FP patterns in a language that allows for
both FP and OOP.

David

 Le 28/11/2012 12:50, Marius Gundersen a écrit :

 Has there been any work done on pure functions in EcmaScript? The way I
 imagine it, there would be a way to indicate that a function should be pure
 (by using a symbol or a new keyword, although I understand new keywords
 aren't terribly popular). The pure function is not allowed to access any
 variable outside its own scope. Any access to a variable outside the scope
 of the function would result in a Reference Error, with an indication that
 the reference attempt was made from a pure function. This also applies to
 any function called from within the pure function. The entire stack of a
 pure function must be pure. This also means the pure function cannot access
 the [this] object. Only the parameters  passed to the function can be used
 in the calculation.

 The syntax could be something like this (the @ indicates that it is pure):

 function sum@(a, b){
   return a+b;
 }

 var sum = function@(a, b){
   return a+b;
 }

 Marius Gundersen


 ___
 es-discuss mailing 
 listes-discuss@mozilla.orghttps://mail.mozilla.org/listinfo/es-discuss



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


Re: Pure functions in EcmaScript

2012-11-28 Thread Andreas Rossberg
On 28 November 2012 14:39, Marius Gundersen gunder...@gmail.com wrote:
 On Wed, Nov 28, 2012 at 1:20 PM, Andreas Rossberg rossb...@google.com
 wrote:
 First, your definition of pure is not quite correct. Any function
 that even _returns_ locally created state in some form (i.e., a new
 object), is impure.

 Fair enough. A better name would probably be side effect free functions.

Well, observable allocation of state, or assignment to parameters,
_are_ side effects.

On the other hand, accessing non-local bindings that are (deeply)
immutable does not constitute an effect, yet you want to forbid it.

Seriously, what is the use case for this rather strange definition?


 Last, short of a static type-and-effect system, I don't see how the
 necessary checks could be implemented without imposing significant
 overhead on almost every primitive operation -- because every
 function, and hence almost any piece of code, might potentially end up
 with a pure function in its call chain, and would need to check for
 that.

 I'm not an implementer of EcmaScript, so I don't have deep knowledge of how
 this could be implemented. I would imagine that a subset of a true pure
 function, where the only restriction would be that only variables passed as
 arguments to the function exist in the scope, would be relatively easy to
 implement. Wouldn't this be a faster implementation than todays functions,
 which have to keep track of scope? These side-effect-free functions would
 only need to contain the variables passed as parameters in their scope.
 Accessing anything outside the scope would result in a reference error.

Modern JS implementations don't do the kind of runtime bookkeeping of
scopes that you seem to assume. Compiled code doesn't even know what a
scope is, it just accesses hardcoded indices into the stack or into
some heap arrays.

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


Re: Pure functions in EcmaScript

2012-11-28 Thread Jussi Kalliokoski
On Wed, Nov 28, 2012 at 3:47 PM, Marius Gundersen gunder...@gmail.comwrote:




 On Wed, Nov 28, 2012 at 1:21 PM, David Bruant bruan...@gmail.com wrote:

  Hi Marius,

 I won't say the idea is bad, but what would be the benefit of this new
 type of function?

 From experience on this list, if a new idea cannot prove to make a major
 difference with what currently exists, it is not considered to be added to
 the ES6 spec.
 The major difference can be in performance, security, language
 extensibility, programming idioms/conveniences, etc.
 Do you have reasons to think pure functions as you propose them make that
 big of an improvement as opposed to JS as it is?


 With many new functional programming possibilities (like map, reduce,
 filter, lambdas) there are many scenarios where the implementer should use
 pure (or as I renamed it in another reply, side-effect-free) functions.
 Library implementers are likely interested in making functions that can
 take lambdas as parameters, and these lambdas (in many cases) should not
 alter any outside state, they should only return a value. A function with
 this restriction could run faster and take up less memory since it only
 needs the values passed to it as arguments in its own scope.

 Mostly I feel this would introduce better coding practises with a focus on
 functional programming rather than object oriented programming. Using
 functions with limited scope would reduce the number of variables written
 to the global scope, and would reduce the amount of state in an
 application. Seeing as FP is a bit of a trend today (due, in part, to the
 popularity of JavaScript), it seems to me like a good idea to implementing
 features which help promote good FP patterns in a language that allows for
 both FP and OOP.


With pure function, are you after

a) The equivalent of `inline` in the C family?
b) Something less state-independent, a function that could be, for example,
parallelized/forked safely?

For a), I'm not sure to which extent implementations already do this. For
b), seems like something related to the RiverTrail project.

Cheers,
Jussi


 David

 Le 28/11/2012 12:50, Marius Gundersen a écrit :

 Has there been any work done on pure functions in EcmaScript? The way I
 imagine it, there would be a way to indicate that a function should be pure
 (by using a symbol or a new keyword, although I understand new keywords
 aren't terribly popular). The pure function is not allowed to access any
 variable outside its own scope. Any access to a variable outside the scope
 of the function would result in a Reference Error, with an indication that
 the reference attempt was made from a pure function. This also applies to
 any function called from within the pure function. The entire stack of a
 pure function must be pure. This also means the pure function cannot access
 the [this] object. Only the parameters  passed to the function can be used
 in the calculation.

 The syntax could be something like this (the @ indicates that it is pure):

 function sum@(a, b){
   return a+b;
 }

 var sum = function@(a, b){
   return a+b;
 }

 Marius Gundersen


 ___
 es-discuss mailing 
 listes-discuss@mozilla.orghttps://mail.mozilla.org/listinfo/es-discuss




 ___
 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: Pure functions in EcmaScript

2012-11-28 Thread David Bruant

Le 28/11/2012 14:47, Marius Gundersen a écrit :
On Wed, Nov 28, 2012 at 1:21 PM, David Bruant bruan...@gmail.com 
mailto:bruan...@gmail.com wrote:


Hi Marius,

I won't say the idea is bad, but what would be the benefit of this
new type of function?

From experience on this list, if a new idea cannot prove to make a
major difference with what currently exists, it is not considered
to be added to the ES6 spec.
The major difference can be in performance, security, language
extensibility, programming idioms/conveniences, etc.
Do you have reasons to think pure functions as you propose them
make that big of an improvement as opposed to JS as it is?


With many new functional programming possibilities (like map, reduce, 
filter, lambdas) there are many scenarios where the implementer should 
use pure (or as I renamed it in another reply, side-effect-free) 
functions.

Why should? What is the problem if people don't?

Library implementers are likely interested in making functions that 
can take lambdas as parameters, and these lambdas (in many cases) 
should not alter any outside state, they should only return a value. A 
function with this restriction could run faster and take up less 
memory since it only needs the values passed to it as arguments in its 
own scope.
could run faster and take up less memory. I agree it could, but it's 
not given it will when implemented. In some cases, it's possible to 
prove that a function is side-effect free, but to the best of my 
knowledge, no implementations has gone to length to do such thing, 
probably, because the cost is too big in regard to the benefits.


Mostly I feel this would introduce better coding practises with a 
focus on functional programming rather than object oriented programming.
I'm only half sympathic to this argument. JS is a language with many 
users with different programming styles. I understand the benefits of 
FP, but don't see why it should be favored over any other style.


Using functions with limited scope would reduce the number of 
variables written to the global scope
I use both OOP and FP styles and I don't see how FP would help for 
global variables. Basically, declaring variables as function local (with 
the var keyword) prevent global leaks.



and would reduce the amount of state in an application.
...and increase the use of temporary values and GC to compensate, 
because JS engines are not really written to optimize for FP? For 
instance, I think, none do tail call optimization yet? (others in the 
list know better on that point)


Seeing as FP is a bit of a trend today (due, in part, to the 
popularity of JavaScript), it seems to me like a good idea to 
implementing features which help promote good FP patterns in a 
language that allows for both FP and OOP.
You mentioned ReferenceError when the functions tries to reach a 
variable outside of its scope. I think it's possible to implement such a 
thing in current JavaScript. Take a look at the Caja code [1] for 
inspiration (sorry the barrier is a bit high as I put it. Ask me 
questions if you need help).
Also, to avoid being tempted to use a scope, just define your function 
as non-nested (global :-s or directly inside an IIFE (Immediately 
Invoked Function Expression))


Just a note:
function@ f(x){
x.a = 1;
}
I think this is a side-effect. Should an error be thrown here too?
If so, does it mean you can't use objects as arguments?


In any case, none of what you answered really convinces me (just to 
clarify, I just hang out on the list, I make no decisions with regard to 
the language) as being a major improvement for the language. It would be 
a good convenience for FP style, that's it.


David

[1] 
http://code.google.com/p/google-caja/source/browse/trunk/src/com/google/caja/ses/startSES.js#635
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Pure functions in EcmaScript

2012-11-28 Thread Andrea Giammarchi
I use the context argument quite a lot in order to be able to recycle those
functions as much as possible so `this` is needed in my case plus map and
filter do not necessary return a new value based on what's in the function.


abc.split().map(function(c){return this(c.charCodeAt(0) - 32)},
String.fromCharCode).join() // ABC

whenever it's a dumb example or not, I don't see that function dangerous,
not serializable, or not pure

my 2 cents

On Wed, Nov 28, 2012 at 5:39 AM, Marius Gundersen gunder...@gmail.comwrote:


 Functions passed to the array methods map, reduce, filter, etc would be
 good candidates for pure/side-effect-free functions. These functions
 shouldn't alter any state; they should only return a new value based on the
 parameter they were sent.

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


Object.getPrototypeOf(arguments) VS [[Class]]

2012-11-28 Thread Andrea Giammarchi
I just wonder if anyone can explain why functions arguments [[Class]] is
Arguments but Object.getPrototypeOf(arguments) is Object.prototype

This looks to me inconsistent against every other [[Class]] different from
Object case:either the class Arguments exists, or it doesn't, don't you
think?

!function(){
Object.getPrototypeOf(arguments) == Object.prototype; // true
{}.toString.call(
  Object.getPrototypeOf(arguments)
) == {}.toString(); // true again
}();

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


Re: Object.getPrototypeOf(arguments) VS [[Class]]

2012-11-28 Thread Brendan Eich
ES1-3 had arguments pretending to be Object but not actually an Object 
instance.


ES5 changed to use an internal class with name Arguments. No Arguments 
constructor, Arguments.prototype, etc.


I don't think we should polish the arguments turd further.

/be

Andrea Giammarchi wrote:
I just wonder if anyone can explain why functions arguments [[Class]] 
is Arguments but Object.getPrototypeOf(arguments) is Object.prototype


This looks to me inconsistent against every other [[Class]] different 
from Object case:either the class Arguments exists, or it doesn't, 
don't you think?


!function(){
Object.getPrototypeOf(arguments) == Object.prototype; // true
{}.toString.call(
  Object.getPrototypeOf(arguments)
) == {}.toString(); // true again
}();

Thanks for clarifications.
___
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: Object.getPrototypeOf(arguments) VS [[Class]]

2012-11-28 Thread Andrea Giammarchi
So the check to know if an object is Arguments cross version would be like
this, correct?

function isArguments(object) {
  return -1  {}.toString.call(object).indexOf( Arguments]) || (
typeof object == object  !(object instanceof Object)
  );
}

alert([
  isArguments({}),
  isArguments(function(){return arguments}())
]);

Thanks



On Wed, Nov 28, 2012 at 8:59 AM, Brendan Eich bren...@mozilla.org wrote:

 ES1-3 had arguments pretending to be Object but not actually an Object
 instance.

 ES5 changed to use an internal class with name Arguments. No Arguments
 constructor, Arguments.prototype, etc.

 I don't think we should polish the arguments turd further.

 /be

 Andrea Giammarchi wrote:

 I just wonder if anyone can explain why functions arguments [[Class]] is
 Arguments but Object.getPrototypeOf(**arguments) is Object.prototype

 This looks to me inconsistent against every other [[Class]] different
 from Object case:either the class Arguments exists, or it doesn't, don't
 you think?

 !function(){
 Object.getPrototypeOf(**arguments) == Object.prototype; // true
 {}.toString.call(
   Object.getPrototypeOf(**arguments)
 ) == {}.toString(); // true again
 }();

 Thanks for clarifications.
 __**_
 es-discuss mailing list
 es-discuss@mozilla.org
 https://mail.mozilla.org/**listinfo/es-discusshttps://mail.mozilla.org/listinfo/es-discuss


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


Re: Object.getPrototypeOf(arguments) VS [[Class]]

2012-11-28 Thread Andrea Giammarchi
null ...

function isArguments(object) {
  return -1  {}.toString.call(object).indexOf( Arguments]) || (
!!object  typeof object == object  !(object instanceof Object)
  );
}

On Wed, Nov 28, 2012 at 9:13 AM, Andrea Giammarchi 
andrea.giammar...@gmail.com wrote:

 function isArguments(object) {
   return -1  {}.toString.call(object).indexOf( Arguments]) || (
 typeof object == object  !(object instanceof Object)
   );
 }

 alert([
   isArguments({}),
   isArguments(function(){return arguments}())
 ]);

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


Re: Pure functions in EcmaScript

2012-11-28 Thread Claus Reinke
With many new functional programming possibilities (like map, reduce, 
filter, lambdas) there are many scenarios where the implementer should 
use pure (or as I renamed it in another reply, side-effect-free) 
functions.

Why should? What is the problem if people don't?


In the non-sequential versions, side-effect-free operators
give more flexibility in scheduling, eg, splitting an array
into sub-arrays, running partial loops on separate processors,
then combine the results.

In sequential code, side-effect-free operators give more
flexibility in refactoring and simplify program understanding
(code segments without access to global state have smaller APIs).

As pointed out by Andreas, achieving that is not easy in JS.
Even when some kind of soft or gradual type system finally
takes over the JS world,-) it'll still have to deal with a lot of
needlessly side-effect-based APIs. So my preference would be
to make sure that ES.next has side-effect-free, expression-level
APIs next to the existing side-effect-based, statement-level APIs, 
wherever possible (starting with object updating/extension).


The definition used by Marius seems to call for closed functions
(no non-local variables), which is not directly related. It sounds
as if he wants to allow local side-effects, as long as they do not
propagate outside the local call stack, but that is not as simple
as using closed functions. Andreas provided counter-examples.

Claus

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


Re: Object.getPrototypeOf(arguments) VS [[Class]]

2012-11-28 Thread Brendan Eich

Andrea Giammarchi wrote:

null ...

function isArguments(object) {
  return -1  {}.toString.call(object).indexOf( Arguments]) || (
!!object  typeof object == object  !(object instanceof Object)


Sorry, this isn't right. When I wrote ES1-3 had arguments pretending to 
be Object but not actually an Object instance I did not mean 
!(argsobj instanceof Object). I meant literally that arguments instances 
are of an internal class. Kind of like proxies, because they alias 
function formal parameters.


In ES1-3 it's hard to detect an arguments object. Something like

  object instanceof Object  !object.propertyIsEnumerable('length')

(where propertyIsEnumerable includes hasOwnProperty)?

/be


  );
}

On Wed, Nov 28, 2012 at 9:13 AM, Andrea Giammarchi 
andrea.giammar...@gmail.com mailto:andrea.giammar...@gmail.com wrote:


function isArguments(object) {
  return -1  {}.toString.call(object).indexOf( Arguments]) || (
typeof object == object  !(object instanceof Object)
  );
}

alert([
  isArguments({}),
  isArguments(function(){return arguments}())
]);


___
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: Pure functions in EcmaScript

2012-11-28 Thread David Bruant

Le 28/11/2012 18:19, Claus Reinke a écrit :
With many new functional programming possibilities (like map, 
reduce, filter, lambdas) there are many scenarios where the 
implementer should use pure (or as I renamed it in another reply, 
side-effect-free) functions.

Why should? What is the problem if people don't?


In the non-sequential versions, side-effect-free operators
give more flexibility in scheduling, eg, splitting an array
into sub-arrays, running partial loops on separate processors,
then combine the results.
I agree, but it's far from being applicable in JS apparently (I see you 
agree later in your response). I suggested this as my very first 
Bugzilla bug. I encourage to read the comments: 
https://bugzilla.mozilla.org/show_bug.cgi?id=593706


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


Re: Object.getPrototypeOf(arguments) VS [[Class]]

2012-11-28 Thread Andrea Giammarchi
object instanceof Object  !object.propertyIsEnumerable('**length')

every Array will be ... uhm, I remember the trick then was about looping
through for/in ... problem is, if length is 0 there's no way to udnerstand
if that object is arguments or not.

Right

On Wed, Nov 28, 2012 at 9:44 AM, Brendan Eich bren...@mozilla.org wrote:

 object instanceof Object  !object.propertyIsEnumerable('**length')

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


Re: Object.getPrototypeOf(arguments) VS [[Class]]

2012-11-28 Thread Andrea Giammarchi
https://gist.github.com/4163041

that should be it.

Thanks


On Wed, Nov 28, 2012 at 9:56 AM, Andrea Giammarchi 
andrea.giammar...@gmail.com wrote:

 object instanceof Object  !object.propertyIsEnumerable('**length')

 every Array will be ... uhm, I remember the trick then was about looping
 through for/in ... problem is, if length is 0 there's no way to udnerstand
 if that object is arguments or not.

 Right

 On Wed, Nov 28, 2012 at 9:44 AM, Brendan Eich bren...@mozilla.org wrote:

 object instanceof Object  !object.propertyIsEnumerable('**length')



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


Re: Pure functions in EcmaScript

2012-11-28 Thread Oliver Hunt
Just adding an implementers point of view:
Adding a new keyword/annotation is risky and/or complicates language semantics 
-- we don't want to break existing code, so new keywords are hard, likewise 
context dependent keywords can be tricksy: f = function pure(){} means what?

Assuming that there is an annotation that says a function is pure, runtime 
enforcement becomes either very expensive very quickly (possibly tending 
towards the halting problem in the general case), or can randomly throw 
exceptions.  Your sum function is a trivial case:
   function sum(a,b) { return a + b } // I'm pure

 We want to ensure sum has no side effects so we either typecheck on entry to 
ensure we will not need make a function call for the a and b typeconversions, 
or we throw on the first attempt to make a typeconversion (the exception will 
occur before any side effects, so you're still safe just annoyed).

But what about:
function bizzaroSum(a, b) {
while (a.b) a = a .b;
return a + b;
}
?

An ahead of time type check has unbounded time complexity, so there is no 
reason to not just execute and throw on a side effecting operation.

(Also what if a.b is a getter that simply returns 1 - does that count as a side 
effect because of the implied call, or does it not? after all there's not 
actually any side effect here)

So the only efficient way of dealing with a pure function is to run the code 
and perform type checks as you go to ensure that no calls are happening.

This gets us to _almost_ the level of performance modern JS engines are already 
getting, without having any concept of pure.  If your code is doing sensible 
things, and the types are consistent every supposed gain you get from purity 
is already there.

But your purity constraints means no side-effects, no general case calls, 
neither of these limits is helpful to modern JS engines as they will happily 
inline functions anyway regardless of purity, and will just do a stack rewrite 
and fallback to general code if their assumptions turn out to be false.

As an aside, the performance issues JSC at least has with map, reduce, etc is 
VM re-entry.  For us that's a much more significant performance problem than 
code gen quality.

--Oliver

On Nov 28, 2012, at 9:45 AM, David Bruant bruan...@gmail.com wrote:

 Le 28/11/2012 18:19, Claus Reinke a écrit :
 With many new functional programming possibilities (like map, reduce, 
 filter, lambdas) there are many scenarios where the implementer should use 
 pure (or as I renamed it in another reply, side-effect-free) functions.
 Why should? What is the problem if people don't?
 
 In the non-sequential versions, side-effect-free operators
 give more flexibility in scheduling, eg, splitting an array
 into sub-arrays, running partial loops on separate processors,
 then combine the results.
 I agree, but it's far from being applicable in JS apparently (I see you agree 
 later in your response). I suggested this as my very first Bugzilla bug. I 
 encourage to read the comments: 
 https://bugzilla.mozilla.org/show_bug.cgi?id=593706
 
 David
 ___
 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


Default value argument for Map/WeakMap.prototype.get()

2012-11-28 Thread Jason Orendorff
I propose adding an optional second argument to the .get() method on Map
and WeakMap.

Map.prototype.get(key[, defaultValue])

The default value would be returned only when the given key is not in the
map. That is, in the last step of the spec for these two methods, instead
of Return undefined, it would say Return defaultValue.

Python and Ruby have this. (In Ruby it's called fetch.) It's handy in
cases like:

var counts = new Map;
for (let word of words)
counts.set(word, counts.get(word, 0) + 1);

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


Re: Default value argument for Map/WeakMap.prototype.get()

2012-11-28 Thread Andrea Giammarchi
it was there and it has been removed ... curious to see if it will be back.

Said that, same way you do

obj.prop = obj.prop || def;

you can do

obj.set(prop, obj.get(prop) || {});

I know it's not the equivalent since you might want to be able to set null,
false, , NaN, etc etc ... but it's easy to add utilities to current logic
while it might be ambiguous to change defaultValue behavior later on.

As example, I might want to consider an inherited property as valid value
while what you are suggesting, in a more generic approach, is not
considering inheritance because the property is not own

br






On Wed, Nov 28, 2012 at 11:07 AM, Jason Orendorff jason.orendo...@gmail.com
 wrote:

 I propose adding an optional second argument to the .get() method on Map
 and WeakMap.

 Map.prototype.get(key[, defaultValue])

 The default value would be returned only when the given key is not in the
 map. That is, in the last step of the spec for these two methods, instead
 of Return undefined, it would say Return defaultValue.

 Python and Ruby have this. (In Ruby it's called fetch.) It's handy in
 cases like:

 var counts = new Map;
 for (let word of words)
 counts.set(word, counts.get(word, 0) + 1);

 -j


 ___
 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: Default value argument for Map/WeakMap.prototype.get()

2012-11-28 Thread Andrea Giammarchi
if interested, just because I need to uncomment a line if something will
ever change here:
https://github.com/WebReflection/es6-collections/blob/master/build/es6-collections.js#L48

before it was as you asked already. Many emails on this after :-/


On Wed, Nov 28, 2012 at 11:27 AM, Andrea Giammarchi 
andrea.giammar...@gmail.com wrote:

 it was there and it has been removed ... curious to see if it will be back.

 Said that, same way you do

 obj.prop = obj.prop || def;

 you can do

 obj.set(prop, obj.get(prop) || {});

 I know it's not the equivalent since you might want to be able to set
 null, false, , NaN, etc etc ... but it's easy to add utilities to current
 logic while it might be ambiguous to change defaultValue behavior later on.

 As example, I might want to consider an inherited property as valid value
 while what you are suggesting, in a more generic approach, is not
 considering inheritance because the property is not own

 br






 On Wed, Nov 28, 2012 at 11:07 AM, Jason Orendorff 
 jason.orendo...@gmail.com wrote:

 I propose adding an optional second argument to the .get() method on Map
 and WeakMap.

 Map.prototype.get(key[, defaultValue])

 The default value would be returned only when the given key is not in the
 map. That is, in the last step of the spec for these two methods, instead
 of Return undefined, it would say Return defaultValue.

 Python and Ruby have this. (In Ruby it's called fetch.) It's handy in
 cases like:

 var counts = new Map;
 for (let word of words)
 counts.set(word, counts.get(word, 0) + 1);

 -j


 ___
 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: Default value argument for Map/WeakMap.prototype.get()

2012-11-28 Thread Domenic Denicola
Using https://github.com/substack/defined you can do

var d = require(defined);
var x = d(m.get(key), defaultValue);

Not sure if this is an argument for adding default value because this module is 
so ridiculous ... or against it since it’s so trivial to get the functionality 
yourself.

From: Andrea Giammarchi
Sent: ‎November‎ ‎28‎, ‎2012 ‎14‎:‎27
To: Jason Orendorff
CC: es-discuss
Subject: Re: Default value argument for Map/WeakMap.prototype.get()

it was there and it has been removed ... curious to see if it will be back.

Said that, same way you do

obj.prop = obj.prop || def;

you can do

obj.set(prop, obj.get(prop) || {});

I know it's not the equivalent since you might want to be able to set null, 
false, , NaN, etc etc ... but it's easy to add utilities to current logic 
while it might be ambiguous to change defaultValue behavior later on.

As example, I might want to consider an inherited property as valid value while 
what you are suggesting, in a more generic approach, is not considering 
inheritance because the property is not own

br






On Wed, Nov 28, 2012 at 11:07 AM, Jason Orendorff 
jason.orendo...@gmail.commailto:jason.orendo...@gmail.com wrote:
I propose adding an optional second argument to the .get() method on Map and 
WeakMap.

Map.prototype.get(key[, defaultValue])

The default value would be returned only when the given key is not in the map. 
That is, in the last step of the spec for these two methods, instead of Return 
undefined, it would say Return defaultValue.

Python and Ruby have this. (In Ruby it's called fetch.) It's handy in cases 
like:

var counts = new Map;
for (let word of words)
counts.set(word, counts.get(word, 0) + 1);

-j


___
es-discuss mailing list
es-discuss@mozilla.orgmailto: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: Default value argument for Map/WeakMap.prototype.get()

2012-11-28 Thread Andrea Giammarchi
thing is ... it's not really that trivial.

What if you decide to define a property/value as undefined ?

In this case the equivalent is, AFAICT

function d(map, key, defaultValue) {
  return map.has(key) ? map.get(key) : defaultValue;
}

so that

counts.set(word, d(counts, word, 0) + 1);

the fact is that map.set({}, undefined) is allowed/valid so it's easy to go
down to ambiguity

var m = new Map;
m.set(m, undefined);
m.has(m); // true


br





On Wed, Nov 28, 2012 at 11:52 AM, Domenic Denicola 
dome...@domenicdenicola.com wrote:

  Using https://github.com/substack/defined you can do

 var d = require(defined);
 var x = d(m.get(key), defaultValue);

 Not sure if this is an argument for adding default value because this
 module is so ridiculous ... or against it since it’s so trivial to get the
 functionality yourself.

  *From:* Andrea Giammarchi
 *Sent:* November 28, 2012 14:27
 *To:* Jason Orendorff
 *CC:* es-discuss
 *Subject:* Re: Default value argument for Map/WeakMap.prototype.get()

 it was there and it has been removed ... curious to see if it will be
 back.

  Said that, same way you do

  obj.prop = obj.prop || def;

  you can do

  obj.set(prop, obj.get(prop) || {});

  I know it's not the equivalent since you might want to be able to set
 null, false, , NaN, etc etc ... but it's easy to add utilities to current
 logic while it might be ambiguous to change defaultValue behavior later on.

  As example, I might want to consider an inherited property as valid
 value while what you are suggesting, in a more generic approach, is not
 considering inheritance because the property is not own

  br






 On Wed, Nov 28, 2012 at 11:07 AM, Jason Orendorff 
 jason.orendo...@gmail.com wrote:

 I propose adding an optional second argument to the .get() method on Map
 and WeakMap.

 Map.prototype.get(key[, defaultValue])

 The default value would be returned only when the given key is not in the
 map. That is, in the last step of the spec for these two methods, instead
 of Return undefined, it would say Return defaultValue.

 Python and Ruby have this. (In Ruby it's called fetch.) It's handy in
 cases like:

 var counts = new Map;
 for (let word of words)
 counts.set(word, counts.get(word, 0) + 1);

 -j


 ___
 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: Default value argument for Map/WeakMap.prototype.get()

2012-11-28 Thread Andrea Giammarchi
apologies, I meant it is trivial, but it depends what you are looking for /
need

So, since is that easy to create your own case, then no reason to add the
default argument in the API

On Wed, Nov 28, 2012 at 12:11 PM, Andrea Giammarchi 
andrea.giammar...@gmail.com wrote:

 thing is ... it's not really that trivial.


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


Re: Pure functions in EcmaScript

2012-11-28 Thread Waldemar Horwat
On Wed, Nov 28, 2012 at 5:39 AM, Marius Gundersen gunder...@gmail.comwrote:

 On Wed, Nov 28, 2012 at 1:20 PM, Andreas Rossberg rossb...@google.comwrote:

 Second, due to the extremely impure nature of JavaScript, there aren't
 many useful pure functions you could even write. For example, your
 'sum' function is not pure, because the implicit conversions required
 by + can cause arbitrary side effects.


 Functions passed to the array methods map, reduce, filter, etc would be
 good candidates for pure/side-effect-free functions. These functions
 shouldn't alter any state; they should only return a new value based on the
 parameter they were sent.


You haven't addressed Andreas's point: Almost any function you write is
nonpure, including your sum example. As a fun exercise, go ahead and write
a pure version of your sum example.

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


Re: Pure functions in EcmaScript

2012-11-28 Thread Oliver Hunt

On Nov 28, 2012, at 12:25 PM, Waldemar Horwat walde...@google.com wrote:

 On Wed, Nov 28, 2012 at 5:39 AM, Marius Gundersen gunder...@gmail.com wrote:
 On Wed, Nov 28, 2012 at 1:20 PM, Andreas Rossberg rossb...@google.com wrote:
 Second, due to the extremely impure nature of JavaScript, there aren't
 many useful pure functions you could even write. For example, your
 'sum' function is not pure, because the implicit conversions required
 by + can cause arbitrary side effects.
 
 Functions passed to the array methods map, reduce, filter, etc would be good 
 candidates for pure/side-effect-free functions. These functions shouldn't 
 alter any state; they should only return a new value based on the parameter 
 they were sent.
 
 You haven't addressed Andreas's point: Almost any function you write is 
 nonpure, including your sum example. As a fun exercise, go ahead and write a 
 pure version of your sum example.
 
 Waldemar
Here you go:

function sum(a, b) {
   var undefined;
   switch (typeof a) {
   case number:
   case string:
   break;
   default:
   return +undefined;
   }
   switch (typeof b) {
   case number:
   case string:
   break;
   default:
   return +undefined;
   }
   return a + b;
} 



 
 ___
 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: Notification proxies (Was: possible excessive proxy invariants for Object.keys/etc??)

2012-11-28 Thread Tom Van Cutsem
2012/11/26 Dean Tribble dtrib...@gmail.com

 On Mon, Nov 26, 2012 at 11:33 AM, Tom Van Cutsem tomvc...@gmail.comwrote:

 Thanks for spelling out these examples. While they still don't feel like
 actual important use cases to support, they give a good flavor of the kinds
 of compromises we'd need to make when turning to notification-only proxies.


 I agree. My usual expectation for proxies is to support remote and
 persistent objects. While supporting other scenarios is great, usually
 that's incidental.  Is there a broader list of aspirations for proxies? or
 is this just a all else being equal it would be good if we can do this?


Let's talk about aspirations for proxies. It will help us set priorities.

First, some terminology (originating from CLOS, the mother of all MOPs ;-)
CLOS method combinations allow a composer to distinguish between before,
after and around-style composition:
- before-style wrapping gives you only the ability to get notified before
an operation happens. You can abort, but not change, the result of the
operation. This is what notification-proxies offer.
- after-style wrapping allows you to get notified of an operation
after-the-fact. Depending on the API, the after-wrapper may or may not
get to see the outcome of the operation, and may or may not change the
final outcome passed on to clients.
- around-style wrapping is the most general and allows the composer to
decide if and when to forward, and what result to return. It subsumes
before/after wrapping. This is what direct proxies currently provide.

As far as I can tell, virtual object abstractions like remote/persistent
objects require around-style wrapping, because there's otherwise no
meaningful target to automatically forward to.

Here's a list of use cases that I frequently have in mind when thinking
about proxies, categorized according to whether the use case requires
before/after/around wrapping:

Virtual objects, hence around-style:
- self-hosting exotic objects such as Date, Array (i.e. self-host an
ES5/ES6 environment)
- self-hosting DOM/WebIDL objects such as NodeList

Around-style wrapping (need to be able to change the result of an
operation):
- membranes
- higher-order contracts

Before-style wrapping:
- revocable references

What else?

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


Re: Pure functions in EcmaScript

2012-11-28 Thread David Bruant

Le 28/11/2012 21:35, Oliver Hunt a écrit :


On Nov 28, 2012, at 12:25 PM, Waldemar Horwat walde...@google.com 
mailto:walde...@google.com wrote:


On Wed, Nov 28, 2012 at 5:39 AM, Marius Gundersen 
gunder...@gmail.com mailto:gunder...@gmail.com wrote:


On Wed, Nov 28, 2012 at 1:20 PM, Andreas Rossberg
rossb...@google.com mailto:rossb...@google.com wrote:

Second, due to the extremely impure nature of JavaScript,
there aren't
many useful pure functions you could even write. For example,
your
'sum' function is not pure, because the implicit conversions
required
by + can cause arbitrary side effects.


Functions passed to the array methods map, reduce, filter, etc
would be good candidates for pure/side-effect-free functions.
These functions shouldn't alter any state; they should only
return a new value based on the parameter they were sent.


You haven't addressed Andreas's point: Almost any function you write 
is nonpure, including your sum example. As a fun exercise, go ahead 
and write a pure version of your sum example.


Waldemar

Here you go:

function sum(a, b) {
   var undefined;
   switch (typeof a) {
   case number:
   case string:
   break;
   default:
   return +undefined;
   }
switch (typeof b) {
   case number:
   case string:
   break;
   default:
   return +undefined;
   }
   return a + b;
}
I don't even... Reading this makes me understand why return a+b didn't 
work and... oh well... JavaScript is quite a language...


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


Re: Default value argument for Map/WeakMap.prototype.get()

2012-11-28 Thread Tab Atkins Jr.
On Wed, Nov 28, 2012 at 12:12 PM, Andrea Giammarchi
andrea.giammar...@gmail.com wrote:
 apologies, I meant it is trivial, but it depends what you are looking for /
 need

 So, since is that easy to create your own case, then no reason to add the
 default argument in the API

No, that's not the case.  Even if it's trivial to write it on your
own, if its use-case is sufficiently common, adding it helps with the
overall usability of the language.  After all, by your argument, we
don't need Map#has either, since you can get around it by just doing:

function mapset(map, key, val) { map.set(key, [val]); }
function mapget(map, key) { return map.get(key)[0]; }
function maphas(map, key) { return map.get(key) === undefined; }

This lets you store undefined in a map, and still distinguish it from
the key not being set at all, while using solely Map#get and Map#set,
and a trivial bit of code.

In this case, I agree that getting a default value from a map when the
key is undefined is extremely common (I do it regularly when using
dictionaries in Python), and it should be part of the default API.

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


Re: Pure functions in EcmaScript

2012-11-28 Thread Oliver Hunt

On Nov 28, 2012, at 1:11 PM, David Bruant bruan...@gmail.com wrote:

 Le 28/11/2012 21:35, Oliver Hunt a écrit :
 
 On Nov 28, 2012, at 12:25 PM, Waldemar Horwat walde...@google.com wrote:
 
 On Wed, Nov 28, 2012 at 5:39 AM, Marius Gundersen gunder...@gmail.com 
 wrote:
 On Wed, Nov 28, 2012 at 1:20 PM, Andreas Rossberg rossb...@google.com 
 wrote:
 Second, due to the extremely impure nature of JavaScript, there aren't
 many useful pure functions you could even write. For example, your
 'sum' function is not pure, because the implicit conversions required
 by + can cause arbitrary side effects.
 
 Functions passed to the array methods map, reduce, filter, etc would be 
 good candidates for pure/side-effect-free functions. These functions 
 shouldn't alter any state; they should only return a new value based on the 
 parameter they were sent.
 
 You haven't addressed Andreas's point: Almost any function you write is 
 nonpure, including your sum example. As a fun exercise, go ahead and write 
 a pure version of your sum example.
 
 Waldemar
 Here you go:
 
 function sum(a, b) {
var undefined;
switch (typeof a) {
case number:
case string:
break;
default:
return +undefined;
}
switch (typeof b) {
case number:
case string:
break;
default:
return +undefined;
}
return a + b;
 } 
 I don't even... Reading this makes me understand why return a+b didn't work 
 and... oh well... JavaScript is quite a language...

my favourite bit in all of this was 
var undefined;
...
return +undefined;

Although i realise that 0/0 is possibly going to be a more efficient way to get 
NaN :D

 
 David

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


Re: Default value argument for Map/WeakMap.prototype.get()

2012-11-28 Thread Brendan Eich

Agreed.

Allen, did this default optional parameter to get() get dropped by accident?

/be

Tab Atkins Jr. wrote:

On Wed, Nov 28, 2012 at 12:12 PM, Andrea Giammarchi
andrea.giammar...@gmail.com  wrote:

apologies, I meant it is trivial, but it depends what you are looking for /
need

So, since is that easy to create your own case, then no reason to add the
default argument in the API


No, that's not the case.  Even if it's trivial to write it on your
own, if its use-case is sufficiently common, adding it helps with the
overall usability of the language.  After all, by your argument, we
don't need Map#has either, since you can get around it by just doing:

function mapset(map, key, val) { map.set(key, [val]); }
function mapget(map, key) { return map.get(key)[0]; }
function maphas(map, key) { return map.get(key) === undefined; }

This lets you store undefined in a map, and still distinguish it from
the key not being set at all, while using solely Map#get and Map#set,
and a trivial bit of code.

In this case, I agree that getting a default value from a map when the
key is undefined is extremely common (I do it regularly when using
dictionaries in Python), and it should be part of the default API.

~TJ
___
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: Default value argument for Map/WeakMap.prototype.get()

2012-11-28 Thread Andrea Giammarchi
has is another story and your functions will fail.
I have provided already this example which is perfectly valid:

var m = new Map;
m.set(m, undefined);
m.has(m); // true

all you need in JS, which is not Python, is the ||

m.get(key) || defaultValue

which is the most common case, as you wrote, for maps.

I strongly doubt you gonna store false, empty strings, or null as values,
right?

It's funny I am the first one shouting that

obj.prop = obj.prop || defaultValue

is not a good pattern but here you want a better one for Map.prototype

It's also funny I have already implemented that and it is not me pushing
back so ... I actually don't get anything you said or what you think I
wrote :-/

br




On Wed, Nov 28, 2012 at 1:11 PM, Tab Atkins Jr. jackalm...@gmail.comwrote:

 On Wed, Nov 28, 2012 at 12:12 PM, Andrea Giammarchi
 andrea.giammar...@gmail.com wrote:
  apologies, I meant it is trivial, but it depends what you are looking
 for /
  need
 
  So, since is that easy to create your own case, then no reason to add the
  default argument in the API

 No, that's not the case.  Even if it's trivial to write it on your
 own, if its use-case is sufficiently common, adding it helps with the
 overall usability of the language.  After all, by your argument, we
 don't need Map#has either, since you can get around it by just doing:

 function mapset(map, key, val) { map.set(key, [val]); }
 function mapget(map, key) { return map.get(key)[0]; }
 function maphas(map, key) { return map.get(key) === undefined; }

 This lets you store undefined in a map, and still distinguish it from
 the key not being set at all, while using solely Map#get and Map#set,
 and a trivial bit of code.

 In this case, I agree that getting a default value from a map when the
 key is undefined is extremely common (I do it regularly when using
 dictionaries in Python), and it should be part of the default API.

 ~TJ

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


Re: Pure functions in EcmaScript

2012-11-28 Thread Brendan Eich

David Bruant wrote:
I don't even... Reading this makes me understand why return a+b 
didn't work and... oh well... JavaScript is quite a language...


I said at JSConf.au that parts of JS are like an old-school Adventure 
game. Sometimes you get eaten by a grue.


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


Re: Default value argument for Map/WeakMap.prototype.get()

2012-11-28 Thread Andrea Giammarchi
it's also like this in the wiki:
http://wiki.ecmascript.org/doku.php?id=harmony:weak_maps#alternate_spec_based_on_ff6.0a1


On Wed, Nov 28, 2012 at 1:15 PM, Brendan Eich bren...@mozilla.org wrote:

 Agreed.

 Allen, did this default optional parameter to get() get dropped by
 accident?

 /be

 Tab Atkins Jr. wrote:

 On Wed, Nov 28, 2012 at 12:12 PM, Andrea Giammarchi
 andrea.giammar...@gmail.com  wrote:

 apologies, I meant it is trivial, but it depends what you are looking
 for /
 need

 So, since is that easy to create your own case, then no reason to add the
 default argument in the API


 No, that's not the case.  Even if it's trivial to write it on your
 own, if its use-case is sufficiently common, adding it helps with the
 overall usability of the language.  After all, by your argument, we
 don't need Map#has either, since you can get around it by just doing:

 function mapset(map, key, val) { map.set(key, [val]); }
 function mapget(map, key) { return map.get(key)[0]; }
 function maphas(map, key) { return map.get(key) === undefined; }

 This lets you store undefined in a map, and still distinguish it from
 the key not being set at all, while using solely Map#get and Map#set,
 and a trivial bit of code.

 In this case, I agree that getting a default value from a map when the
 key is undefined is extremely common (I do it regularly when using
 dictionaries in Python), and it should be part of the default API.

 ~TJ
 __**_
 es-discuss mailing list
 es-discuss@mozilla.org
 https://mail.mozilla.org/**listinfo/es-discusshttps://mail.mozilla.org/listinfo/es-discuss


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


Re: Pure functions in EcmaScript

2012-11-28 Thread Axel Rauschmayer
Would returning NaN be impure (apart from running the risk of it having been 
changed to something different, globally)?

On Nov 28, 2012, at 21:35 , Oliver Hunt oli...@apple.com wrote:

 
 On Nov 28, 2012, at 12:25 PM, Waldemar Horwat walde...@google.com wrote:
 
 On Wed, Nov 28, 2012 at 5:39 AM, Marius Gundersen gunder...@gmail.com 
 wrote:
 On Wed, Nov 28, 2012 at 1:20 PM, Andreas Rossberg rossb...@google.com 
 wrote:
 Second, due to the extremely impure nature of JavaScript, there aren't
 many useful pure functions you could even write. For example, your
 'sum' function is not pure, because the implicit conversions required
 by + can cause arbitrary side effects.
 
 Functions passed to the array methods map, reduce, filter, etc would be good 
 candidates for pure/side-effect-free functions. These functions shouldn't 
 alter any state; they should only return a new value based on the parameter 
 they were sent.
 
 You haven't addressed Andreas's point: Almost any function you write is 
 nonpure, including your sum example. As a fun exercise, go ahead and write a 
 pure version of your sum example.
 
 Waldemar
 Here you go:
 
 function sum(a, b) {
var undefined;
switch (typeof a) {
case number:
case string:
break;
default:
return +undefined;
}
switch (typeof b) {
case number:
case string:
break;
default:
return +undefined;
}
return a + b;
 } 
 
 
 
 
 ___
 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

-- 
Dr. Axel Rauschmayer
a...@rauschma.de

home: rauschma.de
twitter: twitter.com/rauschma
blog: 2ality.com

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


Default value for Map

2012-11-28 Thread Yehuda Katz
There are many cases involving nested data structures where the ability to
define a default value in Maps would be helpful.

Straw Man:

var map = new Map(= [])
var arr = map.get('foo')
arr === map.get('foo') // true

This enables:

map.get('foo').push(obj)

Which would be (*very*) approximately equivalent to:

class MapWithDefault extends Map {
  constructor(default) {
this.defaultValue = default;
super();
  }

  get(key) {
if (!this.contains('foo')) {
  let value = this.defaultValue(key);
  map.set(key, value);
}

return super(key);
  }
}

-- 
Yehuda Katz
(ph) 718.877.1325
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Notification proxies (Was: possible excessive proxy invariants for Object.keys/etc??)

2012-11-28 Thread Brandon Benvie
Object.observe would fit under after correct?


On Wed, Nov 28, 2012 at 4:09 PM, Tom Van Cutsem tomvc...@gmail.com wrote:

 2012/11/26 Dean Tribble dtrib...@gmail.com

 On Mon, Nov 26, 2012 at 11:33 AM, Tom Van Cutsem tomvc...@gmail.comwrote:

 Thanks for spelling out these examples. While they still don't feel like
 actual important use cases to support, they give a good flavor of the kinds
 of compromises we'd need to make when turning to notification-only proxies.


 I agree. My usual expectation for proxies is to support remote and
 persistent objects. While supporting other scenarios is great, usually
 that's incidental.  Is there a broader list of aspirations for proxies? or
 is this just a all else being equal it would be good if we can do this?


 Let's talk about aspirations for proxies. It will help us set priorities.

 First, some terminology (originating from CLOS, the mother of all MOPs
 ;-)
 CLOS method combinations allow a composer to distinguish between before,
 after and around-style composition:
 - before-style wrapping gives you only the ability to get notified
 before an operation happens. You can abort, but not change, the result of
 the operation. This is what notification-proxies offer.
 - after-style wrapping allows you to get notified of an operation
 after-the-fact. Depending on the API, the after-wrapper may or may not
 get to see the outcome of the operation, and may or may not change the
 final outcome passed on to clients.
 - around-style wrapping is the most general and allows the composer to
 decide if and when to forward, and what result to return. It subsumes
 before/after wrapping. This is what direct proxies currently provide.

 As far as I can tell, virtual object abstractions like remote/persistent
 objects require around-style wrapping, because there's otherwise no
 meaningful target to automatically forward to.

 Here's a list of use cases that I frequently have in mind when thinking
 about proxies, categorized according to whether the use case requires
 before/after/around wrapping:

 Virtual objects, hence around-style:
 - self-hosting exotic objects such as Date, Array (i.e. self-host an
 ES5/ES6 environment)
 - self-hosting DOM/WebIDL objects such as NodeList

 Around-style wrapping (need to be able to change the result of an
 operation):
 - membranes
 - higher-order contracts

 Before-style wrapping:
 - revocable references

 What else?

 Cheers,
 Tom

 ___
 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: Default value for Map

2012-11-28 Thread Brendan Eich
See also 
https://mail.mozilla.org/pipermail/es-discuss/2012-January/019723.html 
where defaultdict was raised on es-discuss for the first time (if I'm 
not mistaken).


/be

Yehuda Katz wrote:
There are many cases involving nested data structures where the 
ability to define a default value in Maps would be helpful.


Straw Man:

var map = new Map(= [])
var arr = map.get('foo')
arr === map.get('foo') // true

This enables:

map.get('foo').push(obj)

Which would be (*very*) approximately equivalent to:

class MapWithDefault extends Map {
  constructor(default) {
this.defaultValue = default;
super();
  }

  get(key) {
if (!this.contains('foo')) {
  let value = this.defaultValue(key);
  map.set(key, value);
}

return super(key);
  }
}

--
Yehuda Katz
(ph) 718.877.1325
___
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: Pure functions in EcmaScript

2012-11-28 Thread Brendan Eich

Axel Rauschmayer wrote:
Would returning NaN be impure (apart from running the risk of it 
having been changed to something different, globally)?


You can't say apart from..., that's exactly the risk. It could be 
replaced with a global getter that has effects.


Isolating a pure function to a sandbox or prepared global environment 
saves this, but then the function's pure annotation can't be enough to 
express what's required.


/be


On Nov 28, 2012, at 21:35 , Oliver Hunt oli...@apple.com 
mailto:oli...@apple.com wrote:




On Nov 28, 2012, at 12:25 PM, Waldemar Horwat walde...@google.com 
mailto:walde...@google.com wrote:


On Wed, Nov 28, 2012 at 5:39 AM, Marius Gundersen 
gunder...@gmail.com mailto:gunder...@gmail.com wrote:


On Wed, Nov 28, 2012 at 1:20 PM, Andreas Rossberg
rossb...@google.com mailto:rossb...@google.com wrote:

Second, due to the extremely impure nature of JavaScript,
there aren't
many useful pure functions you could even write. For
example, your
'sum' function is not pure, because the implicit conversions
required
by + can cause arbitrary side effects.


Functions passed to the array methods map, reduce, filter, etc
would be good candidates for pure/side-effect-free functions.
These functions shouldn't alter any state; they should only
return a new value based on the parameter they were sent.


You haven't addressed Andreas's point: Almost any function you write 
is nonpure, including your sum example. As a fun exercise, go ahead 
and write a pure version of your sum example.


Waldemar

Here you go:

function sum(a, b) {
   var undefined;
   switch (typeof a) {
   case number:
   case string:
   break;
   default:
   return +undefined;
   }
switch (typeof b) {
   case number:
   case string:
   break;
   default:
   return +undefined;
   }
   return a + b;
}





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


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


--
Dr. Axel Rauschmayer
a...@rauschma.de mailto:a...@rauschma.de

home: rauschma.de http://rauschma.de
twitter: twitter.com/rauschma http://twitter.com/rauschma
blog: 2ality.com http://2ality.com

___
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: Default value argument for Map/WeakMap.prototype.get()

2012-11-28 Thread Andrea Giammarchi
Good, so now my only concern is about the fact ternary or || is better for
GC and performance, i.e.

var query = map.get('queried', $('myquery'));

If you repeat above example code 100 times, for 100 times you'll re-query
the DOM.
I might be the only one here but I can see already abuses of this second
argument.

This is as example not true using the ternary or the || operator

var query = map.has('queried') ? map.get('queried') : $('myquery');

// or quick and dirty
var query = map.get('queried') || $('myquery');

but in both cases $('myquery') is performed many times because there's no
shortcut able to set and return values, which is eventually the next logic
thing to change to this API.


What I believe is equivalently needed is a set method that returns the set
value so that


var query = map.has('queried') ? map.get('queried') :
map.set('queried', $('myquery'));

// or quick and dirty
var query = map.get('queried') || map.set('queried', $('myquery'));

in both cases the $('myquery') will be invoked only once, accordingly with
the fact it's returning an object and not a falsy value.

This is also much more familiar for developers that are used to write such
code:

var query = obj.queried || (obj.queried = $('myquery'));

This is in my opinion the best practice while, going back to the beginning
of this reply, the extra argument to the get() method will bring to
developers a bad pattern, IMHO

  1. it's easy to forget to store it later
  2. it executes eventually the expensive assignment/procedure regardless
the key is present or not

At least point 1 could be solved with a third argument, false by default,
able to store automatically the defaultValue if missing.


map.get('queried', $('myquery'), true).each(whatever);

Above example will ensure that map.get('queried') next time will return the
very first defaultValue that has been stored ...


Here, a universe of ambiguity created by a second argument that more I
write about it, less makes sense even if handy.

My 2 cents











On Wed, Nov 28, 2012 at 1:46 PM, Allen Wirfs-Brock al...@wirfs-brock.comwrote:

 It isn't in the wiki proposal, so it probably didn't get included when I
 created those  chapter 15 sections.  If there is consensus on those
 optional arguments I can add them.

 Allen


 On Nov 28, 2012, at 1:15 PM, Brendan Eich wrote:

  Agreed.
 
  Allen, did this default optional parameter to get() get dropped by
 accident?
 
  /be
 
  Tab Atkins Jr. wrote:
  On Wed, Nov 28, 2012 at 12:12 PM, Andrea Giammarchi
  andrea.giammar...@gmail.com  wrote:
  apologies, I meant it is trivial, but it depends what you are looking
 for /
  need
 
  So, since is that easy to create your own case, then no reason to add
 the
  default argument in the API
 
  No, that's not the case.  Even if it's trivial to write it on your
  own, if its use-case is sufficiently common, adding it helps with the
  overall usability of the language.  After all, by your argument, we
  don't need Map#has either, since you can get around it by just doing:
 
  function mapset(map, key, val) { map.set(key, [val]); }
  function mapget(map, key) { return map.get(key)[0]; }
  function maphas(map, key) { return map.get(key) === undefined; }
 
  This lets you store undefined in a map, and still distinguish it from
  the key not being set at all, while using solely Map#get and Map#set,
  and a trivial bit of code.
 
  In this case, I agree that getting a default value from a map when the
  key is undefined is extremely common (I do it regularly when using
  dictionaries in Python), and it should be part of the default API.
 
  ~TJ
  ___
  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: Notification proxies (Was: possible excessive proxy invariants for Object.keys/etc??)

2012-11-28 Thread David Bruant

Le 26/11/2012 21:39, David Bruant a écrit :

Le 26/11/2012 20:59, Tom Van Cutsem a écrit :

2012/11/26 David Bruant bruan...@gmail.com mailto:bruan...@gmail.com

We could define a symbolic value (like StopIteration for
iterators) that would mean forward to target. By essence of
what forwarding to the target means, there would be no need to
perform the least invariant check. We can call it ForwardToTarget :-)


I think we've previously entertained a similar proposal when a 
handler was encountering the .public property of a private property 
it didn't know, and then wanted to signal to the proxy I don't know 
this private name, please forward.
True. I had the feeling the idea wasn't entirely knew, but I couldn't 
recall what was the inspiration for it.


I recall one issue was that you'd really want a unique token per trap 
invocation, which costs.
I don't understand why a unique token per trap invocation would be 
necessary.

I still don't understand this point.
I've gone spelunking. I've found:
* the wiki page [1] (reflecting July meeting) which mentions that 
returning undefined would express I don't know the private name, please 
forward

* Confirmed on July 31st [2].
* Introduction of the idea of putting the verification of known names 
somewhere else than for each trap return [3]. Some discussion in between 
about this idea. Introduction of the idea of adding a third argument [4] 
after which I think stops all discussions about returning something in 
traps to prove knowledge of a private name or forwarding when not knowing.


I don't remember the point about a token per trap invocation and I 
haven't been able to find it (but I haven't read everything).


In any case, for throw ForwardToTarget, I don't see why it would be 
necessary. It seems it would work unambiguously with meta-handlers, with 
target-as-a-proxy or with manipulate-any-other-proxy-inside-a-trap 
(which target-as-a-proxy is an instance of).


David

[1] 
http://wiki.ecmascript.org/doku.php?id=harmony:direct_proxies#discussed_during_tc39_july_2012_meeting_microsoft_redmond

[2] https://mail.mozilla.org/pipermail/es-discuss/2012-July/024246.html
[3] https://mail.mozilla.org/pipermail/es-discuss/2012-July/024256.html
[4] https://mail.mozilla.org/pipermail/es-discuss/2012-August/024313.html
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Pure functions in EcmaScript

2012-11-28 Thread Axel Rauschmayer
Ah, global getter. Didn’t think of that.

On Nov 28, 2012, at 22:47 , Brendan Eich bren...@mozilla.org wrote:

 Axel Rauschmayer wrote:
 Would returning NaN be impure (apart from running the risk of it having been 
 changed to something different, globally)?
 
 You can't say apart from..., that's exactly the risk. It could be replaced 
 with a global getter that has effects.
 
 Isolating a pure function to a sandbox or prepared global environment saves 
 this, but then the function's pure annotation can't be enough to express 
 what's required.
 
 /be
 
 On Nov 28, 2012, at 21:35 , Oliver Hunt oli...@apple.com 
 mailto:oli...@apple.com wrote:
 
 
 On Nov 28, 2012, at 12:25 PM, Waldemar Horwat walde...@google.com 
 mailto:walde...@google.com wrote:
 
 On Wed, Nov 28, 2012 at 5:39 AM, Marius Gundersen gunder...@gmail.com 
 mailto:gunder...@gmail.com wrote:
 
On Wed, Nov 28, 2012 at 1:20 PM, Andreas Rossberg
rossb...@google.com mailto:rossb...@google.com wrote:
 
Second, due to the extremely impure nature of JavaScript,
there aren't
many useful pure functions you could even write. For
example, your
'sum' function is not pure, because the implicit conversions
required
by + can cause arbitrary side effects.
 
 
Functions passed to the array methods map, reduce, filter, etc
would be good candidates for pure/side-effect-free functions.
These functions shouldn't alter any state; they should only
return a new value based on the parameter they were sent.
 
 
 You haven't addressed Andreas's point: Almost any function you write is 
 nonpure, including your sum example. As a fun exercise, go ahead and write 
 a pure version of your sum example.
 
Waldemar
 Here you go:
 
 function sum(a, b) {
   var undefined;
   switch (typeof a) {
   case number:
   case string:
   break;
   default:
   return +undefined;
   }
 switch (typeof b) {
   case number:
   case string:
   break;
   default:
   return +undefined;
   }
   return a + b;
 }
 
 
 
 
 ___
 es-discuss mailing list
 es-discuss@mozilla.org mailto:es-discuss@mozilla.org
 https://mail.mozilla.org/listinfo/es-discuss
 
 ___
 es-discuss mailing list
 es-discuss@mozilla.org mailto:es-discuss@mozilla.org
 https://mail.mozilla.org/listinfo/es-discuss
 
 -- 
 Dr. Axel Rauschmayer
 a...@rauschma.de mailto:a...@rauschma.de
 
 home: rauschma.de http://rauschma.de
 twitter: twitter.com/rauschma http://twitter.com/rauschma
 blog: 2ality.com http://2ality.com
 
 ___
 es-discuss mailing list
 es-discuss@mozilla.org
 https://mail.mozilla.org/listinfo/es-discuss
 

-- 
Dr. Axel Rauschmayer
a...@rauschma.de

home: rauschma.de
twitter: twitter.com/rauschma
blog: 2ality.com

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


Re: Default value for Map

2012-11-28 Thread Yehuda Katz
Just to clarify, the existing Map has a first parameter, so there would
need to be some additional API work here (second parameter with undefined
first parameter, second class, `defaultValue` setter, etc.).


On Wed, Nov 28, 2012 at 1:45 PM, Brendan Eich bren...@mozilla.org wrote:

 See also https://mail.mozilla.org/**pipermail/es-discuss/2012-**
 January/019723.htmlhttps://mail.mozilla.org/pipermail/es-discuss/2012-January/019723.htmlwhere
  defaultdict was raised on es-discuss for the first time (if I'm not
 mistaken).

 /be

 Yehuda Katz wrote:

 There are many cases involving nested data structures where the ability
 to define a default value in Maps would be helpful.

 Straw Man:

 var map = new Map(= [])
 var arr = map.get('foo')
 arr === map.get('foo') // true

 This enables:

 map.get('foo').push(obj)

 Which would be (*very*) approximately equivalent to:


 class MapWithDefault extends Map {
   constructor(default) {
 this.defaultValue = default;
 super();
   }

   get(key) {
 if (!this.contains('foo')) {
   let value = this.defaultValue(key);
   map.set(key, value);
 }

 return super(key);
   }
 }

 --
 Yehuda Katz
 (ph) 718.877.1325
 __**_
 es-discuss mailing list
 es-discuss@mozilla.org
 https://mail.mozilla.org/**listinfo/es-discusshttps://mail.mozilla.org/listinfo/es-discuss




-- 
Yehuda Katz
(ph) 718.877.1325
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Default value argument for Map/WeakMap.prototype.get()

2012-11-28 Thread Tab Atkins Jr.
On Wed, Nov 28, 2012 at 1:16 PM, Andrea Giammarchi
andrea.giammar...@gmail.com wrote:
 has is another story and your functions will fail.
 I have provided already this example which is perfectly valid:

 var m = new Map;
 m.set(m, undefined);
 m.has(m); // true

...what?  Why would my functions fail?  Assuming you use them instead
of the built-in map functions, they work just fine.

 all you need in JS, which is not Python, is the ||

 m.get(key) || defaultValue

 which is the most common case, as you wrote, for maps.

This fails if the value is 0, null, false, undefined, or any other falsey value.

 I strongly doubt you gonna store false, empty strings, or null as values,
 right?

It's completely reasonable to store those things, and I have done
exactly that when using dictionaries in languages like Python and
Lisp.

 It's also funny I have already implemented that and it is not me pushing
 back so ... I actually don't get anything you said or what you think I wrote

You said (paraphrasing, obviously) there's no need to add this
feature, because authors can just add a one-line function that
accomplishes it.  I was just responding that this is a bad argument;
while the ease of coding it yourself is a relevant factor, it's not
the only one, as one should also consider how often it'll be used.

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


Re: Notification proxies (Was: possible excessive proxy invariants for Object.keys/etc??)

2012-11-28 Thread Dean Tribble
On Wed, Nov 28, 2012 at 1:09 PM, Tom Van Cutsem tomvc...@gmail.com wrote:

 2012/11/26 Dean Tribble dtrib...@gmail.com

 ...
 I agree. My usual expectation for proxies is to support remote and
 persistent objects. While supporting other scenarios is great, usually
 that's incidental.  Is there a broader list of aspirations for proxies? or
 is this just a all else being equal it would be good if we can do this?


 Let's talk about aspirations for proxies. It will help us set priorities.
 First, some terminology (originating from CLOS, the mother of all MOPs
 ;-)


As a general point, I encourage you to look for other inspiration than CLOS
MOP for doign proxies (whose mother was really InterlispD). Meta-level
access deeply impacts security,maintainability,
reliability, understandability, etc. The tighter and more structured you
can make your meta-level access, the easier it will be to to implement,
use, and maintain (e.g., both coroutines and downward functions are more
understandable, easier to implement, easier to secure, etc. than general
continuations and call-cc).


 CLOS method combinations allow a composer to distinguish between before,
 after and around-style composition:
 - before-style wrapping gives you only the ability to get notified
 before an operation happens. You can abort, but not change, the result of
 the operation. This is what notification-proxies offer.


You *can* change the result of the operation. You do so by modifying the
state before the operation proceeds, of course. You could also extend the
notification support to notify after so you could clenup (avoiding a
callback hack).


 - after-style wrapping allows you to get notified of an operation
 after-the-fact. Depending on the API, the after-wrapper may or may not
 get to see the outcome of the operation, and may or may not change the
 final outcome passed on to clients.
 - around-style wrapping is the most general and allows the composer to
 decide if and when to forward, and what result to return. It subsumes
 before/after wrapping. This is what direct proxies currently provide.


It does not subsume before/after wrapping, because it loses the integrity
of before/after (e.g., the wrapper can lie and cheat, where the before and
after cannot).  That may be worth it, but it is substantially different.

Another variant is the differential version:  the differential trap is
like a notification, but it can also return virtual additions (or an
iterator of additions).  The proxy then invokes the primitive on the
target, and appends (with de-dupping, etc.) the virtual additions. This
allows the simple case to just use hte target, but also allows all of
Allen's additional cases.

 As far as I can tell, virtual object abstractions like remote/persistent
 objects require around-style wrapping, because there's otherwise no
 meaningful target to automatically forward to.


I thought the target in that case is an internal object to represent or
reify the meta-state of the remote or persistent object. I think that still
makes sense in both the persistent object and remote object cases.


 Here's a list of use cases that I frequently have in mind when thinking
 about proxies, categorized according to whether the use case requires
 before/after/around wrapping:

 Virtual objects, hence around-style:
 - self-hosting exotic objects such as Date, Array (i.e. self-host an
 ES5/ES6 environment)
 - self-hosting DOM/WebIDL objects such as NodeList


I should note that I'm not advocating a notification-only style for all
your proxy needs; having get operations able to generate virtual results
makes lots of sense. I primary suggest it for operations that are currently
implemented by the system (i.e., user code cannot normally intervene) and
that might be relied on for security-relevant behavior. wrapping return
results of user operations in a proxy makes perfect sense to me.


 Around-style wrapping (need to be able to change the result of an
 operation):
 - membranes
 - higher-order contracts

 Before-style wrapping:
 - revocable references


You can validate arguments, the state of the destination object (e.g., if
you were implementing a state machine), logging

 What else?


There is the pattern derived from the meter pattern in KeyKOS:  the handler
is only invoked on exception (e.g., like a page fault).  For example, a
primitive stream gets read operations against. Normally they proceed as a
primitive against an implementation-provided buffer so that next is
really darned fast. When the buffer is exhausted, instead of throwing an
error to the caller, the error is thrown to the handler (called a keeper)
which goes through some user-defined effort to refill the buffer, then the
read is retried.  This allows most data transfer to such a stream to use
fast, batch-oriented primitives, while supporting an arbitrary source of
contents.
___
es-discuss mailing list
es-discuss@mozilla.org

Re: Default value argument for Map/WeakMap.prototype.get()

2012-11-28 Thread Andrea Giammarchi
right, I have explained my concern better in my latest reply.

br


On Wed, Nov 28, 2012 at 2:41 PM, Tab Atkins Jr. jackalm...@gmail.comwrote:

 On Wed, Nov 28, 2012 at 1:16 PM, Andrea Giammarchi
 andrea.giammar...@gmail.com wrote:
  has is another story and your functions will fail.
  I have provided already this example which is perfectly valid:
 
  var m = new Map;
  m.set(m, undefined);
  m.has(m); // true

 ...what?  Why would my functions fail?  Assuming you use them instead
 of the built-in map functions, they work just fine.

  all you need in JS, which is not Python, is the ||
 
  m.get(key) || defaultValue
 
  which is the most common case, as you wrote, for maps.

 This fails if the value is 0, null, false, undefined, or any other falsey
 value.

  I strongly doubt you gonna store false, empty strings, or null as values,
  right?

 It's completely reasonable to store those things, and I have done
 exactly that when using dictionaries in languages like Python and
 Lisp.

  It's also funny I have already implemented that and it is not me pushing
  back so ... I actually don't get anything you said or what you think I
 wrote

 You said (paraphrasing, obviously) there's no need to add this
 feature, because authors can just add a one-line function that
 accomplishes it.  I was just responding that this is a bad argument;
 while the ease of coding it yourself is a relevant factor, it's not
 the only one, as one should also consider how often it'll be used.

 ~TJ

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


Re: Pure functions in EcmaScript

2012-11-28 Thread Oliver Hunt
IIRC NaN is readonly, but you'd need to be able to guarantee the lexical scope 
between your function definition and the global object did have any shadowing :D

--Oliver

On Nov 28, 2012, at 1:32 PM, Axel Rauschmayer a...@rauschma.de wrote:

 Would returning NaN be impure (apart from running the risk of it having been 
 changed to something different, globally)?
 
 On Nov 28, 2012, at 21:35 , Oliver Hunt oli...@apple.com wrote:
 
 
 On Nov 28, 2012, at 12:25 PM, Waldemar Horwat walde...@google.com wrote:
 
 On Wed, Nov 28, 2012 at 5:39 AM, Marius Gundersen gunder...@gmail.com 
 wrote:
 On Wed, Nov 28, 2012 at 1:20 PM, Andreas Rossberg rossb...@google.com 
 wrote:
 Second, due to the extremely impure nature of JavaScript, there aren't
 many useful pure functions you could even write. For example, your
 'sum' function is not pure, because the implicit conversions required
 by + can cause arbitrary side effects.
 
 Functions passed to the array methods map, reduce, filter, etc would be 
 good candidates for pure/side-effect-free functions. These functions 
 shouldn't alter any state; they should only return a new value based on the 
 parameter they were sent.
 
 You haven't addressed Andreas's point: Almost any function you write is 
 nonpure, including your sum example. As a fun exercise, go ahead and write 
 a pure version of your sum example.
 
 Waldemar
 Here you go:
 
 function sum(a, b) {
var undefined;
switch (typeof a) {
case number:
case string:
break;
default:
return +undefined;
}
switch (typeof b) {
case number:
case string:
break;
default:
return +undefined;
}
return a + b;
 } 
 
 
 
 
 ___
 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
 
 -- 
 Dr. Axel Rauschmayer
 a...@rauschma.de
 
 home: rauschma.de
 twitter: twitter.com/rauschma
 blog: 2ality.com
 

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


Re: Problems with strict-mode caller poisoning

2012-11-28 Thread Andreas Rossberg
On 29 November 2012 00:16, Dave Fugate dave.fug...@gmail.com wrote:
 Believe you're correct on the former, but perhaps not the latter=)

 E.g.:
  6 /**
  7* @path ch15/15.3/15.3.5/15.3.5.4/15.3.5.4_2-1gs.js
  8* @description Strict mode - checking access to strict function
 caller from strict function (FunctionDeclaration defined within strict mode)
  9   * @onlyStrict
 10  * @negative TypeError
 11  */
 12
 13
 14 use strict;
 15 function f() {
 16 return gNonStrict();
 17 }
 18 f();
 19
 20
 21 function gNonStrict() {
 22 return gNonStrict.caller;
 23 }

 is globally scoped strict mode and passes only when a TypeError gets thrown
 indicating strict mode is in effect.

The bug with this test (and others) is that gNonStrict is _not_ a
non-strict function, its name notwithstanding. Hence the test throws
for the wrong reason, namely because strict-function.caller is a
poisoned getter, not because of Sec 15.3.5.4, which it is supposed to
test.

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


Object.prototype.get bye bye Object.defineProperty

2012-11-28 Thread Andrea Giammarchi
This was not true at some point, but now it seems to be the case in every
browser.

Just

Object.prototype.get = function(){};


and any further attempt to use Object.defineProperty(obj, key, {value:123})
will fail because defineProperty checks inherited get property, or set, and
these cannot be used together with value ...

Is this a bug or kinda a joke ?

Scary stuff, IMHO, thanks for clarifications.

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


Re: Object.prototype.get bye bye Object.defineProperty

2012-11-28 Thread Allen Wirfs-Brock

On Nov 28, 2012, at 6:40 PM, Andrea Giammarchi wrote:

 This was not true at some point, but now it seems to be the case in every 
 browser.
 
 Just 
 Object.prototype.get = function(){};
 
 and any further attempt to use Object.defineProperty(obj, key, {value:123}) 
 will fail because defineProperty checks inherited get property, or set, and 
 these cannot be used together with value ... 
 
 Is this a bug or kinda a joke ?

It's what the ES5/5.1 spec says. this is the first time I've seen this raised 
as an issue and as far as I know it was always been that way.

It conceivably could be changed to only check own properties but I wonder if 
that might not break more code than that which actually has this problem.  
There are at least semi-plausable reasons why you might want to intentionally 
use inherited properties in a property descriptor:

var defaultDataProperty = {enumerable: true, configurable: true, writable: 
true};

Object.defineProperty(obj,key, Object.create(defaultDataProperty, {value: 123});

Who knows whether anybody does things like this.

You can protect yourself against exposure to such Object.prototype attacks  by 
using patterns like:

Object.defineProperty(obj,key,Object.create(null, {value:   123};

Allen





 
 Scary stuff, IMHO, thanks for clarifications.
 
 br
 ___
 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: Problems with strict-mode caller poisoning

2012-11-28 Thread Dave Fugate
The naming 'gNonStrict' here refers to the function not containing a use
strict declaration itself, not that it's subject to strict mode.  Sorry
this intent wasn't clearer.

Section 15.3.5.4 step 2 in my copy of ES5 http://es5.github.com/#x15.3.5.4
reads:
If *P* is *caller *and *v* is a strict mode Function object, throw a *
TypeError http://es5.github.com/#x15.11.6.5* exception.

Is something other than Function's [[Get]] really supposed to be called in
this snippet?  E.g., 13.2.19.b.  If so, seems like they're still valid test
cases, only they apply to step 1 of 15.3.5.4, not step 2?


On Wed, Nov 28, 2012 at 4:43 PM, Andreas Rossberg rossb...@google.comwrote:

 On 29 November 2012 00:16, Dave Fugate dave.fug...@gmail.com wrote:
  Believe you're correct on the former, but perhaps not the latter=)
 
  E.g.:
   6 /**
   7* @path ch15/15.3/15.3.5/15.3.5.4/15.3.5.4_2-1gs.js
   8* @description Strict mode - checking access to strict function
  caller from strict function (FunctionDeclaration defined within strict
 mode)
   9   * @onlyStrict
  10  * @negative TypeError
  11  */
  12
  13
  14 use strict;
  15 function f() {
  16 return gNonStrict();
  17 }
  18 f();
  19
  20
  21 function gNonStrict() {
  22 return gNonStrict.caller;
  23 }
 
  is globally scoped strict mode and passes only when a TypeError gets
 thrown
  indicating strict mode is in effect.

 The bug with this test (and others) is that gNonStrict is _not_ a
 non-strict function, its name notwithstanding. Hence the test throws
 for the wrong reason, namely because strict-function.caller is a
 poisoned getter, not because of Sec 15.3.5.4, which it is supposed to
 test.

 /Andreas

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


Re: Problems with strict-mode caller poisoning

2012-11-28 Thread Andreas Rossberg
On 29 November 2012 06:06, Dave Fugate dave.fug...@gmail.com wrote:
 The naming 'gNonStrict' here refers to the function not containing a use
 strict declaration itself, not that it's subject to strict mode.  Sorry
 this intent wasn't clearer.

 Section 15.3.5.4 step 2 in my copy of ES5 reads:
 If P is caller and v is a strict mode Function object, throw a
 TypeError exception.

 Is something other than Function's [[Get]] really supposed to be called in
 this snippet?  E.g., 13.2.19.b.  If so, seems like they're still valid test
 cases, only they apply to step 1 of 15.3.5.4, not step 2?

I suppose so, but was that the intention? Either way, there currently
is no test that actually tests step 2.

/Andreas


 On Wed, Nov 28, 2012 at 4:43 PM, Andreas Rossberg rossb...@google.com
 wrote:

 On 29 November 2012 00:16, Dave Fugate dave.fug...@gmail.com wrote:
  Believe you're correct on the former, but perhaps not the latter=)
 
  E.g.:
   6 /**
   7* @path ch15/15.3/15.3.5/15.3.5.4/15.3.5.4_2-1gs.js
   8* @description Strict mode - checking access to strict
  function
  caller from strict function (FunctionDeclaration defined within strict
  mode)
   9   * @onlyStrict
  10  * @negative TypeError
  11  */
  12
  13
  14 use strict;
  15 function f() {
  16 return gNonStrict();
  17 }
  18 f();
  19
  20
  21 function gNonStrict() {
  22 return gNonStrict.caller;
  23 }
 
  is globally scoped strict mode and passes only when a TypeError gets
  thrown
  indicating strict mode is in effect.

 The bug with this test (and others) is that gNonStrict is _not_ a
 non-strict function, its name notwithstanding. Hence the test throws
 for the wrong reason, namely because strict-function.caller is a
 poisoned getter, not because of Sec 15.3.5.4, which it is supposed to
 test.

 /Andreas


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


Re: Object.prototype.get bye bye Object.defineProperty

2012-11-28 Thread Brandon Benvie
To answer that question, I do. I reuse descriptors often for performance
but also use prototypal inheritance as well.Since most descriptors share
the same common properties for all but one (or two) fields, they are an
ideal candidate for use with prototypal inheritance.

The answer though in that case is easy enough though, make sure the
prototype descriptor is created with Object.create(null). This wouldn't
solve compatibility issues with in-the-wild code but it solves the issue
for most people who care enough to use anything dealing with descriptors.


Who knows whether anybody does things like this

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


Re: Notification proxies (Was: possible excessive proxy invariants for Object.keys/etc??)

2012-11-28 Thread Allen Wirfs-Brock

On Nov 28, 2012, at 1:09 PM, Tom Van Cutsem wrote:

 2012/11/26 Dean Tribble dtrib...@gmail.com
 On Mon, Nov 26, 2012 at 11:33 AM, Tom Van Cutsem tomvc...@gmail.com wrote:
 Thanks for spelling out these examples. While they still don't feel like 
 actual important use cases to support, they give a good flavor of the kinds 
 of compromises we'd need to make when turning to notification-only proxies.
 
 I agree. My usual expectation for proxies is to support remote and persistent 
 objects. While supporting other scenarios is great, usually that's 
 incidental.  Is there a broader list of aspirations for proxies? or is this 
 just a all else being equal it would be good if we can do this?
 
 Let's talk about aspirations for proxies. It will help us set priorities.
 
 First, some terminology (originating from CLOS, the mother of all MOPs ;-)
 CLOS method combinations allow a composer to distinguish between before, 
 after and around-style composition:
 - before-style wrapping gives you only the ability to get notified before 
 an operation happens. You can abort, but not change, the result of the 
 operation. This is what notification-proxies offer.
 - after-style wrapping allows you to get notified of an operation 
 after-the-fact. Depending on the API, the after-wrapper may or may not get 
 to see the outcome of the operation, and may or may not change the final 
 outcome passed on to clients.
 - around-style wrapping is the most general and allows the composer to 
 decide if and when to forward, and what result to return. It subsumes 
 before/after wrapping. This is what direct proxies currently provide.
 
 As far as I can tell, virtual object abstractions like remote/persistent 
 objects require around-style wrapping, because there's otherwise no 
 meaningful target to automatically forward to.
 
 Here's a list of use cases that I frequently have in mind when thinking about 
 proxies, categorized according to whether the use case requires 
 before/after/around wrapping:
 
 Virtual objects, hence around-style:
 - self-hosting exotic objects such as Date, Array (i.e. self-host an 
 ES5/ES6 environment)
 - self-hosting DOM/WebIDL objects such as NodeList
-virtualizing a backing store as properties. 
-supported extended property attributes
 
 Around-style wrapping (need to be able to change the result of an operation):
 - membranes
 - higher-order contracts

introducing new inheritance schemes, eg, multiple inheritance

 
 Before-style wrapping:
 - revocable references

After-style

a doesNotUnderstand wrapper -- run the operation, but if the result is 
undefined check if missing property and if so, call  DNU handler


 
 What else?
 
 Cheers,
 Tom
 ___
 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