Re: Callable objects protocol

2018-12-05 Thread Isiah Meadows
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
cont...@isiahmeadows.com
www.isiahmeadows.com

On Wed, Dec 5, 2018 at 12:27 PM Ranando King  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 
>  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  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  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 
  wrote:
>
> > the apply hook needs objects anyway.
>
> I meant functions
>
> On Wed, Dec 5, 2018 at 1:33 PM Andrea Giammarchi 
>  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  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 
>>>  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  wrote:
>
> Something along the lines of Symbol.iterator protocol for defining 
> callback objects i.e: Symbol.callable:
>
> const obj = {
> 

Re: Callable objects protocol

2018-12-05 Thread Ranando King
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.giammar...@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  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 
>> 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.giammar...@gmail.com> wrote:
>>>
 > the apply hook needs objects anyway.

 I meant functions

 On Wed, Dec 5, 2018 at 1:33 PM Andrea Giammarchi <
 andrea.giammar...@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  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.giammar...@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  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@mozilla.org
 https://mail.mozilla.org/listinfo/es-discuss


Re: Callable objects protocol

2018-12-05 Thread Andrea Giammarchi
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  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 
> 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.giammar...@gmail.com> wrote:
>>
>>> > the apply hook needs objects anyway.
>>>
>>> I meant functions
>>>
>>> On Wed, Dec 5, 2018 at 1:33 PM Andrea Giammarchi <
>>> andrea.giammar...@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  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.giammar...@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  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@mozilla.org
>>> https://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
>>>
>>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Callable objects protocol

2018-12-05 Thread Ranando King
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  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.giammar...@gmail.com> wrote:
>
>> > the apply hook needs objects anyway.
>>
>> I meant functions
>>
>> On Wed, Dec 5, 2018 at 1:33 PM Andrea Giammarchi <
>> andrea.giammar...@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  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.giammar...@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  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@mozilla.org
>> https://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
>>
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Callable objects protocol

2018-12-04 Thread Isiah Meadows
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 
wrote:

> > the apply hook needs objects anyway.
>
> I meant functions
>
> On Wed, Dec 5, 2018 at 1:33 PM Andrea Giammarchi <
> andrea.giammar...@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  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.giammar...@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  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@mozilla.org
> https://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
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Callable objects protocol

2018-12-04 Thread Andrea Giammarchi
> the apply hook needs objects anyway.

I meant functions

On Wed, Dec 5, 2018 at 1:33 PM Andrea Giammarchi <
andrea.giammar...@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  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.giammar...@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  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@mozilla.org
 https://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: Callable objects protocol

2018-12-04 Thread Andrea Giammarchi
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  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.giammar...@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  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@mozilla.org
>>> https://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: Callable objects protocol

2018-12-04 Thread Ranando King
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.giammar...@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  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@mozilla.org
>> https://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: Callable objects protocol

2018-12-04 Thread Andrea Giammarchi
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  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@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: Callable objects protocol

2018-12-04 Thread Ranando King
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  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  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  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 
>>> wrote:
>>>
 Edit: the wrapper needs to be a function, so ignore that last email.
 It's wrong.

 -

 Isiah Meadows
 cont...@isiahmeadows.com
 www.isiahmeadows.com

 On Tue, Dec 4, 2018 at 2:14 PM Isiah Meadows 
 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
 > cont...@isiahmeadows.com
 > www.isiahmeadows.com
 > On Tue, Dec 4, 2018 at 12:02 PM Sultan  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@mozilla.org
 > > https://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: Callable objects protocol

2018-12-04 Thread Sultan
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  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  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 
>> wrote:
>>
>>> Edit: the wrapper needs to be a function, so ignore that last email.
>>> It's wrong.
>>>
>>> -
>>>
>>> Isiah Meadows
>>> cont...@isiahmeadows.com
>>> www.isiahmeadows.com
>>>
>>> On Tue, Dec 4, 2018 at 2:14 PM Isiah Meadows 
>>> 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
>>> > cont...@isiahmeadows.com
>>> > www.isiahmeadows.com
>>> > On Tue, Dec 4, 2018 at 12:02 PM Sultan  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@mozilla.org
>>> > > https://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: Callable objects protocol

2018-12-04 Thread Ranando King
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  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 
> wrote:
>
>> Edit: the wrapper needs to be a function, so ignore that last email. It's
>> wrong.
>>
>> -
>>
>> Isiah Meadows
>> cont...@isiahmeadows.com
>> www.isiahmeadows.com
>>
>> On Tue, Dec 4, 2018 at 2:14 PM Isiah Meadows 
>> 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
>> > cont...@isiahmeadows.com
>> > www.isiahmeadows.com
>> > On Tue, Dec 4, 2018 at 12:02 PM Sultan  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@mozilla.org
>> > > https://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: Callable objects protocol

2018-12-04 Thread Ranando King
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  wrote:

> Edit: the wrapper needs to be a function, so ignore that last email. It's
> wrong.
>
> -
>
> Isiah Meadows
> cont...@isiahmeadows.com
> www.isiahmeadows.com
>
> On Tue, Dec 4, 2018 at 2:14 PM Isiah Meadows 
> 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
> > cont...@isiahmeadows.com
> > www.isiahmeadows.com
> > On Tue, Dec 4, 2018 at 12:02 PM Sultan  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@mozilla.org
> > > https://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: Callable objects protocol

2018-12-04 Thread Isiah Meadows
Edit: the wrapper needs to be a function, so ignore that last email. It's wrong.

-

Isiah Meadows
cont...@isiahmeadows.com
www.isiahmeadows.com

On Tue, Dec 4, 2018 at 2:14 PM Isiah Meadows  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
> cont...@isiahmeadows.com
> www.isiahmeadows.com
> On Tue, Dec 4, 2018 at 12:02 PM Sultan  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@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: Callable objects protocol

2018-12-04 Thread Isiah Meadows
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
cont...@isiahmeadows.com
www.isiahmeadows.com
On Tue, Dec 4, 2018 at 12:02 PM Sultan  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@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: Callable objects protocol

2018-12-04 Thread Logan Smyth
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  wrote:

> BTW, `typeof new Proxy({}, {apply() { return 1 }})` returns
> `"object"`, not `"function"`. Not sure this is any different.
>
> -
>
> Isiah Meadows
> cont...@isiahmeadows.com
> www.isiahmeadows.com
> On Tue, Dec 4, 2018 at 2:02 PM Jordan Harband  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.crow...@farsightsoftware.com> wrote:
> >>
> >> On Tue, Dec 4, 2018 at 5:02 PM Sultan
> >>  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@mozilla.org
> >> https://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
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Callable objects protocol

2018-12-04 Thread Isiah Meadows
BTW, `typeof new Proxy({}, {apply() { return 1 }})` returns
`"object"`, not `"function"`. Not sure this is any different.

-

Isiah Meadows
cont...@isiahmeadows.com
www.isiahmeadows.com
On Tue, Dec 4, 2018 at 2:02 PM Jordan Harband  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 
>  wrote:
>>
>> On Tue, Dec 4, 2018 at 5:02 PM Sultan
>>  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@mozilla.org
>> https://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: Callable objects protocol

2018-12-04 Thread Jordan Harband
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.crow...@farsightsoftware.com> wrote:

> On Tue, Dec 4, 2018 at 5:02 PM Sultan
>  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@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: Callable objects protocol

2018-12-04 Thread T.J. Crowder
On Tue, Dec 4, 2018 at 5:02 PM Sultan
 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@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: callable objects ?

2012-04-19 Thread David Bruant

Le 19/04/2012 01:00, Brendan Eich a écrit :

David Bruant wrote:

 var p = Proxy(target, {});
 p(); // throws exception because the proxy is reported as not 
having

  // a @call property
In the get trap of the proxy, the @call private name is transformed into
its public conterpart. When, by default, the trap forwards to the
target, the public alter-ego is coerced into a string. Consequently, the
actual @call property of the target isn't found.


Hmm, I see. The idea was to avoid leaking private names via hostile 
proxies, but here we have a friendly proxy that wants to get the 
private-named target property.
Yes. The interaction of proxies and private name has only been 
considered under the consideration that proxies can be hostile. And 
indeed, there are cases where there is no need to protect the private 
name from the proxy. One is publicly available private names (aka 
unique names).
That was the root of the reasoning behind Alternative proposal to 
privateName.public [1].

I've summurized some approaches [2] that could be taken.


With direct proxies, if the target already has the private-named 
property, and the handler ({} here) has no traps that might steal a 
non-substituted private name, why would we substitute the public name 
for the private @call?
This doesn't scale. Private names could be added or removed from the 
target by some who have direct access to it (not intermediated with a 
proxy).


David

[1] https://mail.mozilla.org/pipermail/es-discuss/2011-December/018908.html
[2] https://mail.mozilla.org/pipermail/es-discuss/2011-December/019005.html
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: callable objects ?

2012-04-19 Thread David Bruant

Le 19/04/2012 01:54, Brandon Benvie a écrit :
(or you simply don't trap the access, which is the route for 
[[prototype]], [[instanceof]], etc which now makes even more sense to 
me in light of this)
Not trapping seems like a valid option [1]. The rationale for the 
.public counterpart in the private name proposal is that the proxy 
should not have access to the private name. However, if it doesn't 
(directly or indirectly), it can't do anything useful. Under these 
conditions, the trap might as well not been called.


David

[1] https://mail.mozilla.org/pipermail/es-discuss/2011-December/019005.html
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: callable objects ?

2012-04-19 Thread Tom Van Cutsem
I still like the idea of distinguishing private from unique names,
where private = invisible via reflection  proxies and unique = visible
via reflection  proxies (cf. the thread David linked to).

As for how direct proxies might help: yes, I've previously proposed several
solutions:
- One was to not allow proxies to trap private names, and always forward
private name access unconditionally, as mentioned by Brandon.
- The other was essentially Brendan's current proposal: if the trap is
missing, forward the private name access to the target without converting
it into a public object, except I also proposed factoring out private name
access into separate getPrivate/setPrivate traps. See:

https://mail.mozilla.org/pipermail/es-discuss/2011-December/018937.html
https://mail.mozilla.org/pipermail/es-discuss/2011-December/018938.html

Cheers,
Tom

2012/4/19 David Bruant bruan...@gmail.com

 Le 19/04/2012 01:54, Brandon Benvie a écrit :

  (or you simply don't trap the access, which is the route for
 [[prototype]], [[instanceof]], etc which now makes even more sense to me in
 light of this)

 Not trapping seems like a valid option [1]. The rationale for the .public
 counterpart in the private name proposal is that the proxy should not have
 access to the private name. However, if it doesn't (directly or
 indirectly), it can't do anything useful. Under these conditions, the trap
 might as well not been called.

 David

 [1] https://mail.mozilla.org/**pipermail/es-discuss/2011-**
 December/019005.htmlhttps://mail.mozilla.org/pipermail/es-discuss/2011-December/019005.html

 __**_
 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: callable objects ?

