Callable objects protocol
On Tue, Dec 4, 2018 at 5:02 PM Sultan <thysultan at gmail.com> wrote:
Something along the lines of Symbol.iterator protocol for defining callback objects i.e: Symbol.callable:
That's interesting. What's the primary motivation? Binding the data? That's easily done with a closure ([fiddle1):
const obj = (() => {
let value = 'value';
return () => value;
})();
console.log(obj() === 'value'); // true
It's a bit more verbose than one would like, but usually that's washed out by the implementation (which is really trivial above).
You can also do it with a Proxy on a function, but it doesn't really buy you anything.
Be interested to know more about why you want non-function callable objects.
-- T.J. Crowder
On Tue, Dec 4, 2018 at 5:02 PM Sultan <thysultan at gmail.com> wrote: > > Something along the lines of Symbol.iterator protocol for defining > callback objects i.e: Symbol.callable: That's interesting. What's the primary motivation? Binding the data? That's easily done with a closure ([fiddle[1]): ```js const obj = (() => { let value = 'value'; return () => value; })(); console.log(obj() === 'value'); // true ``` It's a bit more verbose than one would like, but usually that's washed out by the implementation (which is really trivial above). You can also do it with a Proxy on a function, but it doesn't really buy you anything. Be interested to know more about why you want non-function callable objects. -- T.J. Crowder [1]: http://jsfiddle.net/8qvpc7Lh/ -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20181204/23eec201/attachment.html>
What would typeof
return on a callable object? There's a lot of code on
the web that uses a typeof of "function" to determine if something is safe
to call. There's also a lot of code on the web that uses a typeof of
"function" to do type detection. How would you suggest a callable object
navigate these potentially conflicting constraints?
What would `typeof` return on a callable object? There's a lot of code on the web that uses a typeof of "function" to determine if something is safe to call. There's also a lot of code on the web that uses a typeof of "function" to do type detection. How would you suggest a callable object navigate these potentially conflicting constraints? On Tue, Dec 4, 2018 at 10:07 AM T.J. Crowder < tj.crowder at farsightsoftware.com> wrote: > On Tue, Dec 4, 2018 at 5:02 PM Sultan > <thysultan at gmail.com> wrote: > > > > Something along the lines of Symbol.iterator protocol for defining > > callback objects i.e: Symbol.callable: > > That's interesting. What's the primary motivation? Binding the data? > That's easily done with a closure ([fiddle[1]): > > ```js > const obj = (() => { > let value = 'value'; > return () => value; > })(); > > console.log(obj() === 'value'); // true > ``` > > It's a bit more verbose than one would like, but usually that's washed out > by the implementation (which is really trivial above). > > You can also do it with a Proxy on a function, but it doesn't really buy > you anything. > > Be interested to know more about why you want non-function callable > objects. > > -- T.J. Crowder > > [1]: http://jsfiddle.net/8qvpc7Lh/ > _______________________________________________ > 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/20181204/96779449/attachment.html>
BTW, typeof new Proxy({}, {apply() { return 1 }})
returns
"object"
, not "function"
. Not sure this is any different.
Isiah Meadows contact at isiahmeadows.com, www.isiahmeadows.com
BTW, `typeof new Proxy({}, {apply() { return 1 }})` returns `"object"`, not `"function"`. Not sure this is any different. ----- Isiah Meadows contact at isiahmeadows.com www.isiahmeadows.com On Tue, Dec 4, 2018 at 2:02 PM Jordan Harband <ljharb at gmail.com> wrote: > > What would `typeof` return on a callable object? There's a lot of code on the web that uses a typeof of "function" to determine if something is safe to call. There's also a lot of code on the web that uses a typeof of "function" to do type detection. How would you suggest a callable object navigate these potentially conflicting constraints? > > On Tue, Dec 4, 2018 at 10:07 AM T.J. Crowder <tj.crowder at farsightsoftware.com> wrote: >> >> On Tue, Dec 4, 2018 at 5:02 PM Sultan >> <thysultan at gmail.com> wrote: >> > >> > Something along the lines of Symbol.iterator protocol for defining >> > callback objects i.e: Symbol.callable: >> >> That's interesting. What's the primary motivation? Binding the data? That's easily done with a closure ([fiddle[1]): >> >> ```js >> const obj = (() => { >> let value = 'value'; >> return () => value; >> })(); >> >> console.log(obj() === 'value'); // true >> ``` >> >> It's a bit more verbose than one would like, but usually that's washed out by the implementation (which is really trivial above). >> >> You can also do it with a Proxy on a function, but it doesn't really buy you anything. >> >> Be interested to know more about why you want non-function callable objects. >> >> -- T.J. Crowder >> >> [1]: http://jsfiddle.net/8qvpc7Lh/ >> _______________________________________________ >> 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
The type of the target is what affects typeof, indirectly by setting the
[[Call]] value. If an apply
or construct
trap handler is given and the
target isn't a function, they are ignored. See step 7 in
www.ecma-international.org/ecma-262/9.0/index.html#sec
The type of the target is what affects typeof, indirectly by setting the [[Call]] value. If an `apply` or `construct` trap handler is given and the target isn't a function, they are ignored. See step 7 in https://www.ecma-international.org/ecma-262/9.0/index.html#sec-proxycreate On Tue, Dec 4, 2018 at 2:08 PM Isiah Meadows <isiahmeadows at gmail.com> wrote: > BTW, `typeof new Proxy({}, {apply() { return 1 }})` returns > `"object"`, not `"function"`. Not sure this is any different. > > ----- > > Isiah Meadows > contact at isiahmeadows.com > www.isiahmeadows.com > On Tue, Dec 4, 2018 at 2:02 PM Jordan Harband <ljharb at gmail.com> wrote: > > > > What would `typeof` return on a callable object? There's a lot of code > on the web that uses a typeof of "function" to determine if something is > safe to call. There's also a lot of code on the web that uses a typeof of > "function" to do type detection. How would you suggest a callable object > navigate these potentially conflicting constraints? > > > > On Tue, Dec 4, 2018 at 10:07 AM T.J. Crowder < > tj.crowder at farsightsoftware.com> wrote: > >> > >> On Tue, Dec 4, 2018 at 5:02 PM Sultan > >> <thysultan at gmail.com> wrote: > >> > > >> > Something along the lines of Symbol.iterator protocol for defining > >> > callback objects i.e: Symbol.callable: > >> > >> That's interesting. What's the primary motivation? Binding the data? > That's easily done with a closure ([fiddle[1]): > >> > >> ```js > >> const obj = (() => { > >> let value = 'value'; > >> return () => value; > >> })(); > >> > >> console.log(obj() === 'value'); // true > >> ``` > >> > >> It's a bit more verbose than one would like, but usually that's washed > out by the implementation (which is really trivial above). > >> > >> You can also do it with a Proxy on a function, but it doesn't really > buy you anything. > >> > >> Be interested to know more about why you want non-function callable > objects. > >> > >> -- T.J. Crowder > >> > >> [1]: http://jsfiddle.net/8qvpc7Lh/ > >> _______________________________________________ > >> 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 > _______________________________________________ > 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/20181204/0c5f3dd8/attachment.html>
BTW, there are proxies 1, and one of the proxy hooks is to intercept calls 2.
Your "callable object" proposal would be literally as simple as this to implement:
const callable = Symbol.for("callable")
const handler = {
apply(target, thisArg, argsList) {
return Reflect.apply(target[callable], thisArg, argsList)
},
}
function makeCallable(obj) { return new Proxy(obj, handler) }
// Your example, ported
const obj = makeCallable({
[callable]: function (...args) { return this[Symbol.for('value')] },
[Symbol.for(''value')]: 'value',
})
assert(obj() === 'value')
obj[callable] = () => 1
assert(obj() === 1)
Isiah Meadows contact at isiahmeadows.com, www.isiahmeadows.com
BTW, there are proxies [1], and one of the proxy hooks is to intercept calls [2]. [1]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy [2]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy/handler/apply Your "callable object" proposal would be literally as simple as this to implement: ```js const callable = Symbol.for("callable") const handler = { apply(target, thisArg, argsList) { return Reflect.apply(target[callable], thisArg, argsList) }, } function makeCallable(obj) { return new Proxy(obj, handler) } // Your example, ported const obj = makeCallable({ [callable]: function (...args) { return this[Symbol.for('value')] }, [Symbol.for(''value')]: 'value', }) assert(obj() === 'value') obj[callable] = () => 1 assert(obj() === 1) ``` ----- Isiah Meadows contact at isiahmeadows.com www.isiahmeadows.com On Tue, Dec 4, 2018 at 12:02 PM Sultan <thysultan at gmail.com> wrote: > > Something along the lines of Symbol.iterator protocol for defining callback objects i.e: Symbol.callable: > > const obj = { > [Symbol.callable]: function (...args) { return this[Symbol.for('value')] }, > [Symbol.for(''value')]: 'value', > } > > assert(obj() === 'value') > _______________________________________________ > es-discuss mailing list > es-discuss at mozilla.org > https://mail.mozilla.org/listinfo/es-discuss
Edit: the wrapper needs to be a function, so ignore that last email. It's wrong.
Isiah Meadows contact at isiahmeadows.com, www.isiahmeadows.com
Edit: the wrapper needs to be a function, so ignore that last email. It's wrong. ----- Isiah Meadows contact at isiahmeadows.com www.isiahmeadows.com On Tue, Dec 4, 2018 at 2:14 PM Isiah Meadows <isiahmeadows at gmail.com> wrote: > > BTW, there are proxies [1], and one of the proxy hooks is to intercept > calls [2]. > > [1]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy > [2]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy/handler/apply > > Your "callable object" proposal would be literally as simple as this > to implement: > > ```js > const callable = Symbol.for("callable") > const handler = { > apply(target, thisArg, argsList) { > return Reflect.apply(target[callable], thisArg, argsList) > }, > } > function makeCallable(obj) { return new Proxy(obj, handler) } > > // Your example, ported > const obj = makeCallable({ > [callable]: function (...args) { return this[Symbol.for('value')] }, > [Symbol.for(''value')]: 'value', > }) > > assert(obj() === 'value') > obj[callable] = () => 1 > assert(obj() === 1) > ``` > > ----- > > Isiah Meadows > contact at isiahmeadows.com > www.isiahmeadows.com > On Tue, Dec 4, 2018 at 12:02 PM Sultan <thysultan at gmail.com> wrote: > > > > Something along the lines of Symbol.iterator protocol for defining callback objects i.e: Symbol.callable: > > > > const obj = { > > [Symbol.callable]: function (...args) { return this[Symbol.for('value')] }, > > [Symbol.for(''value')]: 'value', > > } > > > > assert(obj() === 'value') > > _______________________________________________ > > es-discuss mailing list > > es-discuss at mozilla.org > > https://mail.mozilla.org/listinfo/es-discuss
Ok.... maybe I'm thinking a little to literally, but isn't a function already a callable object?
function obj() {
return obj.value;
}
obj.value = "value";
assert(obj() === "value");
Ok.... maybe I'm thinking a little to literally, but isn't a function already a callable object? ```js function obj() { return obj.value; } obj.value = "value"; assert(obj() === "value"); ``` On Tue, Dec 4, 2018 at 1:16 PM Isiah Meadows <isiahmeadows at gmail.com> wrote: > Edit: the wrapper needs to be a function, so ignore that last email. It's > wrong. > > ----- > > Isiah Meadows > contact at isiahmeadows.com > www.isiahmeadows.com > > On Tue, Dec 4, 2018 at 2:14 PM Isiah Meadows <isiahmeadows at gmail.com> > wrote: > > > > BTW, there are proxies [1], and one of the proxy hooks is to intercept > > calls [2]. > > > > [1]: > https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy > > [2]: > https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy/handler/apply > > > > Your "callable object" proposal would be literally as simple as this > > to implement: > > > > ```js > > const callable = Symbol.for("callable") > > const handler = { > > apply(target, thisArg, argsList) { > > return Reflect.apply(target[callable], thisArg, argsList) > > }, > > } > > function makeCallable(obj) { return new Proxy(obj, handler) } > > > > // Your example, ported > > const obj = makeCallable({ > > [callable]: function (...args) { return this[Symbol.for('value')] }, > > [Symbol.for(''value')]: 'value', > > }) > > > > assert(obj() === 'value') > > obj[callable] = () => 1 > > assert(obj() === 1) > > ``` > > > > ----- > > > > Isiah Meadows > > contact at isiahmeadows.com > > www.isiahmeadows.com > > On Tue, Dec 4, 2018 at 12:02 PM Sultan <thysultan at gmail.com> wrote: > > > > > > Something along the lines of Symbol.iterator protocol for defining > callback objects i.e: Symbol.callable: > > > > > > const obj = { > > > [Symbol.callable]: function (...args) { return > this[Symbol.for('value')] }, > > > [Symbol.for(''value')]: 'value', > > > } > > > > > > assert(obj() === 'value') > > > _______________________________________________ > > > 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/20181204/d7b0bd50/attachment.html>
Thinking again, this might be a request for static lexical scope variables such that:
function obj() {
static value = { test: 42 };
return obj.value;
}
var a = obj();
assert(obj() === a);
Thinking again, this might be a request for static lexical scope variables such that: ```js function obj() { static value = { test: 42 }; return obj.value; } var a = obj(); assert(obj() === a); ``` On Tue, Dec 4, 2018 at 4:05 PM Ranando King <kingmph at gmail.com> wrote: > Ok.... maybe I'm thinking a little to literally, but isn't a function > already a callable object? > > ```js > function obj() { > return obj.value; > } > obj.value = "value"; > > assert(obj() === "value"); > ``` > > On Tue, Dec 4, 2018 at 1:16 PM Isiah Meadows <isiahmeadows at gmail.com> > wrote: > >> Edit: the wrapper needs to be a function, so ignore that last email. It's >> wrong. >> >> ----- >> >> Isiah Meadows >> contact at isiahmeadows.com >> www.isiahmeadows.com >> >> On Tue, Dec 4, 2018 at 2:14 PM Isiah Meadows <isiahmeadows at gmail.com> >> wrote: >> > >> > BTW, there are proxies [1], and one of the proxy hooks is to intercept >> > calls [2]. >> > >> > [1]: >> https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy >> > [2]: >> https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy/handler/apply >> > >> > Your "callable object" proposal would be literally as simple as this >> > to implement: >> > >> > ```js >> > const callable = Symbol.for("callable") >> > const handler = { >> > apply(target, thisArg, argsList) { >> > return Reflect.apply(target[callable], thisArg, argsList) >> > }, >> > } >> > function makeCallable(obj) { return new Proxy(obj, handler) } >> > >> > // Your example, ported >> > const obj = makeCallable({ >> > [callable]: function (...args) { return this[Symbol.for('value')] }, >> > [Symbol.for(''value')]: 'value', >> > }) >> > >> > assert(obj() === 'value') >> > obj[callable] = () => 1 >> > assert(obj() === 1) >> > ``` >> > >> > ----- >> > >> > Isiah Meadows >> > contact at isiahmeadows.com >> > www.isiahmeadows.com >> > On Tue, Dec 4, 2018 at 12:02 PM Sultan <thysultan at gmail.com> wrote: >> > > >> > > Something along the lines of Symbol.iterator protocol for defining >> callback objects i.e: Symbol.callable: >> > > >> > > const obj = { >> > > [Symbol.callable]: function (...args) { return >> this[Symbol.for('value')] }, >> > > [Symbol.for(''value')]: 'value', >> > > } >> > > >> > > assert(obj() === 'value') >> > > _______________________________________________ >> > > 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/20181204/d8f36d97/attachment-0001.html>
Yes function objects are already callable objects. This is meant to allow authors the ability to make callable non-function objects with this new protocol.
typeof nonFunctionCallableObject === 'object'. As much as Symbol.iterator is used to determine if a non-native object is an iterator so too would Symbol.callable with to non-function callables.
One of the utilities of this can be visualized in the getter/setter type callables: fn() gets the value, fn(a) sets the value, this is normally supplied with methods to allow an outsider the ability to be reactive to changes of the underlining value something akin to observables.
One way to implement this is as T.J mentioned – using a closure:
function closure () { var value = 'value' return function (a) { return arguments.length ? value = a : value } }
Another would be to treat functions as the objects they truly are:
function object () { function value (a) { return arguments.length ? this.value = a : this.value } value.value = null }
Or as this proposal would allow;
An idiomatic class-based implementation with a shared callable protocol that is extendable by other classes:
class prototype { Symbol.callable { return args.length ? this.value = args[0] : args[0] } }
const a = new prototype()
assert(a(1) === 1, a() === 1)
Yes function objects are already callable objects. This is meant to allow authors the ability to make callable non-function objects with this new protocol. typeof nonFunctionCallableObject === 'object'. As much as Symbol.iterator is used to determine if a non-native object is an iterator so too would Symbol.callable with regards to non-function callables. One of the utilities of this can be visualized in the getter/setter type callables: fn() gets the value, fn(a) sets the value, this is normally supplied with methods to allow an outsider the ability to be reactive to changes of the underlining value something akin to observables. One way to implement this is as T.J mentioned – using a closure: function closure () { var value = 'value' return function (a) { return arguments.length ? value = a : value } } Another would be to treat functions as the objects they truly are: function object () { function value (a) { return arguments.length ? this.value = a : this.value } value.value = null } Or as this proposal would allow; An idiomatic class-based implementation with a shared callable protocol that is extendable by other classes: class prototype { [Symbol.callable](...args) { return args.length ? this.value = args[0] : args[0] } } const a = new prototype() assert(a(1) === 1, a() === 1) On Wed, Dec 5, 2018 at 1:15 AM Ranando King <kingmph at gmail.com> wrote: > Thinking again, this might be a request for static lexical scope variables > such that: > > ```js > function obj() { > static value = { test: 42 }; > return obj.value; > } > > var a = obj(); > assert(obj() === a); > ``` > > On Tue, Dec 4, 2018 at 4:05 PM Ranando King <kingmph at gmail.com> wrote: > >> Ok.... maybe I'm thinking a little to literally, but isn't a function >> already a callable object? >> >> ```js >> function obj() { >> return obj.value; >> } >> obj.value = "value"; >> >> assert(obj() === "value"); >> ``` >> >> On Tue, Dec 4, 2018 at 1:16 PM Isiah Meadows <isiahmeadows at gmail.com> >> wrote: >> >>> Edit: the wrapper needs to be a function, so ignore that last email. >>> It's wrong. >>> >>> ----- >>> >>> Isiah Meadows >>> contact at isiahmeadows.com >>> www.isiahmeadows.com >>> >>> On Tue, Dec 4, 2018 at 2:14 PM Isiah Meadows <isiahmeadows at gmail.com> >>> wrote: >>> > >>> > BTW, there are proxies [1], and one of the proxy hooks is to intercept >>> > calls [2]. >>> > >>> > [1]: >>> https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy >>> > [2]: >>> https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy/handler/apply >>> > >>> > Your "callable object" proposal would be literally as simple as this >>> > to implement: >>> > >>> > ```js >>> > const callable = Symbol.for("callable") >>> > const handler = { >>> > apply(target, thisArg, argsList) { >>> > return Reflect.apply(target[callable], thisArg, argsList) >>> > }, >>> > } >>> > function makeCallable(obj) { return new Proxy(obj, handler) } >>> > >>> > // Your example, ported >>> > const obj = makeCallable({ >>> > [callable]: function (...args) { return this[Symbol.for('value')] >>> }, >>> > [Symbol.for(''value')]: 'value', >>> > }) >>> > >>> > assert(obj() === 'value') >>> > obj[callable] = () => 1 >>> > assert(obj() === 1) >>> > ``` >>> > >>> > ----- >>> > >>> > Isiah Meadows >>> > contact at isiahmeadows.com >>> > www.isiahmeadows.com >>> > On Tue, Dec 4, 2018 at 12:02 PM Sultan <thysultan at gmail.com> wrote: >>> > > >>> > > Something along the lines of Symbol.iterator protocol for defining >>> callback objects i.e: Symbol.callable: >>> > > >>> > > const obj = { >>> > > [Symbol.callable]: function (...args) { return >>> this[Symbol.for('value')] }, >>> > > [Symbol.for(''value')]: 'value', >>> > > } >>> > > >>> > > assert(obj() === 'value') >>> > > _______________________________________________ >>> > > 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/20181205/ad95ecef/attachment-0001.html>
Ok. I get what you're after. So what's to be gained by being able to make
an object directly callable over simply using functions? I remember that in
C++ there was the concept of a "functor" where overloading operator()
would allow you to treat instances as functions, and that had some limited
utility to it (like creating delegate functions). But those use cases are
already easily possible in ES by other means.
Ok. I get what you're after. So what's to be gained by being able to make an object directly callable over simply using functions? I remember that in C++ there was the concept of a "functor" where overloading `operator()` would allow you to treat instances as functions, and that had some limited utility to it (like creating delegate functions). But those use cases are already easily possible in ES by other means. On Tue, Dec 4, 2018 at 7:25 PM Sultan <thysultan at gmail.com> wrote: > Yes function objects are already callable objects. This is meant to allow > authors the ability to make callable non-function objects with this new > protocol. > > typeof nonFunctionCallableObject === 'object'. As much as Symbol.iterator > is used to determine if a non-native object is an iterator so too would > Symbol.callable with regards to non-function callables. > > One of the utilities of this can be visualized in the getter/setter type > callables: fn() gets the value, fn(a) sets the value, this is normally > supplied with methods to allow an outsider the ability to be reactive to > changes of the underlining value something akin to observables. > > One way to implement this is as T.J mentioned – using a closure: > > function closure () { > var value = 'value' > return function (a) { return arguments.length ? value = a : value } > } > > Another would be to treat functions as the objects they truly are: > > function object () { > function value (a) { return arguments.length ? this.value = a : this.value > } > value.value = null > } > > Or as this proposal would allow; > > An idiomatic class-based implementation with a shared callable protocol > that is extendable by other classes: > > class prototype { > [Symbol.callable](...args) { return args.length ? this.value = args[0] : > args[0] } > } > > const a = new prototype() > > assert(a(1) === 1, a() === 1) > > On Wed, Dec 5, 2018 at 1:15 AM Ranando King <kingmph at gmail.com> wrote: > >> Thinking again, this might be a request for static lexical scope >> variables such that: >> >> ```js >> function obj() { >> static value = { test: 42 }; >> return obj.value; >> } >> >> var a = obj(); >> assert(obj() === a); >> ``` >> >> On Tue, Dec 4, 2018 at 4:05 PM Ranando King <kingmph at gmail.com> wrote: >> >>> Ok.... maybe I'm thinking a little to literally, but isn't a function >>> already a callable object? >>> >>> ```js >>> function obj() { >>> return obj.value; >>> } >>> obj.value = "value"; >>> >>> assert(obj() === "value"); >>> ``` >>> >>> On Tue, Dec 4, 2018 at 1:16 PM Isiah Meadows <isiahmeadows at gmail.com> >>> wrote: >>> >>>> Edit: the wrapper needs to be a function, so ignore that last email. >>>> It's wrong. >>>> >>>> ----- >>>> >>>> Isiah Meadows >>>> contact at isiahmeadows.com >>>> www.isiahmeadows.com >>>> >>>> On Tue, Dec 4, 2018 at 2:14 PM Isiah Meadows <isiahmeadows at gmail.com> >>>> wrote: >>>> > >>>> > BTW, there are proxies [1], and one of the proxy hooks is to intercept >>>> > calls [2]. >>>> > >>>> > [1]: >>>> https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy >>>> > [2]: >>>> https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy/handler/apply >>>> > >>>> > Your "callable object" proposal would be literally as simple as this >>>> > to implement: >>>> > >>>> > ```js >>>> > const callable = Symbol.for("callable") >>>> > const handler = { >>>> > apply(target, thisArg, argsList) { >>>> > return Reflect.apply(target[callable], thisArg, argsList) >>>> > }, >>>> > } >>>> > function makeCallable(obj) { return new Proxy(obj, handler) } >>>> > >>>> > // Your example, ported >>>> > const obj = makeCallable({ >>>> > [callable]: function (...args) { return this[Symbol.for('value')] >>>> }, >>>> > [Symbol.for(''value')]: 'value', >>>> > }) >>>> > >>>> > assert(obj() === 'value') >>>> > obj[callable] = () => 1 >>>> > assert(obj() === 1) >>>> > ``` >>>> > >>>> > ----- >>>> > >>>> > Isiah Meadows >>>> > contact at isiahmeadows.com >>>> > www.isiahmeadows.com >>>> > On Tue, Dec 4, 2018 at 12:02 PM Sultan <thysultan at gmail.com> wrote: >>>> > > >>>> > > Something along the lines of Symbol.iterator protocol for defining >>>> callback objects i.e: Symbol.callable: >>>> > > >>>> > > const obj = { >>>> > > [Symbol.callable]: function (...args) { return >>>> this[Symbol.for('value')] }, >>>> > > [Symbol.for(''value')]: 'value', >>>> > > } >>>> > > >>>> > > assert(obj() === 'value') >>>> > > _______________________________________________ >>>> > > 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/20181204/2aaf158b/attachment.html>
How about this:
// the poly
if (!Symbol.callable)
Symbol.callable = Symbol('callable');
// the setup
class Callable extends Function {
constructor(object) {
super('return arguments.callee[Symbol.callable](...arguments)');
// sloppy mode FTW!
Object.setPrototypeOf(this, object);
}
}
// the example
const obj = new Callable({
[Symbol.callable](value) {
return value + this.value;
},
value: 123
});
obj(7); // 130
How about this: ```js // the poly if (!Symbol.callable) Symbol.callable = Symbol('callable'); // the setup class Callable extends Function { constructor(object) { super('return arguments.callee[Symbol.callable](...arguments)'); // sloppy mode FTW! Object.setPrototypeOf(this, object); } } // the example const obj = new Callable({ [Symbol.callable](value) { return value + this.value; }, value: 123 }); obj(7); // 130 ``` On Wed, Dec 5, 2018 at 12:02 AM Sultan <thysultan at gmail.com> wrote: > Something along the lines of Symbol.iterator protocol for defining > callback objects i.e: Symbol.callable: > > const obj = { > [Symbol.callable]: function (...args) { return > this[Symbol.for('value')] }, > [Symbol.for(''value')]: 'value', > } > > assert(obj() === 'value') > _______________________________________________ > 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/20181205/a43b479b/attachment.html>
Maybe I asked it wrong.
How is making an ordinary object callable at all useful for anything that can't already be easily handled via objects and functions? (looking for use cases here) How does this make coding easier to do and understand? (for the AST parser and for the human)
Maybe I asked it wrong. How is making an ordinary object callable at all useful for anything that can't already be easily handled via objects and functions? (looking for use cases here) How does this make coding easier to do and understand? (for the AST parser and for the human) On Tue, Dec 4, 2018 at 11:54 PM Andrea Giammarchi < andrea.giammarchi at gmail.com> wrote: > How about this: > > ```js > > // the poly > if (!Symbol.callable) > Symbol.callable = Symbol('callable'); > > // the setup > class Callable extends Function { > constructor(object) { > super('return arguments.callee[Symbol.callable](...arguments)'); > // sloppy mode FTW! > Object.setPrototypeOf(this, object); > } > } > > > // the example > const obj = new Callable({ > [Symbol.callable](value) { > return value + this.value; > }, > value: 123 > }); > > obj(7); // 130 > > > ``` > > On Wed, Dec 5, 2018 at 12:02 AM Sultan <thysultan at gmail.com> wrote: > >> Something along the lines of Symbol.iterator protocol for defining >> callback objects i.e: Symbol.callable: >> >> const obj = { >> [Symbol.callable]: function (...args) { return >> this[Symbol.for('value')] }, >> [Symbol.for(''value')]: 'value', >> } >> >> assert(obj() === 'value') >> _______________________________________________ >> 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/20181205/1b982bf7/attachment-0001.html>
I've actually replied to the op, I didn't mean to answer you directly, but the only reason I wrote that is because I could, no other reasons.
However, people unaware of the handleEvent pattern for event listeners often hope to be able to pass objects as listeners, ignoring the fact they can do that already (but they need a handleEvent method, own or inherited, in that object).
There is at least another use case I can't remember now, but I do remember doing the Proxy dance before ending up realizing that the apply hook needs objects anyway.
But yeah, I don't think it's a must have, specially because we can have something similar already, as shown in my example.
I've actually replied to the op, I didn't mean to answer you directly, but the only reason I wrote that is because I could, no other reasons. However, people unaware of the handleEvent pattern for event listeners often hope to be able to pass objects as listeners, ignoring the fact they can do that already (but they need a handleEvent method, own or inherited, in that object). There is at least another use case I can't remember now, but I do remember doing the Proxy dance before ending up realizing that the apply hook needs objects anyway. But yeah, I don't think it's a must have, specially because we can have something similar already, as shown in my example. On Wed, Dec 5, 2018 at 1:25 PM Ranando King <kingmph at gmail.com> wrote: > Maybe I asked it wrong. > > How is making an ordinary object callable at all useful for anything that > can't already be easily handled via objects and functions? (looking for use > cases here) > How does this make coding easier to do and understand? (for the AST parser > and for the human) > > On Tue, Dec 4, 2018 at 11:54 PM Andrea Giammarchi < > andrea.giammarchi at gmail.com> wrote: > >> How about this: >> >> ```js >> >> // the poly >> if (!Symbol.callable) >> Symbol.callable = Symbol('callable'); >> >> // the setup >> class Callable extends Function { >> constructor(object) { >> super('return arguments.callee[Symbol.callable](...arguments)'); >> // sloppy mode FTW! >> Object.setPrototypeOf(this, object); >> } >> } >> >> >> // the example >> const obj = new Callable({ >> [Symbol.callable](value) { >> return value + this.value; >> }, >> value: 123 >> }); >> >> obj(7); // 130 >> >> >> ``` >> >> On Wed, Dec 5, 2018 at 12:02 AM Sultan <thysultan at gmail.com> wrote: >> >>> Something along the lines of Symbol.iterator protocol for defining >>> callback objects i.e: Symbol.callable: >>> >>> const obj = { >>> [Symbol.callable]: function (...args) { return >>> this[Symbol.for('value')] }, >>> [Symbol.for(''value')]: 'value', >>> } >>> >>> assert(obj() === 'value') >>> _______________________________________________ >>> 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/20181205/28725c34/attachment.html>
the apply hook needs objects anyway.
I meant functions
> the apply hook needs objects anyway. I meant functions On Wed, Dec 5, 2018 at 1:33 PM Andrea Giammarchi < andrea.giammarchi at gmail.com> wrote: > I've actually replied to the op, I didn't mean to answer you directly, but > the only reason I wrote that is because I could, no other reasons. > > However, people unaware of the handleEvent pattern for event listeners > often hope to be able to pass objects as listeners, ignoring the fact they > can do that already (but they need a handleEvent method, own or inherited, > in that object). > > There is at least another use case I can't remember now, but I do remember > doing the Proxy dance before ending up realizing that the apply hook needs > objects anyway. > > But yeah, I don't think it's a must have, specially because we can have > something similar already, as shown in my example. > > > On Wed, Dec 5, 2018 at 1:25 PM Ranando King <kingmph at gmail.com> wrote: > >> Maybe I asked it wrong. >> >> How is making an ordinary object callable at all useful for anything that >> can't already be easily handled via objects and functions? (looking for use >> cases here) >> How does this make coding easier to do and understand? (for the AST >> parser and for the human) >> >> On Tue, Dec 4, 2018 at 11:54 PM Andrea Giammarchi < >> andrea.giammarchi at gmail.com> wrote: >> >>> How about this: >>> >>> ```js >>> >>> // the poly >>> if (!Symbol.callable) >>> Symbol.callable = Symbol('callable'); >>> >>> // the setup >>> class Callable extends Function { >>> constructor(object) { >>> super('return arguments.callee[Symbol.callable](...arguments)'); >>> // sloppy mode FTW! >>> Object.setPrototypeOf(this, object); >>> } >>> } >>> >>> >>> // the example >>> const obj = new Callable({ >>> [Symbol.callable](value) { >>> return value + this.value; >>> }, >>> value: 123 >>> }); >>> >>> obj(7); // 130 >>> >>> >>> ``` >>> >>> On Wed, Dec 5, 2018 at 12:02 AM Sultan <thysultan at gmail.com> wrote: >>> >>>> Something along the lines of Symbol.iterator protocol for defining >>>> callback objects i.e: Symbol.callable: >>>> >>>> const obj = { >>>> [Symbol.callable]: function (...args) { return >>>> this[Symbol.for('value')] }, >>>> [Symbol.for(''value')]: 'value', >>>> } >>>> >>>> assert(obj() === 'value') >>>> _______________________________________________ >>>> 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/20181205/08b016c5/attachment.html>
Personally, I'd prefer something else: a means of a function object literal that's still callable, but I can tack other properties to it easily. Something like this, maybe:
{
(...args) { ... },
}
In this, the this
value is set to the callee itself, not the given this
value.
Not married to the syntax, but I want the functionality.
Personally, I'd prefer something else: a means of a function object literal that's still callable, but I can tack other properties to it easily. Something like this, maybe: ```js { (...args) { ... }, } ``` In this, the `this` value is set to the callee itself, not the given `this` value. Not married to the syntax, but I want the functionality. On Wed, Dec 5, 2018 at 01:34 Andrea Giammarchi <andrea.giammarchi at gmail.com> wrote: > > the apply hook needs objects anyway. > > I meant functions > > On Wed, Dec 5, 2018 at 1:33 PM Andrea Giammarchi < > andrea.giammarchi at gmail.com> wrote: > >> I've actually replied to the op, I didn't mean to answer you directly, >> but the only reason I wrote that is because I could, no other reasons. >> >> However, people unaware of the handleEvent pattern for event listeners >> often hope to be able to pass objects as listeners, ignoring the fact they >> can do that already (but they need a handleEvent method, own or inherited, >> in that object). >> >> There is at least another use case I can't remember now, but I do >> remember doing the Proxy dance before ending up realizing that the apply >> hook needs objects anyway. >> >> But yeah, I don't think it's a must have, specially because we can have >> something similar already, as shown in my example. >> >> >> On Wed, Dec 5, 2018 at 1:25 PM Ranando King <kingmph at gmail.com> wrote: >> >>> Maybe I asked it wrong. >>> >>> How is making an ordinary object callable at all useful for anything >>> that can't already be easily handled via objects and functions? (looking >>> for use cases here) >>> How does this make coding easier to do and understand? (for the AST >>> parser and for the human) >>> >>> On Tue, Dec 4, 2018 at 11:54 PM Andrea Giammarchi < >>> andrea.giammarchi at gmail.com> wrote: >>> >>>> How about this: >>>> >>>> ```js >>>> >>>> // the poly >>>> if (!Symbol.callable) >>>> Symbol.callable = Symbol('callable'); >>>> >>>> // the setup >>>> class Callable extends Function { >>>> constructor(object) { >>>> super('return arguments.callee[Symbol.callable](...arguments)'); >>>> // sloppy mode FTW! >>>> Object.setPrototypeOf(this, object); >>>> } >>>> } >>>> >>>> >>>> // the example >>>> const obj = new Callable({ >>>> [Symbol.callable](value) { >>>> return value + this.value; >>>> }, >>>> value: 123 >>>> }); >>>> >>>> obj(7); // 130 >>>> >>>> >>>> ``` >>>> >>>> On Wed, Dec 5, 2018 at 12:02 AM Sultan <thysultan at gmail.com> wrote: >>>> >>>>> Something along the lines of Symbol.iterator protocol for defining >>>>> callback objects i.e: Symbol.callable: >>>>> >>>>> const obj = { >>>>> [Symbol.callable]: function (...args) { return >>>>> this[Symbol.for('value')] }, >>>>> [Symbol.for(''value')]: 'value', >>>>> } >>>>> >>>>> assert(obj() === 'value') >>>>> _______________________________________________ >>>>> 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 >>>> >>> _______________________________________________ > 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/20181205/56d274c9/attachment-0001.html>
That's the kind of thing I was shooting for with static lexical scope variables. There's 2 problems with it given the way things are going though. Take a look.
function foo() {
static a=1,
b=2,
c=3;
}
By the way I'm thinking, this would create 3 static variables within foo
that are only initialized once and retain whatever value is set on them
across invocations. Basically, the object foo
carries around a closure
containing those values. Problem is, this is private to foo. That conflicts
with class-fields and it's sigil-means-private model.
Ignoring that, public static variables can also be done (but it'd be the
first ever introduction of public
in ES.
function foo() {
static public a=1,
b=2,
c=3;
}
This would make foo.a
, foo.b
, & foo.c
accessible as public properties
of foo
.
Think this needs to be a proposal?
That's the kind of thing I was shooting for with static lexical scope variables. There's 2 problems with it given the way things are going though. Take a look. ```js function foo() { static a=1, b=2, c=3; } ``` By the way I'm thinking, this would create 3 static variables within foo that are only initialized once and retain whatever value is set on them across invocations. Basically, the object `foo` carries around a closure containing those values. Problem is, this is private to foo. That conflicts with class-fields and it's sigil-means-private model. Ignoring that, public static variables can also be done (but it'd be the first ever introduction of `public` in ES. ```js function foo() { static public a=1, b=2, c=3; } ``` This would make `foo.a`, `foo.b`, & `foo.c` accessible as public properties of `foo`. Think this needs to be a proposal? On Wed, Dec 5, 2018 at 1:39 AM Isiah Meadows <isiahmeadows at gmail.com> wrote: > Personally, I'd prefer something else: a means of a function object > literal that's still callable, but I can tack other properties to it > easily. Something like this, maybe: > > ```js > { > (...args) { ... }, > } > ``` > > In this, the `this` value is set to the callee itself, not the given > `this` value. > > Not married to the syntax, but I want the functionality. > On Wed, Dec 5, 2018 at 01:34 Andrea Giammarchi < > andrea.giammarchi at gmail.com> wrote: > >> > the apply hook needs objects anyway. >> >> I meant functions >> >> On Wed, Dec 5, 2018 at 1:33 PM Andrea Giammarchi < >> andrea.giammarchi at gmail.com> wrote: >> >>> I've actually replied to the op, I didn't mean to answer you directly, >>> but the only reason I wrote that is because I could, no other reasons. >>> >>> However, people unaware of the handleEvent pattern for event listeners >>> often hope to be able to pass objects as listeners, ignoring the fact they >>> can do that already (but they need a handleEvent method, own or inherited, >>> in that object). >>> >>> There is at least another use case I can't remember now, but I do >>> remember doing the Proxy dance before ending up realizing that the apply >>> hook needs objects anyway. >>> >>> But yeah, I don't think it's a must have, specially because we can have >>> something similar already, as shown in my example. >>> >>> >>> On Wed, Dec 5, 2018 at 1:25 PM Ranando King <kingmph at gmail.com> wrote: >>> >>>> Maybe I asked it wrong. >>>> >>>> How is making an ordinary object callable at all useful for anything >>>> that can't already be easily handled via objects and functions? (looking >>>> for use cases here) >>>> How does this make coding easier to do and understand? (for the AST >>>> parser and for the human) >>>> >>>> On Tue, Dec 4, 2018 at 11:54 PM Andrea Giammarchi < >>>> andrea.giammarchi at gmail.com> wrote: >>>> >>>>> How about this: >>>>> >>>>> ```js >>>>> >>>>> // the poly >>>>> if (!Symbol.callable) >>>>> Symbol.callable = Symbol('callable'); >>>>> >>>>> // the setup >>>>> class Callable extends Function { >>>>> constructor(object) { >>>>> super('return arguments.callee[Symbol.callable](...arguments)'); >>>>> // sloppy mode FTW! >>>>> Object.setPrototypeOf(this, object); >>>>> } >>>>> } >>>>> >>>>> >>>>> // the example >>>>> const obj = new Callable({ >>>>> [Symbol.callable](value) { >>>>> return value + this.value; >>>>> }, >>>>> value: 123 >>>>> }); >>>>> >>>>> obj(7); // 130 >>>>> >>>>> >>>>> ``` >>>>> >>>>> On Wed, Dec 5, 2018 at 12:02 AM Sultan <thysultan at gmail.com> wrote: >>>>> >>>>>> Something along the lines of Symbol.iterator protocol for defining >>>>>> callback objects i.e: Symbol.callable: >>>>>> >>>>>> const obj = { >>>>>> [Symbol.callable]: function (...args) { return >>>>>> this[Symbol.for('value')] }, >>>>>> [Symbol.for(''value')]: 'value', >>>>>> } >>>>>> >>>>>> assert(obj() === 'value') >>>>>> _______________________________________________ >>>>>> 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 >>>>> >>>> _______________________________________________ >> 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/20181205/206ba5a0/attachment.html>
I don't think introducing public
here has any value. We have static #a = 1
eventually for private already, the default should follow the classes
behavior, IMO
I don't think introducing `public` here has any value. We have `static #a = 1` eventually for private already, the default should follow the classes behavior, IMO On Wed, Dec 5, 2018 at 10:46 PM Ranando King <kingmph at gmail.com> wrote: > That's the kind of thing I was shooting for with static lexical scope > variables. There's 2 problems with it given the way things are going > though. Take a look. > > ```js > function foo() { > static a=1, > b=2, > c=3; > } > ``` > By the way I'm thinking, this would create 3 static variables within foo > that are only initialized once and retain whatever value is set on them > across invocations. Basically, the object `foo` carries around a closure > containing those values. Problem is, this is private to foo. That conflicts > with class-fields and it's sigil-means-private model. > > Ignoring that, public static variables can also be done (but it'd be the > first ever introduction of `public` in ES. > ```js > function foo() { > static public a=1, > b=2, > c=3; > } > ``` > This would make `foo.a`, `foo.b`, & `foo.c` accessible as public > properties of `foo`. > > Think this needs to be a proposal? > > > On Wed, Dec 5, 2018 at 1:39 AM Isiah Meadows <isiahmeadows at gmail.com> > wrote: > >> Personally, I'd prefer something else: a means of a function object >> literal that's still callable, but I can tack other properties to it >> easily. Something like this, maybe: >> >> ```js >> { >> (...args) { ... }, >> } >> ``` >> >> In this, the `this` value is set to the callee itself, not the given >> `this` value. >> >> Not married to the syntax, but I want the functionality. >> On Wed, Dec 5, 2018 at 01:34 Andrea Giammarchi < >> andrea.giammarchi at gmail.com> wrote: >> >>> > the apply hook needs objects anyway. >>> >>> I meant functions >>> >>> On Wed, Dec 5, 2018 at 1:33 PM Andrea Giammarchi < >>> andrea.giammarchi at gmail.com> wrote: >>> >>>> I've actually replied to the op, I didn't mean to answer you directly, >>>> but the only reason I wrote that is because I could, no other reasons. >>>> >>>> However, people unaware of the handleEvent pattern for event listeners >>>> often hope to be able to pass objects as listeners, ignoring the fact they >>>> can do that already (but they need a handleEvent method, own or inherited, >>>> in that object). >>>> >>>> There is at least another use case I can't remember now, but I do >>>> remember doing the Proxy dance before ending up realizing that the apply >>>> hook needs objects anyway. >>>> >>>> But yeah, I don't think it's a must have, specially because we can have >>>> something similar already, as shown in my example. >>>> >>>> >>>> On Wed, Dec 5, 2018 at 1:25 PM Ranando King <kingmph at gmail.com> wrote: >>>> >>>>> Maybe I asked it wrong. >>>>> >>>>> How is making an ordinary object callable at all useful for anything >>>>> that can't already be easily handled via objects and functions? (looking >>>>> for use cases here) >>>>> How does this make coding easier to do and understand? (for the AST >>>>> parser and for the human) >>>>> >>>>> On Tue, Dec 4, 2018 at 11:54 PM Andrea Giammarchi < >>>>> andrea.giammarchi at gmail.com> wrote: >>>>> >>>>>> How about this: >>>>>> >>>>>> ```js >>>>>> >>>>>> // the poly >>>>>> if (!Symbol.callable) >>>>>> Symbol.callable = Symbol('callable'); >>>>>> >>>>>> // the setup >>>>>> class Callable extends Function { >>>>>> constructor(object) { >>>>>> super('return arguments.callee[Symbol.callable](...arguments)'); >>>>>> // sloppy mode FTW! >>>>>> Object.setPrototypeOf(this, object); >>>>>> } >>>>>> } >>>>>> >>>>>> >>>>>> // the example >>>>>> const obj = new Callable({ >>>>>> [Symbol.callable](value) { >>>>>> return value + this.value; >>>>>> }, >>>>>> value: 123 >>>>>> }); >>>>>> >>>>>> obj(7); // 130 >>>>>> >>>>>> >>>>>> ``` >>>>>> >>>>>> On Wed, Dec 5, 2018 at 12:02 AM Sultan <thysultan at gmail.com> wrote: >>>>>> >>>>>>> Something along the lines of Symbol.iterator protocol for defining >>>>>>> callback objects i.e: Symbol.callable: >>>>>>> >>>>>>> const obj = { >>>>>>> [Symbol.callable]: function (...args) { return >>>>>>> this[Symbol.for('value')] }, >>>>>>> [Symbol.for(''value')]: 'value', >>>>>>> } >>>>>>> >>>>>>> assert(obj() === 'value') >>>>>>> _______________________________________________ >>>>>>> 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 >>>>>> >>>>> _______________________________________________ >>> 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/20181205/782f2164/attachment-0001.html>
Andrea, if class-fields becomes the accepted standard for private then that
would work, but it's awfully redundant. A closure is the very definition of
"private" in ES. So what does it mean to have a static #foo
lexically
declared? From inside the function, it would be no more private than var bar
. That would lead to confusion. See the problem?
Andrea, if class-fields becomes the accepted standard for private then that would work, but it's awfully redundant. A closure is the very definition of "private" in ES. So what does it mean to have a `static #foo` lexically declared? From inside the function, it would be no more private than `var bar`. That would lead to confusion. See the problem? On Wed, Dec 5, 2018 at 10:02 AM Andrea Giammarchi < andrea.giammarchi at gmail.com> wrote: > I don't think introducing `public` here has any value. We have `static #a > = 1` eventually for private already, the default should follow the classes > behavior, IMO > > On Wed, Dec 5, 2018 at 10:46 PM Ranando King <kingmph at gmail.com> wrote: > >> That's the kind of thing I was shooting for with static lexical scope >> variables. There's 2 problems with it given the way things are going >> though. Take a look. >> >> ```js >> function foo() { >> static a=1, >> b=2, >> c=3; >> } >> ``` >> By the way I'm thinking, this would create 3 static variables within foo >> that are only initialized once and retain whatever value is set on them >> across invocations. Basically, the object `foo` carries around a closure >> containing those values. Problem is, this is private to foo. That conflicts >> with class-fields and it's sigil-means-private model. >> >> Ignoring that, public static variables can also be done (but it'd be the >> first ever introduction of `public` in ES. >> ```js >> function foo() { >> static public a=1, >> b=2, >> c=3; >> } >> ``` >> This would make `foo.a`, `foo.b`, & `foo.c` accessible as public >> properties of `foo`. >> >> Think this needs to be a proposal? >> >> >> On Wed, Dec 5, 2018 at 1:39 AM Isiah Meadows <isiahmeadows at gmail.com> >> wrote: >> >>> Personally, I'd prefer something else: a means of a function object >>> literal that's still callable, but I can tack other properties to it >>> easily. Something like this, maybe: >>> >>> ```js >>> { >>> (...args) { ... }, >>> } >>> ``` >>> >>> In this, the `this` value is set to the callee itself, not the given >>> `this` value. >>> >>> Not married to the syntax, but I want the functionality. >>> On Wed, Dec 5, 2018 at 01:34 Andrea Giammarchi < >>> andrea.giammarchi at gmail.com> wrote: >>> >>>> > the apply hook needs objects anyway. >>>> >>>> I meant functions >>>> >>>> On Wed, Dec 5, 2018 at 1:33 PM Andrea Giammarchi < >>>> andrea.giammarchi at gmail.com> wrote: >>>> >>>>> I've actually replied to the op, I didn't mean to answer you directly, >>>>> but the only reason I wrote that is because I could, no other reasons. >>>>> >>>>> However, people unaware of the handleEvent pattern for event listeners >>>>> often hope to be able to pass objects as listeners, ignoring the fact they >>>>> can do that already (but they need a handleEvent method, own or inherited, >>>>> in that object). >>>>> >>>>> There is at least another use case I can't remember now, but I do >>>>> remember doing the Proxy dance before ending up realizing that the apply >>>>> hook needs objects anyway. >>>>> >>>>> But yeah, I don't think it's a must have, specially because we can >>>>> have something similar already, as shown in my example. >>>>> >>>>> >>>>> On Wed, Dec 5, 2018 at 1:25 PM Ranando King <kingmph at gmail.com> wrote: >>>>> >>>>>> Maybe I asked it wrong. >>>>>> >>>>>> How is making an ordinary object callable at all useful for anything >>>>>> that can't already be easily handled via objects and functions? (looking >>>>>> for use cases here) >>>>>> How does this make coding easier to do and understand? (for the AST >>>>>> parser and for the human) >>>>>> >>>>>> On Tue, Dec 4, 2018 at 11:54 PM Andrea Giammarchi < >>>>>> andrea.giammarchi at gmail.com> wrote: >>>>>> >>>>>>> How about this: >>>>>>> >>>>>>> ```js >>>>>>> >>>>>>> // the poly >>>>>>> if (!Symbol.callable) >>>>>>> Symbol.callable = Symbol('callable'); >>>>>>> >>>>>>> // the setup >>>>>>> class Callable extends Function { >>>>>>> constructor(object) { >>>>>>> super('return arguments.callee[Symbol.callable](...arguments)'); >>>>>>> // sloppy mode FTW! >>>>>>> Object.setPrototypeOf(this, object); >>>>>>> } >>>>>>> } >>>>>>> >>>>>>> >>>>>>> // the example >>>>>>> const obj = new Callable({ >>>>>>> [Symbol.callable](value) { >>>>>>> return value + this.value; >>>>>>> }, >>>>>>> value: 123 >>>>>>> }); >>>>>>> >>>>>>> obj(7); // 130 >>>>>>> >>>>>>> >>>>>>> ``` >>>>>>> >>>>>>> On Wed, Dec 5, 2018 at 12:02 AM Sultan <thysultan at gmail.com> wrote: >>>>>>> >>>>>>>> Something along the lines of Symbol.iterator protocol for defining >>>>>>>> callback objects i.e: Symbol.callable: >>>>>>>> >>>>>>>> const obj = { >>>>>>>> [Symbol.callable]: function (...args) { return >>>>>>>> this[Symbol.for('value')] }, >>>>>>>> [Symbol.for(''value')]: 'value', >>>>>>>> } >>>>>>>> >>>>>>>> assert(obj() === 'value') >>>>>>>> _______________________________________________ >>>>>>>> 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 >>>>>>> >>>>>> _______________________________________________ >>>> 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/20181205/33391e67/attachment.html>
BTW, another reason I want that kind of "function literal" is because I deliberately want to not just expose a function, but expose one with properties, as part of a public API.
Isiah Meadows contact at isiahmeadows.com, www.isiahmeadows.com
BTW, another reason I want that kind of "function literal" is because I deliberately want to not just expose a function, but expose one *with properties*, as part of a public API. ----- Isiah Meadows contact at isiahmeadows.com www.isiahmeadows.com On Wed, Dec 5, 2018 at 12:27 PM Ranando King <kingmph at gmail.com> wrote: > > Andrea, if class-fields becomes the accepted standard for private then that would work, but it's awfully redundant. A closure is the very definition of "private" in ES. So what does it mean to have a `static #foo` lexically declared? From inside the function, it would be no more private than `var bar`. That would lead to confusion. See the problem? > > On Wed, Dec 5, 2018 at 10:02 AM Andrea Giammarchi <andrea.giammarchi at gmail.com> wrote: >> >> I don't think introducing `public` here has any value. We have `static #a = 1` eventually for private already, the default should follow the classes behavior, IMO >> >> On Wed, Dec 5, 2018 at 10:46 PM Ranando King <kingmph at gmail.com> wrote: >>> >>> That's the kind of thing I was shooting for with static lexical scope variables. There's 2 problems with it given the way things are going though. Take a look. >>> >>> ```js >>> function foo() { >>> static a=1, >>> b=2, >>> c=3; >>> } >>> ``` >>> By the way I'm thinking, this would create 3 static variables within foo that are only initialized once and retain whatever value is set on them across invocations. Basically, the object `foo` carries around a closure containing those values. Problem is, this is private to foo. That conflicts with class-fields and it's sigil-means-private model. >>> >>> Ignoring that, public static variables can also be done (but it'd be the first ever introduction of `public` in ES. >>> ```js >>> function foo() { >>> static public a=1, >>> b=2, >>> c=3; >>> } >>> ``` >>> This would make `foo.a`, `foo.b`, & `foo.c` accessible as public properties of `foo`. >>> >>> Think this needs to be a proposal? >>> >>> >>> On Wed, Dec 5, 2018 at 1:39 AM Isiah Meadows <isiahmeadows at gmail.com> wrote: >>>> >>>> Personally, I'd prefer something else: a means of a function object literal that's still callable, but I can tack other properties to it easily. Something like this, maybe: >>>> >>>> ```js >>>> { >>>> (...args) { ... }, >>>> } >>>> ``` >>>> >>>> In this, the `this` value is set to the callee itself, not the given `this` value. >>>> >>>> Not married to the syntax, but I want the functionality. >>>> On Wed, Dec 5, 2018 at 01:34 Andrea Giammarchi <andrea.giammarchi at gmail.com> wrote: >>>>> >>>>> > the apply hook needs objects anyway. >>>>> >>>>> I meant functions >>>>> >>>>> On Wed, Dec 5, 2018 at 1:33 PM Andrea Giammarchi <andrea.giammarchi at gmail.com> wrote: >>>>>> >>>>>> I've actually replied to the op, I didn't mean to answer you directly, but the only reason I wrote that is because I could, no other reasons. >>>>>> >>>>>> However, people unaware of the handleEvent pattern for event listeners often hope to be able to pass objects as listeners, ignoring the fact they can do that already (but they need a handleEvent method, own or inherited, in that object). >>>>>> >>>>>> There is at least another use case I can't remember now, but I do remember doing the Proxy dance before ending up realizing that the apply hook needs objects anyway. >>>>>> >>>>>> But yeah, I don't think it's a must have, specially because we can have something similar already, as shown in my example. >>>>>> >>>>>> >>>>>> On Wed, Dec 5, 2018 at 1:25 PM Ranando King <kingmph at gmail.com> wrote: >>>>>>> >>>>>>> Maybe I asked it wrong. >>>>>>> >>>>>>> How is making an ordinary object callable at all useful for anything that can't already be easily handled via objects and functions? (looking for use cases here) >>>>>>> How does this make coding easier to do and understand? (for the AST parser and for the human) >>>>>>> >>>>>>> On Tue, Dec 4, 2018 at 11:54 PM Andrea Giammarchi <andrea.giammarchi at gmail.com> wrote: >>>>>>>> >>>>>>>> How about this: >>>>>>>> >>>>>>>> ```js >>>>>>>> >>>>>>>> // the poly >>>>>>>> if (!Symbol.callable) >>>>>>>> Symbol.callable = Symbol('callable'); >>>>>>>> >>>>>>>> // the setup >>>>>>>> class Callable extends Function { >>>>>>>> constructor(object) { >>>>>>>> super('return arguments.callee[Symbol.callable](...arguments)'); >>>>>>>> // sloppy mode FTW! >>>>>>>> Object.setPrototypeOf(this, object); >>>>>>>> } >>>>>>>> } >>>>>>>> >>>>>>>> >>>>>>>> // the example >>>>>>>> const obj = new Callable({ >>>>>>>> [Symbol.callable](value) { >>>>>>>> return value + this.value; >>>>>>>> }, >>>>>>>> value: 123 >>>>>>>> }); >>>>>>>> >>>>>>>> obj(7); // 130 >>>>>>>> >>>>>>>> >>>>>>>> ``` >>>>>>>> >>>>>>>> On Wed, Dec 5, 2018 at 12:02 AM Sultan <thysultan at gmail.com> wrote: >>>>>>>>> >>>>>>>>> Something along the lines of Symbol.iterator protocol for defining callback objects i.e: Symbol.callable: >>>>>>>>> >>>>>>>>> const obj = { >>>>>>>>> [Symbol.callable]: function (...args) { return this[Symbol.for('value')] }, >>>>>>>>> [Symbol.for(''value')]: 'value', >>>>>>>>> } >>>>>>>>> >>>>>>>>> assert(obj() === 'value') >>>>>>>>> _______________________________________________ >>>>>>>>> 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 >>>>> >>>>> _______________________________________________ >>>>> es-discuss mailing list >>>>> es-discuss at mozilla.org >>>>> https://mail.mozilla.org/listinfo/es-discuss
Something along the lines of Symbol.iterator protocol for defining callback objects i.e: Symbol.callable:
const obj = { [Symbol.callable]: function (...args) { return this[Symbol.for('value')] }, [Symbol.for(''value')]: 'value', }
assert(obj() === 'value')