Enriched Descriptors, maybe ES7 ?

Andrea Giammarchi andrea.giammarchi at gmail.com
Sun Mar 9 12:52:08 PDT 2014


As it is now, Proxies could indirectly benefit from these enriched
descriptors.

My current implementation wraps directly `Object.create`,
`Object.defineProperty` and `Object.defineProperties` so that:

```javascript

function Person(name) {
  this.name = name;
  this.children = [];
}

Object.defineProperties(
  Person.prototype, {
  name: {
    type: 'string',
    writable: true,
    enumerable: true,
    value: 'unknown'
  },
  age: {
    type: 'number',
    writable: true,
    enumerable: true,
    value: 0
  },
  children: {
    type: Array, // of Persons
    writable: true,
    enumerable: true
  },
  birthday: {
    returns: 'number',
    value: function () {
      return ++this.age;
    }
  }
});

var me = new Person('ag');
me.birthday(); // yay, I'm 1 now!

```

Ideally, if this would ever be adopted, descriptors should be stored with
custom properties so that `Object.getOwnPropertyDescriptor(O, k)` could
pass these around ... well, the good part is that my proposal works out of
the box so even if ignored these properties are just fine as describing the
intent.

Long story short, you [add this script on top](
https://github.com/WebReflection/define-strict-properties/tree/master/build)
and if you do this it'll throw Errors:

```
me.age = me.name;
// throws 'expected number, received ag'

me.children = {};
// throws expected Array received object
```

The Proxy is able to guard in a similar way but it's an explicit layer/men
in the middle while having typed descriptors supporting overloads and
returns for function properties go further than just getting and setting
properties, i.e.

```javascript

Object.defineProperty(
  window,
  'sum',
  {
    arguments: [
      ['string', 'number'],
      ['number', 'number'],
      ['number', 'string']
    ],
    returns: ['number'],
    value: function (a, b) {
      return parseFloat(a) + parseFloat(b);
    }
  }
);

sum(1, '2'); // 3
sum('3', 2); // 5
sum(4, 5);   // 9
sum('6', '7'); // throws


```

Back to 2009, [dojo.lang.typed](
http://dojotoolkit.org/reference-guide/1.9/dojox/lang/typed.html) used a
similar approach for its own classes definition but that was before ES5
introduced descriptors which are not so commonly used, being very verbose,
but absolutely beautifully crafted to describe "classes" properties, IMO.

Having a standardized way to offer this natively and having a drop-in/off
polyfill on the way could only, still IMO, benefits in the long term with
tools possibly capable to understand type a-la TypeScript in VS and engines
could take advantage of these descriptors to boost up with or without
proxies around.

I am sure I am missing some case and being an early refactoring of an old
proposal I am trying to do it as OK as possible.

Thanks again for your time and thoughts.

Best Regards





On Sun, Mar 9, 2014 at 10:16 AM, Allen Wirfs-Brock <allen at wirfs-brock.com>wrote:

> Note that ES6 proxies as specified permits
> Object.defineProperty/getOwnPropertyDescriptor to pass custom attributes in
> property descriptors and even passes them along (not sure if anybody has
> actually implemented this yet) wherever there is a internal get
> descriptor/set descriptor sequence.  Proxies that support custom attributes
> might be an interest way toi experiment with some of these ideas.
>
> Allen
>
>
> On Mar 8, 2014, at 10:45 AM, Andrea Giammarchi wrote:
>
> Yesterday, after my DHTMLConf talk, some developer asked me to
> present/propose my idea about introducing **optional** types in an ES5
> compatible way.
>
> Here a quick overview of properties which aim is to guard types or methods
> signatures, compatible with overloads for both number of arguments, and
> acepted type per each argument and each "guarding group".
>
> ```
> propertyName: {
>     // ES5
>     writable: true/false
>     enumerable: true/false
>     configurable: true/false
>     get: Function
>     set: Function
>     value: any
>
>     // my complementary, non obtrusive, info
>     type: string(as typeof obj)|
>           Function(as instanceof)|
>           Object(as isPrototypeOf)
>     returns: type|[type1, type2, typeN]
>     arguments: [type]|[[type], [type]]
> }
>
> ```
>
> The return type can be different too, but I didn't forget to include the
> special type 'any' as white flag.
>
> All types and what they mean are [better described here](
> https://github.com/WebReflection/define-strict-properties#types).
>
> The most handy use case is probably
> `Object.defineProperties(Class.prototype, typedDescriptrs)` since each
> instance will be automatically guarded inheriting the guarded behavior.
>
> As mentioned in [this project goals](
> https://github.com/WebReflection/define-strict-properties#objectcreateproto-typedproperties),
> an ideal/dream goal would be having tools capable of
> documenting/understanding typed properties such IDE or even "transpilers"
> and in a parallel universe JS engines capable to natively use such info per
> each descriptor when available and both speed up properties get/set
> operations guarding natively the specific type.
>
> As example, this system made possible to implement a [StructType shim](
> https://github.com/WebReflection/define-strict-properties/blob/master/src/StructType.js#L57)
> in few lines of code.
>
> I don't expect this to be discussed soon but I wanted to point at this
> library now that is just officially born, despite I've proposed something
> similar in my blog already in 2010, so that if there's any big
> gotcha/mistake/nonsense in it I am in time to fix/improve or change.
>
> Thanks for your patience reading till the end and for any thoughts or
> hints that might come out.
>
> Best Regards and happy JS Fest!
>
>
>
>
>
> _______________________________________________
> es-discuss mailing list
> es-discuss at mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20140309/1110556f/attachment.html>


More information about the es-discuss mailing list