2012-04-19 Thread David Bruant

Le 19/04/2012 16:55, Tom Van Cutsem a écrit :
I still like the idea of distinguishing private from unique names, 
where private = invisible via reflection  proxies and unique = 
visible via reflection  proxies (cf. the thread David linked to).
Additionally to this proposal, if the getOwnPropertyNames 
non-configurability invariant (must report all sealed properties) can 
be renegociated to not necessarily include unique names, then proxies 
can use unique names as private names (and not be forced to disclose 
them on Object.getOwnPropertyNames()).


By the way, I'm realizing now that the getOwnPropertyNames trap does 
string coercion on elements of the array returned by the trap. How will 
this work with private names? Hopefully, these won't be coerced, but 
based on what? Will private names have a particular [[Native Brand]]?


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


Re: callable objects ?

2012-04-19 Thread Brendan Eich

David Bruant wrote:
By the way, I'm realizing now that the getOwnPropertyNames trap does 
string coercion on elements of the array returned by the trap. How 
will this work with private names? Hopefully, these won't be coerced, 
but based on what? Will private names have a particular [[Native Brand]]? 


My understanding (not necessarily reflected in the private name objects 
proposal, alas) was that we would not break *any* existing reflection 
facility (for-in, Object.getOwnPropertyNames, etc.) by suddenly 
returning non-string property names. No reflection on private names.


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


Re: callable objects ?

2012-04-18 Thread Andreas Rossberg
I'm sorry, but can somebody explain what the real use case for all
this would be? And why proxies do not already cover it? Do we really
need to make _every_ object into half a (mutable?) function proxy now?

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


Re: callable objects ?

2012-04-18 Thread David Bruant

Le 17/04/2012 22:44, Brendan Eich a écrit :

Brendan Eich wrote:

Irakli Gozalishvili wrote:
It would be amazing to have clojure like protocols in JS  even 
without `IFn`. I think it's very good feet and very useful in JS 
where each library has it's own flavored API. I wrote more about it 
here: 
http://jeditoolkit.com/2012/03/21/protocol-based-polymorphism.html#post


Still hoping Mark will weigh in.


Ok, I talked to Mark and Tom Van Cutsem, and they see no problem 
provided we prevent overriding built-in [[Call]] and [[Construct]] on 
function objects.


Let there be private names @call and @construct (I'll spell them this 
way to avoid tedious imports of const bindings from @std or another 
built-in module).


(...)

This also simplifies direct proxies by allowing any proxy to have call 
and construct traps.
Speaking of proxies and private names, how would the 2 private name 
interact with the proxies? It seems that it would be poorly because of 
the private-names-can-be-revealed-as-property-names-in-traps rule.
Is it time to consider unique names? Since @call and @construct would be 
available to anyone, they are not much that private anyway.



Change 11.4.3 The typeof Operator, the table row with Object 
(native or host and does implement [[Call]]) in column 1, to test not 
for [[Call]] and *not* for @call, rather to test [[NativeBrand]] === 
Function (see ES6 draft 15.2.4.2 Object.prototype.toString ( )).


This last point is important: we do not want an object's typeof-type 
to change by giving it a @call property.
This was a strong concern and the solution is satisfying as far as I'm 
concerned.


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


Re: callable objects ?

2012-04-18 Thread Brendan Eich

The original post in this thread, from David Nolen, cited

https://gist.github.com/2346460

In general there are more callable objects under the sun than function 
objects, but if the only way to make one is to write a proxy (now a 
direct proxy), the tax is too high:


* Two object allocations not one.
* A priori set-up when you might need mutation of an existing object to 
become callable.


These may not motivate you, I'm not trying to sell anyone. We should 
discuss utility and trade-offs more, so thanks for posting.


David mentioned Dart's considering a callable protocol too. I found this:

http://groups.google.com/a/dartlang.org/group/misc/browse_frm/thread/6b4f18132adfaa78/c2cfd0daadba67f1?lnk=gstq=callable#c2cfd0daadba67f1

but I'm not sure if it is the latest. Perhaps you know more?

/be

Andreas Rossberg wrote:

I'm sorry, but can somebody explain what the real use case for all
this would be? And why proxies do not already cover it? Do we really
need to make _every_ object into half a (mutable?) function proxy now?

/Andreas
___
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: callable objects ?

2012-04-18 Thread David Bruant

Le 17/04/2012 22:44, Brendan Eich a écrit :
Let there be private names @call and @construct (I'll spell them this 
way to avoid tedious imports of const bindings from @std or another 
built-in module).


Let Clause 15.3.5 include new non-configurable, non-writable 
properties of function objects named by @call and @construct (built-in 
functions have only @call). The values are built-in and need a bit 
more thought than I can spare now, but see below: @call's value is 
close to the original value of Function.prototype.call, and 
@construct's value is straightforward enough I think.


(...)

Change 11.2.3 Function Calls to use @call not [[Call]], passing the 
/thisValue/ and /argList/ according to the Function.prototype.call 
convention: (thisValue, ...argList).

@call as own property only or is it inherited as well?

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


Re: callable objects ?

2012-04-18 Thread Brendan Eich

David Bruant wrote:
Change 11.2.3 Function Calls to use @call not [[Call]], passing the 
/thisValue/ and /argList/ according to the Function.prototype.call 
convention: (thisValue, ...argList).

@call as own property only or is it inherited as well?


I see no reason to require own.

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


Re: callable objects ?

2012-04-18 Thread David Bruant
Le 18/04/2012 17:14, Brendan Eich a écrit :
 David Bruant wrote:
 Change 11.2.3 Function Calls to use @call not [[Call]], passing
 the /thisValue/ and /argList/ according to the
 Function.prototype.call convention: (thisValue, ...argList).
 @call as own property only or is it inherited as well?

 I see no reason to require own.
After giving some more thoughts:

function f(){
return 12;
}

var o = Object.create(f);
o();

