introduction of statefull functions (inspired by Scala language) - advanced specification of "operator()" for arbitrary objects

Igor Baklan io.baklan at gmail.com
Sat May 14 11:22:39 UTC 2016


> I would like to point out that this particular example could be done in
terms of existing proxies ...

Yes, for this simplistic case that you properly mentioned, operation `[]`
is enough, but when i writing that example I rather keep in mind js [Map](
https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Map)
and object keys. So the goal is also simplified syntax of accessing and
mutating maps, like:

```js

var map = new Map();
var key = {foo: "bar"};
var val = {some: "value"};

map(key) = val; // same as map.set(key, val) if "`_()=_`" operation would
be properly implemented on Map
console.assert(map(key) === val); // same as (map.get(key) === val)
map.delete(key);
console.assert(map(key) == null);

```
If `"_()=_"` operation will be available in language, then anyone will be
able to implement his own `MultiDimMap` multidimensional map (on top of
existing single-dimensional map), with usage similar  to following


```js

var map = new MultiDimMap();
var key0 = {foo: "bar"};
var key1 = {foo1: "bar1"};
var val = {some: "value"};

map(key0, key1) = val;
console.assert(map(key0, key1) === val);
map.delete(key0, key1);
console.assert(map(key0, key1) == null);

```

Also to provide more complete information about current state of similar
feature in other languages, it would be good to take a look on [C#
indexers](https://msdn.microsoft.com/en-us/library/6x16t2tx.aspx). It also
provides extensive possibility to implement `"_[]=_"` operation with
arbitrary number of arguments, so in case of C# expressions like
`obj.idxr[arg1, arg2, ... , argN] = val` is pretty valid (if `obj.idxr`
indexer properly implemented in `obj`). But this feature looks for me more
ambiguous with current implementation of Proxy object (more specifically
with current definition of `set` and `get` methods of [proxy handler](
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy/handler)).
In particular `set` states signature:

```
set: function(target, property, value, receiver)
```

but if we will have a list of arguments (like `obj[arg1, ... , argN]`) then
what should be passed to `property` argument, if it will be `property ==
[arg1, ... , argN]` then it looks like OK, but if we pass only one
argument, like `obj[Array.from(arg1, ... , argN)]` what should be in
`property` , of course it should be rather `property == [ [arg1, ... ,
argN] ]` but still it looks little bit ambiguous.

So for me [Scala](http://docs.scala-lang.org/cheatsheets/) approach for
"indexing" with `"()"` / `"()="` operations looks more nice.

(More information about Scala approach to `apply`/`update` - `"()"` /
`"()="` can be found at
https://www.scala-academy.com/tutorials/scala-apply-update-methods-tutorial,
also about maps:
https://www.safaribooksonline.com/library/view/scala-cookbook/9781449340292/ch11s15.html,
http://docs.scala-lang.org/overviews/collections/maps#operations-in-class-mutablemap
)


On 13 May 2016 at 20:29, Isiah Meadows <isiahmeadows at gmail.com> wrote:

> I would like to point out that this particular example could be done in
> terms of existing proxies now:
>
> ```js
> var sttFunc = new Proxy({}, {
>     get(target, key) {
>         console.log("get: [", key, "]");
>         return key;
>     },
>     set(target, key, value) {
>         console.log("set: [", key, "] = ", val);
>         return true; // success
>     }
> });
>
> // Usage:
> sttFunc["key"] = "value"; // set: [key] = value
> sttFunc["key"]; // get: [key]
> ```
>
> On Thu, May 12, 2016, 15:02 Jason Orendorff <jason.orendorff at gmail.com>
> wrote:
>
>> The nice thing about @@symbol-named methods is that we *don't* have to
>> extend the Proxy API for them. They're just method calls.
>>
>> This is why there's no hasInstance Proxy trap. `instanceof` basically
>> boils down to a method call, and we already have Proxy traps for
>> method calls: `get` and `apply`.
>>
>> It's a good thing, too, because adding a new Proxy trap is a last
>> resort. Just from a conceptual standpoint, the less complicated
>> objects are, the better; just because there are 14 *fundamental*
>> operations on objects doesn't mean we're eager to add more. But
>> there's also an inherent compatibility issue. Whenever you add a new
>> trap, the deal is, all existing Proxy handlers were written without
>> consideration for the new operation. So old code, used in combination
>> with the new language feature, would tend to break.
>>
>> Cheers,
>> -j
>>
>>
>> On Thu, May 12, 2016 at 9:42 AM, Igor Baklan <io.baklan at gmail.com> wrote:
>> > It would be nice to "bring sense" to expressions like "obj(a1, ... ,
>> aN) =
>> > val".  (like "obj(x)  = y")
>> > In Scala langue it defined in pretty clear and simple way:
>> >
>> >    "obj(a1, ... , aN)" <==> "obj.apply(a1, ... , aN)"
>> >    "obj(a1, ... , an) = val" <==> "obj.update(a1, ... , aN, val)"
>> >
>> > Of course this applied only to that cases when obj was not defined like
>> > method (in case of regular methods "mth(args) = val" will cause compile
>> time
>> > error).
>> > So in Scala even arrays and maps are accessed and updated using "()"
>> > operator
>> >
>> >    js( arr[index] = val ) <==> scala( arr(index) = val )
>> >
>> > (see http://www.scala-lang.org/api/2.10.0/index.html#scala.Array ,
>> >
>> http://docs.scala-lang.org/overviews/collections/maps#operations-in-class-mutablemap
>> > , etc)
>> >
>> > So the proposals are:
>> >
>> > (1) to introduce symbols like @@apply and @@update with very similar to
>> > Scala meaning (for cases when 'obj.sttFunc' is not a function)
>> >
>> >   "obj.sttFunc(a1, ... , aN) = val" ==> "obj.sttFunc[Symbol.update]
>> > (obj.sttFunc, obj, [a1, ... , aN], val)"
>> >   "obj.sttFunc(a1, ... , aN)" ==> "obj.sttFunc[Symbol.apply]
>> (obj.sttFunc,
>> > obj, [a1, ... , aN])"
>> >
>> > (2) to extend Prxoy object specification to support update action along
>> with
>> > apply action:
>> >
>> > I would like to write something similar to
>> >
>> > var target = {
>> >    jsApply: function(key){
>> >       console.log("apply: ", key);
>> >       return key;
>> >    },
>> >    jsUpdate: function(key, val){
>> >       console.log("update: (", key, ") = ", val);
>> >       return val;
>> >    }
>> > };
>> > var sttFunc = new Proxy(target, {
>> >    apply: function(target, thisArg, argumentsList) {
>> >       target.jsApply.apply(thisArg, argumentsList);
>> >    },
>> >    update:  function(target, thisArg, argumentsList, assignValue) {
>> >       target.jsApply.apply(thisArg,
>> > Array.from(argumentsList).concat([assignValue]));
>> >    }
>> > });
>> >
>> > And then run it as following
>> >
>> >> sttFunc ("key") = "value";
>> >
>> > update: ( key ) =  value
>> >
>> >> sttFunc ("key");
>> >
>> > apply:  key
>> > "key"
>> >
>> >
>> > _______________________________________________
>> > es-discuss mailing list
>> > es-discuss at mozilla.org
>> > https://mail.mozilla.org/listinfo/es-discuss
>> >
>> _______________________________________________
>> es-discuss mailing list
>> es-discuss at mozilla.org
>> https://mail.mozilla.org/listinfo/es-discuss
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20160514/379f0b34/attachment.html>


More information about the es-discuss mailing list