Pure functions in EcmaScript
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
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
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
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
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
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
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
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
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]]
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]]
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]]
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]]
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
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]]
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
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]]
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]]
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
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()
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()
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()
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()
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()
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()
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
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
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/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
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()
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
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()
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()
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
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()
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
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
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??)
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
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
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()
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??)
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
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
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()
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??)
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()
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
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
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
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
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
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
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
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??)
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