Currently this throws a TypeError (o isn't a function). If the @call
property was inherited, the inherited @call would be called (and no
error would be thrown).
I don't know to what extent it matters, but it's worth noting there
would be this difference.

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


Re: callable objects ?

2012-04-18 Thread Brendan Eich
Yes, I thought of that -- currently o() throws, so in the best case, 
there's no impediment to relaxing things to allow o() to call. In the 
worst case, code that caught or counted on the exception somehow might 
break.


Mainly the own-only restriction seems less-good compared to how, e.g. 
proxy traps or accessors are found, via full prototype-based delegation. 
Are some of these proposed and novel base-level traps better off 
own-only, in spite of this general rule?


/be

David Bruant wrote:

Le 18/04/2012 17:14, Brendan Eich a écrit :

David Bruant wrote:

Change 11.2.3 Function Calls to use @call not [[Call]], passing
the /thisValue/ and /argList/ according to the
Function.prototype.call convention: (thisValue, ...argList).

@call as own property only or is it inherited as well?

I see no reason to require own.

After giving some more thoughts:

 function f(){
 return 12;
 }

 var o = Object.create(f);
 o();

Currently this throws a TypeError (o isn't a function). If the @call
property was inherited, the inherited @call would be called (and no
error would be thrown).
I don't know to what extent it matters, but it's worth noting there
would be this difference.

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


Re: callable objects ?

2012-04-18 Thread David Bruant
Le 18/04/2012 19:48, Brendan Eich a écrit :
 Mainly the own-only restriction seems less-good compared to how, e.g.
 proxy traps or accessors are found, via full prototype-based delegation.
I agree with your point.

However, I'd like to restate that interaction between proxies and
private names as currently design is unusable:

var callName = import @call;

var target = {
[callName]: function(){console.log('yo')}
};

var p = Proxy(target, {});
p(); // throws exception because the proxy is reported as not having
a @call property

In the get trap of the proxy, the @call private name is transformed into
its public conterpart. When, by default, the trap forwards to the
target, the public alter-ego is coerced into a string. Consequently, the
actual @call property of the target isn't found.


 Are some of these proposed and novel base-level traps better off
 own-only, in spite of this general rule?
Did you mean traps or private properties? Assuming private properties.
The precedent here is the different non-standard pseudo-properties.
For __noSuchMethod__, it is inherited which is probably what is
expected. I tested with:
===
var o = {};
o.__noSuchMethod__ = function(n){
console.log('__noSuchMethod__ call', n);
}

o.a();

var o2 = Object.create(o);

o2.c()
===

__defineGetter__ and __defineSetter__ only made sense as if considered
as own properties I think.

__proto__ would make sense as an own property reflecting directly
objects own internal [[Prototype]] property (which seems to be V8
behavior). Reality and security concerns make it a different story

Besides specific cases of things that touch the specific aspects of
singular object, I agree that inheriting is better.

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


Re: callable objects ?

2012-04-18 Thread Brendan Eich

David Bruant wrote:

Le 18/04/2012 19:48, Brendan Eich a écrit :

Mainly the own-only restriction seems less-good compared to how, e.g.
proxy traps or accessors are found, via full prototype-based delegation.

I agree with your point.

However, I'd like to restate that interaction between proxies and
private names as currently design is unusable:

 var callName = import @call;

 var target = {
 [callName]: function(){console.log('yo')}
 };


Just as an aside, and to avoid confusion (import doesn't work that way), 
let's say it is:


var target = {
@call: function(){console.log('yo')}
};



 var p = Proxy(target, {});
 p(); // throws exception because the proxy is reported as not having
  // a @call property
In the get trap of the proxy, the @call private name is transformed into
its public conterpart. When, by default, the trap forwards to the
target, the public alter-ego is coerced into a string. Consequently, the
actual @call property of the target isn't found.


Hmm, I see. The idea was to avoid leaking private names via hostile 
proxies, but here we have a friendly proxy that wants to get the 
private-named target property.


Tom, didn't our thinking on private names predate direct proxies? Or is 
that not relevant? In the old model, the handler would need traps (some 
fundamental ones at least) that special-case the public name substituted 
for @call. Perhaps we need something more automagic for direct proxies 
that still prevents private name leaks.


With direct proxies, if the target already has the private-named 
property, and the handler ({} here) has no traps that might steal a 
non-substituted private name, why would we substitute the public name 
for the private @call?


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


Re: callable objects ?

2012-04-18 Thread Brandon Benvie
Proxies seem to be able to support this well given a little bit of extra
specification. A proxy attempts to forward the apply/construct action
naively to its target. The result is it either succeeds or doesn't, and the
same invariant checks would apply (private names have the same rules for
configurability right?).

The only difference is that a proxy won't know the result before actually
attempting to follow through, which means that private non-configurable
properties are a kind of booby trap if you *don't* always forward
everything.
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: callable objects ?

2012-04-18 Thread Brandon Benvie
Errr that only applies to private properties that manifest in public
results, as @construct and @call were described. In other cases the private
name I would guess is simply not enforceable because there's no direct link
between the private property and the outside world that has to be enforced.
The shows a flaw of linking a private property with a predictable
observable result.

On Wed, Apr 18, 2012 at 7:26 PM, Brandon Benvie
bran...@brandonbenvie.comwrote:

 Proxies seem to be able to support this well given a little bit of extra
 specification. A proxy attempts to forward the apply/construct action
 naively to its target. The result is it either succeeds or doesn't, and the
 same invariant checks would apply (private names have the same rules for
 configurability right?).

 The only difference is that a proxy won't know the result before actually
 attempting to follow through, which means that private non-configurable
 properties are a kind of booby trap if you *don't* always forward
 everything.

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


Re: callable objects ?

2012-04-18 Thread Brendan Eich
The issue you may be missing (sorry if I'm mis-reading your post) is: 
hostile proxy passed into module that detects private-named properties 
on incoming objects. If the proxy has a handler that traps get, e.g., 
the private name will leak and the hostile party can now use it to 
decorate a trojan.


So it seems to me the issue with direct proxies of whether the handler 
has a relevant trap for a given access matters.


/be

Brandon Benvie wrote:
Proxies seem to be able to support this well given a little bit of 
extra specification. A proxy attempts to forward the apply/construct 
action naively to its target. The result is it either succeeds or 
doesn't, and the same invariant checks would apply (private names have 
the same rules for configurability right?).


The only difference is that a proxy won't know the result before 
actually attempting to follow through, which means that private 
non-configurable properties are a kind of booby trap if you *don't* 
always forward everything.

___
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: callable objects ?

2012-04-18 Thread Tab Atkins Jr.
On Wed, Apr 18, 2012 at 4:31 PM, Brandon Benvie
bran...@brandonbenvie.com wrote:
 Errr that only applies to private properties that manifest in public
 results, as @construct and @call were described. In other cases the private
 name I would guess is simply not enforceable because there's no direct link
 between the private property and the outside world that has to be enforced.
 The shows a flaw of linking a private property with a predictable observable
 result.

The private name proposal has the ability to create ordinary unique
names (same basic functionality, but enumerable and passed directly to
proxies), right?  Obviously all the names used in the standard library
should be merely unique, not private, as you're not attempting to hide
anything, just prevent accidental name clashes.

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


Re: callable objects ?

2012-04-18 Thread Brandon Benvie
In that case I think it's worth noting that there is fundamentally
different consequences between those two concepts then and requirements of
one shouldn't be the same for the other. it's possible to have a private
property that's non-configurable which has no bearing on proxies while
that's obviously not true of anything public.
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: callable objects ?

2012-04-18 Thread Brendan Eich
Good point, but 
http://wiki.ecmascript.org/doku.php?id=harmony:private_name_objects 
still has that visibility flag as an open issue.


We need to settle this, sooner is better ;-).

/be

Tab Atkins Jr. wrote:

On Wed, Apr 18, 2012 at 4:31 PM, Brandon Benvie
bran...@brandonbenvie.com  wrote:

Errr that only applies to private properties that manifest in public
results, as @construct and @call were described. In other cases the private
name I would guess is simply not enforceable because there's no direct link
between the private property and the outside world that has to be enforced.
The shows a flaw of linking a private property with a predictable observable
result.


The private name proposal has the ability to create ordinary unique
names (same basic functionality, but enumerable and passed directly to
proxies), right?  Obviously all the names used in the standard library
should be merely unique, not private, as you're not attempting to hide
anything, just prevent accidental name clashes.

~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: callable objects ?

2012-04-18 Thread Brandon Benvie
This has been a useful thought experiment then.

Private properties which are defined as directly linked to observable
results seem to be a bad idea because that means a proxy is required to
either always forward anything that can invoke that observable
public/private relationship or the other option is unenforced invariants.

If you keep the link between a private property and directly
linked observable results opaque then you can allow proxies to completely
ignore any invariant about them because there is no actual invariant to
enforce.
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: callable objects ?

2012-04-17 Thread Brendan Eich

Brendan Eich wrote:

Irakli Gozalishvili wrote:
It would be amazing to have clojure like protocols in JS  even 
without `IFn`. I think it's very good feet and very useful in JS 
where each library has it's own flavored API. I wrote more about it 
here: 
http://jeditoolkit.com/2012/03/21/protocol-based-polymorphism.html#post


Still hoping Mark will weigh in.


Ok, I talked to Mark and Tom Van Cutsem, and they see no problem 
provided we prevent overriding built-in [[Call]] and [[Construct]] on 
function objects.


Let there be private names @call and @construct (I'll spell them this 
way to avoid tedious imports of const bindings from @std or another 
built-in module).


Let Clause 15.3.5 include new non-configurable, non-writable properties 
of function objects named by @call and @construct (built-in functions 
have only @call). The values are built-in and need a bit more thought 
than I can spare now, but see below: @call's value is close to the 
original value of Function.prototype.call, and @construct's value is 
straightforward enough I think.


Change 11.2.2 The new Operator to use @construct not [[Construct]], 
passing the /argList// spread as actual positional parameters: (...argList).


Change 11.2.3 Function Calls to use @call not [[Call]], passing the 
/thisValue/ and /argList/ according to the Function.prototype.call 
convention: (thisValue, ...argList).


Change 11.4.3 The typeof Operator, the table row with Object (native 
or host and does implement [[Call]]) in column 1, to test not for 
[[Call]] and *not* for @call, rather to test [[NativeBrand]] === 
Function (see ES6 draft 15.2.4.2 Object.prototype.toString ( )).


This last point is important: we do not want an object's typeof-type to 
change by giving it a @call property. But we do want to enable call and 
construct protocols to be built by users, by giving objects @call and 
@construct properties.


This also simplifies direct proxies by allowing any proxy to have call 
and construct traps.


Comments welcome.

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


Re: callable objects ?

2012-04-17 Thread Brendan Eich

Brendan Eich wrote:
This last point is important: we do not want an object's typeof-type 
to change by giving it a @call property. But we do want to enable call 
and construct protocols to be built by users, by giving objects @call 
and @construct properties.


I did not include an Object.isCallable(v) API that returns true if 
(@call in v), but we could add that. Testing (@call in v) seems simple 
enough.


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


Re: callable objects ?

2012-04-17 Thread Mark S. Miller
+1 for simple enough. It's also shorter (12 vs 20)

On Tue, Apr 17, 2012 at 2:02 PM, Brendan Eich bren...@mozilla.org wrote:

 Brendan Eich wrote:

 This last point is important: we do not want an object's typeof-type to
 change by giving it a @call property. But we do want to enable call and
 construct protocols to be built by users, by giving objects @call and
 @construct properties.


 I did not include an Object.isCallable(v) API that returns true if (@call
 in v), but we could add that. Testing (@call in v) seems simple enough.


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




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


RE: callable objects ?

2012-04-17 Thread Domenic Denicola
It seems rather non-intention-revealing.


From: es-discuss-boun...@mozilla.org [es-discuss-boun...@mozilla.org] on behalf 
of Mark S. Miller [erig...@google.com]
Sent: Tuesday, April 17, 2012 17:20
To: Brendan Eich
Cc: Tom Van Cutsem; Mark Miller; es-discuss
Subject: Re: callable objects ?

+1 for simple enough. It's also shorter (12 vs 20)

On Tue, Apr 17, 2012 at 2:02 PM, Brendan Eich 
bren...@mozilla.orgmailto:bren...@mozilla.org wrote:
Brendan Eich wrote:
This last point is important: we do not want an object's typeof-type to change 
by giving it a @call property. But we do want to enable call and construct 
protocols to be built by users, by giving objects @call and @construct 
properties.

I did not include an Object.isCallable(v) API that returns true if (@call in 
v), but we could add that. Testing (@call in v) seems simple enough.


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



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


Re: callable objects ?

2012-04-17 Thread Russell Leggett
On Tue, Apr 17, 2012 at 4:44 PM, Brendan Eich bren...@mozilla.org wrote:

 Brendan Eich wrote:

 Irakli Gozalishvili wrote:

 It would be amazing to have clojure like protocols in JS  even without
 `IFn`. I think it's very good feet and very useful in JS where each library
 has it's own flavored API. I wrote more about it here:
 http://jeditoolkit.com/2012/**03/21/protocol-based-**
 polymorphism.html#posthttp://jeditoolkit.com/2012/03/21/protocol-based-polymorphism.html#post


 Still hoping Mark will weigh in.


 Ok, I talked to Mark and Tom Van Cutsem, and they see no problem provided
 we prevent overriding built-in [[Call]] and [[Construct]] on function
 objects.

 Let there be private names @call and @construct (I'll spell them this way
 to avoid tedious imports of const bindings from @std or another built-in
 module).

 Let Clause 15.3.5 include new non-configurable, non-writable properties of
 function objects named by @call and @construct (built-in functions have
 only @call). The values are built-in and need a bit more thought than I can
 spare now, but see below: @call's value is close to the original value of
 Function.prototype.call, and @construct's value is straightforward enough I
 think.

 Change 11.2.2 The new Operator to use @construct not [[Construct]],
 passing the /argList// spread as actual positional parameters: (...argList).

 Change 11.2.3 Function Calls to use @call not [[Call]], passing the
 /thisValue/ and /argList/ according to the Function.prototype.call
 convention: (thisValue, ...argList).

 Change 11.4.3 The typeof Operator, the table row with Object (native or
 host and does implement [[Call]]) in column 1, to test not for [[Call]]
 and *not* for @call, rather to test [[NativeBrand]] === Function (see ES6
 draft 15.2.4.2 Object.prototype.toString ( )).

 This last point is important: we do not want an object's typeof-type to
 change by giving it a @call property. But we do want to enable call and
 construct protocols to be built by users, by giving objects @call and
 @construct properties.

 This also simplifies direct proxies by allowing any proxy to have call and
 construct traps.

 Comments welcome.


What would happen if the object only defined one of these, but was used
with the wrong one? Let's say I create an object Foo with @call, but not
@construct, and then said new Foo()? Would it use @call and result in an
error? What about vice versa?

- Russ





 /be
 __**_
 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: callable objects ?

2012-04-17 Thread Brendan Eich

Already specified by ES6 as patched by my mail ;-).

There's no fallback on @call from missing @construct. You have to say 
what you mean. If you define @call and someone uses 'new', without an 
inherited @construct you get a TypeError per 11.2.2 The new Operator.


/be

Russell Leggett wrote:
What would happen if the object only defined one of these, but was 
used with the wrong one? Let's say I create an object Foo with @call, 
but not @construct, and then said new Foo()? Would it use @call and 
result in an error? What about vice versa?



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


Re: callable objects ?

2012-04-17 Thread Axel Rauschmayer
Awesome. That gives you all the building blocks for trying out object exemplars 
via a library.

I would add: [[HasInstance]] - @hasInstance



On Apr 17, 2012, at 22:44 , Brendan Eich wrote:

 Brendan Eich wrote:
 Irakli Gozalishvili wrote:
 It would be amazing to have clojure like protocols in JS  even without 
 `IFn`. I think it's very good feet and very useful in JS where each library 
 has it's own flavored API. I wrote more about it here: 
 http://jeditoolkit.com/2012/03/21/protocol-based-polymorphism.html#post
 
 Still hoping Mark will weigh in.
 
 Ok, I talked to Mark and Tom Van Cutsem, and they see no problem provided we 
 prevent overriding built-in [[Call]] and [[Construct]] on function objects.
 
 Let there be private names @call and @construct (I'll spell them this way to 
 avoid tedious imports of const bindings from @std or another built-in 
 module).
 
 Let Clause 15.3.5 include new non-configurable, non-writable properties of 
 function objects named by @call and @construct (built-in functions have only 
 @call). The values are built-in and need a bit more thought than I can spare 
 now, but see below: @call's value is close to the original value of 
 Function.prototype.call, and @construct's value is straightforward enough I 
 think.
 
 Change 11.2.2 The new Operator to use @construct not [[Construct]], passing 
 the /argList// spread as actual positional parameters: (...argList).
 
 Change 11.2.3 Function Calls to use @call not [[Call]], passing the 
 /thisValue/ and /argList/ according to the Function.prototype.call 
 convention: (thisValue, ...argList).
 
 Change 11.4.3 The typeof Operator, the table row with Object (native or 
 host and does implement [[Call]]) in column 1, to test not for [[Call]] and 
 *not* for @call, rather to test [[NativeBrand]] === Function (see ES6 draft 
 15.2.4.2 Object.prototype.toString ( )).
 
 This last point is important: we do not want an object's typeof-type to 
 change by giving it a @call property. But we do want to enable call and 
 construct protocols to be built by users, by giving objects @call and 
 @construct properties.
 
 This also simplifies direct proxies by allowing any proxy to have call and 
 construct traps.
 
 Comments welcome.
 
 /be
 ___
 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: callable objects ?

2012-04-17 Thread Brendan Eich

Axel Rauschmayer wrote:

I would add: [[HasInstance]] - @hasInstance


Yes, that one goes with @construct, and it seems safe to hook at 
base-level because only instanceof uses [[HasInstance]].


As Mark and Tom argued in the Proxy design docs, stratifying in a new 
proxy object is much safer when the trap is called all over, internally, 
and at points in ECMA-262 and real VMs where usercode is not expected 
to nest.


Further-base level traps need to be considered carefully on a 
case-by-case basis.


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


Re: callable objects ?

2012-04-17 Thread Brendan Eich

Brendan Eich wrote:
Let Clause 15.3.5 include new non-configurable, non-writable 
properties of function objects named by @call and @construct (built-in 
functions have only @call).


Allen points out that for self-hosting Date and the like (this came up 
with the Intl work too, we think), leaving @construct configurable or at 
least writable is necessary.


Tom and Mark rightly suggest that @call should not be something you can 
override on a function object. But is @construct safe to override?


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


Re: callable objects ?

2012-04-17 Thread Brandon Benvie
This is quite awesome. It seems like it might actually simplify a number of
things in the process.
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: callable objects ?

2012-04-17 Thread Dean Landolt
On Tue, Apr 17, 2012 at 7:06 PM, Brendan Eich bren...@mozilla.org wrote:

 Axel Rauschmayer wrote:

 I would add: [[HasInstance]] - @hasInstance


 Yes, that one goes with @construct, and it seems safe to hook at
 base-level because only instanceof uses [[HasInstance]].

 As Mark and Tom argued in the Proxy design docs, stratifying in a new
 proxy object is much safer when the trap is called all over, internally,
 and at points in ECMA-262 and real VMs where usercode is not expected to
 nest.

 Further-base level traps need to be considered carefully on a case-by-case
 basis.



This is really nice to see! For a while now I've figured the separate
namespace that name objects offer could be a really useful, simplifying
force...

Now to try and stretch this a bit further: I wonder if __proto__ shouldn't
be stratified with a @prototypeOf name -- read-only, of course, except
during instantiation. We ought to be able to write to the @prototypeOf name
in a @construct function, right? Thus, if we could overwrite @construct on
functions this could subsume | (or | -- I can never remember which
direction that's supposed to point :P)...

Of course if we were to go this far why not take it one more step and offer
up a @constructor name that's invariably linked to the @construct function
responsible for creating an instance? And finally, we may as well go all
out and also stratify the prototype property with a @prototype name. This
last one's not an immediate win (but seems like the right thing long term),
but the others solve real problems in a way consistent with the @call and
@construct approach above. I couldn't speak to whether it's safe to
override a function's @construct but if it turns out to be, what do people
think of this?
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: callable objects ?

2012-04-14 Thread Irakli Gozalishvili
It would be amazing to have clojure like protocols in JS  even without `IFn`. I 
think it's very good feet and very useful in JS where each library has it's own 
flavored API. I wrote more about it here: 
http://jeditoolkit.com/2012/03/21/protocol-based-polymorphism.html#post

Also why would callable objects return `function` on `typeof(callable)`. As a 
matter of fact I think it should be `object` and something new like 
`Object.isCallable(object)` may be used to check for call-ability. This way old 
code either will reject non functions or will shim `Object.isCallable` to 
support new constructs. 


Regards
--
Irakli Gozalishvili
Web: http://www.jeditoolkit.com/


On Wednesday, 2012-04-11 at 11:54 , Brendan Eich wrote:

 Michael Fogus wrote:
  I know some things about ClojureScript and would be happy to answer
  any direct questions. However, I think its notion (and Clojure proper)
  is that functions are data are functions is very powerful.
  
 
 
 It's a great idea (I first met John McCarthy in 1977 when I was 16). Too 
 bad JS was not allowed to be Scheme in the browser.
 
  A lot of
  interesting patterns fall out of this as others have pointed out.
  
 
 
 I'm ready to jump in with both feet, except for JS's age and the 
 possibility that too much code on the web counts on things like
 
 (typeof x == function) = x() works and x.apply is the expected built-in
 
 No problem, you say, we can leave typeof alone and add a callable 
 predicate and evangelize that. Ok, provided the callable protocol uses 
 an ES6 private name (think gensym), any public name could be in use and 
 make a false positive when testing callability.
 
 So let's use a well-known private (unique, should say) name, e.g.
 
 module std {
 ...
 export const invokeName = Name.create(invoke);
 
 export function callable(v) {
 if (typeof v == function)
 return true;
 if (typeof v == object  v != null)
 return invokeName in v; // could be pickier but let's start here
 return false;
 }
 }
 
 // make an object obj be callable:
 obj[invokeName] = function (...args) { /* ... */ };
 
 Looks ok, ignoring details such as how the client code gets the standard 
 unique name binding (import invokeName from @std or some such).
 
 One can't assume apply or call or other Function.prototype heritage is 
 in x just because callable(x) returns true. Callability is wider and 
 weaker than typeof-result function.
 
 IIRC, security conscious folks do not want an attacker to be able to 
 make any old object callable. Cc'ing Mark for his thoughts.
 
 /be
 ___
 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
https://mail.mozilla.org/listinfo/es-discuss


Re: callable objects ?

2012-04-14 Thread Brendan Eich

Irakli Gozalishvili wrote:
It would be amazing to have clojure like protocols in JS  even without 
`IFn`. I think it's very good feet and very useful in JS where each 
library has it's own flavored API. I wrote more about it here: 
http://jeditoolkit.com/2012/03/21/protocol-based-polymorphism.html#post


Still hoping Mark will weigh in.


Also why would callable objects return `function` on `typeof(callable)`.
I didn't say that was a good idea, I only noted that we're breaking an 
invariant for native objects. Not unthinkable!


As a matter of fact I think it should be `object` and something new 
like `Object.isCallable(object)`


See callable(x) below. Putting it on Object and using isCallable 
Java-style naming seems safer but makes me sad -- so verbose!


/be

may be used to check for call-ability. This way old code either will 
reject non functions or will shim `Object.isCallable` to support new 
constructs.



Regards
--
Irakli Gozalishvili
Web: http://www.jeditoolkit.com/

On Wednesday, 2012-04-11 at 11:54 , Brendan Eich wrote:


Michael Fogus wrote:

I know some things about ClojureScript and would be happy to answer
any direct questions. However, I think its notion (and Clojure proper)
is that functions are data are functions is very powerful.


It's a great idea (I first met John McCarthy in 1977 when I was 16). Too
bad JS was not allowed to be Scheme in the browser.


A lot of
interesting patterns fall out of this as others have pointed out.


I'm ready to jump in with both feet, except for JS's age and the
possibility that too much code on the web counts on things like

(typeof x == function) = x() works and x.apply is the expected 
built-in


No problem, you say, we can leave typeof alone and add a callable
predicate and evangelize that. Ok, provided the callable protocol uses
an ES6 private name (think gensym), any public name could be in use and
make a false positive when testing callability.

So let's use a well-known private (unique, should say) name, e.g.

module std {
...
export const invokeName = Name.create(invoke);

export function callable(v) {
if (typeof v == function)
return true;
if (typeof v == object  v != null)
return invokeName in v; // could be pickier but let's start here
return false;
}
}

// make an object obj be callable:
obj[invokeName] = function (...args) { /* ... */ };

Looks ok, ignoring details such as how the client code gets the standard
unique name binding (import invokeName from @std or some such).

One can't assume apply or call or other Function.prototype heritage is
in x just because callable(x) returns true. Callability is wider and
weaker than typeof-result function.

IIRC, security conscious folks do not want an attacker to be able to
make any old object callable. Cc'ing Mark for his thoughts.

/be
___
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
https://mail.mozilla.org/listinfo/es-discuss

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


Re: callable objects ?

2012-04-11 Thread David Nolen
This extremely useful feature is under discussion for Dart as well.

David

On Wed, Apr 11, 2012 at 1:15 PM, Michael Fogus mefo...@gmail.com wrote:

 I know some things about ClojureScript and would be happy to answer
 any direct questions. However, I think its notion (and Clojure proper)
 is that functions are data are functions is very powerful. A lot of
 interesting patterns fall out of this as others have pointed out.

 Brendan Eich wrote:
  This gist about ClojureScript
 
  https://gist.github.com/2346460
 
  reminded me of this thread. I need to spend more time learning
  ClojureScript; maybe someone who knows it has a thought.
 ___
 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: callable objects ?

2012-04-11 Thread Brendan Eich

Michael Fogus wrote:

I know some things about ClojureScript and would be happy to answer
any direct questions. However, I think its notion (and Clojure proper)
is that functions are data are functions is very powerful.


It's a great idea (I first met John McCarthy in 1977 when I was 16). Too 
bad JS was not allowed to be Scheme in the browser.



  A lot of
interesting patterns fall out of this as others have pointed out.


I'm ready to jump in with both feet, except for JS's age and the 
possibility that too much code on the web counts on things like


(typeof x == function) = x() works and x.apply is the expected built-in

No problem, you say, we can leave typeof alone and add a callable 
predicate and evangelize that. Ok, provided the callable protocol uses 
an ES6 private name (think gensym), any public name could be in use and 
make a false positive when testing callability.


So let's use a well-known private (unique, should say) name, e.g.

module std {
  ...
  export const invokeName = Name.create(invoke);

  export function callable(v) {
if (typeof v == function)
  return true;
if (typeof v == object  v != null)
  return invokeName in v; // could be pickier but let's start here
return false;
  }
}

// make an object obj be callable:
obj[invokeName] = function (...args) { /* ... */ };

Looks ok, ignoring details such as how the client code gets the standard 
unique name binding (import invokeName from @std or some such).


One can't assume apply or call or other Function.prototype heritage is 
in x just because callable(x) returns true. Callability is wider and 
weaker than typeof-result function.


IIRC, security conscious folks do not want an attacker to be able to 
make any old object callable. Cc'ing Mark for his thoughts.


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


Re: callable objects ?

2012-04-11 Thread Michael Fogus
 JS was not allowed to be Scheme in the browser.

There will be 42 Scheme-JS transpilers by the end of 2012.

;-)

 No problem, you say, we can leave typeof alone and add a callable predicate
 and evangelize that. Ok, provided the callable protocol uses an ES6 private
 name (think gensym), any public name could be in use and make a false
 positive when testing callability.

Most of what you describe is a consequence of backwards compatibility
and maximum dynamicity. ClojureScript gets a pass on these problems
(for the most part) because of its focus for use and compilation
model. Agreed adding these capabilities into JS is a sticky situation
and not something that I envy. I'm glad smarter people than me are
working on it.
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: callable objects ?

2012-04-09 Thread Brendan Eich

This gist about ClojureScript

https://gist.github.com/2346460

reminded me of this thread. I need to spend more time learning 
ClojureScript; maybe someone who knows it has a thought.


/be

Irakli Gozalishvili wrote:

I have prototyped desugared version of callable objects here:

https://gist.github.com/2312621

I could not use short object syntax and unnamed method as proposed in 
original post, so I used regular object syntax and `new` as method 
name for unnamed `method`. I tried to illustrates that callable 
objects may be more elegant alternative to classes specially in 
combination with `|` (which I expressed as `extend` function).


Regards
--
Irakli Gozalishvili
Web: http://www.jeditoolkit.com/

On Wednesday, 2012-04-04 at 24:56 , David Bruant wrote:


Le 04/04/2012 02:41, Irakli Gozalishvili a écrit :


On Tuesday, 2012-04-03 at 14:07 , David Bruant wrote:


Le 03/04/2012 22:00, Irakli Gozalishvili a écrit :
Here is more or less what I have in mind: 
https://gist.github.com/2295048


// class
var Point = {
(x, y) {
this.getX = { () { return x; } }
this.getY = { () { return x; } }
}
toString() {
return '' + this.getX() + ',' + this.getY() + '';
}
}

Interesting new function syntax.
The prototype and function body could even be declared together. 
What about 'length'?


Also such callable objects provide shorter alternative to current 
function syntax:

// shorter than function
numbers.
filter({ (x) { return x % 2 } }).
// maybe single expression can be even shorter like arrow functions ?
map({ (x) x * x }).
forEach({ (x) { this.add(x) } }, that);

+1

Also this would allow interesting APIs similar to those found in 
clojure:


// maps / sets similar like in clojure ?
var map = WeakMap(), key = {}, value = {};
map.set(key, value);
map(key) // = value

So far so good.


key(map) // = value
This cannot work for backward-compat reasons. In ES1-5, key = {} 
creates a regular (non-callable) object.





Well I did not suggested it should be backwards compatible, also nor 
classes nor shorter object syntax is backwards compatible.


They are to the extent that they throw an error for being invalid 
syntax in previous version. This is the case for your proposal and 
that's a good thing since that's the back door to introducing new 
features.

However, proposals should be backward compatible in semantics.

In your case:

var map = WeakMap(), key = {}, value = {};
map.set(key, value);
map(key) // = value
key(map) // = value

since key is callable, you have (typeof key === 'function') while ES5 
requires (typeof key === 'object') for objects that are constructed 
with '{}'. There is code out there that relies on typeof for argument 
shifting: 'if the first argument is a function, use that as callback, 
otherwise, use the second argument (first argument being an option 
non-callable object)'. There is this pattern all over the place in 
the mongodb node client as in 
https://github.com/christkv/node-mongodb-native/blob/master/lib/mongodb/collection.js#L85
In other cases, to pass a handler, some API check if the argument if 
an object and in that case use the 'handle' property or use the 
function is what has been passed is callable.
So, preserving typeof invariants regarding 'object'/'function' is 
crucial to backward compatibility.


Likewise for arrays. In ES1-5, (typeof [] === 'object') and the 
suggested semantics of your proposal would break that.


As far as I'm concerned, just the object-literal version of function 
is a brilliant idea, no need for the additional semantics.


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


Re: callable objects ?

2012-04-05 Thread Irakli Gozalishvili
I have prototyped desugared version of callable objects here:  

https://gist.github.com/2312621  

I could not use short object syntax and unnamed method as proposed in original 
post, so I used regular object syntax and `new` as method name for unnamed 
`method`. I tried to illustrates that callable objects may be more elegant 
alternative to classes specially in combination with `|` (which I expressed as 
`extend` function).
Regards
--
Irakli Gozalishvili
Web: http://www.jeditoolkit.com/


On Wednesday, 2012-04-04 at 24:56 , David Bruant wrote:

 Le 04/04/2012 02:41, Irakli Gozalishvili a écrit :  
   
   
  On Tuesday, 2012-04-03 at 14:07 , David Bruant wrote:
   
   Le 03/04/2012 22:00, Irakli Gozalishvili a écrit :  
Here is more or less what I have in mind: 
https://gist.github.com/2295048  
 
// class
var Point = {
  (x, y) {
this.getX = { () { return x; } }
this.getY = { () { return x; } }
  }
 
  toString() {
return '' + this.getX() + ',' + this.getY() + '';
  }
}
 
 
 
 
 
 

   Interesting new function syntax.
   The prototype and function body could even be declared together. What 
   about 'length'?

Also such callable objects provide shorter alternative to current 
function syntax:  
// shorter than function
 
numbers.
  filter({ (x) { return x % 2 } }).
  // maybe single expression can be even shorter like arrow functions ?
  map({ (x) x * x }).
  forEach({ (x) { this.add(x) } }, that);
 
 
 
 
 
 

   +1

Also this would allow interesting APIs similar to those found in 
clojure:  
 
// maps / sets similar like in clojure ?
var map = WeakMap(), key = {}, value = {};
 
map.set(key, value);
map(key) // = value
 
 
 
 
 
 

   So far so good.

key(map) // = value This cannot work for backward-compat reasons. In 
ES1-5, key = {} creates a regular (non-callable) object.

   
   
  Well I did not suggested it should be backwards compatible, also nor 
  classes nor shorter object syntax is backwards compatible.  
 They are to the extent that they throw an error for being invalid syntax in 
 previous version. This is the case for your proposal and that's a good thing 
 since that's the back door to introducing new features.
 However, proposals should be backward compatible in semantics.
  
 In your case:
  
 var map = WeakMap(), key = {}, value = {};
 map.set(key, value);
 map(key) // = value
 key(map) // = value
  
 since key is callable, you have (typeof key === 'function') while ES5 
 requires (typeof key === 'object') for objects that are constructed with 
 '{}'. There is code out there that relies on typeof for argument shifting: 
 'if the first argument is a function, use that as callback, otherwise, use 
 the second argument (first argument being an option non-callable object)'. 
 There is this pattern all over the place in the mongodb node client as in 
 https://github.com/christkv/node-mongodb-native/blob/master/lib/mongodb/collection.js#L85
 In other cases, to pass a handler, some API check if the argument if an 
 object and in that case use the 'handle' property or use the function is what 
 has been passed is callable.
 So, preserving typeof invariants regarding 'object'/'function' is crucial to 
 backward compatibility.
  
 Likewise for arrays. In ES1-5, (typeof [] === 'object') and the suggested 
 semantics of your proposal would break that.
  
 As far as I'm concerned, just the object-literal version of function is a 
 brilliant idea, no need for the additional semantics.
  
 David

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


Re: callable objects ?

2012-04-04 Thread David Bruant

Le 04/04/2012 02:41, Irakli Gozalishvili a écrit :


On Tuesday, 2012-04-03 at 14:07 , David Bruant wrote:


Le 03/04/2012 22:00, Irakli Gozalishvili a écrit :
Here is more or less what I have in mind: 
https://gist.github.com/2295048


// class
var Point = {
(x, y) {
this.getX = { () { return x; } }
this.getY = { () { return x; } }
}
toString() {
return '' + this.getX() + ',' + this.getY() + '';
}
}

Interesting new function syntax.
The prototype and function body could even be declared together. What 
about 'length'?


Also such callable objects provide shorter alternative to current 
function syntax:

// shorter than function
numbers.
filter({ (x) { return x % 2 } }).
// maybe single expression can be even shorter like arrow functions ?
map({ (x) x * x }).
forEach({ (x) { this.add(x) } }, that);

+1

Also this would allow interesting APIs similar to those found in 
clojure:


// maps / sets similar like in clojure ?
var map = WeakMap(), key = {}, value = {};
map.set(key, value);
map(key) // = value

So far so good.


key(map) // = value
This cannot work for backward-compat reasons. In ES1-5, key = {} 
creates a regular (non-callable) object.





Well I did not suggested it should be backwards compatible, also nor 
classes nor shorter object syntax is backwards compatible.


They are to the extent that they throw an error for being invalid syntax 
in previous version. This is the case for your proposal and that's a 
good thing since that's the back door to introducing new features.

However, proposals should be backward compatible in semantics.

In your case:

var map = WeakMap(), key = {}, value = {};
map.set(key, value);
map(key) // = value
key(map) // = value

since key is callable, you have (typeof key === 'function') while ES5 
requires (typeof key === 'object') for objects that are constructed with 
'{}'. There is code out there that relies on typeof for argument 
shifting: 'if the first argument is a function, use that as callback, 
otherwise, use the second argument (first argument being an option 
non-callable object)'. There is this pattern all over the place in the 
mongodb node client as in 
https://github.com/christkv/node-mongodb-native/blob/master/lib/mongodb/collection.js#L85
In other cases, to pass a handler, some API check if the argument if an 
object and in that case use the 'handle' property or use the function is 
what has been passed is callable.
So, preserving typeof invariants regarding 'object'/'function' is 
crucial to backward compatibility.


Likewise for arrays. In ES1-5, (typeof [] === 'object') and the 
suggested semantics of your proposal would break that.


As far as I'm concerned, just the object-literal version of function is 
a brilliant idea, no need for the additional semantics.


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


Re: callable objects ?

2012-04-03 Thread Russell Leggett
I agree that this is really elegant. I have almost the exact same construct
in a language I'm designing. I don't know if it has a place in JS, but you
have my approval. :)

- Russ

On Tue, Apr 3, 2012 at 4:00 PM, Irakli Gozalishvili rfo...@gmail.comwrote:

  Hi,

 Please excuse me if this will sound too crazy, but this idea have being
 growing in my head for so long that I can't stop myself from proposing it
 here. I have experimented many different ways of doing inheritance in JS:

 1. Starting with a simple sugar that reduces machinery involved, similar
 to backbone.js
 https://github.com/Gozala/extendables

 2. Finishing with class free prototypal inheritance
 https://github.com/Gozala/selfish

 I have to say that experience with selfish turned out very interesting, it
 made things so much simpler no special forms, no twisted relations between
 constructors and objects, just a plain objects. Most of these things are
 not obvious until you start using them, but the fact that exemplars
 (classes) are no different from regular objects in the system makes things
 much simpler.

 That being said I have also came to realize that in most of the cases
 functions as exemplars would be a better feet than objects. As a matter of
 fact if objects could be made callable I think it could could have replaced
 most of the things that classes are targeting in more elegant way.

 Here is more or less what I have in mind: https://gist.github.com/2295048

 // class
 var Point = {
   (x, y) {
 this.getX = { () { return x; } }
 this.getY = { () { return x; } }
   }

   toString() {
 return '' + this.getX() + ',' + this.getY() + '';
   }
 }

 var a = new Point(0, 0)
 var b = new Point(1, 7)

 // Examples from class proposal

 // extend is like create with a diff that second arg is an object.
 var SkinnedMesh = Object.extend(THREE.Mesh, {
   (geometry, materials) {
 // call the superclass constructor
 THREE.Mesh.call(this, geometry, materials);

 // initialize instance properties
 this.identityMatrix = new THREE.Matrix4();
 this.bones = [];
 this.boneMatrices = [];

 // ...
   }

   update (camera) {
 THREE.Mesh.update.call(this);
   }
 });

 Also such callable objects provide shorter alternative to current function
 syntax:

 // shorter than function

 numbers.
   filter({ (x) { return x % 2 } }).
   // maybe single expression can be even shorter like arrow functions ?
   map({ (x) x * x }).
   forEach({ (x) { this.add(x) } }, that);


 Also this would allow interesting APIs similar to those found in clojure:

 // maps / sets similar like in clojure ?
 var map = WeakMap(), key = {}, value = {};

 map.set(key, value);
 map(key) // = value
 key(map) // = value


 And maybe built-ins could have it for doing `[]` work:


 // Maybe even non-magical replacement for  `[]`

 [ 'a', 'b', 'c' ](1)  // = 'b'
 ({ a: 1, b: 2 })('a') // = 1
 ('b')({ a: 1, b: 2 })   // = 2


 Regards
 --
 Irakli Gozalishvili
 Web: http://www.jeditoolkit.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: callable objects ?

2012-04-03 Thread David Bruant
Le 03/04/2012 22:00, Irakli Gozalishvili a écrit :
 Here is more or less what I have in mind: https://gist.github.com/2295048

 // class
 var Point = {
   (x, y) {
 this.getX = { () { return x; } }
 this.getY = { () { return x; } }
   }
   toString() {
 return '' + this.getX() + ',' + this.getY() + '';
   }
 }
Interesting new function syntax.
The prototype and function body could even be declared together. What
about 'length'?

 Also such callable objects provide shorter alternative to current
 function syntax:
 // shorter than function
 numbers.
   filter({ (x) { return x % 2 } }).
   // maybe single expression can be even shorter like arrow functions ?
   map({ (x) x * x }).
   forEach({ (x) { this.add(x) } }, that);
+1

 Also this would allow interesting APIs similar to those found in clojure:

 // maps / sets similar like in clojure ?
 var map = WeakMap(), key = {}, value = {};
 map.set(key, value);
 map(key) // = value
So far so good.

 key(map) // = value
This cannot work for backward-compat reasons. In ES1-5, key = {}
creates a regular (non-callable) object.

 And maybe built-ins could have it for doing `[]` work:
 // Maybe even non-magical replacement for `[]`
 [ 'a', 'b', 'c' ](1) // = 'b'
Again, this is a valid ES1-5 expression and throws an error. Arrays and
function have diverging opinions on the 'length' property.

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


Re: callable objects ?

2012-04-03 Thread Irakli Gozalishvili


On Tuesday, 2012-04-03 at 14:07 , David Bruant wrote:

 Le 03/04/2012 22:00, Irakli Gozalishvili a écrit :  
  Here is more or less what I have in mind: https://gist.github.com/2295048  
   
  // class
  var Point = {
(x, y) {
  this.getX = { () { return x; } }
  this.getY = { () { return x; } }
}
   
toString() {
  return '' + this.getX() + ',' + this.getY() + '';
}
  }
   
   
   
   
   
  
 Interesting new function syntax.
 The prototype and function body could even be declared together. What about 
 'length'?
  
  Also such callable objects provide shorter alternative to current function 
  syntax:  
  // shorter than function
   
  numbers.
filter({ (x) { return x % 2 } }).
// maybe single expression can be even shorter like arrow functions ?
map({ (x) x * x }).
forEach({ (x) { this.add(x) } }, that);
   
   
   
   
   
  
 +1
  
  Also this would allow interesting APIs similar to those found in clojure:  
   
  // maps / sets similar like in clojure ?
  var map = WeakMap(), key = {}, value = {};
   
  map.set(key, value);
  map(key) // = value
   
   
   
   
   
  
 So far so good.
  
  key(map) // = value This cannot work for backward-compat reasons. In 
  ES1-5, key = {} creates a regular (non-callable) object.
  


Well I did not suggested it should be backwards compatible, also nor classes 
nor shorter object syntax is backwards compatible.


  And maybe built-ins could have it for doing `[]` work:
   
   
  // Maybe even non-magical replacement for `[]`
   
  [ 'a', 'b', 'c' ](1) // = 'b'
   
   
   
   
   
  
 Again, this is a valid ES1-5 expression and throws an error. Arrays and 
 function have diverging opinions on the 'length' property.
  
 David

Also de-sugared version may be provided (and even prototyped today using 
__proto__):

var Point = Function.create(Object.prototype, function(x, y) {
this.getX = function() { return x };
this.getY = function() { return y };
}, {
toString: function() {
return '' + this.getX() + ',' + this.getY() + ''
  }
});
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: callable objects ?

2012-04-03 Thread Irakli Gozalishvili


On Tuesday, 2012-04-03 at 13:47 , Axel Rauschmayer wrote:

 I think you should make the distinction between [[Call]] and [[Construct]].  
  


You can do it via (this insntanceof ..) already and dispatch to call / 
construct if you want.  
  
 But both would be great to have for objects. It’s probably best to create 
 importable names.
  

Importable names won't allow shorter than function form though, so I think just 
() {} is better.  
  
  
 Then making the `new` operator available to object exemplars becomes indeed 
 simple. For example:
  
 // Root object exemplar
 import Construct from somewhere;
 let ObjectExemplar = {
 [Construct](...args) {
 let inst = Object.create(this);
 let result = inst.init(...args);
 return (result === undefined ? inst : result);
 }
 }
  
  
  
 On Apr 3, 2012, at 22:00 , Irakli Gozalishvili wrote:
  Hi,  
   
  Please excuse me if this will sound too crazy, but this idea have being 
  growing in my head for so long that I can't stop myself from proposing it 
  here. I have experimented many different ways of doing inheritance in JS:
   
  1. Starting with a simple sugar that reduces machinery involved, similar to 
  backbone.js
  https://github.com/Gozala/extendables
   
  2. Finishing with class free prototypal inheritance
  https://github.com/Gozala/selfish
   
  I have to say that experience with selfish turned out very interesting, it 
  made things so much simpler no special forms, no twisted relations between 
  constructors and objects, just a plain objects. Most of these things are 
  not obvious until you start using them, but the fact that exemplars 
  (classes) are no different from regular objects in the system makes things 
  much simpler.  
   
  That being said I have also came to realize that in most of the cases 
  functions as exemplars would be a better feet than objects. As a matter of 
  fact if objects could be made callable I think it could could have replaced 
  most of the things that classes are targeting in more elegant way.  
   
  Here is more or less what I have in mind: https://gist.github.com/2295048
   
  // class
  var Point = {
(x, y) {
  this.getX = { () { return x; } }
  this.getY = { () { return x; } }
}
   
toString() {
  return '' + this.getX() + ',' + this.getY() + '';
}
  }
   
  var a = new Point(0, 0)
  var b = new Point(1, 7)
   
  // Examples from class proposal
   
  // extend is like create with a diff that second arg is an object.
  var SkinnedMesh = Object.extend(THREE.Mesh, {
(geometry, materials) {
  // call the superclass constructor
  THREE.Mesh.call(this, geometry, materials);
   
  // initialize instance properties
  this.identityMatrix = new THREE.Matrix4();
  this.bones = [];
  this.boneMatrices = [];
   
  // ...
}
   
update (camera) {
  THREE.Mesh.update.call(this);
}
  });
   
  Also such callable objects provide shorter alternative to current function 
  syntax:
  // shorter than function
   
  numbers.
filter({ (x) { return x % 2 } }).
// maybe single expression can be even shorter like arrow functions ?
map({ (x) x * x }).
forEach({ (x) { this.add(x) } }, that);
   
   
  Also this would allow interesting APIs similar to those found in clojure:
   
  // maps / sets similar like in clojure ?
  var map = WeakMap(), key = {}, value = {};
   
  map.set(key, value);
  map(key) // = value
  key(map) // = value
   
   
  And maybe built-ins could have it for doing `[]` work:
   
   
  // Maybe even non-magical replacement for `[]`
   
  [ 'a', 'b', 'c' ](1) // = 'b'
  ({ a: 1, b: 2 })('a') // = 1
  ('b')({ a: 1, b: 2 }) // = 2
   
   
   
   
  Regards
  --
  Irakli Gozalishvili
  Web: http://www.jeditoolkit.com/
   
  ___
  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


Re: callable objects ?

2012-04-03 Thread Irakli Gozalishvili
Also I just realized that I have not mentioned it but I meant that new Point(0, 
0) would do following:

var point = Object.create(Point);
var value = Function.apply.call(point, arguments);
return typeof(value) === 'undefined' ? point : value;

Regards
--
Irakli Gozalishvili
Web: http://www.jeditoolkit.com/


On Tuesday, 2012-04-03 at 17:44 , Irakli Gozalishvili wrote:

  
  
 On Tuesday, 2012-04-03 at 13:47 , Axel Rauschmayer wrote:
  
  I think you should make the distinction between [[Call]] and [[Construct]]. 
   
   
   
  
  
 You can do it via (this insntanceof ..) already and dispatch to call / 
 construct if you want.  
   
  But both would be great to have for objects. It’s probably best to create 
  importable names.
   
  
 Importable names won't allow shorter than function form though, so I think 
 just () {} is better.  
   
  Then making the `new` operator available to object exemplars becomes indeed 
  simple. For example:
   
  // Root object exemplar
  import Construct from somewhere;
  let ObjectExemplar = {
  [Construct](...args) {
  let inst = Object.create(this);
  let result = inst.init(...args);
  return (result === undefined ? inst : result);
  }
  }
   
   
   
  On Apr 3, 2012, at 22:00 , Irakli Gozalishvili wrote:
   Hi,  

   Please excuse me if this will sound too crazy, but this idea have being 
   growing in my head for so long that I can't stop myself from proposing it 
   here. I have experimented many different ways of doing inheritance in JS:

   1. Starting with a simple sugar that reduces machinery involved, similar 
   to backbone.js
   https://github.com/Gozala/extendables

   2. Finishing with class free prototypal inheritance
   https://github.com/Gozala/selfish

   I have to say that experience with selfish turned out very interesting, 
   it made things so much simpler no special forms, no twisted relations 
   between constructors and objects, just a plain objects. Most of these 
   things are not obvious until you start using them, but the fact that 
   exemplars (classes) are no different from regular objects in the system 
   makes things much simpler.  

   That being said I have also came to realize that in most of the cases 
   functions as exemplars would be a better feet than objects. As a matter 
   of fact if objects could be made callable I think it could could have 
   replaced most of the things that classes are targeting in more elegant 
   way.  

   Here is more or less what I have in mind: https://gist.github.com/2295048

   // class
   var Point = {
 (x, y) {
   this.getX = { () { return x; } }
   this.getY = { () { return x; } }
 }

 toString() {
   return '' + this.getX() + ',' + this.getY() + '';
 }
   }

   var a = new Point(0, 0)
   var b = new Point(1, 7)

   // Examples from class proposal

   // extend is like create with a diff that second arg is an object.
   var SkinnedMesh = Object.extend(THREE.Mesh, {
 (geometry, materials) {
   // call the superclass constructor
   THREE.Mesh.call(this, geometry, materials);

   // initialize instance properties
   this.identityMatrix = new THREE.Matrix4();
   this.bones = [];
   this.boneMatrices = [];

   // ...
 }

 update (camera) {
   THREE.Mesh.update.call(this);
 }
   });

   Also such callable objects provide shorter alternative to current 
   function syntax:
   // shorter than function

   numbers.
 filter({ (x) { return x % 2 } }).
 // maybe single expression can be even shorter like arrow functions ?
 map({ (x) x * x }).
 forEach({ (x) { this.add(x) } }, that);


   Also this would allow interesting APIs similar to those found in clojure:

   // maps / sets similar like in clojure ?
   var map = WeakMap(), key = {}, value = {};

   map.set(key, value);
   map(key) // = value
   key(map) // = value


   And maybe built-ins could have it for doing `[]` work:


   // Maybe even non-magical replacement for `[]`

   [ 'a', 'b', 'c' ](1) // = 'b'
   ({ a: 1, b: 2 })('a') // = 1
   ('b')({ a: 1, b: 2 }) // = 2




   Regards
   --
   Irakli Gozalishvili
   Web: http://www.jeditoolkit.com/

   ___
   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