Map literal
I agree this is pretty important. Using actual maps really frees up a lot of complexity, but the syntax is cumbersome to say the least.
Whatever the decided syntax, bare words as string keys is a really bad idea IMO. The key syntax should be parsed as an expression, like the values are, and like they are in basically every other language.
Another outstanding issue is that we might want the syntax for
Immutable.Map
, or WeakMap
, or MapTwoPointOh
that improves deficiency
$x, $y and $z. I'd say introducing a special syntax for Map
right now is
not ideal.
Rather, we have an opportunity to instead devise a syntax for an abstract map. While we're at it, we might as well do the same for an abstract list. Why should maps have all the fun?
const {List: IList, Map: IMap} = Immutable;
const bar = 43;
const map = IMap#{"foo": 42, bar: 44}; // keys "foo" and 43
const list = IList#[4, 5, 6, 7, Map#{map: "why not?"}]; // 5th element is
a Map with one key, which is the Immutable.Map above
const weakMap = WeakMap#{map: "It's an Immutable", list: "Also Immutable"};
// WeakMap keys are the objects map and list
It could desugar as, for the sake of example:
Foo#{key: value, ...}
➔
Foo[Symbol.literalOf]([[key, value], ...][Symbol.iterator]())
and
Foo#[value, ...]
➔
Foo[Symbol.literalOf]([value, ...][Symbol.iterator]())
The nice thing about this is it's extensible and future proofs the language
a little bit. The actual arrays need not exist if engines choose to
implement this more efficiently - the syntax just results in an iterator
which yields the elements of the literal. The only difference between the
[]
and the {}
notation ise that the {}
notation enforces
syntactically valid key-value pairs and are a little less heavy on brackets.
I know literally every proposal ever these days seems to claim the #
symbol now, so that's clearly an issue to contend with... :)
Alex
I agree this is pretty important. Using actual maps really frees up a lot of complexity, but the syntax is cumbersome to say the least. Whatever the decided syntax, bare words as string keys is a really bad idea IMO. The key syntax should be parsed as an expression, like the values are, and like they are in basically every other language. Another outstanding issue is that we might want the syntax for `Immutable.Map`, or `WeakMap`, or `MapTwoPointOh` that improves deficiency $x, $y and $z. I'd say introducing a special syntax for `Map` right now is not ideal. Rather, we have an opportunity to instead devise a syntax for an abstract map. While we're at it, we might as well do the same for an abstract list. Why should maps have all the fun? ``` const {List: IList, Map: IMap} = Immutable; const bar = 43; const map = IMap#{"foo": 42, bar: 44}; // keys "foo" and 43 const list = IList#[4, 5, 6, 7, Map#{map: "why not?"}]; // 5th element is a Map with one key, which is the Immutable.Map above const weakMap = WeakMap#{map: "It's an Immutable", list: "Also Immutable"}; // WeakMap keys are the objects map and list ``` It could desugar as, for the sake of example: ``` Foo#{key: value, ...} ➔ Foo[Symbol.literalOf]([[key, value], ...][Symbol.iterator]()) ``` and ``` Foo#[value, ...] ➔ Foo[Symbol.literalOf]([value, ...][Symbol.iterator]()) ``` The nice thing about this is it's extensible and future proofs the language a little bit. The actual arrays need not exist if engines choose to implement this more efficiently - the syntax just results in an iterator which yields the elements of the literal. The only difference between the `[]` and the `{}` notation ise that the `{}` notation enforces syntactically valid key-value pairs and are a little less heavy on brackets. I know literally every proposal ever these days seems to claim the `#` symbol now, so that's clearly an issue to contend with... :) Alex On 27 October 2015 at 22:55, Mohsen Azimi <me at azimi.me> wrote: > I'm using Maps a lot now and I was thinking why there is no "easy" way of > declaring them like objects and arrays. > > I'm sure I'm not the first one who came up with the idea of having Map > literal declaration. There are many ways we can introduce new syntax for > declaring Maps via a literal syntax such as: > > ``` > let map = [window: 'window', document: 'document']; > ``` > or > ``` > let map = {{window: 'window', document: 'document'}} > ``` > and possibly many more. > > I searched the discussions but couldn't find a topic on this. Have you > discussed this before? > > _______________________________________________ > 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/20151027/52ab85e2/attachment-0001.html>
fwiw, my Object.entries proposal (
ljharb/proposal-object-values-entries ) would allow you
to do: new Map(Object.entries({ a: 'b', b: 'c' }))
.
fwiw, my Object.entries proposal ( https://github.com/ljharb/proposal-object-values-entries ) would allow you to do: `new Map(Object.entries({ a: 'b', b: 'c' }))`. On Tue, Oct 27, 2015 at 4:36 PM, Alexander Jones <alex at weej.com> wrote: > I agree this is pretty important. Using actual maps really frees up a lot > of complexity, but the syntax is cumbersome to say the least. > > Whatever the decided syntax, bare words as string keys is a really bad > idea IMO. The key syntax should be parsed as an expression, like the values > are, and like they are in basically every other language. > > Another outstanding issue is that we might want the syntax for > `Immutable.Map`, or `WeakMap`, or `MapTwoPointOh` that improves deficiency > $x, $y and $z. I'd say introducing a special syntax for `Map` right now is > not ideal. > > Rather, we have an opportunity to instead devise a syntax for an abstract > map. While we're at it, we might as well do the same for an abstract list. > Why should maps have all the fun? > > ``` > const {List: IList, Map: IMap} = Immutable; > const bar = 43; > const map = IMap#{"foo": 42, bar: 44}; // keys "foo" and 43 > const list = IList#[4, 5, 6, 7, Map#{map: "why not?"}]; // 5th element is > a Map with one key, which is the Immutable.Map above > const weakMap = WeakMap#{map: "It's an Immutable", list: "Also > Immutable"}; // WeakMap keys are the objects map and list > ``` > > It could desugar as, for the sake of example: > > ``` > Foo#{key: value, ...} > ➔ > Foo[Symbol.literalOf]([[key, value], ...][Symbol.iterator]()) > ``` > > and > > ``` > Foo#[value, ...] > ➔ > Foo[Symbol.literalOf]([value, ...][Symbol.iterator]()) > ``` > > The nice thing about this is it's extensible and future proofs the > language a little bit. The actual arrays need not exist if engines choose > to implement this more efficiently - the syntax just results in an iterator > which yields the elements of the literal. The only difference between the > `[]` and the `{}` notation ise that the `{}` notation enforces > syntactically valid key-value pairs and are a little less heavy on brackets. > > I know literally every proposal ever these days seems to claim the `#` > symbol now, so that's clearly an issue to contend with... :) > > Alex > > > On 27 October 2015 at 22:55, Mohsen Azimi <me at azimi.me> wrote: > >> I'm using Maps a lot now and I was thinking why there is no "easy" way of >> declaring them like objects and arrays. >> >> I'm sure I'm not the first one who came up with the idea of having Map >> literal declaration. There are many ways we can introduce new syntax for >> declaring Maps via a literal syntax such as: >> >> ``` >> let map = [window: 'window', document: 'document']; >> ``` >> or >> ``` >> let map = {{window: 'window', document: 'document'}} >> ``` >> and possibly many more. >> >> I searched the discussions but couldn't find a topic on this. Have you >> discussed this before? >> >> _______________________________________________ >> es-discuss mailing list >> es-discuss at mozilla.org >> https://mail.mozilla.org/listinfo/es-discuss >> >> > > _______________________________________________ > es-discuss mailing list > es-discuss at mozilla.org > https://mail.mozilla.org/listinfo/es-discuss > > -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20151027/5b025436/attachment-0001.html>
Quite verbose, harder to optimize and only supports string keys.
Quite verbose, harder to optimize and only supports string keys. On Wednesday, 28 October 2015, Jordan Harband <ljharb at gmail.com> wrote: > fwiw, my Object.entries proposal ( > https://github.com/ljharb/proposal-object-values-entries ) would allow > you to do: `new Map(Object.entries({ a: 'b', b: 'c' }))`. > > On Tue, Oct 27, 2015 at 4:36 PM, Alexander Jones <alex at weej.com > <javascript:_e(%7B%7D,'cvml','alex at weej.com');>> wrote: > >> I agree this is pretty important. Using actual maps really frees up a lot >> of complexity, but the syntax is cumbersome to say the least. >> >> Whatever the decided syntax, bare words as string keys is a really bad >> idea IMO. The key syntax should be parsed as an expression, like the values >> are, and like they are in basically every other language. >> >> Another outstanding issue is that we might want the syntax for >> `Immutable.Map`, or `WeakMap`, or `MapTwoPointOh` that improves deficiency >> $x, $y and $z. I'd say introducing a special syntax for `Map` right now is >> not ideal. >> >> Rather, we have an opportunity to instead devise a syntax for an abstract >> map. While we're at it, we might as well do the same for an abstract list. >> Why should maps have all the fun? >> >> ``` >> const {List: IList, Map: IMap} = Immutable; >> const bar = 43; >> const map = IMap#{"foo": 42, bar: 44}; // keys "foo" and 43 >> const list = IList#[4, 5, 6, 7, Map#{map: "why not?"}]; // 5th element >> is a Map with one key, which is the Immutable.Map above >> const weakMap = WeakMap#{map: "It's an Immutable", list: "Also >> Immutable"}; // WeakMap keys are the objects map and list >> ``` >> >> It could desugar as, for the sake of example: >> >> ``` >> Foo#{key: value, ...} >> ➔ >> Foo[Symbol.literalOf]([[key, value], ...][Symbol.iterator]()) >> ``` >> >> and >> >> ``` >> Foo#[value, ...] >> ➔ >> Foo[Symbol.literalOf]([value, ...][Symbol.iterator]()) >> ``` >> >> The nice thing about this is it's extensible and future proofs the >> language a little bit. The actual arrays need not exist if engines choose >> to implement this more efficiently - the syntax just results in an iterator >> which yields the elements of the literal. The only difference between the >> `[]` and the `{}` notation ise that the `{}` notation enforces >> syntactically valid key-value pairs and are a little less heavy on brackets. >> >> I know literally every proposal ever these days seems to claim the `#` >> symbol now, so that's clearly an issue to contend with... :) >> >> Alex >> >> >> On 27 October 2015 at 22:55, Mohsen Azimi <me at azimi.me >> <javascript:_e(%7B%7D,'cvml','me at azimi.me');>> wrote: >> >>> I'm using Maps a lot now and I was thinking why there is no "easy" way >>> of declaring them like objects and arrays. >>> >>> I'm sure I'm not the first one who came up with the idea of having Map >>> literal declaration. There are many ways we can introduce new syntax for >>> declaring Maps via a literal syntax such as: >>> >>> ``` >>> let map = [window: 'window', document: 'document']; >>> ``` >>> or >>> ``` >>> let map = {{window: 'window', document: 'document'}} >>> ``` >>> and possibly many more. >>> >>> I searched the discussions but couldn't find a topic on this. Have you >>> discussed this before? >>> >>> _______________________________________________ >>> es-discuss mailing list >>> es-discuss at mozilla.org >>> <javascript:_e(%7B%7D,'cvml','es-discuss at mozilla.org');> >>> https://mail.mozilla.org/listinfo/es-discuss >>> >>> >> >> _______________________________________________ >> es-discuss mailing list >> es-discuss at mozilla.org >> <javascript:_e(%7B%7D,'cvml','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/20151028/1c33e283/attachment.html>
On Wed, Oct 28, 2015 at 8:36 AM, Alexander Jones <alex at weej.com> wrote:
I agree this is pretty important. Using actual maps really frees up a lot of complexity, but the syntax is cumbersome to say the least.
Whatever the decided syntax, bare words as string keys is a really bad idea IMO. The key syntax should be parsed as an expression, like the values are, and like they are in basically every other language.
Another outstanding issue is that we might want the syntax for
Immutable.Map
, orWeakMap
, orMapTwoPointOh
that improves deficiency $x, $y and $z. I'd say introducing a special syntax forMap
right now is not ideal.
Currently, the "extensible literal syntax" for this isn't that bad:
const bar = 43; const map = Immutable.Map([["foo", 42], [bar, 44]]);
It's a little more verbose because the entries have to be surrounded by [], but hey.
On Wed, Oct 28, 2015 at 8:36 AM, Alexander Jones <alex at weej.com> wrote: > I agree this is pretty important. Using actual maps really frees up a lot of > complexity, but the syntax is cumbersome to say the least. > > Whatever the decided syntax, bare words as string keys is a really bad idea > IMO. The key syntax should be parsed as an expression, like the values are, > and like they are in basically every other language. > > Another outstanding issue is that we might want the syntax for > `Immutable.Map`, or `WeakMap`, or `MapTwoPointOh` that improves deficiency > $x, $y and $z. I'd say introducing a special syntax for `Map` right now is > not ideal. Currently, the "extensible literal syntax" for this isn't that bad: const bar = 43; const map = Immutable.Map([["foo", 42], [bar, 44]]); It's a little more verbose because the entries have to be surrounded by [], but hey. ~TJ
True, but easy to mess up and only be treated to a runtime error. Three nested brackets at the start and end could definitely be better, and this just encourages people to use POJSOs instead. Also not a very uniform interface if you look at how to construct a Map, Set or Immutable.List at present, though admittedly constructor call for the ES6 types would be a partial improvement.
True, but easy to mess up and only be treated to a runtime error. Three nested brackets at the start and end could definitely be better, and this just encourages people to use POJSOs instead. Also not a very uniform interface if you look at how to construct a Map, Set or Immutable.List at present, though admittedly constructor call for the ES6 types would be a partial improvement. On Wednesday, 28 October 2015, Tab Atkins Jr. <jackalmage at gmail.com> wrote: > On Wed, Oct 28, 2015 at 8:36 AM, Alexander Jones <alex at weej.com > <javascript:;>> wrote: > > I agree this is pretty important. Using actual maps really frees up a > lot of > > complexity, but the syntax is cumbersome to say the least. > > > > Whatever the decided syntax, bare words as string keys is a really bad > idea > > IMO. The key syntax should be parsed as an expression, like the values > are, > > and like they are in basically every other language. > > > > Another outstanding issue is that we might want the syntax for > > `Immutable.Map`, or `WeakMap`, or `MapTwoPointOh` that improves > deficiency > > $x, $y and $z. I'd say introducing a special syntax for `Map` right now > is > > not ideal. > > Currently, the "extensible literal syntax" for this isn't that bad: > > const bar = 43; > const map = Immutable.Map([["foo", 42], [bar, 44]]); > > It's a little more verbose because the entries have to be surrounded > by [], but hey. > > ~TJ > -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20151028/e0ab71ad/attachment.html>
const map = IMap#{"foo": 42, bar: 44};
It could desugar as, for the sake of example:
Foo#{key: value, ...} ➔ Foo[Symbol.literalOf]([[key, value], ...][Symbol.iterator]())
I like this proposal. However, Maps should guarantee insertion order when traversing the keys and values and desugaring it like that does not respect this guarantee or more precisely it will lead to (in my opinion) unexpected order of the keys.
Object.keys({1: 6, bar: 'Hello', 2: 8}); // → [ '1', '2', 'bar' ]
If I'm not mistaken this will be same order for {1: 6, bar: 'Hello', 2: 8}[Symbol.iterator]()
.
This implies that:
Map#{1: 6, bar: 'Hello', 2: 8};
Will not have entries in the order [[1, 6], ['bar', 'Hello'], [2,8]]
but
instead [[1,6], [2,8], ['bar','Hello']]
.
This means that possible future destructuring of a Map will be harder to reason about.
2015-10-28 2:21 GMT+01:00 Alexander Jones <alex at weej.com>:
> ``` > const map = IMap#{"foo": 42, bar: 44}; > ``` > It could desugar as, for the sake of example: > > ``` > Foo#{key: value, ...} > ➔ > Foo[Symbol.literalOf]([[key, value], ...][Symbol.iterator]()) > ``` I like this proposal. However, Maps should guarantee insertion order when traversing the keys and values and desugaring it like that does not respect this guarantee or more precisely it will lead to (in my opinion) unexpected order of the keys. ``` Object.keys({1: 6, bar: 'Hello', 2: 8}); // → [ '1', '2', 'bar' ] ``` If I'm not mistaken this will be same order for `{1: 6, bar: 'Hello', 2: 8}[Symbol.iterator]()`. This implies that: ``` Map#{1: 6, bar: 'Hello', 2: 8}; ``` Will not have entries in the order `[[1, 6], ['bar', 'Hello'], [2,8]]` but instead `[[1,6], [2,8], ['bar','Hello']]`. This means that possible future destructuring of a Map will be harder to reason about. 2015-10-28 2:21 GMT+01:00 Alexander Jones <alex at weej.com>: > True, but easy to mess up and only be treated to a runtime error. Three > nested brackets at the start and end could definitely be better, and > this just encourages people to use POJSOs instead. Also not a very uniform > interface if you look at how to construct a Map, Set or Immutable.List at > present, though admittedly constructor call for the ES6 types would be a > partial improvement. > > On Wednesday, 28 October 2015, Tab Atkins Jr. <jackalmage at gmail.com> > wrote: > >> On Wed, Oct 28, 2015 at 8:36 AM, Alexander Jones <alex at weej.com> wrote: >> > I agree this is pretty important. Using actual maps really frees up a >> lot of >> > complexity, but the syntax is cumbersome to say the least. >> > >> > Whatever the decided syntax, bare words as string keys is a really bad >> idea >> > IMO. The key syntax should be parsed as an expression, like the values >> are, >> > and like they are in basically every other language. >> > >> > Another outstanding issue is that we might want the syntax for >> > `Immutable.Map`, or `WeakMap`, or `MapTwoPointOh` that improves >> deficiency >> > $x, $y and $z. I'd say introducing a special syntax for `Map` right now >> is >> > not ideal. >> >> Currently, the "extensible literal syntax" for this isn't that bad: >> >> const bar = 43; >> const map = Immutable.Map([["foo", 42], [bar, 44]]); >> >> It's a little more verbose because the entries have to be surrounded >> by [], but hey. >> >> ~TJ >> > > _______________________________________________ > 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/20151028/067f014d/attachment-0001.html>
Not sure I understand - the desugaring I wrote would absolutely preserve the written ordering because it speaks in terms of an ArrayIterator of key-value pairs. If the map type to which it's applied chooses to forget the ordering then that's fine.
Alex
Hi Victor Not sure I understand - the desugaring I wrote would absolutely preserve the written ordering because it speaks in terms of an ArrayIterator of key-value pairs. If the map type to which it's applied chooses to forget the ordering then that's fine. Alex On Wednesday, 28 October 2015, Viktor Kronvall <viktor.kronvall at gmail.com> wrote: > > ``` > > const map = IMap#{"foo": 42, bar: 44}; > > ``` > > It could desugar as, for the sake of example: > > > > ``` > > Foo#{key: value, ...} > > ➔ > > Foo[Symbol.literalOf]([[key, value], ...][Symbol.iterator]()) > > ``` > > I like this proposal. However, Maps should guarantee insertion order when > traversing the keys and values and desugaring it like that does not respect > this guarantee or more precisely it will lead to (in my opinion) unexpected > order of the keys. > > ``` > Object.keys({1: 6, bar: 'Hello', 2: 8}); // → [ '1', '2', 'bar' ] > ``` > > If I'm not mistaken this will be same order for `{1: 6, bar: 'Hello', 2: > 8}[Symbol.iterator]()`. > > This implies that: > > ``` > Map#{1: 6, bar: 'Hello', 2: 8}; > ``` > > Will not have entries in the order `[[1, 6], ['bar', 'Hello'], [2,8]]` but > instead `[[1,6], [2,8], ['bar','Hello']]`. > > This means that possible future destructuring of a Map will be harder to > reason about. > > > 2015-10-28 2:21 GMT+01:00 Alexander Jones <alex at weej.com > <javascript:_e(%7B%7D,'cvml','alex at weej.com');>>: > >> True, but easy to mess up and only be treated to a runtime error. Three >> nested brackets at the start and end could definitely be better, and >> this just encourages people to use POJSOs instead. Also not a very uniform >> interface if you look at how to construct a Map, Set or Immutable.List at >> present, though admittedly constructor call for the ES6 types would be a >> partial improvement. >> >> On Wednesday, 28 October 2015, Tab Atkins Jr. <jackalmage at gmail.com >> <javascript:_e(%7B%7D,'cvml','jackalmage at gmail.com');>> wrote: >> >>> On Wed, Oct 28, 2015 at 8:36 AM, Alexander Jones <alex at weej.com> wrote: >>> > I agree this is pretty important. Using actual maps really frees up a >>> lot of >>> > complexity, but the syntax is cumbersome to say the least. >>> > >>> > Whatever the decided syntax, bare words as string keys is a really bad >>> idea >>> > IMO. The key syntax should be parsed as an expression, like the values >>> are, >>> > and like they are in basically every other language. >>> > >>> > Another outstanding issue is that we might want the syntax for >>> > `Immutable.Map`, or `WeakMap`, or `MapTwoPointOh` that improves >>> deficiency >>> > $x, $y and $z. I'd say introducing a special syntax for `Map` right >>> now is >>> > not ideal. >>> >>> Currently, the "extensible literal syntax" for this isn't that bad: >>> >>> const bar = 43; >>> const map = Immutable.Map([["foo", 42], [bar, 44]]); >>> >>> It's a little more verbose because the entries have to be surrounded >>> by [], but hey. >>> >>> ~TJ >>> >> >> _______________________________________________ >> es-discuss mailing list >> es-discuss at mozilla.org >> <javascript:_e(%7B%7D,'cvml','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/20151028/c214f4c7/attachment.html>
Hello Alexander,
I see now that I misread your desugaring.
I read:
Map#{1: 6, bar: 'Hello', 2: 8};
as being desugared to:
Map[Symbol.literalOf]({1: 6, bar: 'Hello', 2: 8}[Symbol.iterator]());
But your proposal clearly states that is should be:
Map[Symbol.literalOf]([[1, 6], ['bar', 'Hello'], [2,8]][Symbol.iterator]());
Which would preserve lexical ordering of entries. The fault is completely mine. Sorry.
I like this proposal as it is extensible and not that noisy in syntax.
Using the #
for this doesn't
seem like a bad idea either. People coming from Erlang will be familiar
with this as well.
2015-10-28 10:53 GMT+01:00 Alexander Jones <alex at weej.com>:
Hello Alexander, I see now that I misread your desugaring. I read: ``` Map#{1: 6, bar: 'Hello', 2: 8}; ``` as being desugared to: ``` Map[Symbol.literalOf]({1: 6, bar: 'Hello', 2: 8}[Symbol.iterator]()); ``` But your proposal clearly states that is should be: ``` Map[Symbol.literalOf]([[1, 6], ['bar', 'Hello'], [2,8]][Symbol.iterator]()); ``` Which would preserve lexical ordering of entries. The fault is completely mine. Sorry. I like this proposal as it is extensible and not that noisy in syntax. Using the `#` for this doesn't seem like a bad idea either. People coming from Erlang will be familiar with this as well. 2015-10-28 10:53 GMT+01:00 Alexander Jones <alex at weej.com>: > Hi Victor > > Not sure I understand - the desugaring I wrote would absolutely preserve > the written ordering because it speaks in terms of an ArrayIterator of > key-value pairs. If the map type to which it's applied chooses to forget > the ordering then that's fine. > > Alex > > > On Wednesday, 28 October 2015, Viktor Kronvall <viktor.kronvall at gmail.com> > wrote: > >> > ``` >> > const map = IMap#{"foo": 42, bar: 44}; >> > ``` >> > It could desugar as, for the sake of example: >> > >> > ``` >> > Foo#{key: value, ...} >> > ➔ >> > Foo[Symbol.literalOf]([[key, value], ...][Symbol.iterator]()) >> > ``` >> >> I like this proposal. However, Maps should guarantee insertion order when >> traversing the keys and values and desugaring it like that does not respect >> this guarantee or more precisely it will lead to (in my opinion) unexpected >> order of the keys. >> >> ``` >> Object.keys({1: 6, bar: 'Hello', 2: 8}); // → [ '1', '2', 'bar' ] >> ``` >> >> If I'm not mistaken this will be same order for `{1: 6, bar: 'Hello', 2: >> 8}[Symbol.iterator]()`. >> >> This implies that: >> >> ``` >> Map#{1: 6, bar: 'Hello', 2: 8}; >> ``` >> >> Will not have entries in the order `[[1, 6], ['bar', 'Hello'], [2,8]]` >> but instead `[[1,6], [2,8], ['bar','Hello']]`. >> >> This means that possible future destructuring of a Map will be harder to >> reason about. >> >> >> 2015-10-28 2:21 GMT+01:00 Alexander Jones <alex at weej.com>: >> >>> True, but easy to mess up and only be treated to a runtime error. Three >>> nested brackets at the start and end could definitely be better, and >>> this just encourages people to use POJSOs instead. Also not a very uniform >>> interface if you look at how to construct a Map, Set or Immutable.List at >>> present, though admittedly constructor call for the ES6 types would be a >>> partial improvement. >>> >>> On Wednesday, 28 October 2015, Tab Atkins Jr. <jackalmage at gmail.com> >>> wrote: >>> >>>> On Wed, Oct 28, 2015 at 8:36 AM, Alexander Jones <alex at weej.com> wrote: >>>> > I agree this is pretty important. Using actual maps really frees up a >>>> lot of >>>> > complexity, but the syntax is cumbersome to say the least. >>>> > >>>> > Whatever the decided syntax, bare words as string keys is a really >>>> bad idea >>>> > IMO. The key syntax should be parsed as an expression, like the >>>> values are, >>>> > and like they are in basically every other language. >>>> > >>>> > Another outstanding issue is that we might want the syntax for >>>> > `Immutable.Map`, or `WeakMap`, or `MapTwoPointOh` that improves >>>> deficiency >>>> > $x, $y and $z. I'd say introducing a special syntax for `Map` right >>>> now is >>>> > not ideal. >>>> >>>> Currently, the "extensible literal syntax" for this isn't that bad: >>>> >>>> const bar = 43; >>>> const map = Immutable.Map([["foo", 42], [bar, 44]]); >>>> >>>> It's a little more verbose because the entries have to be surrounded >>>> by [], but hey. >>>> >>>> ~TJ >>>> >>> >>> _______________________________________________ >>> 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/20151028/ba2416d8/attachment.html>
Ok, thanks for clarifying. Not only does it preserve order but it also
permits non-string keys. You're still missing one detail which is that
bar
would actually be a variable not a string key.
Another example to clarify that the key part would be an expression:
Map#{foo(42) + 7: "bar"}
I prefer this over the precedent set by object literals which would require that [] are used around a key expression ("computed key") simply due to relieving the syntax noise, which is what this idea is all about. Also, this is how it works in Python and I make no apologies about the similarities ;)
Alex
Ok, thanks for clarifying. Not only does it preserve order but it also permits non-string keys. You're still missing one detail which is that `bar` would actually be a variable not a string key. Another example to clarify that the key part would be an expression: ``` Map#{foo(42) + 7: "bar"} ``` I prefer this over the precedent set by object literals which would require that [] are used around a key expression ("computed key") simply due to relieving the syntax noise, which is what this idea is all about. Also, this is how it works in Python and I make no apologies about the similarities ;) Alex On Wednesday, 28 October 2015, Viktor Kronvall <viktor.kronvall at gmail.com> wrote: > Hello Alexander, > > I see now that I misread your desugaring. > > I read: > > ``` > Map#{1: 6, bar: 'Hello', 2: 8}; > ``` > as being desugared to: > > ``` > Map[Symbol.literalOf]({1: 6, bar: 'Hello', 2: 8}[Symbol.iterator]()); > ``` > > But your proposal clearly states that is should be: > > ``` > Map[Symbol.literalOf]([[1, 6], ['bar', 'Hello'], > [2,8]][Symbol.iterator]()); > ``` > > Which would preserve lexical ordering of entries. The fault is completely > mine. Sorry. > > I like this proposal as it is extensible and not that noisy in syntax. > Using the `#` for this doesn't > seem like a bad idea either. People coming from Erlang will be familiar > with this as well. > > > 2015-10-28 10:53 GMT+01:00 Alexander Jones <alex at weej.com > <javascript:_e(%7B%7D,'cvml','alex at weej.com');>>: > >> Hi Victor >> >> Not sure I understand - the desugaring I wrote would absolutely preserve >> the written ordering because it speaks in terms of an ArrayIterator of >> key-value pairs. If the map type to which it's applied chooses to forget >> the ordering then that's fine. >> >> Alex >> >> >> On Wednesday, 28 October 2015, Viktor Kronvall <viktor.kronvall at gmail.com >> <javascript:_e(%7B%7D,'cvml','viktor.kronvall at gmail.com');>> wrote: >> >>> > ``` >>> > const map = IMap#{"foo": 42, bar: 44}; >>> > ``` >>> > It could desugar as, for the sake of example: >>> > >>> > ``` >>> > Foo#{key: value, ...} >>> > ➔ >>> > Foo[Symbol.literalOf]([[key, value], ...][Symbol.iterator]()) >>> > ``` >>> >>> I like this proposal. However, Maps should guarantee insertion order >>> when traversing the keys and values and desugaring it like that does not >>> respect this guarantee or more precisely it will lead to (in my opinion) >>> unexpected order of the keys. >>> >>> ``` >>> Object.keys({1: 6, bar: 'Hello', 2: 8}); // → [ '1', '2', 'bar' ] >>> ``` >>> >>> If I'm not mistaken this will be same order for `{1: 6, bar: 'Hello', 2: >>> 8}[Symbol.iterator]()`. >>> >>> This implies that: >>> >>> ``` >>> Map#{1: 6, bar: 'Hello', 2: 8}; >>> ``` >>> >>> Will not have entries in the order `[[1, 6], ['bar', 'Hello'], [2,8]]` >>> but instead `[[1,6], [2,8], ['bar','Hello']]`. >>> >>> This means that possible future destructuring of a Map will be harder to >>> reason about. >>> >>> >>> 2015-10-28 2:21 GMT+01:00 Alexander Jones <alex at weej.com>: >>> >>>> True, but easy to mess up and only be treated to a runtime error. Three >>>> nested brackets at the start and end could definitely be better, and >>>> this just encourages people to use POJSOs instead. Also not a very uniform >>>> interface if you look at how to construct a Map, Set or Immutable.List at >>>> present, though admittedly constructor call for the ES6 types would be a >>>> partial improvement. >>>> >>>> On Wednesday, 28 October 2015, Tab Atkins Jr. <jackalmage at gmail.com> >>>> wrote: >>>> >>>>> On Wed, Oct 28, 2015 at 8:36 AM, Alexander Jones <alex at weej.com> >>>>> wrote: >>>>> > I agree this is pretty important. Using actual maps really frees up >>>>> a lot of >>>>> > complexity, but the syntax is cumbersome to say the least. >>>>> > >>>>> > Whatever the decided syntax, bare words as string keys is a really >>>>> bad idea >>>>> > IMO. The key syntax should be parsed as an expression, like the >>>>> values are, >>>>> > and like they are in basically every other language. >>>>> > >>>>> > Another outstanding issue is that we might want the syntax for >>>>> > `Immutable.Map`, or `WeakMap`, or `MapTwoPointOh` that improves >>>>> deficiency >>>>> > $x, $y and $z. I'd say introducing a special syntax for `Map` right >>>>> now is >>>>> > not ideal. >>>>> >>>>> Currently, the "extensible literal syntax" for this isn't that bad: >>>>> >>>>> const bar = 43; >>>>> const map = Immutable.Map([["foo", 42], [bar, 44]]); >>>>> >>>>> It's a little more verbose because the entries have to be surrounded >>>>> by [], but hey. >>>>> >>>>> ~TJ >>>>> >>>> >>>> _______________________________________________ >>>> 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/20151028/913714ac/attachment-0001.html>
Alexander Jones wrote:
Ok, thanks for clarifying. Not only does it preserve order but it also permits non-string keys. You're still missing one detail which is that
bar
would actually be a variable not a string key.Another example to clarify that the key part would be an expression:
Map#{foo(42) + 7: "bar"}
I prefer this over the precedent set by object literals which would require that [] are used around a key expression ("computed key") simply
I, on the other hand, think it should match object literals completely. So your example would be
Map#{[foo(42)+7]: "bar"}
Yes, it's just for consistency and less WTF moment while learning the details.
OTOH, there could be consistent contraproposal of:
Object#{foo(42) + 7: "bar"}
null#{foo(42) + 7: "bar"}
#{foo(42) + 7: "bar"}
where the first is equivalent to {[foo(42)+7]: "bar"}, the second is pure container (Object.create(null)) filled with properties, and the third is the default case, but I don't know which of the previous two - the first is probably less confusing, though the feels more clean.
Alexander Jones wrote: > Ok, thanks for clarifying. Not only does it preserve order but it also > permits non-string keys. You're still missing one detail which is that > `bar` would actually be a variable not a string key. > > Another example to clarify that the key part would be an expression: > > ``` > Map#{foo(42) + 7: "bar"} > ``` > > I prefer this over the precedent set by object literals which would > require that [] are used around a key expression ("computed key") simply I, on the other hand, think it should match object literals completely. So your example would be ``` Map#{[foo(42)+7]: "bar"} ``` Yes, it's just for consistency and less WTF moment while learning the details. OTOH, there could be consistent contraproposal of: ``` Object#{foo(42) + 7: "bar"} null#{foo(42) + 7: "bar"} #{foo(42) + 7: "bar"} ``` where the first is equivalent to {[foo(42)+7]: "bar"}, the second is pure container (Object.create(null)) filled with properties, and the third is the default case, but I don't know which of the previous two - the first is probably less confusing, though the feels more clean. > due to relieving the syntax noise, which is what this idea is all about. > Also, this is how it works in Python and I make no apologies about the > similarities ;) > > Alex > > On Wednesday, 28 October 2015, Viktor Kronvall > <viktor.kronvall at gmail.com <mailto:viktor.kronvall at gmail.com>> wrote: > > Hello Alexander, > > I see now that I misread your desugaring. > > I read: > > ``` > Map#{1: 6, bar: 'Hello', 2: 8}; > ``` > as being desugared to: > > ``` > Map[Symbol.literalOf]({1: 6, bar: 'Hello', 2: 8}[Symbol.iterator]()); > ``` > > But your proposal clearly states that is should be: > > ``` > Map[Symbol.literalOf]([[1, 6], ['bar', 'Hello'], > [2,8]][Symbol.iterator]()); > ``` > > Which would preserve lexical ordering of entries. The fault is > completely mine. Sorry. > > I like this proposal as it is extensible and not that noisy in > syntax. Using the `#` for this doesn't > seem like a bad idea either. People coming from Erlang will be > familiar with this as well. > > > 2015-10-28 10:53 GMT+01:00 Alexander Jones <alex at weej.com > <javascript:_e(%7B%7D,'cvml','alex at weej.com');>>: > > Hi Victor > > Not sure I understand - the desugaring I wrote would absolutely > preserve the written ordering because it speaks in terms of an > ArrayIterator of key-value pairs. If the map type to which it's > applied chooses to forget the ordering then that's fine. > > Alex > > > On Wednesday, 28 October 2015, Viktor Kronvall > <viktor.kronvall at gmail.com > <javascript:_e(%7B%7D,'cvml','viktor.kronvall at gmail.com');>> wrote: > > > ``` > > const map = IMap#{"foo": 42, bar: 44}; > > ``` > > It could desugar as, for the sake of example: > > > > ``` > > Foo#{key: value, ...} > > ➔ > > Foo[Symbol.literalOf]([[key, value], ...][Symbol.iterator]()) > > ``` > > I like this proposal. However, Maps should guarantee > insertion order when traversing the keys and values and > desugaring it like that does not respect this guarantee or > more precisely it will lead to (in my opinion) unexpected > order of the keys. > > ``` > Object.keys({1: 6, bar: 'Hello', 2: 8}); // → [ '1', '2', > 'bar' ] > ``` > > If I'm not mistaken this will be same order for `{1: 6, bar: > 'Hello', 2: 8}[Symbol.iterator]()`. > > This implies that: > > ``` > Map#{1: 6, bar: 'Hello', 2: 8}; > ``` > > Will not have entries in the order `[[1, 6], ['bar', > 'Hello'], [2,8]]` but instead `[[1,6], [2,8], ['bar','Hello']]`. > > This means that possible future destructuring of a Map will > be harder to reason about. > > > 2015-10-28 2:21 GMT+01:00 Alexander Jones <alex at weej.com>: > > True, but easy to mess up and only be treated to a > runtime error. Three nested brackets at the start and > end could definitely be better, and this just encourages > people to use POJSOs instead. Also not a very uniform > interface if you look at how to construct a Map, Set or > Immutable.List at present, though admittedly constructor > call for the ES6 types would be a partial improvement. > > On Wednesday, 28 October 2015, Tab Atkins Jr. > <jackalmage at gmail.com> wrote: > > On Wed, Oct 28, 2015 at 8:36 AM, Alexander Jones > <alex at weej.com> wrote: > > I agree this is pretty important. Using actual > maps really frees up a lot of > > complexity, but the syntax is cumbersome to say > the least. > > > > Whatever the decided syntax, bare words as string > keys is a really bad idea > > IMO. The key syntax should be parsed as an > expression, like the values are, > > and like they are in basically every other language. > > > > Another outstanding issue is that we might want > the syntax for > > `Immutable.Map`, or `WeakMap`, or `MapTwoPointOh` > that improves deficiency > > $x, $y and $z. I'd say introducing a special > syntax for `Map` right now is > > not ideal. > > Currently, the "extensible literal syntax" for this > isn't that bad: > > const bar = 43; > const map = Immutable.Map([["foo", 42], [bar, 44]]); > > It's a little more verbose because the entries have > to be surrounded > by [], but hey. > > ~TJ > > > _______________________________________________ > es-discuss mailing list > es-discuss at mozilla.org > https://mail.mozilla.org/listinfo/es-discuss > > > > _______________________________________________ > es-discuss mailing list > es-discuss at mozilla.org > https://mail.mozilla.org/listinfo/es-discuss
Herby Vojčík wrote:
OTOH, there could be consistent contraproposal of:
Object#{foo(42) + 7: "bar"} null#{foo(42) + 7: "bar"} #{foo(42) + 7: "bar"}
where the first is equivalent to {[foo(42)+7]: "bar"}, the second is pure container (Object.create(null)) filled with properties, and the third is the default case, but I don't know which of the previous two - the first is probably less confusing, though the feels more clean. ... though the second feels more ...
Herby Vojčík wrote: > OTOH, there could be consistent contraproposal of: > > ``` > Object#{foo(42) + 7: "bar"} > null#{foo(42) + 7: "bar"} > #{foo(42) + 7: "bar"} > ``` > > where the first is equivalent to {[foo(42)+7]: "bar"}, the second is > pure container (Object.create(null)) filled with properties, and the > third is the default case, but I don't know which of the previous two - > the first is probably less confusing, though the feels more clean. ... though the second feels more ...
Agree with your concerns about symmetry with object literals, but many of the uses of maps benefit from having non string keys, and in such case generally everything would involve wrapping in []. Trying to use an Array as a key would be quite ugly with the extra squares required
const precachedResults = MyMap#{[[1, 2, 3]]: [1, 4, 9]}
vs
const precachedResults = MyMap#{[1, 2, 3]: [1, 4, 9]}
Perhaps a middle ground could be that if you want to use an expression that would otherwise be a bare word, you enclose in parens. The visual binding of the colon is deceptive anyway, so I tend to do this if the key expression contains a space:
MyMap#{1 + 2 + 3: 6}
vs.
MyMap#{(1 + 2 + 3): 6}
But I think I still prefer that the parsing for the key part is just standard expression evaluation, personally, and the POJSO literal barewords remain the only special case.
Indeed,
Object#{1: "one", Symbol(): "sym"}
Could Object-key-ify the keys, i.e. turn them into strings if not
symbols, and Just Work (but a default implementation on the Object
prototype is questionable!). That said I'm not sure we should be using
Object for this kind of thing. At this point I don't know what a raw
#{}
should produce... There may be a better use case for it in the
future, horrible ASI complexities notwithstanding.
Alex
Hi Herby Agree with your concerns about symmetry with object literals, but many of the uses of maps benefit from having non string keys, and in such case generally everything would involve wrapping in []. Trying to use an Array as a key would be quite ugly with the extra squares required ``` const precachedResults = MyMap#{[[1, 2, 3]]: [1, 4, 9]} vs const precachedResults = MyMap#{[1, 2, 3]: [1, 4, 9]} ``` Perhaps a middle ground could be that if you want to use an expression that would otherwise be a bare word, you enclose in parens. The visual binding of the colon is deceptive anyway, so I tend to do this if the key expression contains a space: ``` MyMap#{1 + 2 + 3: 6} vs. MyMap#{(1 + 2 + 3): 6} ``` But I think I still prefer that the parsing for the key part is just standard expression evaluation, personally, and the POJSO literal barewords remain the only special case. Indeed, ``` Object#{1: "one", Symbol(): "sym"} ``` Could Object-key-ify the keys, i.e. turn them into strings if not symbols, and Just Work (but a default implementation on the Object prototype is questionable!). That said I'm not sure we should be using Object for this kind of thing. At this point I don't know what a raw `#{}` should produce... There may be a better use case for it in the future, horrible ASI complexities notwithstanding. Alex On Wednesday, 28 October 2015, Herby Vojčík <herby at mailbox.sk> wrote: > > > Alexander Jones wrote: > >> Ok, thanks for clarifying. Not only does it preserve order but it also >> permits non-string keys. You're still missing one detail which is that >> `bar` would actually be a variable not a string key. >> >> Another example to clarify that the key part would be an expression: >> >> ``` >> Map#{foo(42) + 7: "bar"} >> ``` >> >> I prefer this over the precedent set by object literals which would >> require that [] are used around a key expression ("computed key") simply >> > > I, on the other hand, think it should match object literals completely. So > your example would be > > ``` > Map#{[foo(42)+7]: "bar"} > ``` > > Yes, it's just for consistency and less WTF moment while learning the > details. > > OTOH, there could be consistent contraproposal of: > > ``` > Object#{foo(42) + 7: "bar"} > null#{foo(42) + 7: "bar"} > #{foo(42) + 7: "bar"} > ``` > > where the first is equivalent to {[foo(42)+7]: "bar"}, the second is pure > container (Object.create(null)) filled with properties, and the third is > the default case, but I don't know which of the previous two - the first is > probably less confusing, though the feels more clean. > > due to relieving the syntax noise, which is what this idea is all about. >> Also, this is how it works in Python and I make no apologies about the >> similarities ;) >> >> Alex >> >> On Wednesday, 28 October 2015, Viktor Kronvall >> <viktor.kronvall at gmail.com <mailto:viktor.kronvall at gmail.com>> wrote: >> >> Hello Alexander, >> >> I see now that I misread your desugaring. >> >> I read: >> >> ``` >> Map#{1: 6, bar: 'Hello', 2: 8}; >> ``` >> as being desugared to: >> >> ``` >> Map[Symbol.literalOf]({1: 6, bar: 'Hello', 2: 8}[Symbol.iterator]()); >> ``` >> >> But your proposal clearly states that is should be: >> >> ``` >> Map[Symbol.literalOf]([[1, 6], ['bar', 'Hello'], >> [2,8]][Symbol.iterator]()); >> ``` >> >> Which would preserve lexical ordering of entries. The fault is >> completely mine. Sorry. >> >> I like this proposal as it is extensible and not that noisy in >> syntax. Using the `#` for this doesn't >> seem like a bad idea either. People coming from Erlang will be >> familiar with this as well. >> >> >> 2015-10-28 10:53 GMT+01:00 Alexander Jones <alex at weej.com >> <javascript:_e(%7B%7D,'cvml','alex at weej.com');>>: >> >> Hi Victor >> >> Not sure I understand - the desugaring I wrote would absolutely >> preserve the written ordering because it speaks in terms of an >> ArrayIterator of key-value pairs. If the map type to which it's >> applied chooses to forget the ordering then that's fine. >> >> Alex >> >> >> On Wednesday, 28 October 2015, Viktor Kronvall >> <viktor.kronvall at gmail.com >> <javascript:_e(%7B%7D,'cvml','viktor.kronvall at gmail.com');>> >> wrote: >> >> > ``` >> > const map = IMap#{"foo": 42, bar: 44}; >> > ``` >> > It could desugar as, for the sake of example: >> > >> > ``` >> > Foo#{key: value, ...} >> > ➔ >> > Foo[Symbol.literalOf]([[key, value], >> ...][Symbol.iterator]()) >> > ``` >> >> I like this proposal. However, Maps should guarantee >> insertion order when traversing the keys and values and >> desugaring it like that does not respect this guarantee or >> more precisely it will lead to (in my opinion) unexpected >> order of the keys. >> >> ``` >> Object.keys({1: 6, bar: 'Hello', 2: 8}); // → [ '1', '2', >> 'bar' ] >> ``` >> >> If I'm not mistaken this will be same order for `{1: 6, bar: >> 'Hello', 2: 8}[Symbol.iterator]()`. >> >> This implies that: >> >> ``` >> Map#{1: 6, bar: 'Hello', 2: 8}; >> ``` >> >> Will not have entries in the order `[[1, 6], ['bar', >> 'Hello'], [2,8]]` but instead `[[1,6], [2,8], >> ['bar','Hello']]`. >> >> This means that possible future destructuring of a Map will >> be harder to reason about. >> >> >> 2015-10-28 2:21 GMT+01:00 Alexander Jones <alex at weej.com>: >> >> True, but easy to mess up and only be treated to a >> runtime error. Three nested brackets at the start and >> end could definitely be better, and this just encourages >> people to use POJSOs instead. Also not a very uniform >> interface if you look at how to construct a Map, Set or >> Immutable.List at present, though admittedly constructor >> call for the ES6 types would be a partial improvement. >> >> On Wednesday, 28 October 2015, Tab Atkins Jr. >> <jackalmage at gmail.com> wrote: >> >> On Wed, Oct 28, 2015 at 8:36 AM, Alexander Jones >> <alex at weej.com> wrote: >> > I agree this is pretty important. Using actual >> maps really frees up a lot of >> > complexity, but the syntax is cumbersome to say >> the least. >> > >> > Whatever the decided syntax, bare words as string >> keys is a really bad idea >> > IMO. The key syntax should be parsed as an >> expression, like the values are, >> > and like they are in basically every other >> language. >> > >> > Another outstanding issue is that we might want >> the syntax for >> > `Immutable.Map`, or `WeakMap`, or `MapTwoPointOh` >> that improves deficiency >> > $x, $y and $z. I'd say introducing a special >> syntax for `Map` right now is >> > not ideal. >> >> Currently, the "extensible literal syntax" for this >> isn't that bad: >> >> const bar = 43; >> const map = Immutable.Map([["foo", 42], [bar, 44]]); >> >> It's a little more verbose because the entries have >> to be surrounded >> by [], but hey. >> >> ~TJ >> >> >> _______________________________________________ >> es-discuss mailing list >> es-discuss at mozilla.org >> https://mail.mozilla.org/listinfo/es-discuss >> >> >> >> _______________________________________________ >> es-discuss mailing list >> es-discuss at mozilla.org >> https://mail.mozilla.org/listinfo/es-discuss >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20151028/e17c9e57/attachment-0001.html>
Ah, there is actually a good case for keeping barewords in object literals but removing them from map literals, and that's due to objects accessing string properties as bare words, too. This is almost never the case for other map types.
const o = {foo: 42};
o.foo === 42;
o.bar = 43;
const m = Map#{"foo": 42};
m.get("foo") === 42;
m.set("bar", 43);
Would you agree?
Ah, there is actually a good case for keeping barewords in object literals but removing them from map literals, and that's due to objects accessing string properties as bare words, too. This is almost never the case for other map types. ``` const o = {foo: 42}; o.foo === 42; o.bar = 43; const m = Map#{"foo": 42}; m.get("foo") === 42; m.set("bar", 43); ``` Would you agree? On Wednesday, 28 October 2015, Alexander Jones <alex at weej.com> wrote: > Hi Herby > > Agree with your concerns about symmetry with object literals, but many of > the uses of maps benefit from having non string keys, and in such case > generally everything would involve wrapping in []. Trying to use an Array > as a key would be quite ugly with the extra squares required > > ``` > const precachedResults = MyMap#{[[1, 2, 3]]: [1, 4, 9]} > vs > const precachedResults = MyMap#{[1, 2, 3]: [1, 4, 9]} > ``` > > Perhaps a middle ground could be that if you want to use an expression > that would otherwise be a bare word, you enclose in parens. The visual > binding of the colon is deceptive anyway, so I tend to do this if the key > expression contains a space: > > ``` > MyMap#{1 + 2 + 3: 6} > vs. > MyMap#{(1 + 2 + 3): 6} > ``` > > But I think I still prefer that the parsing for the key part is just > standard expression evaluation, personally, and the POJSO literal barewords > remain the only special case. > > Indeed, > > ``` > Object#{1: "one", Symbol(): "sym"} > ``` > > Could Object-key-ify the keys, i.e. turn them into strings if not > symbols, and Just Work (but a default implementation on the Object > prototype is questionable!). That said I'm not sure we should be using > Object for this kind of thing. At this point I don't know what a raw > `#{}` should produce... There may be a better use case for it in the > future, horrible ASI complexities notwithstanding. > > Alex > > > On Wednesday, 28 October 2015, Herby Vojčík <herby at mailbox.sk > <javascript:_e(%7B%7D,'cvml','herby at mailbox.sk');>> wrote: > >> >> >> Alexander Jones wrote: >> >>> Ok, thanks for clarifying. Not only does it preserve order but it also >>> permits non-string keys. You're still missing one detail which is that >>> `bar` would actually be a variable not a string key. >>> >>> Another example to clarify that the key part would be an expression: >>> >>> ``` >>> Map#{foo(42) + 7: "bar"} >>> ``` >>> >>> I prefer this over the precedent set by object literals which would >>> require that [] are used around a key expression ("computed key") simply >>> >> >> I, on the other hand, think it should match object literals completely. >> So your example would be >> >> ``` >> Map#{[foo(42)+7]: "bar"} >> ``` >> >> Yes, it's just for consistency and less WTF moment while learning the >> details. >> >> OTOH, there could be consistent contraproposal of: >> >> ``` >> Object#{foo(42) + 7: "bar"} >> null#{foo(42) + 7: "bar"} >> #{foo(42) + 7: "bar"} >> ``` >> >> where the first is equivalent to {[foo(42)+7]: "bar"}, the second is pure >> container (Object.create(null)) filled with properties, and the third is >> the default case, but I don't know which of the previous two - the first is >> probably less confusing, though the feels more clean. >> >> due to relieving the syntax noise, which is what this idea is all about. >>> Also, this is how it works in Python and I make no apologies about the >>> similarities ;) >>> >>> Alex >>> >>> On Wednesday, 28 October 2015, Viktor Kronvall >>> <viktor.kronvall at gmail.com <mailto:viktor.kronvall at gmail.com>> wrote: >>> >>> Hello Alexander, >>> >>> I see now that I misread your desugaring. >>> >>> I read: >>> >>> ``` >>> Map#{1: 6, bar: 'Hello', 2: 8}; >>> ``` >>> as being desugared to: >>> >>> ``` >>> Map[Symbol.literalOf]({1: 6, bar: 'Hello', 2: 8}[Symbol.iterator]()); >>> ``` >>> >>> But your proposal clearly states that is should be: >>> >>> ``` >>> Map[Symbol.literalOf]([[1, 6], ['bar', 'Hello'], >>> [2,8]][Symbol.iterator]()); >>> ``` >>> >>> Which would preserve lexical ordering of entries. The fault is >>> completely mine. Sorry. >>> >>> I like this proposal as it is extensible and not that noisy in >>> syntax. Using the `#` for this doesn't >>> seem like a bad idea either. People coming from Erlang will be >>> familiar with this as well. >>> >>> >>> 2015-10-28 10:53 GMT+01:00 Alexander Jones <alex at weej.com >>> <javascript:_e(%7B%7D,'cvml','alex at weej.com');>>: >>> >>> Hi Victor >>> >>> Not sure I understand - the desugaring I wrote would absolutely >>> preserve the written ordering because it speaks in terms of an >>> ArrayIterator of key-value pairs. If the map type to which it's >>> applied chooses to forget the ordering then that's fine. >>> >>> Alex >>> >>> >>> On Wednesday, 28 October 2015, Viktor Kronvall >>> <viktor.kronvall at gmail.com >>> <javascript:_e(%7B%7D,'cvml','viktor.kronvall at gmail.com');>> >>> wrote: >>> >>> > ``` >>> > const map = IMap#{"foo": 42, bar: 44}; >>> > ``` >>> > It could desugar as, for the sake of example: >>> > >>> > ``` >>> > Foo#{key: value, ...} >>> > ➔ >>> > Foo[Symbol.literalOf]([[key, value], >>> ...][Symbol.iterator]()) >>> > ``` >>> >>> I like this proposal. However, Maps should guarantee >>> insertion order when traversing the keys and values and >>> desugaring it like that does not respect this guarantee or >>> more precisely it will lead to (in my opinion) unexpected >>> order of the keys. >>> >>> ``` >>> Object.keys({1: 6, bar: 'Hello', 2: 8}); // → [ '1', '2', >>> 'bar' ] >>> ``` >>> >>> If I'm not mistaken this will be same order for `{1: 6, bar: >>> 'Hello', 2: 8}[Symbol.iterator]()`. >>> >>> This implies that: >>> >>> ``` >>> Map#{1: 6, bar: 'Hello', 2: 8}; >>> ``` >>> >>> Will not have entries in the order `[[1, 6], ['bar', >>> 'Hello'], [2,8]]` but instead `[[1,6], [2,8], >>> ['bar','Hello']]`. >>> >>> This means that possible future destructuring of a Map will >>> be harder to reason about. >>> >>> >>> 2015-10-28 2:21 GMT+01:00 Alexander Jones <alex at weej.com>: >>> >>> True, but easy to mess up and only be treated to a >>> runtime error. Three nested brackets at the start and >>> end could definitely be better, and this just encourages >>> people to use POJSOs instead. Also not a very uniform >>> interface if you look at how to construct a Map, Set or >>> Immutable.List at present, though admittedly constructor >>> call for the ES6 types would be a partial improvement. >>> >>> On Wednesday, 28 October 2015, Tab Atkins Jr. >>> <jackalmage at gmail.com> wrote: >>> >>> On Wed, Oct 28, 2015 at 8:36 AM, Alexander Jones >>> <alex at weej.com> wrote: >>> > I agree this is pretty important. Using actual >>> maps really frees up a lot of >>> > complexity, but the syntax is cumbersome to say >>> the least. >>> > >>> > Whatever the decided syntax, bare words as string >>> keys is a really bad idea >>> > IMO. The key syntax should be parsed as an >>> expression, like the values are, >>> > and like they are in basically every other >>> language. >>> > >>> > Another outstanding issue is that we might want >>> the syntax for >>> > `Immutable.Map`, or `WeakMap`, or `MapTwoPointOh` >>> that improves deficiency >>> > $x, $y and $z. I'd say introducing a special >>> syntax for `Map` right now is >>> > not ideal. >>> >>> Currently, the "extensible literal syntax" for this >>> isn't that bad: >>> >>> const bar = 43; >>> const map = Immutable.Map([["foo", 42], [bar, 44]]); >>> >>> It's a little more verbose because the entries have >>> to be surrounded >>> by [], but hey. >>> >>> ~TJ >>> >>> >>> _______________________________________________ >>> es-discuss mailing list >>> es-discuss at mozilla.org >>> https://mail.mozilla.org/listinfo/es-discuss >>> >>> >>> >>> _______________________________________________ >>> es-discuss mailing list >>> es-discuss at mozilla.org >>> https://mail.mozilla.org/listinfo/es-discuss >>> >> -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20151028/490e0e7f/attachment.html>
When I look at Map#{"foo": 42}
I don't see much difference with new Map([['foo', 42]])
.
Since you can pass expressions there, it's already possible to do it with
current syntax. There is only a bunch of extra brackets([
and ]
) that I
don't like.
When I look at `Map#{"foo": 42}` I don't see much difference with `new Map([['foo', 42]])`. Since you can pass expressions there, it's already possible to do it with current syntax. There is only a bunch of extra brackets(`[` and `]`) that I don't like. On Wed, Oct 28, 2015 at 5:51 AM Alexander Jones <alex at weej.com> wrote: > Ah, there is actually a good case for keeping barewords in object literals > but removing them from map literals, and that's due to objects accessing > string properties as bare words, too. This is almost never the case for > other map types. > > ``` > const o = {foo: 42}; > o.foo === 42; > o.bar = 43; > > const m = Map#{"foo": 42}; > m.get("foo") === 42; > m.set("bar", 43); > ``` > > Would you agree? > > > On Wednesday, 28 October 2015, Alexander Jones <alex at weej.com> wrote: > >> Hi Herby >> >> Agree with your concerns about symmetry with object literals, but many of >> the uses of maps benefit from having non string keys, and in such case >> generally everything would involve wrapping in []. Trying to use an Array >> as a key would be quite ugly with the extra squares required >> >> ``` >> const precachedResults = MyMap#{[[1, 2, 3]]: [1, 4, 9]} >> vs >> const precachedResults = MyMap#{[1, 2, 3]: [1, 4, 9]} >> ``` >> >> Perhaps a middle ground could be that if you want to use an expression >> that would otherwise be a bare word, you enclose in parens. The visual >> binding of the colon is deceptive anyway, so I tend to do this if the key >> expression contains a space: >> >> ``` >> MyMap#{1 + 2 + 3: 6} >> vs. >> MyMap#{(1 + 2 + 3): 6} >> ``` >> >> But I think I still prefer that the parsing for the key part is just >> standard expression evaluation, personally, and the POJSO literal barewords >> remain the only special case. >> >> Indeed, >> >> ``` >> Object#{1: "one", Symbol(): "sym"} >> ``` >> >> Could Object-key-ify the keys, i.e. turn them into strings if not >> symbols, and Just Work (but a default implementation on the Object >> prototype is questionable!). That said I'm not sure we should be using >> Object for this kind of thing. At this point I don't know what a raw >> `#{}` should produce... There may be a better use case for it in the >> future, horrible ASI complexities notwithstanding. >> >> Alex >> >> >> On Wednesday, 28 October 2015, Herby Vojčík <herby at mailbox.sk> wrote: >> >>> >>> >>> Alexander Jones wrote: >>> >>>> Ok, thanks for clarifying. Not only does it preserve order but it also >>>> permits non-string keys. You're still missing one detail which is that >>>> `bar` would actually be a variable not a string key. >>>> >>>> Another example to clarify that the key part would be an expression: >>>> >>>> ``` >>>> Map#{foo(42) + 7: "bar"} >>>> ``` >>>> >>>> I prefer this over the precedent set by object literals which would >>>> require that [] are used around a key expression ("computed key") simply >>>> >>> >>> I, on the other hand, think it should match object literals completely. >>> So your example would be >>> >>> ``` >>> Map#{[foo(42)+7]: "bar"} >>> ``` >>> >>> Yes, it's just for consistency and less WTF moment while learning the >>> details. >>> >>> OTOH, there could be consistent contraproposal of: >>> >>> ``` >>> Object#{foo(42) + 7: "bar"} >>> null#{foo(42) + 7: "bar"} >>> #{foo(42) + 7: "bar"} >>> ``` >>> >>> where the first is equivalent to {[foo(42)+7]: "bar"}, the second is >>> pure container (Object.create(null)) filled with properties, and the third >>> is the default case, but I don't know which of the previous two - the first >>> is probably less confusing, though the feels more clean. >>> >>> due to relieving the syntax noise, which is what this idea is all about. >>>> Also, this is how it works in Python and I make no apologies about the >>>> similarities ;) >>>> >>>> Alex >>>> >>>> On Wednesday, 28 October 2015, Viktor Kronvall >>>> <viktor.kronvall at gmail.com <mailto:viktor.kronvall at gmail.com>> wrote: >>>> >>>> Hello Alexander, >>>> >>>> I see now that I misread your desugaring. >>>> >>>> I read: >>>> >>>> ``` >>>> Map#{1: 6, bar: 'Hello', 2: 8}; >>>> ``` >>>> as being desugared to: >>>> >>>> ``` >>>> Map[Symbol.literalOf]({1: 6, bar: 'Hello', 2: >>>> 8}[Symbol.iterator]()); >>>> ``` >>>> >>>> But your proposal clearly states that is should be: >>>> >>>> ``` >>>> Map[Symbol.literalOf]([[1, 6], ['bar', 'Hello'], >>>> [2,8]][Symbol.iterator]()); >>>> ``` >>>> >>>> Which would preserve lexical ordering of entries. The fault is >>>> completely mine. Sorry. >>>> >>>> I like this proposal as it is extensible and not that noisy in >>>> syntax. Using the `#` for this doesn't >>>> seem like a bad idea either. People coming from Erlang will be >>>> familiar with this as well. >>>> >>>> >>>> 2015-10-28 10:53 GMT+01:00 Alexander Jones <alex at weej.com >>>> <javascript:_e(%7B%7D,'cvml','alex at weej.com');>>: >>>> >>>> Hi Victor >>>> >>>> Not sure I understand - the desugaring I wrote would absolutely >>>> preserve the written ordering because it speaks in terms of an >>>> ArrayIterator of key-value pairs. If the map type to which it's >>>> applied chooses to forget the ordering then that's fine. >>>> >>>> Alex >>>> >>>> >>>> On Wednesday, 28 October 2015, Viktor Kronvall >>>> <viktor.kronvall at gmail.com >>>> <javascript:_e(%7B%7D,'cvml','viktor.kronvall at gmail.com');>> >>>> wrote: >>>> >>>> > ``` >>>> > const map = IMap#{"foo": 42, bar: 44}; >>>> > ``` >>>> > It could desugar as, for the sake of example: >>>> > >>>> > ``` >>>> > Foo#{key: value, ...} >>>> > ➔ >>>> > Foo[Symbol.literalOf]([[key, value], >>>> ...][Symbol.iterator]()) >>>> > ``` >>>> >>>> I like this proposal. However, Maps should guarantee >>>> insertion order when traversing the keys and values and >>>> desugaring it like that does not respect this guarantee or >>>> more precisely it will lead to (in my opinion) unexpected >>>> order of the keys. >>>> >>>> ``` >>>> Object.keys({1: 6, bar: 'Hello', 2: 8}); // → [ '1', '2', >>>> 'bar' ] >>>> ``` >>>> >>>> If I'm not mistaken this will be same order for `{1: 6, bar: >>>> 'Hello', 2: 8}[Symbol.iterator]()`. >>>> >>>> This implies that: >>>> >>>> ``` >>>> Map#{1: 6, bar: 'Hello', 2: 8}; >>>> ``` >>>> >>>> Will not have entries in the order `[[1, 6], ['bar', >>>> 'Hello'], [2,8]]` but instead `[[1,6], [2,8], >>>> ['bar','Hello']]`. >>>> >>>> This means that possible future destructuring of a Map will >>>> be harder to reason about. >>>> >>>> >>>> 2015-10-28 2:21 GMT+01:00 Alexander Jones <alex at weej.com>: >>>> >>>> True, but easy to mess up and only be treated to a >>>> runtime error. Three nested brackets at the start and >>>> end could definitely be better, and this just encourages >>>> people to use POJSOs instead. Also not a very uniform >>>> interface if you look at how to construct a Map, Set or >>>> Immutable.List at present, though admittedly constructor >>>> call for the ES6 types would be a partial improvement. >>>> >>>> On Wednesday, 28 October 2015, Tab Atkins Jr. >>>> <jackalmage at gmail.com> wrote: >>>> >>>> On Wed, Oct 28, 2015 at 8:36 AM, Alexander Jones >>>> <alex at weej.com> wrote: >>>> > I agree this is pretty important. Using actual >>>> maps really frees up a lot of >>>> > complexity, but the syntax is cumbersome to say >>>> the least. >>>> > >>>> > Whatever the decided syntax, bare words as string >>>> keys is a really bad idea >>>> > IMO. The key syntax should be parsed as an >>>> expression, like the values are, >>>> > and like they are in basically every other >>>> language. >>>> > >>>> > Another outstanding issue is that we might want >>>> the syntax for >>>> > `Immutable.Map`, or `WeakMap`, or `MapTwoPointOh` >>>> that improves deficiency >>>> > $x, $y and $z. I'd say introducing a special >>>> syntax for `Map` right now is >>>> > not ideal. >>>> >>>> Currently, the "extensible literal syntax" for this >>>> isn't that bad: >>>> >>>> const bar = 43; >>>> const map = Immutable.Map([["foo", 42], [bar, 44]]); >>>> >>>> It's a little more verbose because the entries have >>>> to be surrounded >>>> by [], but hey. >>>> >>>> ~TJ >>>> >>>> >>>> _______________________________________________ >>>> es-discuss mailing list >>>> es-discuss at mozilla.org >>>> https://mail.mozilla.org/listinfo/es-discuss >>>> >>>> >>>> >>>> _______________________________________________ >>>> es-discuss mailing list >>>> es-discuss at mozilla.org >>>> https://mail.mozilla.org/listinfo/es-discuss >>>> >>> _______________________________________________ > es-discuss mailing list > es-discuss at mozilla.org > https://mail.mozilla.org/listinfo/es-discuss > -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20151028/8db2efb4/attachment-0001.html>
Difference between any proposed here syntax and current state ( new Map([ [1,2], [2,3] ]); ) is..
3 characters + 2 characters/entry.
2015-10-28 17:22 GMT+01:00 Mohsen Azimi <me at azimi.me>:
Difference between any proposed here syntax and current state ( new Map([ [1,2], [2,3] ]); ) is.. 3 characters + 2 characters/entry. 2015-10-28 17:22 GMT+01:00 Mohsen Azimi <me at azimi.me>: > When I look at `Map#{"foo": 42}` I don't see much difference with `new > Map([['foo', 42]])`. > > Since you can pass expressions there, it's already possible to do it with > current syntax. There is only a bunch of extra brackets(`[` and `]`) that I > don't like. > > > On Wed, Oct 28, 2015 at 5:51 AM Alexander Jones <alex at weej.com> wrote: > >> Ah, there is actually a good case for keeping barewords in object >> literals but removing them from map literals, and that's due to objects >> accessing string properties as bare words, too. This is almost never the >> case for other map types. >> >> ``` >> const o = {foo: 42}; >> o.foo === 42; >> o.bar = 43; >> >> const m = Map#{"foo": 42}; >> m.get("foo") === 42; >> m.set("bar", 43); >> ``` >> >> Would you agree? >> >> >> On Wednesday, 28 October 2015, Alexander Jones <alex at weej.com> wrote: >> >>> Hi Herby >>> >>> Agree with your concerns about symmetry with object literals, but many >>> of the uses of maps benefit from having non string keys, and in such case >>> generally everything would involve wrapping in []. Trying to use an Array >>> as a key would be quite ugly with the extra squares required >>> >>> ``` >>> const precachedResults = MyMap#{[[1, 2, 3]]: [1, 4, 9]} >>> vs >>> const precachedResults = MyMap#{[1, 2, 3]: [1, 4, 9]} >>> ``` >>> >>> Perhaps a middle ground could be that if you want to use an expression >>> that would otherwise be a bare word, you enclose in parens. The visual >>> binding of the colon is deceptive anyway, so I tend to do this if the key >>> expression contains a space: >>> >>> ``` >>> MyMap#{1 + 2 + 3: 6} >>> vs. >>> MyMap#{(1 + 2 + 3): 6} >>> ``` >>> >>> But I think I still prefer that the parsing for the key part is just >>> standard expression evaluation, personally, and the POJSO literal barewords >>> remain the only special case. >>> >>> Indeed, >>> >>> ``` >>> Object#{1: "one", Symbol(): "sym"} >>> ``` >>> >>> Could Object-key-ify the keys, i.e. turn them into strings if not >>> symbols, and Just Work (but a default implementation on the Object >>> prototype is questionable!). That said I'm not sure we should be using >>> Object for this kind of thing. At this point I don't know what a raw >>> `#{}` should produce... There may be a better use case for it in the >>> future, horrible ASI complexities notwithstanding. >>> >>> Alex >>> >>> >>> On Wednesday, 28 October 2015, Herby Vojčík <herby at mailbox.sk> wrote: >>> >>>> >>>> >>>> Alexander Jones wrote: >>>> >>>>> Ok, thanks for clarifying. Not only does it preserve order but it also >>>>> permits non-string keys. You're still missing one detail which is that >>>>> `bar` would actually be a variable not a string key. >>>>> >>>>> Another example to clarify that the key part would be an expression: >>>>> >>>>> ``` >>>>> Map#{foo(42) + 7: "bar"} >>>>> ``` >>>>> >>>>> I prefer this over the precedent set by object literals which would >>>>> require that [] are used around a key expression ("computed key") >>>>> simply >>>>> >>>> >>>> I, on the other hand, think it should match object literals completely. >>>> So your example would be >>>> >>>> ``` >>>> Map#{[foo(42)+7]: "bar"} >>>> ``` >>>> >>>> Yes, it's just for consistency and less WTF moment while learning the >>>> details. >>>> >>>> OTOH, there could be consistent contraproposal of: >>>> >>>> ``` >>>> Object#{foo(42) + 7: "bar"} >>>> null#{foo(42) + 7: "bar"} >>>> #{foo(42) + 7: "bar"} >>>> ``` >>>> >>>> where the first is equivalent to {[foo(42)+7]: "bar"}, the second is >>>> pure container (Object.create(null)) filled with properties, and the third >>>> is the default case, but I don't know which of the previous two - the first >>>> is probably less confusing, though the feels more clean. >>>> >>>> due to relieving the syntax noise, which is what this idea is all about. >>>>> Also, this is how it works in Python and I make no apologies about the >>>>> similarities ;) >>>>> >>>>> Alex >>>>> >>>>> On Wednesday, 28 October 2015, Viktor Kronvall >>>>> <viktor.kronvall at gmail.com <mailto:viktor.kronvall at gmail.com>> wrote: >>>>> >>>>> Hello Alexander, >>>>> >>>>> I see now that I misread your desugaring. >>>>> >>>>> I read: >>>>> >>>>> ``` >>>>> Map#{1: 6, bar: 'Hello', 2: 8}; >>>>> ``` >>>>> as being desugared to: >>>>> >>>>> ``` >>>>> Map[Symbol.literalOf]({1: 6, bar: 'Hello', 2: >>>>> 8}[Symbol.iterator]()); >>>>> ``` >>>>> >>>>> But your proposal clearly states that is should be: >>>>> >>>>> ``` >>>>> Map[Symbol.literalOf]([[1, 6], ['bar', 'Hello'], >>>>> [2,8]][Symbol.iterator]()); >>>>> ``` >>>>> >>>>> Which would preserve lexical ordering of entries. The fault is >>>>> completely mine. Sorry. >>>>> >>>>> I like this proposal as it is extensible and not that noisy in >>>>> syntax. Using the `#` for this doesn't >>>>> seem like a bad idea either. People coming from Erlang will be >>>>> familiar with this as well. >>>>> >>>>> >>>>> 2015-10-28 10:53 GMT+01:00 Alexander Jones <alex at weej.com >>>>> <javascript:_e(%7B%7D,'cvml','alex at weej.com');>>: >>>>> >>>>> Hi Victor >>>>> >>>>> Not sure I understand - the desugaring I wrote would absolutely >>>>> preserve the written ordering because it speaks in terms of an >>>>> ArrayIterator of key-value pairs. If the map type to which it's >>>>> applied chooses to forget the ordering then that's fine. >>>>> >>>>> Alex >>>>> >>>>> >>>>> On Wednesday, 28 October 2015, Viktor Kronvall >>>>> <viktor.kronvall at gmail.com >>>>> <javascript:_e(%7B%7D,'cvml','viktor.kronvall at gmail.com');>> >>>>> wrote: >>>>> >>>>> > ``` >>>>> > const map = IMap#{"foo": 42, bar: 44}; >>>>> > ``` >>>>> > It could desugar as, for the sake of example: >>>>> > >>>>> > ``` >>>>> > Foo#{key: value, ...} >>>>> > ➔ >>>>> > Foo[Symbol.literalOf]([[key, value], >>>>> ...][Symbol.iterator]()) >>>>> > ``` >>>>> >>>>> I like this proposal. However, Maps should guarantee >>>>> insertion order when traversing the keys and values and >>>>> desugaring it like that does not respect this guarantee or >>>>> more precisely it will lead to (in my opinion) unexpected >>>>> order of the keys. >>>>> >>>>> ``` >>>>> Object.keys({1: 6, bar: 'Hello', 2: 8}); // → [ '1', '2', >>>>> 'bar' ] >>>>> ``` >>>>> >>>>> If I'm not mistaken this will be same order for `{1: 6, >>>>> bar: >>>>> 'Hello', 2: 8}[Symbol.iterator]()`. >>>>> >>>>> This implies that: >>>>> >>>>> ``` >>>>> Map#{1: 6, bar: 'Hello', 2: 8}; >>>>> ``` >>>>> >>>>> Will not have entries in the order `[[1, 6], ['bar', >>>>> 'Hello'], [2,8]]` but instead `[[1,6], [2,8], >>>>> ['bar','Hello']]`. >>>>> >>>>> This means that possible future destructuring of a Map will >>>>> be harder to reason about. >>>>> >>>>> >>>>> 2015-10-28 2:21 GMT+01:00 Alexander Jones <alex at weej.com>: >>>>> >>>>> True, but easy to mess up and only be treated to a >>>>> runtime error. Three nested brackets at the start and >>>>> end could definitely be better, and this just >>>>> encourages >>>>> people to use POJSOs instead. Also not a very uniform >>>>> interface if you look at how to construct a Map, Set or >>>>> Immutable.List at present, though admittedly >>>>> constructor >>>>> call for the ES6 types would be a partial improvement. >>>>> >>>>> On Wednesday, 28 October 2015, Tab Atkins Jr. >>>>> <jackalmage at gmail.com> wrote: >>>>> >>>>> On Wed, Oct 28, 2015 at 8:36 AM, Alexander Jones >>>>> <alex at weej.com> wrote: >>>>> > I agree this is pretty important. Using actual >>>>> maps really frees up a lot of >>>>> > complexity, but the syntax is cumbersome to say >>>>> the least. >>>>> > >>>>> > Whatever the decided syntax, bare words as >>>>> string >>>>> keys is a really bad idea >>>>> > IMO. The key syntax should be parsed as an >>>>> expression, like the values are, >>>>> > and like they are in basically every other >>>>> language. >>>>> > >>>>> > Another outstanding issue is that we might want >>>>> the syntax for >>>>> > `Immutable.Map`, or `WeakMap`, or >>>>> `MapTwoPointOh` >>>>> that improves deficiency >>>>> > $x, $y and $z. I'd say introducing a special >>>>> syntax for `Map` right now is >>>>> > not ideal. >>>>> >>>>> Currently, the "extensible literal syntax" for this >>>>> isn't that bad: >>>>> >>>>> const bar = 43; >>>>> const map = Immutable.Map([["foo", 42], [bar, >>>>> 44]]); >>>>> >>>>> It's a little more verbose because the entries have >>>>> to be surrounded >>>>> by [], but hey. >>>>> >>>>> ~TJ >>>>> >>>>> >>>>> _______________________________________________ >>>>> es-discuss mailing list >>>>> es-discuss at mozilla.org >>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>> >>>>> >>>>> >>>>> _______________________________________________ >>>>> es-discuss mailing list >>>>> es-discuss at mozilla.org >>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>> >>>> _______________________________________________ >> es-discuss mailing list >> es-discuss at mozilla.org >> https://mail.mozilla.org/listinfo/es-discuss >> > > _______________________________________________ > 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/20151028/213efd09/attachment-0001.html>
I don’t love any of the specific suggestions so far, but saving 3 + 2n keystrokes isn't the point – readability and learnability are. Visually, new Map([[‘foo’, 42]])
is a mess.
I don’t love any of the specific suggestions so far, but saving 3 + 2n keystrokes isn't the point – readability and learnability are. Visually, `new Map([[‘foo’, 42]])` is a mess. > On Oct 28, 2015, at 9:28 AM, Michał Wadas <michalwadas at gmail.com> wrote: > > Difference between any proposed here syntax and current state ( new Map([ [1,2], [2,3] ]); ) is.. > > 3 characters + 2 characters/entry. > > > > > 2015-10-28 17:22 GMT+01:00 Mohsen Azimi <me at azimi.me <mailto:me at azimi.me>>: > When I look at `Map#{"foo": 42}` I don't see much difference with `new Map([['foo', 42]])`. > > Since you can pass expressions there, it's already possible to do it with current syntax. There is only a bunch of extra brackets(`[` and `]`) that I don't like. > > > On Wed, Oct 28, 2015 at 5:51 AM Alexander Jones <alex at weej.com <mailto:alex at weej.com>> wrote: > Ah, there is actually a good case for keeping barewords in object literals but removing them from map literals, and that's due to objects accessing string properties as bare words, too. This is almost never the case for other map types. > > ``` > const o = {foo: 42}; > o.foo === 42; > o.bar = 43; > > const m = Map#{"foo": 42}; > m.get("foo") === 42; > m.set("bar", 43); > ``` > > Would you agree? > > > On Wednesday, 28 October 2015, Alexander Jones <alex at weej.com <mailto:alex at weej.com>> wrote: > Hi Herby > > Agree with your concerns about symmetry with object literals, but many of the uses of maps benefit from having non string keys, and in such case generally everything would involve wrapping in []. Trying to use an Array as a key would be quite ugly with the extra squares required > > ``` > const precachedResults = MyMap#{[[1, 2, 3]]: [1, 4, 9]} > vs > const precachedResults = MyMap#{[1, 2, 3]: [1, 4, 9]} > ``` > > Perhaps a middle ground could be that if you want to use an expression that would otherwise be a bare word, you enclose in parens. The visual binding of the colon is deceptive anyway, so I tend to do this if the key expression contains a space: > > ``` > MyMap#{1 + 2 + 3: 6} > vs. > MyMap#{(1 + 2 + 3): 6} > ``` > > But I think I still prefer that the parsing for the key part is just standard expression evaluation, personally, and the POJSO literal barewords remain the only special case. > > Indeed, > > ``` > Object#{1: "one", Symbol(): "sym"} > ``` > > Could Object-key-ify the keys, i.e. turn them into strings if not symbols, and Just Work (but a default implementation on the Object prototype is questionable!). That said I'm not sure we should be using Object for this kind of thing. At this point I don't know what a raw `#{}` should produce... There may be a better use case for it in the future, horrible ASI complexities notwithstanding. > > Alex > > > On Wednesday, 28 October 2015, Herby Vojčík <herby at mailbox.sk <>> wrote: > > > Alexander Jones wrote: > Ok, thanks for clarifying. Not only does it preserve order but it also > permits non-string keys. You're still missing one detail which is that > `bar` would actually be a variable not a string key. > > Another example to clarify that the key part would be an expression: > > ``` > Map#{foo(42) + 7: "bar"} > ``` > > I prefer this over the precedent set by object literals which would > require that [] are used around a key expression ("computed key") simply > > I, on the other hand, think it should match object literals completely. So your example would be > > ``` > Map#{[foo(42)+7]: "bar"} > ``` > > Yes, it's just for consistency and less WTF moment while learning the details. > > OTOH, there could be consistent contraproposal of: > > ``` > Object#{foo(42) + 7: "bar"} > null#{foo(42) + 7: "bar"} > #{foo(42) + 7: "bar"} > ``` > > where the first is equivalent to {[foo(42)+7]: "bar"}, the second is pure container (Object.create(null)) filled with properties, and the third is the default case, but I don't know which of the previous two - the first is probably less confusing, though the feels more clean. > > due to relieving the syntax noise, which is what this idea is all about. > Also, this is how it works in Python and I make no apologies about the > similarities ;) > > Alex > > On Wednesday, 28 October 2015, Viktor Kronvall > <viktor.kronvall at gmail.com <> <mailto:viktor.kronvall at gmail.com <>>> wrote: > > Hello Alexander, > > I see now that I misread your desugaring. > > I read: > > ``` > Map#{1: 6, bar: 'Hello', 2: 8}; > ``` > as being desugared to: > > ``` > Map[Symbol.literalOf]({1: 6, bar: 'Hello', 2: 8}[Symbol.iterator]()); > ``` > > But your proposal clearly states that is should be: > > ``` > Map[Symbol.literalOf]([[1, 6], ['bar', 'Hello'], > [2,8]][Symbol.iterator]()); > ``` > > Which would preserve lexical ordering of entries. The fault is > completely mine. Sorry. > > I like this proposal as it is extensible and not that noisy in > syntax. Using the `#` for this doesn't > seem like a bad idea either. People coming from Erlang will be > familiar with this as well. > > > 2015-10-28 10:53 GMT+01:00 Alexander Jones <alex at weej.com <> > <javascript:_e(%7B%7D,'cvml','alex at weej.com <>');>>: > > Hi Victor > > Not sure I understand - the desugaring I wrote would absolutely > preserve the written ordering because it speaks in terms of an > ArrayIterator of key-value pairs. If the map type to which it's > applied chooses to forget the ordering then that's fine. > > Alex > > > On Wednesday, 28 October 2015, Viktor Kronvall > <viktor.kronvall at gmail.com <> > <javascript:_e(%7B%7D,'cvml','viktor.kronvall at gmail.com <>');>> wrote: > > > ``` > > const map = IMap#{"foo": 42, bar: 44}; > > ``` > > It could desugar as, for the sake of example: > > > > ``` > > Foo#{key: value, ...} > > ➔ > > Foo[Symbol.literalOf]([[key, value], ...][Symbol.iterator]()) > > ``` > > I like this proposal. However, Maps should guarantee > insertion order when traversing the keys and values and > desugaring it like that does not respect this guarantee or > more precisely it will lead to (in my opinion) unexpected > order of the keys. > > ``` > Object.keys({1: 6, bar: 'Hello', 2: 8}); // → [ '1', '2', > 'bar' ] > ``` > > If I'm not mistaken this will be same order for `{1: 6, bar: > 'Hello', 2: 8}[Symbol.iterator]()`. > > This implies that: > > ``` > Map#{1: 6, bar: 'Hello', 2: 8}; > ``` > > Will not have entries in the order `[[1, 6], ['bar', > 'Hello'], [2,8]]` but instead `[[1,6], [2,8], ['bar','Hello']]`. > > This means that possible future destructuring of a Map will > be harder to reason about. > > > 2015-10-28 2:21 GMT+01:00 Alexander Jones <alex at weej.com <>>: > > True, but easy to mess up and only be treated to a > runtime error. Three nested brackets at the start and > end could definitely be better, and this just encourages > people to use POJSOs instead. Also not a very uniform > interface if you look at how to construct a Map, Set or > Immutable.List at present, though admittedly constructor > call for the ES6 types would be a partial improvement. > > On Wednesday, 28 October 2015, Tab Atkins Jr. > <jackalmage at gmail.com <>> wrote: > > On Wed, Oct 28, 2015 at 8:36 AM, Alexander Jones > <alex at weej.com <>> wrote: > > I agree this is pretty important. Using actual > maps really frees up a lot of > > complexity, but the syntax is cumbersome to say > the least. > > > > Whatever the decided syntax, bare words as string > keys is a really bad idea > > IMO. The key syntax should be parsed as an > expression, like the values are, > > and like they are in basically every other language. > > > > Another outstanding issue is that we might want > the syntax for > > `Immutable.Map`, or `WeakMap`, or `MapTwoPointOh` > that improves deficiency > > $x, $y and $z. I'd say introducing a special > syntax for `Map` right now is > > not ideal. > > Currently, the "extensible literal syntax" for this > isn't that bad: > > const bar = 43; > const map = Immutable.Map([["foo", 42], [bar, 44]]); > > It's a little more verbose because the entries have > to be surrounded > by [], but hey. > > ~TJ > > > _______________________________________________ > es-discuss mailing list > es-discuss at mozilla.org <> > https://mail.mozilla.org/listinfo/es-discuss <https://mail.mozilla.org/listinfo/es-discuss> > > > > _______________________________________________ > es-discuss mailing list > es-discuss at mozilla.org <> > https://mail.mozilla.org/listinfo/es-discuss <https://mail.mozilla.org/listinfo/es-discuss> > _______________________________________________ > es-discuss mailing list > es-discuss at mozilla.org <mailto:es-discuss at mozilla.org> > https://mail.mozilla.org/listinfo/es-discuss <https://mail.mozilla.org/listinfo/es-discuss> > > _______________________________________________ > es-discuss mailing list > es-discuss at mozilla.org <mailto:es-discuss at mozilla.org> > https://mail.mozilla.org/listinfo/es-discuss <https://mail.mozilla.org/listinfo/es-discuss> > > > _______________________________________________ > es-discuss mailing list > es-discuss at mozilla.org > https://mail.mozilla.org/listinfo/es-discuss -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20151028/1dcc595a/attachment-0001.html>
Also I would like to reiterate that errors in the shape of the N-by-2 array are only caught at runtime. That's really not ideal.
Also I would like to reiterate that errors in the shape of the N-by-2 array are only caught at runtime. That's really not ideal. On Wednesday, 28 October 2015, Dave Porter <david_porter at apple.com> wrote: > I don’t love any of the specific suggestions so far, but saving 3 + 2n > keystrokes isn't the point – readability and learnability are. Visually, > `new Map([[‘foo’, 42]])` is a mess. > > On Oct 28, 2015, at 9:28 AM, Michał Wadas <michalwadas at gmail.com > <javascript:_e(%7B%7D,'cvml','michalwadas at gmail.com');>> wrote: > > Difference between any proposed here syntax and current state ( new Map([ > [1,2], [2,3] ]); ) is.. > > 3 characters + 2 characters/entry. > > > > > 2015-10-28 17:22 GMT+01:00 Mohsen Azimi <me at azimi.me > <javascript:_e(%7B%7D,'cvml','me at azimi.me');>>: > >> When I look at `Map#{"foo": 42}` I don't see much difference with `new >> Map([['foo', 42]])`. >> >> Since you can pass expressions there, it's already possible to do it with >> current syntax. There is only a bunch of extra brackets(`[` and `]`) that I >> don't like. >> >> >> On Wed, Oct 28, 2015 at 5:51 AM Alexander Jones <alex at weej.com >> <javascript:_e(%7B%7D,'cvml','alex at weej.com');>> wrote: >> >>> Ah, there is actually a good case for keeping barewords in object >>> literals but removing them from map literals, and that's due to objects >>> accessing string properties as bare words, too. This is almost never the >>> case for other map types. >>> >>> ``` >>> const o = {foo: 42}; >>> o.foo === 42; >>> o.bar = 43; >>> >>> const m = Map#{"foo": 42}; >>> m.get("foo") === 42; >>> m.set("bar", 43); >>> ``` >>> >>> Would you agree? >>> >>> >>> On Wednesday, 28 October 2015, Alexander Jones <alex at weej.com >>> <javascript:_e(%7B%7D,'cvml','alex at weej.com');>> wrote: >>> >>>> Hi Herby >>>> >>>> Agree with your concerns about symmetry with object literals, but many >>>> of the uses of maps benefit from having non string keys, and in such case >>>> generally everything would involve wrapping in []. Trying to use an Array >>>> as a key would be quite ugly with the extra squares required >>>> >>>> ``` >>>> const precachedResults = MyMap#{[[1, 2, 3]]: [1, 4, 9]} >>>> vs >>>> const precachedResults = MyMap#{[1, 2, 3]: [1, 4, 9]} >>>> ``` >>>> >>>> Perhaps a middle ground could be that if you want to use an expression >>>> that would otherwise be a bare word, you enclose in parens. The visual >>>> binding of the colon is deceptive anyway, so I tend to do this if the key >>>> expression contains a space: >>>> >>>> ``` >>>> MyMap#{1 + 2 + 3: 6} >>>> vs. >>>> MyMap#{(1 + 2 + 3): 6} >>>> ``` >>>> >>>> But I think I still prefer that the parsing for the key part is just >>>> standard expression evaluation, personally, and the POJSO literal barewords >>>> remain the only special case. >>>> >>>> Indeed, >>>> >>>> ``` >>>> Object#{1: "one", Symbol(): "sym"} >>>> ``` >>>> >>>> Could Object-key-ify the keys, i.e. turn them into strings if not >>>> symbols, and Just Work (but a default implementation on the Object >>>> prototype is questionable!). That said I'm not sure we should be using >>>> Object for this kind of thing. At this point I don't know what a raw >>>> `#{}` should produce... There may be a better use case for it in the >>>> future, horrible ASI complexities notwithstanding. >>>> >>>> Alex >>>> >>>> >>>> On Wednesday, 28 October 2015, Herby Vojčík <herby at mailbox.sk> wrote: >>>> >>>>> >>>>> >>>>> Alexander Jones wrote: >>>>> >>>>>> Ok, thanks for clarifying. Not only does it preserve order but it also >>>>>> permits non-string keys. You're still missing one detail which is that >>>>>> `bar` would actually be a variable not a string key. >>>>>> >>>>>> Another example to clarify that the key part would be an expression: >>>>>> >>>>>> ``` >>>>>> Map#{foo(42) + 7: "bar"} >>>>>> ``` >>>>>> >>>>>> I prefer this over the precedent set by object literals which would >>>>>> require that [] are used around a key expression ("computed key") >>>>>> simply >>>>>> >>>>> >>>>> I, on the other hand, think it should match object literals >>>>> completely. So your example would be >>>>> >>>>> ``` >>>>> Map#{[foo(42)+7]: "bar"} >>>>> ``` >>>>> >>>>> Yes, it's just for consistency and less WTF moment while learning the >>>>> details. >>>>> >>>>> OTOH, there could be consistent contraproposal of: >>>>> >>>>> ``` >>>>> Object#{foo(42) + 7: "bar"} >>>>> null#{foo(42) + 7: "bar"} >>>>> #{foo(42) + 7: "bar"} >>>>> ``` >>>>> >>>>> where the first is equivalent to {[foo(42)+7]: "bar"}, the second is >>>>> pure container (Object.create(null)) filled with properties, and the third >>>>> is the default case, but I don't know which of the previous two - the first >>>>> is probably less confusing, though the feels more clean. >>>>> >>>>> due to relieving the syntax noise, which is what this idea is all >>>>>> about. >>>>>> Also, this is how it works in Python and I make no apologies about the >>>>>> similarities ;) >>>>>> >>>>>> Alex >>>>>> >>>>>> On Wednesday, 28 October 2015, Viktor Kronvall >>>>>> <viktor.kronvall at gmail.com <mailto:viktor.kronvall at gmail.com>> wrote: >>>>>> >>>>>> Hello Alexander, >>>>>> >>>>>> I see now that I misread your desugaring. >>>>>> >>>>>> I read: >>>>>> >>>>>> ``` >>>>>> Map#{1: 6, bar: 'Hello', 2: 8}; >>>>>> ``` >>>>>> as being desugared to: >>>>>> >>>>>> ``` >>>>>> Map[Symbol.literalOf]({1: 6, bar: 'Hello', 2: >>>>>> 8}[Symbol.iterator]()); >>>>>> ``` >>>>>> >>>>>> But your proposal clearly states that is should be: >>>>>> >>>>>> ``` >>>>>> Map[Symbol.literalOf]([[1, 6], ['bar', 'Hello'], >>>>>> [2,8]][Symbol.iterator]()); >>>>>> ``` >>>>>> >>>>>> Which would preserve lexical ordering of entries. The fault is >>>>>> completely mine. Sorry. >>>>>> >>>>>> I like this proposal as it is extensible and not that noisy in >>>>>> syntax. Using the `#` for this doesn't >>>>>> seem like a bad idea either. People coming from Erlang will be >>>>>> familiar with this as well. >>>>>> >>>>>> >>>>>> 2015-10-28 10:53 GMT+01:00 Alexander Jones <alex at weej.com >>>>>> <javascript:_e(%7B%7D,'cvml','alex at weej.com');>>: >>>>>> >>>>>> Hi Victor >>>>>> >>>>>> Not sure I understand - the desugaring I wrote would >>>>>> absolutely >>>>>> preserve the written ordering because it speaks in terms of an >>>>>> ArrayIterator of key-value pairs. If the map type to which >>>>>> it's >>>>>> applied chooses to forget the ordering then that's fine. >>>>>> >>>>>> Alex >>>>>> >>>>>> >>>>>> On Wednesday, 28 October 2015, Viktor Kronvall >>>>>> <viktor.kronvall at gmail.com >>>>>> <javascript:_e(%7B%7D,'cvml','viktor.kronvall at gmail.com');>> >>>>>> wrote: >>>>>> >>>>>> > ``` >>>>>> > const map = IMap#{"foo": 42, bar: 44}; >>>>>> > ``` >>>>>> > It could desugar as, for the sake of example: >>>>>> > >>>>>> > ``` >>>>>> > Foo#{key: value, ...} >>>>>> > ➔ >>>>>> > Foo[Symbol.literalOf]([[key, value], >>>>>> ...][Symbol.iterator]()) >>>>>> > ``` >>>>>> >>>>>> I like this proposal. However, Maps should guarantee >>>>>> insertion order when traversing the keys and values and >>>>>> desugaring it like that does not respect this guarantee or >>>>>> more precisely it will lead to (in my opinion) unexpected >>>>>> order of the keys. >>>>>> >>>>>> ``` >>>>>> Object.keys({1: 6, bar: 'Hello', 2: 8}); // → [ '1', '2', >>>>>> 'bar' ] >>>>>> ``` >>>>>> >>>>>> If I'm not mistaken this will be same order for `{1: 6, >>>>>> bar: >>>>>> 'Hello', 2: 8}[Symbol.iterator]()`. >>>>>> >>>>>> This implies that: >>>>>> >>>>>> ``` >>>>>> Map#{1: 6, bar: 'Hello', 2: 8}; >>>>>> ``` >>>>>> >>>>>> Will not have entries in the order `[[1, 6], ['bar', >>>>>> 'Hello'], [2,8]]` but instead `[[1,6], [2,8], >>>>>> ['bar','Hello']]`. >>>>>> >>>>>> This means that possible future destructuring of a Map >>>>>> will >>>>>> be harder to reason about. >>>>>> >>>>>> >>>>>> 2015-10-28 2:21 GMT+01:00 Alexander Jones <alex at weej.com >>>>>> >: >>>>>> >>>>>> True, but easy to mess up and only be treated to a >>>>>> runtime error. Three nested brackets at the start and >>>>>> end could definitely be better, and this just >>>>>> encourages >>>>>> people to use POJSOs instead. Also not a very uniform >>>>>> interface if you look at how to construct a Map, Set >>>>>> or >>>>>> Immutable.List at present, though admittedly >>>>>> constructor >>>>>> call for the ES6 types would be a partial improvement. >>>>>> >>>>>> On Wednesday, 28 October 2015, Tab Atkins Jr. >>>>>> <jackalmage at gmail.com> wrote: >>>>>> >>>>>> On Wed, Oct 28, 2015 at 8:36 AM, Alexander Jones >>>>>> <alex at weej.com> wrote: >>>>>> > I agree this is pretty important. Using actual >>>>>> maps really frees up a lot of >>>>>> > complexity, but the syntax is cumbersome to say >>>>>> the least. >>>>>> > >>>>>> > Whatever the decided syntax, bare words as >>>>>> string >>>>>> keys is a really bad idea >>>>>> > IMO. The key syntax should be parsed as an >>>>>> expression, like the values are, >>>>>> > and like they are in basically every other >>>>>> language. >>>>>> > >>>>>> > Another outstanding issue is that we might want >>>>>> the syntax for >>>>>> > `Immutable.Map`, or `WeakMap`, or >>>>>> `MapTwoPointOh` >>>>>> that improves deficiency >>>>>> > $x, $y and $z. I'd say introducing a special >>>>>> syntax for `Map` right now is >>>>>> > not ideal. >>>>>> >>>>>> Currently, the "extensible literal syntax" for >>>>>> this >>>>>> isn't that bad: >>>>>> >>>>>> const bar = 43; >>>>>> const map = Immutable.Map([["foo", 42], [bar, >>>>>> 44]]); >>>>>> >>>>>> It's a little more verbose because the entries >>>>>> have >>>>>> to be surrounded >>>>>> by [], but hey. >>>>>> >>>>>> ~TJ >>>>>> >>>>>> >>>>>> _______________________________________________ >>>>>> es-discuss mailing list >>>>>> es-discuss at mozilla.org >>>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>>> >>>>>> >>>>>> >>>>>> _______________________________________________ >>>>>> es-discuss mailing list >>>>>> es-discuss at mozilla.org >>>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>>> >>>>> _______________________________________________ >>> es-discuss mailing list >>> es-discuss at mozilla.org >>> <javascript:_e(%7B%7D,'cvml','es-discuss at mozilla.org');> >>> https://mail.mozilla.org/listinfo/es-discuss >>> >> >> _______________________________________________ >> es-discuss mailing list >> es-discuss at mozilla.org >> <javascript:_e(%7B%7D,'cvml','es-discuss at mozilla.org');> >> https://mail.mozilla.org/listinfo/es-discuss >> >> > _______________________________________________ > es-discuss mailing list > es-discuss at mozilla.org > <javascript:_e(%7B%7D,'cvml','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/20151028/f33cc0f6/attachment-0001.html>
Why not make it desugar to a direct function call with a single array of pairs? It's so parsed as a regular object, so shorthands can still be used.
Map#{foo: 1, bar: 2, 3: "baz"}
Map[Symbol.fromHash]([[foo", 1], ["bar", 2], ["3", "baz]])
Object#{foo: 1, bar: 2, 3: "baz"}
Object[Symbol.fromHash]([[foo", 1], ["bar", 2], ["3", "baz]])
Object.null#{foo: 1, bar: 2, 3: "baz"}
Object.null[Symbol.fromHash]([[foo", 1], ["bar", 2], ["3", "baz]])
(bar
doesn't have [[Construct]])
Object#{foo, bar() {}}
Object[Symbol.fromHash]([[foo", foo], ["bar", function () {}]])
And as for implementation, use this:
extend class Map {
static [Symbol.fromHash](pairs) {
return new this(pairs);
}
}
// etc...
function SetKeys(target, pairs) {
for (const [key, value] of pairs) {
target[key] = value
}
return target
}
extend class Object {
static [Symbol.fromHash](pairs) {
return SetKeys({}, pairs)
}
static null(pairs) {
return SetKeys(Object.create(null), pairs)
}
}
Pretty simple IMHO. A helper decorator could even be made.
Why not make it desugar to a direct function call with a single array of pairs? It's so parsed as a regular object, so shorthands can still be used. `Map#{foo: 1, bar: 2, 3: "baz"}` `Map[Symbol.fromHash]([[foo", 1], ["bar", 2], ["3", "baz]])` `Object#{foo: 1, bar: 2, 3: "baz"}` `Object[Symbol.fromHash]([[foo", 1], ["bar", 2], ["3", "baz]])` `Object.null#{foo: 1, bar: 2, 3: "baz"}` `Object.null[Symbol.fromHash]([[foo", 1], ["bar", 2], ["3", "baz]])` (`bar` doesn't have [[Construct]]) `Object#{foo, bar() {}}` `Object[Symbol.fromHash]([[foo", foo], ["bar", function () {}]])` And as for implementation, use this: ```js extend class Map { static [Symbol.fromHash](pairs) { return new this(pairs); } } // etc... function SetKeys(target, pairs) { for (const [key, value] of pairs) { target[key] = value } return target } extend class Object { static [Symbol.fromHash](pairs) { return SetKeys({}, pairs) } static null(pairs) { return SetKeys(Object.create(null), pairs) } } ``` Pretty simple IMHO. A helper decorator could even be made. On Wed, Oct 28, 2015, 14:34 Alexander Jones <alex at weej.com> wrote: > Also I would like to reiterate that errors in the shape of the N-by-2 > array are only caught at runtime. That's really not ideal. > > On Wednesday, 28 October 2015, Dave Porter <david_porter at apple.com> wrote: > >> I don’t love any of the specific suggestions so far, but saving 3 + 2n >> keystrokes isn't the point – readability and learnability are. Visually, >> `new Map([[‘foo’, 42]])` is a mess. >> >> On Oct 28, 2015, at 9:28 AM, Michał Wadas <michalwadas at gmail.com> wrote: >> >> Difference between any proposed here syntax and current state ( new Map([ >> [1,2], [2,3] ]); ) is.. >> >> 3 characters + 2 characters/entry. >> >> >> >> >> 2015-10-28 17:22 GMT+01:00 Mohsen Azimi <me at azimi.me>: >> >>> When I look at `Map#{"foo": 42}` I don't see much difference with `new >>> Map([['foo', 42]])`. >>> >>> Since you can pass expressions there, it's already possible to do it >>> with current syntax. There is only a bunch of extra brackets(`[` and `]`) >>> that I don't like. >>> >>> >>> On Wed, Oct 28, 2015 at 5:51 AM Alexander Jones <alex at weej.com> wrote: >>> >>>> Ah, there is actually a good case for keeping barewords in object >>>> literals but removing them from map literals, and that's due to objects >>>> accessing string properties as bare words, too. This is almost never the >>>> case for other map types. >>>> >>>> ``` >>>> const o = {foo: 42}; >>>> o.foo === 42; >>>> o.bar = 43; >>>> >>>> const m = Map#{"foo": 42}; >>>> m.get("foo") === 42; >>>> m.set("bar", 43); >>>> ``` >>>> >>>> Would you agree? >>>> >>>> >>>> On Wednesday, 28 October 2015, Alexander Jones <alex at weej.com> wrote: >>>> >>>>> Hi Herby >>>>> >>>>> Agree with your concerns about symmetry with object literals, but many >>>>> of the uses of maps benefit from having non string keys, and in such case >>>>> generally everything would involve wrapping in []. Trying to use an Array >>>>> as a key would be quite ugly with the extra squares required >>>>> >>>>> ``` >>>>> const precachedResults = MyMap#{[[1, 2, 3]]: [1, 4, 9]} >>>>> vs >>>>> const precachedResults = MyMap#{[1, 2, 3]: [1, 4, 9]} >>>>> ``` >>>>> >>>>> Perhaps a middle ground could be that if you want to use an expression >>>>> that would otherwise be a bare word, you enclose in parens. The visual >>>>> binding of the colon is deceptive anyway, so I tend to do this if the key >>>>> expression contains a space: >>>>> >>>>> ``` >>>>> MyMap#{1 + 2 + 3: 6} >>>>> vs. >>>>> MyMap#{(1 + 2 + 3): 6} >>>>> ``` >>>>> >>>>> But I think I still prefer that the parsing for the key part is just >>>>> standard expression evaluation, personally, and the POJSO literal barewords >>>>> remain the only special case. >>>>> >>>>> Indeed, >>>>> >>>>> ``` >>>>> Object#{1: "one", Symbol(): "sym"} >>>>> ``` >>>>> >>>>> Could Object-key-ify the keys, i.e. turn them into strings if not >>>>> symbols, and Just Work (but a default implementation on the Object >>>>> prototype is questionable!). That said I'm not sure we should be using >>>>> Object for this kind of thing. At this point I don't know what a raw >>>>> `#{}` should produce... There may be a better use case for it in the >>>>> future, horrible ASI complexities notwithstanding. >>>>> >>>>> Alex >>>>> >>>>> >>>>> On Wednesday, 28 October 2015, Herby Vojčík <herby at mailbox.sk> wrote: >>>>> >>>>>> >>>>>> >>>>>> Alexander Jones wrote: >>>>>> >>>>>>> Ok, thanks for clarifying. Not only does it preserve order but it >>>>>>> also >>>>>>> permits non-string keys. You're still missing one detail which is >>>>>>> that >>>>>>> `bar` would actually be a variable not a string key. >>>>>>> >>>>>>> Another example to clarify that the key part would be an expression: >>>>>>> >>>>>>> ``` >>>>>>> Map#{foo(42) + 7: "bar"} >>>>>>> ``` >>>>>>> >>>>>>> I prefer this over the precedent set by object literals which would >>>>>>> require that [] are used around a key expression ("computed key") >>>>>>> simply >>>>>>> >>>>>> >>>>>> I, on the other hand, think it should match object literals >>>>>> completely. So your example would be >>>>>> >>>>>> ``` >>>>>> Map#{[foo(42)+7]: "bar"} >>>>>> ``` >>>>>> >>>>>> Yes, it's just for consistency and less WTF moment while learning the >>>>>> details. >>>>>> >>>>>> OTOH, there could be consistent contraproposal of: >>>>>> >>>>>> ``` >>>>>> Object#{foo(42) + 7: "bar"} >>>>>> null#{foo(42) + 7: "bar"} >>>>>> #{foo(42) + 7: "bar"} >>>>>> ``` >>>>>> >>>>>> where the first is equivalent to {[foo(42)+7]: "bar"}, the second is >>>>>> pure container (Object.create(null)) filled with properties, and the third >>>>>> is the default case, but I don't know which of the previous two - the first >>>>>> is probably less confusing, though the feels more clean. >>>>>> >>>>>> due to relieving the syntax noise, which is what this idea is all >>>>>>> about. >>>>>>> Also, this is how it works in Python and I make no apologies about >>>>>>> the >>>>>>> similarities ;) >>>>>>> >>>>>>> Alex >>>>>>> >>>>>>> On Wednesday, 28 October 2015, Viktor Kronvall >>>>>>> <viktor.kronvall at gmail.com <mailto:viktor.kronvall at gmail.com>> >>>>>>> wrote: >>>>>>> >>>>>>> Hello Alexander, >>>>>>> >>>>>>> I see now that I misread your desugaring. >>>>>>> >>>>>>> I read: >>>>>>> >>>>>>> ``` >>>>>>> Map#{1: 6, bar: 'Hello', 2: 8}; >>>>>>> ``` >>>>>>> as being desugared to: >>>>>>> >>>>>>> ``` >>>>>>> Map[Symbol.literalOf]({1: 6, bar: 'Hello', 2: >>>>>>> 8}[Symbol.iterator]()); >>>>>>> ``` >>>>>>> >>>>>>> But your proposal clearly states that is should be: >>>>>>> >>>>>>> ``` >>>>>>> Map[Symbol.literalOf]([[1, 6], ['bar', 'Hello'], >>>>>>> [2,8]][Symbol.iterator]()); >>>>>>> ``` >>>>>>> >>>>>>> Which would preserve lexical ordering of entries. The fault is >>>>>>> completely mine. Sorry. >>>>>>> >>>>>>> I like this proposal as it is extensible and not that noisy in >>>>>>> syntax. Using the `#` for this doesn't >>>>>>> seem like a bad idea either. People coming from Erlang will be >>>>>>> familiar with this as well. >>>>>>> >>>>>>> >>>>>>> 2015-10-28 10:53 GMT+01:00 Alexander Jones <alex at weej.com >>>>>>> <javascript:_e(%7B%7D,'cvml','alex at weej.com');>>: >>>>>>> >>>>>>> Hi Victor >>>>>>> >>>>>>> Not sure I understand - the desugaring I wrote would >>>>>>> absolutely >>>>>>> preserve the written ordering because it speaks in terms of >>>>>>> an >>>>>>> ArrayIterator of key-value pairs. If the map type to which >>>>>>> it's >>>>>>> applied chooses to forget the ordering then that's fine. >>>>>>> >>>>>>> Alex >>>>>>> >>>>>>> >>>>>>> On Wednesday, 28 October 2015, Viktor Kronvall >>>>>>> <viktor.kronvall at gmail.com >>>>>>> <javascript:_e(%7B%7D,'cvml','viktor.kronvall at gmail.com');>> >>>>>>> wrote: >>>>>>> >>>>>>> > ``` >>>>>>> > const map = IMap#{"foo": 42, bar: 44}; >>>>>>> > ``` >>>>>>> > It could desugar as, for the sake of example: >>>>>>> > >>>>>>> > ``` >>>>>>> > Foo#{key: value, ...} >>>>>>> > ➔ >>>>>>> > Foo[Symbol.literalOf]([[key, value], >>>>>>> ...][Symbol.iterator]()) >>>>>>> > ``` >>>>>>> >>>>>>> I like this proposal. However, Maps should guarantee >>>>>>> insertion order when traversing the keys and values and >>>>>>> desugaring it like that does not respect this guarantee >>>>>>> or >>>>>>> more precisely it will lead to (in my opinion) unexpected >>>>>>> order of the keys. >>>>>>> >>>>>>> ``` >>>>>>> Object.keys({1: 6, bar: 'Hello', 2: 8}); // → [ '1', '2', >>>>>>> 'bar' ] >>>>>>> ``` >>>>>>> >>>>>>> If I'm not mistaken this will be same order for `{1: 6, >>>>>>> bar: >>>>>>> 'Hello', 2: 8}[Symbol.iterator]()`. >>>>>>> >>>>>>> This implies that: >>>>>>> >>>>>>> ``` >>>>>>> Map#{1: 6, bar: 'Hello', 2: 8}; >>>>>>> ``` >>>>>>> >>>>>>> Will not have entries in the order `[[1, 6], ['bar', >>>>>>> 'Hello'], [2,8]]` but instead `[[1,6], [2,8], >>>>>>> ['bar','Hello']]`. >>>>>>> >>>>>>> This means that possible future destructuring of a Map >>>>>>> will >>>>>>> be harder to reason about. >>>>>>> >>>>>>> >>>>>>> 2015-10-28 2:21 GMT+01:00 Alexander Jones <alex at weej.com >>>>>>> >: >>>>>>> >>>>>>> True, but easy to mess up and only be treated to a >>>>>>> runtime error. Three nested brackets at the start and >>>>>>> end could definitely be better, and this just >>>>>>> encourages >>>>>>> people to use POJSOs instead. Also not a very uniform >>>>>>> interface if you look at how to construct a Map, Set >>>>>>> or >>>>>>> Immutable.List at present, though admittedly >>>>>>> constructor >>>>>>> call for the ES6 types would be a partial >>>>>>> improvement. >>>>>>> >>>>>>> On Wednesday, 28 October 2015, Tab Atkins Jr. >>>>>>> <jackalmage at gmail.com> wrote: >>>>>>> >>>>>>> On Wed, Oct 28, 2015 at 8:36 AM, Alexander Jones >>>>>>> <alex at weej.com> wrote: >>>>>>> > I agree this is pretty important. Using actual >>>>>>> maps really frees up a lot of >>>>>>> > complexity, but the syntax is cumbersome to >>>>>>> say >>>>>>> the least. >>>>>>> > >>>>>>> > Whatever the decided syntax, bare words as >>>>>>> string >>>>>>> keys is a really bad idea >>>>>>> > IMO. The key syntax should be parsed as an >>>>>>> expression, like the values are, >>>>>>> > and like they are in basically every other >>>>>>> language. >>>>>>> > >>>>>>> > Another outstanding issue is that we might >>>>>>> want >>>>>>> the syntax for >>>>>>> > `Immutable.Map`, or `WeakMap`, or >>>>>>> `MapTwoPointOh` >>>>>>> that improves deficiency >>>>>>> > $x, $y and $z. I'd say introducing a special >>>>>>> syntax for `Map` right now is >>>>>>> > not ideal. >>>>>>> >>>>>>> Currently, the "extensible literal syntax" for >>>>>>> this >>>>>>> isn't that bad: >>>>>>> >>>>>>> const bar = 43; >>>>>>> const map = Immutable.Map([["foo", 42], [bar, >>>>>>> 44]]); >>>>>>> >>>>>>> It's a little more verbose because the entries >>>>>>> have >>>>>>> to be surrounded >>>>>>> by [], but hey. >>>>>>> >>>>>>> ~TJ >>>>>>> >>>>>>> >>>>>>> _______________________________________________ >>>>>>> es-discuss mailing list >>>>>>> es-discuss at mozilla.org >>>>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>>>> >>>>>>> >>>>>>> >>>>>>> _______________________________________________ >>>>>>> es-discuss mailing list >>>>>>> es-discuss at mozilla.org >>>>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>>>> >>>>>> _______________________________________________ >>>> es-discuss mailing list >>>> es-discuss at mozilla.org >>>> https://mail.mozilla.org/listinfo/es-discuss >>>> >>> >>> _______________________________________________ >>> es-discuss mailing list >>> es-discuss at mozilla.org >>> https://mail.mozilla.org/listinfo/es-discuss >>> >>> >> _______________________________________________ >> es-discuss mailing list >> es-discuss at mozilla.org >> https://mail.mozilla.org/listinfo/es-discuss >> >> >> _______________________________________________ > es-discuss mailing list > es-discuss at mozilla.org > https://mail.mozilla.org/listinfo/es-discuss > -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20151029/a93e33dd/attachment-0001.html>
I don't think borrowing object notation is a good idea. What exactly does
const myMap = Map#{
get foo() { return 100; },
set foo(v) {}
constructor() {}
};
mean?
Honestly, a very significant portion of the use cases I have for actual maps don't involve string keys. So to borrow object notation and have to constantly write keys in [] is pretty naff:
const describe = Dict#{
[1]: "one",
[[1, 2]]: "array of 1 and 2",
[null]: "the null value",
}; // please no!
If it makes people feel too weird to have comma separated, colon split key-value pairs within curlies that don't parse like POJSOs, we could have completely non-ambiguous parse with normal parentheses, I think?
const describe = Dict#(
1: "one",
[1, 2]: "array of 1 and 2",
null: "the null value",
);
That might limit confusion while giving a syntactically clean way to define maps. Let's consider that a future mapping type like Dict compares non-primitive keys by abstract value instead of by reference identity. There are tonnes of nice use cases that open up that are taken for granted in other languages and other classes like Immutable.Map - we're not there yet with ES6 built-ins, so perhaps people might not yet appreciate the value of this.
To reiterate a previous point, object property access with a statically
defined string key is idiomatically written obj.foo
, so it makes sense
for symmetry to have foo
appear as a bareword in a literal defining obj = {foo: 42}
. For most mapping-type classes this symmetry simply does not
apply, and frankly neither should it.
Also, I specifically suggested that the consumed value is an ArrayIterator
rather than an Array, because I feel having an intermediate Array around is
placing too high an importance on the humble Array. If the implementation
really wants an Array to work on internally, they can simply call
Array.from
with little cost. But if they want an Immutable.List they can
have that instead without ever seeing an actual Array. (The Symbol.fromHash
method is just Symbol.literalOf as I called it - same thing, modulo
bikeshed.)
Alex
I don't think borrowing object notation is a good idea. What exactly does ``` const myMap = Map#{ get foo() { return 100; }, set foo(v) {} constructor() {} }; ``` mean? Honestly, a very significant portion of the use cases I have for *actual maps* don't involve string keys. So to borrow object notation and have to constantly write keys in [] is pretty naff: ``` const describe = Dict#{ [1]: "one", [[1, 2]]: "array of 1 and 2", [null]: "the null value", }; // please no! ``` If it makes people feel too weird to have comma separated, colon split key-value pairs within curlies that *don't* parse like POJSOs, we could have completely non-ambiguous parse with normal parentheses, I think? ``` const describe = Dict#( 1: "one", [1, 2]: "array of 1 and 2", null: "the null value", ); ``` That might limit confusion while giving a syntactically clean way to define maps. Let's consider that a future mapping type like Dict compares non-primitive keys by abstract value instead of by reference identity. There are *tonnes* of nice use cases that open up that are taken for granted in other languages and other classes like Immutable.Map - we're not there yet with ES6 built-ins, so perhaps people might not yet appreciate the value of this. To reiterate a previous point, object property access with a statically defined string key is idiomatically written `obj.foo`, so it makes sense for symmetry to have `foo` appear as a bareword in a literal defining `obj = {foo: 42}`. For most mapping-type classes this symmetry simply does not apply, and frankly neither should it. Also, I specifically suggested that the consumed value is an ArrayIterator rather than an Array, because I feel having an intermediate Array around is placing too high an importance on the humble Array. If the implementation really wants an Array to work on internally, they can simply call `Array.from` with little cost. But if they want an Immutable.List they can have that instead without ever seeing an actual Array. (The Symbol.fromHash method is just Symbol.literalOf as I called it - same thing, modulo bikeshed.) Alex On 29 October 2015 at 22:51, Isiah Meadows <isiahmeadows at gmail.com> wrote: > Why not make it desugar to a direct function call with a single array of > pairs? It's so parsed as a regular object, so shorthands can still be used. > > `Map#{foo: 1, bar: 2, 3: "baz"}` > `Map[Symbol.fromHash]([[foo", 1], ["bar", 2], ["3", "baz]])` > > `Object#{foo: 1, bar: 2, 3: "baz"}` > `Object[Symbol.fromHash]([[foo", 1], ["bar", 2], ["3", "baz]])` > > `Object.null#{foo: 1, bar: 2, 3: "baz"}` > `Object.null[Symbol.fromHash]([[foo", 1], ["bar", 2], ["3", "baz]])` > > (`bar` doesn't have [[Construct]]) > `Object#{foo, bar() {}}` > `Object[Symbol.fromHash]([[foo", foo], ["bar", function () {}]])` > > And as for implementation, use this: > > ```js > extend class Map { > static [Symbol.fromHash](pairs) { > return new this(pairs); > } > } > > // etc... > > function SetKeys(target, pairs) { > for (const [key, value] of pairs) { > target[key] = value > } > return target > } > > extend class Object { > static [Symbol.fromHash](pairs) { > return SetKeys({}, pairs) > } > > static null(pairs) { > return SetKeys(Object.create(null), pairs) > } > } > ``` > > Pretty simple IMHO. A helper decorator could even be made. > > On Wed, Oct 28, 2015, 14:34 Alexander Jones <alex at weej.com> wrote: > >> Also I would like to reiterate that errors in the shape of the N-by-2 >> array are only caught at runtime. That's really not ideal. >> >> On Wednesday, 28 October 2015, Dave Porter <david_porter at apple.com> >> wrote: >> >>> I don’t love any of the specific suggestions so far, but saving 3 + 2n >>> keystrokes isn't the point – readability and learnability are. Visually, >>> `new Map([[‘foo’, 42]])` is a mess. >>> >>> On Oct 28, 2015, at 9:28 AM, Michał Wadas <michalwadas at gmail.com> wrote: >>> >>> Difference between any proposed here syntax and current state ( new >>> Map([ [1,2], [2,3] ]); ) is.. >>> >>> 3 characters + 2 characters/entry. >>> >>> >>> >>> >>> 2015-10-28 17:22 GMT+01:00 Mohsen Azimi <me at azimi.me>: >>> >>>> When I look at `Map#{"foo": 42}` I don't see much difference with `new >>>> Map([['foo', 42]])`. >>>> >>>> Since you can pass expressions there, it's already possible to do it >>>> with current syntax. There is only a bunch of extra brackets(`[` and `]`) >>>> that I don't like. >>>> >>>> >>>> On Wed, Oct 28, 2015 at 5:51 AM Alexander Jones <alex at weej.com> wrote: >>>> >>>>> Ah, there is actually a good case for keeping barewords in object >>>>> literals but removing them from map literals, and that's due to objects >>>>> accessing string properties as bare words, too. This is almost never the >>>>> case for other map types. >>>>> >>>>> ``` >>>>> const o = {foo: 42}; >>>>> o.foo === 42; >>>>> o.bar = 43; >>>>> >>>>> const m = Map#{"foo": 42}; >>>>> m.get("foo") === 42; >>>>> m.set("bar", 43); >>>>> ``` >>>>> >>>>> Would you agree? >>>>> >>>>> >>>>> On Wednesday, 28 October 2015, Alexander Jones <alex at weej.com> wrote: >>>>> >>>>>> Hi Herby >>>>>> >>>>>> Agree with your concerns about symmetry with object literals, but >>>>>> many of the uses of maps benefit from having non string keys, and in such >>>>>> case generally everything would involve wrapping in []. Trying to use an >>>>>> Array as a key would be quite ugly with the extra squares required >>>>>> >>>>>> ``` >>>>>> const precachedResults = MyMap#{[[1, 2, 3]]: [1, 4, 9]} >>>>>> vs >>>>>> const precachedResults = MyMap#{[1, 2, 3]: [1, 4, 9]} >>>>>> ``` >>>>>> >>>>>> Perhaps a middle ground could be that if you want to use an >>>>>> expression that would otherwise be a bare word, you enclose in parens. The >>>>>> visual binding of the colon is deceptive anyway, so I tend to do this if >>>>>> the key expression contains a space: >>>>>> >>>>>> ``` >>>>>> MyMap#{1 + 2 + 3: 6} >>>>>> vs. >>>>>> MyMap#{(1 + 2 + 3): 6} >>>>>> ``` >>>>>> >>>>>> But I think I still prefer that the parsing for the key part is just >>>>>> standard expression evaluation, personally, and the POJSO literal barewords >>>>>> remain the only special case. >>>>>> >>>>>> Indeed, >>>>>> >>>>>> ``` >>>>>> Object#{1: "one", Symbol(): "sym"} >>>>>> ``` >>>>>> >>>>>> Could Object-key-ify the keys, i.e. turn them into strings if not >>>>>> symbols, and Just Work (but a default implementation on the Object >>>>>> prototype is questionable!). That said I'm not sure we should be using >>>>>> Object for this kind of thing. At this point I don't know what a raw >>>>>> `#{}` should produce... There may be a better use case for it in the >>>>>> future, horrible ASI complexities notwithstanding. >>>>>> >>>>>> Alex >>>>>> >>>>>> >>>>>> On Wednesday, 28 October 2015, Herby Vojčík <herby at mailbox.sk> wrote: >>>>>> >>>>>>> >>>>>>> >>>>>>> Alexander Jones wrote: >>>>>>> >>>>>>>> Ok, thanks for clarifying. Not only does it preserve order but it >>>>>>>> also >>>>>>>> permits non-string keys. You're still missing one detail which is >>>>>>>> that >>>>>>>> `bar` would actually be a variable not a string key. >>>>>>>> >>>>>>>> Another example to clarify that the key part would be an expression: >>>>>>>> >>>>>>>> ``` >>>>>>>> Map#{foo(42) + 7: "bar"} >>>>>>>> ``` >>>>>>>> >>>>>>>> I prefer this over the precedent set by object literals which would >>>>>>>> require that [] are used around a key expression ("computed key") >>>>>>>> simply >>>>>>>> >>>>>>> >>>>>>> I, on the other hand, think it should match object literals >>>>>>> completely. So your example would be >>>>>>> >>>>>>> ``` >>>>>>> Map#{[foo(42)+7]: "bar"} >>>>>>> ``` >>>>>>> >>>>>>> Yes, it's just for consistency and less WTF moment while learning >>>>>>> the details. >>>>>>> >>>>>>> OTOH, there could be consistent contraproposal of: >>>>>>> >>>>>>> ``` >>>>>>> Object#{foo(42) + 7: "bar"} >>>>>>> null#{foo(42) + 7: "bar"} >>>>>>> #{foo(42) + 7: "bar"} >>>>>>> ``` >>>>>>> >>>>>>> where the first is equivalent to {[foo(42)+7]: "bar"}, the second is >>>>>>> pure container (Object.create(null)) filled with properties, and the third >>>>>>> is the default case, but I don't know which of the previous two - the first >>>>>>> is probably less confusing, though the feels more clean. >>>>>>> >>>>>>> due to relieving the syntax noise, which is what this idea is all >>>>>>>> about. >>>>>>>> Also, this is how it works in Python and I make no apologies about >>>>>>>> the >>>>>>>> similarities ;) >>>>>>>> >>>>>>>> Alex >>>>>>>> >>>>>>>> On Wednesday, 28 October 2015, Viktor Kronvall >>>>>>>> <viktor.kronvall at gmail.com <mailto:viktor.kronvall at gmail.com>> >>>>>>>> wrote: >>>>>>>> >>>>>>>> Hello Alexander, >>>>>>>> >>>>>>>> I see now that I misread your desugaring. >>>>>>>> >>>>>>>> I read: >>>>>>>> >>>>>>>> ``` >>>>>>>> Map#{1: 6, bar: 'Hello', 2: 8}; >>>>>>>> ``` >>>>>>>> as being desugared to: >>>>>>>> >>>>>>>> ``` >>>>>>>> Map[Symbol.literalOf]({1: 6, bar: 'Hello', 2: >>>>>>>> 8}[Symbol.iterator]()); >>>>>>>> ``` >>>>>>>> >>>>>>>> But your proposal clearly states that is should be: >>>>>>>> >>>>>>>> ``` >>>>>>>> Map[Symbol.literalOf]([[1, 6], ['bar', 'Hello'], >>>>>>>> [2,8]][Symbol.iterator]()); >>>>>>>> ``` >>>>>>>> >>>>>>>> Which would preserve lexical ordering of entries. The fault is >>>>>>>> completely mine. Sorry. >>>>>>>> >>>>>>>> I like this proposal as it is extensible and not that noisy in >>>>>>>> syntax. Using the `#` for this doesn't >>>>>>>> seem like a bad idea either. People coming from Erlang will be >>>>>>>> familiar with this as well. >>>>>>>> >>>>>>>> >>>>>>>> 2015-10-28 10:53 GMT+01:00 Alexander Jones <alex at weej.com >>>>>>>> <javascript:_e(%7B%7D,'cvml','alex at weej.com');>>: >>>>>>>> >>>>>>>> Hi Victor >>>>>>>> >>>>>>>> Not sure I understand - the desugaring I wrote would >>>>>>>> absolutely >>>>>>>> preserve the written ordering because it speaks in terms of >>>>>>>> an >>>>>>>> ArrayIterator of key-value pairs. If the map type to which >>>>>>>> it's >>>>>>>> applied chooses to forget the ordering then that's fine. >>>>>>>> >>>>>>>> Alex >>>>>>>> >>>>>>>> >>>>>>>> On Wednesday, 28 October 2015, Viktor Kronvall >>>>>>>> <viktor.kronvall at gmail.com >>>>>>>> <javascript:_e(%7B%7D,'cvml','viktor.kronvall at gmail.com');>> >>>>>>>> wrote: >>>>>>>> >>>>>>>> > ``` >>>>>>>> > const map = IMap#{"foo": 42, bar: 44}; >>>>>>>> > ``` >>>>>>>> > It could desugar as, for the sake of example: >>>>>>>> > >>>>>>>> > ``` >>>>>>>> > Foo#{key: value, ...} >>>>>>>> > ➔ >>>>>>>> > Foo[Symbol.literalOf]([[key, value], >>>>>>>> ...][Symbol.iterator]()) >>>>>>>> > ``` >>>>>>>> >>>>>>>> I like this proposal. However, Maps should guarantee >>>>>>>> insertion order when traversing the keys and values and >>>>>>>> desugaring it like that does not respect this guarantee >>>>>>>> or >>>>>>>> more precisely it will lead to (in my opinion) >>>>>>>> unexpected >>>>>>>> order of the keys. >>>>>>>> >>>>>>>> ``` >>>>>>>> Object.keys({1: 6, bar: 'Hello', 2: 8}); // → [ '1', >>>>>>>> '2', >>>>>>>> 'bar' ] >>>>>>>> ``` >>>>>>>> >>>>>>>> If I'm not mistaken this will be same order for `{1: 6, >>>>>>>> bar: >>>>>>>> 'Hello', 2: 8}[Symbol.iterator]()`. >>>>>>>> >>>>>>>> This implies that: >>>>>>>> >>>>>>>> ``` >>>>>>>> Map#{1: 6, bar: 'Hello', 2: 8}; >>>>>>>> ``` >>>>>>>> >>>>>>>> Will not have entries in the order `[[1, 6], ['bar', >>>>>>>> 'Hello'], [2,8]]` but instead `[[1,6], [2,8], >>>>>>>> ['bar','Hello']]`. >>>>>>>> >>>>>>>> This means that possible future destructuring of a Map >>>>>>>> will >>>>>>>> be harder to reason about. >>>>>>>> >>>>>>>> >>>>>>>> 2015-10-28 2:21 GMT+01:00 Alexander Jones < >>>>>>>> alex at weej.com>: >>>>>>>> >>>>>>>> True, but easy to mess up and only be treated to a >>>>>>>> runtime error. Three nested brackets at the start >>>>>>>> and >>>>>>>> end could definitely be better, and this just >>>>>>>> encourages >>>>>>>> people to use POJSOs instead. Also not a very >>>>>>>> uniform >>>>>>>> interface if you look at how to construct a Map, >>>>>>>> Set or >>>>>>>> Immutable.List at present, though admittedly >>>>>>>> constructor >>>>>>>> call for the ES6 types would be a partial >>>>>>>> improvement. >>>>>>>> >>>>>>>> On Wednesday, 28 October 2015, Tab Atkins Jr. >>>>>>>> <jackalmage at gmail.com> wrote: >>>>>>>> >>>>>>>> On Wed, Oct 28, 2015 at 8:36 AM, Alexander Jones >>>>>>>> <alex at weej.com> wrote: >>>>>>>> > I agree this is pretty important. Using >>>>>>>> actual >>>>>>>> maps really frees up a lot of >>>>>>>> > complexity, but the syntax is cumbersome to >>>>>>>> say >>>>>>>> the least. >>>>>>>> > >>>>>>>> > Whatever the decided syntax, bare words as >>>>>>>> string >>>>>>>> keys is a really bad idea >>>>>>>> > IMO. The key syntax should be parsed as an >>>>>>>> expression, like the values are, >>>>>>>> > and like they are in basically every other >>>>>>>> language. >>>>>>>> > >>>>>>>> > Another outstanding issue is that we might >>>>>>>> want >>>>>>>> the syntax for >>>>>>>> > `Immutable.Map`, or `WeakMap`, or >>>>>>>> `MapTwoPointOh` >>>>>>>> that improves deficiency >>>>>>>> > $x, $y and $z. I'd say introducing a special >>>>>>>> syntax for `Map` right now is >>>>>>>> > not ideal. >>>>>>>> >>>>>>>> Currently, the "extensible literal syntax" for >>>>>>>> this >>>>>>>> isn't that bad: >>>>>>>> >>>>>>>> const bar = 43; >>>>>>>> const map = Immutable.Map([["foo", 42], [bar, >>>>>>>> 44]]); >>>>>>>> >>>>>>>> It's a little more verbose because the entries >>>>>>>> have >>>>>>>> to be surrounded >>>>>>>> by [], but hey. >>>>>>>> >>>>>>>> ~TJ >>>>>>>> >>>>>>>> >>>>>>>> _______________________________________________ >>>>>>>> es-discuss mailing list >>>>>>>> es-discuss at mozilla.org >>>>>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>>>>> >>>>>>>> >>>>>>>> >>>>>>>> _______________________________________________ >>>>>>>> es-discuss mailing list >>>>>>>> es-discuss at mozilla.org >>>>>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>>>>> >>>>>>> _______________________________________________ >>>>> es-discuss mailing list >>>>> es-discuss at mozilla.org >>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>> >>>> >>>> _______________________________________________ >>>> es-discuss mailing list >>>> es-discuss at mozilla.org >>>> https://mail.mozilla.org/listinfo/es-discuss >>>> >>>> >>> _______________________________________________ >>> es-discuss mailing list >>> es-discuss at mozilla.org >>> https://mail.mozilla.org/listinfo/es-discuss >>> >>> >>> _______________________________________________ >> es-discuss mailing list >> es-discuss at mozilla.org >> https://mail.mozilla.org/listinfo/es-discuss >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20151030/239c1854/attachment-0001.html>
That's something no one here really thought of yet. I don't personally have a lot of investment in this.
(@Alex and yes, much of that was based on your idea. It was a great starting point.)
That's something no one here really thought of yet. I don't personally have a lot of investment in this. (@Alex and yes, much of that was based on your idea. It was a great starting point.) On Thu, Oct 29, 2015, 21:23 Alexander Jones <alex at weej.com> wrote: > I don't think borrowing object notation is a good idea. What exactly does > > ``` > const myMap = Map#{ > get foo() { return 100; }, > set foo(v) {} > constructor() {} > }; > ``` > > mean? > > Honestly, a very significant portion of the use cases I have for *actual > maps* don't involve string keys. So to borrow object notation and have to > constantly write keys in [] is pretty naff: > > ``` > const describe = Dict#{ > [1]: "one", > [[1, 2]]: "array of 1 and 2", > [null]: "the null value", > }; // please no! > ``` > > If it makes people feel too weird to have comma separated, colon split > key-value pairs within curlies that *don't* parse like POJSOs, we could > have completely non-ambiguous parse with normal parentheses, I think? > > ``` > const describe = Dict#( > 1: "one", > [1, 2]: "array of 1 and 2", > null: "the null value", > ); > ``` > > That might limit confusion while giving a syntactically clean way to > define maps. Let's consider that a future mapping type like Dict compares > non-primitive keys by abstract value instead of by reference identity. > There are *tonnes* of nice use cases that open up that are taken for > granted in other languages and other classes like Immutable.Map - we're not > there yet with ES6 built-ins, so perhaps people might not yet appreciate > the value of this. > > To reiterate a previous point, object property access with a statically > defined string key is idiomatically written `obj.foo`, so it makes sense > for symmetry to have `foo` appear as a bareword in a literal defining `obj > = {foo: 42}`. For most mapping-type classes this symmetry simply does not > apply, and frankly neither should it. > > Also, I specifically suggested that the consumed value is an ArrayIterator > rather than an Array, because I feel having an intermediate Array around is > placing too high an importance on the humble Array. If the implementation > really wants an Array to work on internally, they can simply call > `Array.from` with little cost. But if they want an Immutable.List they can > have that instead without ever seeing an actual Array. (The Symbol.fromHash > method is just Symbol.literalOf as I called it - same thing, modulo > bikeshed.) > > Alex > > > On 29 October 2015 at 22:51, Isiah Meadows <isiahmeadows at gmail.com> wrote: > >> Why not make it desugar to a direct function call with a single array of >> pairs? It's so parsed as a regular object, so shorthands can still be used. >> >> `Map#{foo: 1, bar: 2, 3: "baz"}` >> `Map[Symbol.fromHash]([[foo", 1], ["bar", 2], ["3", "baz]])` >> >> `Object#{foo: 1, bar: 2, 3: "baz"}` >> `Object[Symbol.fromHash]([[foo", 1], ["bar", 2], ["3", "baz]])` >> >> `Object.null#{foo: 1, bar: 2, 3: "baz"}` >> `Object.null[Symbol.fromHash]([[foo", 1], ["bar", 2], ["3", "baz]])` >> >> (`bar` doesn't have [[Construct]]) >> `Object#{foo, bar() {}}` >> `Object[Symbol.fromHash]([[foo", foo], ["bar", function () {}]])` >> >> And as for implementation, use this: >> >> ```js >> extend class Map { >> static [Symbol.fromHash](pairs) { >> return new this(pairs); >> } >> } >> >> // etc... >> >> function SetKeys(target, pairs) { >> for (const [key, value] of pairs) { >> target[key] = value >> } >> return target >> } >> >> extend class Object { >> static [Symbol.fromHash](pairs) { >> return SetKeys({}, pairs) >> } >> >> static null(pairs) { >> return SetKeys(Object.create(null), pairs) >> } >> } >> ``` >> >> Pretty simple IMHO. A helper decorator could even be made. >> >> On Wed, Oct 28, 2015, 14:34 Alexander Jones <alex at weej.com> wrote: >> >>> Also I would like to reiterate that errors in the shape of the N-by-2 >>> array are only caught at runtime. That's really not ideal. >>> >>> On Wednesday, 28 October 2015, Dave Porter <david_porter at apple.com> >>> wrote: >>> >>>> I don’t love any of the specific suggestions so far, but saving 3 + 2n >>>> keystrokes isn't the point – readability and learnability are. Visually, >>>> `new Map([[‘foo’, 42]])` is a mess. >>>> >>>> On Oct 28, 2015, at 9:28 AM, Michał Wadas <michalwadas at gmail.com> >>>> wrote: >>>> >>>> Difference between any proposed here syntax and current state ( new >>>> Map([ [1,2], [2,3] ]); ) is.. >>>> >>>> 3 characters + 2 characters/entry. >>>> >>>> >>>> >>>> >>>> 2015-10-28 17:22 GMT+01:00 Mohsen Azimi <me at azimi.me>: >>>> >>>>> When I look at `Map#{"foo": 42}` I don't see much difference with `new >>>>> Map([['foo', 42]])`. >>>>> >>>>> Since you can pass expressions there, it's already possible to do it >>>>> with current syntax. There is only a bunch of extra brackets(`[` and `]`) >>>>> that I don't like. >>>>> >>>>> >>>>> On Wed, Oct 28, 2015 at 5:51 AM Alexander Jones <alex at weej.com> wrote: >>>>> >>>>>> Ah, there is actually a good case for keeping barewords in object >>>>>> literals but removing them from map literals, and that's due to objects >>>>>> accessing string properties as bare words, too. This is almost never the >>>>>> case for other map types. >>>>>> >>>>>> ``` >>>>>> const o = {foo: 42}; >>>>>> o.foo === 42; >>>>>> o.bar = 43; >>>>>> >>>>>> const m = Map#{"foo": 42}; >>>>>> m.get("foo") === 42; >>>>>> m.set("bar", 43); >>>>>> ``` >>>>>> >>>>>> Would you agree? >>>>>> >>>>>> >>>>>> On Wednesday, 28 October 2015, Alexander Jones <alex at weej.com> wrote: >>>>>> >>>>>>> Hi Herby >>>>>>> >>>>>>> Agree with your concerns about symmetry with object literals, but >>>>>>> many of the uses of maps benefit from having non string keys, and in such >>>>>>> case generally everything would involve wrapping in []. Trying to use an >>>>>>> Array as a key would be quite ugly with the extra squares required >>>>>>> >>>>>>> ``` >>>>>>> const precachedResults = MyMap#{[[1, 2, 3]]: [1, 4, 9]} >>>>>>> vs >>>>>>> const precachedResults = MyMap#{[1, 2, 3]: [1, 4, 9]} >>>>>>> ``` >>>>>>> >>>>>>> Perhaps a middle ground could be that if you want to use an >>>>>>> expression that would otherwise be a bare word, you enclose in parens. The >>>>>>> visual binding of the colon is deceptive anyway, so I tend to do this if >>>>>>> the key expression contains a space: >>>>>>> >>>>>>> ``` >>>>>>> MyMap#{1 + 2 + 3: 6} >>>>>>> vs. >>>>>>> MyMap#{(1 + 2 + 3): 6} >>>>>>> ``` >>>>>>> >>>>>>> But I think I still prefer that the parsing for the key part is just >>>>>>> standard expression evaluation, personally, and the POJSO literal barewords >>>>>>> remain the only special case. >>>>>>> >>>>>>> Indeed, >>>>>>> >>>>>>> ``` >>>>>>> Object#{1: "one", Symbol(): "sym"} >>>>>>> ``` >>>>>>> >>>>>>> Could Object-key-ify the keys, i.e. turn them into strings if not >>>>>>> symbols, and Just Work (but a default implementation on the Object >>>>>>> prototype is questionable!). That said I'm not sure we should be using >>>>>>> Object for this kind of thing. At this point I don't know what a raw >>>>>>> `#{}` should produce... There may be a better use case for it in the >>>>>>> future, horrible ASI complexities notwithstanding. >>>>>>> >>>>>>> Alex >>>>>>> >>>>>>> >>>>>>> On Wednesday, 28 October 2015, Herby Vojčík <herby at mailbox.sk> >>>>>>> wrote: >>>>>>> >>>>>>>> >>>>>>>> >>>>>>>> Alexander Jones wrote: >>>>>>>> >>>>>>>>> Ok, thanks for clarifying. Not only does it preserve order but it >>>>>>>>> also >>>>>>>>> permits non-string keys. You're still missing one detail which is >>>>>>>>> that >>>>>>>>> `bar` would actually be a variable not a string key. >>>>>>>>> >>>>>>>>> Another example to clarify that the key part would be an >>>>>>>>> expression: >>>>>>>>> >>>>>>>>> ``` >>>>>>>>> Map#{foo(42) + 7: "bar"} >>>>>>>>> ``` >>>>>>>>> >>>>>>>>> I prefer this over the precedent set by object literals which would >>>>>>>>> require that [] are used around a key expression ("computed key") >>>>>>>>> simply >>>>>>>>> >>>>>>>> >>>>>>>> I, on the other hand, think it should match object literals >>>>>>>> completely. So your example would be >>>>>>>> >>>>>>>> ``` >>>>>>>> Map#{[foo(42)+7]: "bar"} >>>>>>>> ``` >>>>>>>> >>>>>>>> Yes, it's just for consistency and less WTF moment while learning >>>>>>>> the details. >>>>>>>> >>>>>>>> OTOH, there could be consistent contraproposal of: >>>>>>>> >>>>>>>> ``` >>>>>>>> Object#{foo(42) + 7: "bar"} >>>>>>>> null#{foo(42) + 7: "bar"} >>>>>>>> #{foo(42) + 7: "bar"} >>>>>>>> ``` >>>>>>>> >>>>>>>> where the first is equivalent to {[foo(42)+7]: "bar"}, the second >>>>>>>> is pure container (Object.create(null)) filled with properties, and the >>>>>>>> third is the default case, but I don't know which of the previous two - the >>>>>>>> first is probably less confusing, though the feels more clean. >>>>>>>> >>>>>>>> due to relieving the syntax noise, which is what this idea is all >>>>>>>>> about. >>>>>>>>> Also, this is how it works in Python and I make no apologies about >>>>>>>>> the >>>>>>>>> similarities ;) >>>>>>>>> >>>>>>>>> Alex >>>>>>>>> >>>>>>>>> On Wednesday, 28 October 2015, Viktor Kronvall >>>>>>>>> <viktor.kronvall at gmail.com <mailto:viktor.kronvall at gmail.com>> >>>>>>>>> wrote: >>>>>>>>> >>>>>>>>> Hello Alexander, >>>>>>>>> >>>>>>>>> I see now that I misread your desugaring. >>>>>>>>> >>>>>>>>> I read: >>>>>>>>> >>>>>>>>> ``` >>>>>>>>> Map#{1: 6, bar: 'Hello', 2: 8}; >>>>>>>>> ``` >>>>>>>>> as being desugared to: >>>>>>>>> >>>>>>>>> ``` >>>>>>>>> Map[Symbol.literalOf]({1: 6, bar: 'Hello', 2: >>>>>>>>> 8}[Symbol.iterator]()); >>>>>>>>> ``` >>>>>>>>> >>>>>>>>> But your proposal clearly states that is should be: >>>>>>>>> >>>>>>>>> ``` >>>>>>>>> Map[Symbol.literalOf]([[1, 6], ['bar', 'Hello'], >>>>>>>>> [2,8]][Symbol.iterator]()); >>>>>>>>> ``` >>>>>>>>> >>>>>>>>> Which would preserve lexical ordering of entries. The fault is >>>>>>>>> completely mine. Sorry. >>>>>>>>> >>>>>>>>> I like this proposal as it is extensible and not that noisy in >>>>>>>>> syntax. Using the `#` for this doesn't >>>>>>>>> seem like a bad idea either. People coming from Erlang will be >>>>>>>>> familiar with this as well. >>>>>>>>> >>>>>>>>> >>>>>>>>> 2015-10-28 10:53 GMT+01:00 Alexander Jones <alex at weej.com >>>>>>>>> <javascript:_e(%7B%7D,'cvml','alex at weej.com');>>: >>>>>>>>> >>>>>>>>> Hi Victor >>>>>>>>> >>>>>>>>> Not sure I understand - the desugaring I wrote would >>>>>>>>> absolutely >>>>>>>>> preserve the written ordering because it speaks in terms >>>>>>>>> of an >>>>>>>>> ArrayIterator of key-value pairs. If the map type to which >>>>>>>>> it's >>>>>>>>> applied chooses to forget the ordering then that's fine. >>>>>>>>> >>>>>>>>> Alex >>>>>>>>> >>>>>>>>> >>>>>>>>> On Wednesday, 28 October 2015, Viktor Kronvall >>>>>>>>> <viktor.kronvall at gmail.com >>>>>>>>> <javascript:_e(%7B%7D,'cvml','viktor.kronvall at gmail.com');>> >>>>>>>>> wrote: >>>>>>>>> >>>>>>>>> > ``` >>>>>>>>> > const map = IMap#{"foo": 42, bar: 44}; >>>>>>>>> > ``` >>>>>>>>> > It could desugar as, for the sake of example: >>>>>>>>> > >>>>>>>>> > ``` >>>>>>>>> > Foo#{key: value, ...} >>>>>>>>> > ➔ >>>>>>>>> > Foo[Symbol.literalOf]([[key, value], >>>>>>>>> ...][Symbol.iterator]()) >>>>>>>>> > ``` >>>>>>>>> >>>>>>>>> I like this proposal. However, Maps should guarantee >>>>>>>>> insertion order when traversing the keys and values and >>>>>>>>> desugaring it like that does not respect this >>>>>>>>> guarantee or >>>>>>>>> more precisely it will lead to (in my opinion) >>>>>>>>> unexpected >>>>>>>>> order of the keys. >>>>>>>>> >>>>>>>>> ``` >>>>>>>>> Object.keys({1: 6, bar: 'Hello', 2: 8}); // → [ '1', >>>>>>>>> '2', >>>>>>>>> 'bar' ] >>>>>>>>> ``` >>>>>>>>> >>>>>>>>> If I'm not mistaken this will be same order for `{1: >>>>>>>>> 6, bar: >>>>>>>>> 'Hello', 2: 8}[Symbol.iterator]()`. >>>>>>>>> >>>>>>>>> This implies that: >>>>>>>>> >>>>>>>>> ``` >>>>>>>>> Map#{1: 6, bar: 'Hello', 2: 8}; >>>>>>>>> ``` >>>>>>>>> >>>>>>>>> Will not have entries in the order `[[1, 6], ['bar', >>>>>>>>> 'Hello'], [2,8]]` but instead `[[1,6], [2,8], >>>>>>>>> ['bar','Hello']]`. >>>>>>>>> >>>>>>>>> This means that possible future destructuring of a Map >>>>>>>>> will >>>>>>>>> be harder to reason about. >>>>>>>>> >>>>>>>>> >>>>>>>>> 2015-10-28 2:21 GMT+01:00 Alexander Jones < >>>>>>>>> alex at weej.com>: >>>>>>>>> >>>>>>>>> True, but easy to mess up and only be treated to a >>>>>>>>> runtime error. Three nested brackets at the start >>>>>>>>> and >>>>>>>>> end could definitely be better, and this just >>>>>>>>> encourages >>>>>>>>> people to use POJSOs instead. Also not a very >>>>>>>>> uniform >>>>>>>>> interface if you look at how to construct a Map, >>>>>>>>> Set or >>>>>>>>> Immutable.List at present, though admittedly >>>>>>>>> constructor >>>>>>>>> call for the ES6 types would be a partial >>>>>>>>> improvement. >>>>>>>>> >>>>>>>>> On Wednesday, 28 October 2015, Tab Atkins Jr. >>>>>>>>> <jackalmage at gmail.com> wrote: >>>>>>>>> >>>>>>>>> On Wed, Oct 28, 2015 at 8:36 AM, Alexander >>>>>>>>> Jones >>>>>>>>> <alex at weej.com> wrote: >>>>>>>>> > I agree this is pretty important. Using >>>>>>>>> actual >>>>>>>>> maps really frees up a lot of >>>>>>>>> > complexity, but the syntax is cumbersome to >>>>>>>>> say >>>>>>>>> the least. >>>>>>>>> > >>>>>>>>> > Whatever the decided syntax, bare words as >>>>>>>>> string >>>>>>>>> keys is a really bad idea >>>>>>>>> > IMO. The key syntax should be parsed as an >>>>>>>>> expression, like the values are, >>>>>>>>> > and like they are in basically every other >>>>>>>>> language. >>>>>>>>> > >>>>>>>>> > Another outstanding issue is that we might >>>>>>>>> want >>>>>>>>> the syntax for >>>>>>>>> > `Immutable.Map`, or `WeakMap`, or >>>>>>>>> `MapTwoPointOh` >>>>>>>>> that improves deficiency >>>>>>>>> > $x, $y and $z. I'd say introducing a special >>>>>>>>> syntax for `Map` right now is >>>>>>>>> > not ideal. >>>>>>>>> >>>>>>>>> Currently, the "extensible literal syntax" for >>>>>>>>> this >>>>>>>>> isn't that bad: >>>>>>>>> >>>>>>>>> const bar = 43; >>>>>>>>> const map = Immutable.Map([["foo", 42], [bar, >>>>>>>>> 44]]); >>>>>>>>> >>>>>>>>> It's a little more verbose because the entries >>>>>>>>> have >>>>>>>>> to be surrounded >>>>>>>>> by [], but hey. >>>>>>>>> >>>>>>>>> ~TJ >>>>>>>>> >>>>>>>>> >>>>>>>>> _______________________________________________ >>>>>>>>> es-discuss mailing list >>>>>>>>> es-discuss at mozilla.org >>>>>>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>>> _______________________________________________ >>>>>>>>> es-discuss mailing list >>>>>>>>> es-discuss at mozilla.org >>>>>>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>>>>>> >>>>>>>> _______________________________________________ >>>>>> es-discuss mailing list >>>>>> es-discuss at mozilla.org >>>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>>> >>>>> >>>>> _______________________________________________ >>>>> es-discuss mailing list >>>>> es-discuss at mozilla.org >>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>> >>>>> >>>> _______________________________________________ >>>> es-discuss mailing list >>>> es-discuss at mozilla.org >>>> https://mail.mozilla.org/listinfo/es-discuss >>>> >>>> >>>> _______________________________________________ >>> es-discuss mailing list >>> es-discuss at mozilla.org >>> https://mail.mozilla.org/listinfo/es-discuss >>> >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20151030/3fce1312/attachment-0001.html>
On Thu, Oct 29, 2015 at 6:23 PM, Alexander Jones <alex at weej.com> wrote:
I don't think borrowing object notation is a good idea. What exactly does
const myMap = Map#{ get foo() { return 100; }, set foo(v) {} constructor() {} };
mean?
Honestly, a very significant portion of the use cases I have for actual maps don't involve string keys. So to borrow object notation and have to constantly write keys in [] is pretty naff:
const describe = Dict#{ [1]: "one", [[1, 2]]: "array of 1 and 2", [null]: "the null value", }; // please no!
If it makes people feel too weird to have comma separated, colon split key-value pairs within curlies that don't parse like POJSOs, we could have completely non-ambiguous parse with normal parentheses, I think?
const describe = Dict#( 1: "one", [1, 2]: "array of 1 and 2", null: "the null value", );
That might limit confusion while giving a syntactically clean way to define maps. Let's consider that a future mapping type like Dict compares non-primitive keys by abstract value instead of by reference identity. There are tonnes of nice use cases that open up that are taken for granted in other languages and other classes like Immutable.Map - we're not there yet with ES6 built-ins, so perhaps people might not yet appreciate the value of this.
To reiterate a previous point, object property access with a statically defined string key is idiomatically written
obj.foo
, so it makes sense for symmetry to havefoo
appear as a bareword in a literal definingobj = {foo: 42}
. For most mapping-type classes this symmetry simply does not apply, and frankly neither should it.Also, I specifically suggested that the consumed value is an ArrayIterator rather than an Array, because I feel having an intermediate Array around is placing too high an importance on the humble Array. If the implementation really wants an Array to work on internally, they can simply call
Array.from
with little cost. But if they want an Immutable.List they can have that instead without ever seeing an actual Array. (The Symbol.fromHash method is just Symbol.literalOf as I called it - same thing, modulo bikeshed.)
I strongly agree with a lot of the points here, and think they suggest the OP's suggestion was generalized in slightly the wrong way. Producing a Map literal is indeed too specific to justify syntax, but what's suggested is not a special way of calling some constructors, but a literal syntax for 2-value iterators.
We have a literal syntax for 1-value iterators: just use an Array. It's lightweight (2 chars + 1 char per item), and typos in the syntax are caught at compile time. Our existing literal syntax for 2-value iterators (an array of length-2 arrays) fails at both of these: it's heavyweight (4 chars + 4 chars per item), and typos in the syntax are only caught at runtime, when it's actually iterated over.
Having a lightweight, compile-time-checked 2-value iterator literal that desugars to an N×2 Array (or ArrayIterator) fixes all these problems, and makes it easy to write Map literals, Immutable.Dict literals, or anything else. Using the hash-paren syntax suggested above:
let m = Map(#(1: "one", [1, 2]: "array of 1 and 2", null: "the null value"));
There's no need to invent a new function-calling syntax or add a new well-known symbol to anything. It Just Works™ as long as the function you pass it to expects a 2-value iterator.
(From other languages, there doesn't appear to be any call for N×3 literals or anything higher
On Thu, Oct 29, 2015 at 6:23 PM, Alexander Jones <alex at weej.com> wrote: > I don't think borrowing object notation is a good idea. What exactly does > > ``` > const myMap = Map#{ > get foo() { return 100; }, > set foo(v) {} > constructor() {} > }; > ``` > > mean? > > Honestly, a very significant portion of the use cases I have for *actual > maps* don't involve string keys. So to borrow object notation and have to > constantly write keys in [] is pretty naff: > > ``` > const describe = Dict#{ > [1]: "one", > [[1, 2]]: "array of 1 and 2", > [null]: "the null value", > }; // please no! > ``` > > If it makes people feel too weird to have comma separated, colon split > key-value pairs within curlies that *don't* parse like POJSOs, we could have > completely non-ambiguous parse with normal parentheses, I think? > > ``` > const describe = Dict#( > 1: "one", > [1, 2]: "array of 1 and 2", > null: "the null value", > ); > ``` > > That might limit confusion while giving a syntactically clean way to define > maps. Let's consider that a future mapping type like Dict compares > non-primitive keys by abstract value instead of by reference identity. There > are *tonnes* of nice use cases that open up that are taken for granted in > other languages and other classes like Immutable.Map - we're not there yet > with ES6 built-ins, so perhaps people might not yet appreciate the value of > this. > > To reiterate a previous point, object property access with a statically > defined string key is idiomatically written `obj.foo`, so it makes sense for > symmetry to have `foo` appear as a bareword in a literal defining `obj = > {foo: 42}`. For most mapping-type classes this symmetry simply does not > apply, and frankly neither should it. > > Also, I specifically suggested that the consumed value is an ArrayIterator > rather than an Array, because I feel having an intermediate Array around is > placing too high an importance on the humble Array. If the implementation > really wants an Array to work on internally, they can simply call > `Array.from` with little cost. But if they want an Immutable.List they can > have that instead without ever seeing an actual Array. (The Symbol.fromHash > method is just Symbol.literalOf as I called it - same thing, modulo > bikeshed.) I strongly agree with a lot of the points here, and think they suggest the OP's suggestion was generalized in slightly the wrong way. Producing a Map literal is indeed too specific to justify syntax, but what's suggested is not a special way of calling some constructors, but *a literal syntax for 2-value iterators*. We have a literal syntax for 1-value iterators: just use an Array. It's lightweight (2 chars + 1 char per item), and typos in the syntax are caught at compile time. Our existing literal syntax for 2-value iterators (an array of length-2 arrays) fails at both of these: it's heavyweight (4 chars + 4 chars per item), and typos in the syntax are only caught at runtime, when it's actually iterated over. Having a lightweight, compile-time-checked 2-value iterator literal that desugars to an N×2 Array (or ArrayIterator) fixes all these problems, and makes it easy to write Map literals, Immutable.Dict literals, or anything else. Using the hash-paren syntax suggested above: ``` let m = Map(#(1: "one", [1, 2]: "array of 1 and 2", null: "the null value")); ``` There's no need to invent a new function-calling syntax or add a new well-known symbol to anything. It Just Works™ as long as the function you pass it to expects a 2-value iterator. (From other languages, there doesn't appear to be any call for N×3 literals or anything higher ~TJ
With that syntax, I'm not even sure it's necessary. It's not much more concise than a list of 2-tuples. Don't quite see the benefit the other than a few characters.
With that syntax, I'm not even sure it's necessary. It's not much more concise than a list of 2-tuples. Don't quite see the benefit the other than a few characters. On Sat, Nov 28, 2015, 22:22 Tab Atkins Jr. <jackalmage at gmail.com> wrote: > On Thu, Oct 29, 2015 at 6:23 PM, Alexander Jones <alex at weej.com> wrote: > > I don't think borrowing object notation is a good idea. What exactly does > > > > ``` > > const myMap = Map#{ > > get foo() { return 100; }, > > set foo(v) {} > > constructor() {} > > }; > > ``` > > > > mean? > > > > Honestly, a very significant portion of the use cases I have for *actual > > maps* don't involve string keys. So to borrow object notation and have to > > constantly write keys in [] is pretty naff: > > > > ``` > > const describe = Dict#{ > > [1]: "one", > > [[1, 2]]: "array of 1 and 2", > > [null]: "the null value", > > }; // please no! > > ``` > > > > If it makes people feel too weird to have comma separated, colon split > > key-value pairs within curlies that *don't* parse like POJSOs, we could > have > > completely non-ambiguous parse with normal parentheses, I think? > > > > ``` > > const describe = Dict#( > > 1: "one", > > [1, 2]: "array of 1 and 2", > > null: "the null value", > > ); > > ``` > > > > That might limit confusion while giving a syntactically clean way to > define > > maps. Let's consider that a future mapping type like Dict compares > > non-primitive keys by abstract value instead of by reference identity. > There > > are *tonnes* of nice use cases that open up that are taken for granted in > > other languages and other classes like Immutable.Map - we're not there > yet > > with ES6 built-ins, so perhaps people might not yet appreciate the value > of > > this. > > > > To reiterate a previous point, object property access with a statically > > defined string key is idiomatically written `obj.foo`, so it makes sense > for > > symmetry to have `foo` appear as a bareword in a literal defining `obj = > > {foo: 42}`. For most mapping-type classes this symmetry simply does not > > apply, and frankly neither should it. > > > > Also, I specifically suggested that the consumed value is an > ArrayIterator > > rather than an Array, because I feel having an intermediate Array around > is > > placing too high an importance on the humble Array. If the implementation > > really wants an Array to work on internally, they can simply call > > `Array.from` with little cost. But if they want an Immutable.List they > can > > have that instead without ever seeing an actual Array. (The > Symbol.fromHash > > method is just Symbol.literalOf as I called it - same thing, modulo > > bikeshed.) > > I strongly agree with a lot of the points here, and think they suggest > the OP's suggestion was generalized in slightly the wrong way. > Producing a Map literal is indeed too specific to justify syntax, but > what's suggested is not a special way of calling some constructors, > but *a literal syntax for 2-value iterators*. > > We have a literal syntax for 1-value iterators: just use an Array. > It's lightweight (2 chars + 1 char per item), and typos in the syntax > are caught at compile time. Our existing literal syntax for 2-value > iterators (an array of length-2 arrays) fails at both of these: it's > heavyweight (4 chars + 4 chars per item), and typos in the syntax are > only caught at runtime, when it's actually iterated over. > > Having a lightweight, compile-time-checked 2-value iterator literal > that desugars to an N×2 Array (or ArrayIterator) fixes all these > problems, and makes it easy to write Map literals, Immutable.Dict > literals, or anything else. Using the hash-paren syntax suggested > above: > > ``` > let m = Map(#(1: "one", [1, 2]: "array of 1 and 2", null: "the null > value")); > ``` > > There's no need to invent a new function-calling syntax or add a new > well-known symbol to anything. It Just Works™ as long as the function > you pass it to expects a 2-value iterator. > > (From other languages, there doesn't appear to be any call for N×3 > literals or anything higher > > ~TJ > -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20151129/247510ec/attachment.html>
I think you're overlooking the parse-time shape checking, Isiah, which in the new world order of type inference and checking seems like a necessity to me.
While I fully appreciate that Tab's solution involves the least number of
specification additions, I still would rather write this without the extra
pair of parens and the new
which was omitted, just to cut down on the
noise and really reduce the number of reasons people have to use Object
instead of a more suitable type. Consider embedding lists as keys in a map
which compares keys by value:
let m = new Dict(#(1: "one", new List(#(1, 2)): "array of 1 and 2", null:
"the null value"));
I think this just starts to look quite gnarly, and the fewer occurrences of
new
I see in declarative code the better.
Re-consider my offered alternative, (putting #{}
and #[]
back on the
table to visually distinguish abstract list and abstract mapping):
let m = Dict#{1: "one", List#[1, 2]: "array of 1 and 2", null: "the null
value"};
let platonics = Set#["tetrahedron", "cube", "octahedron", "dodecahedron",
"icosahedron"];
I think it would also make sense to allow ...
to include the results of
iteration over some other iterable.
let nums = [2, 3, 4];
let setOfNums = Set#[1, 2, 3, ...nums, ...range(20, 50)];
I think you're overlooking the parse-time shape checking, Isiah, which in the new world order of type inference and checking seems like a necessity to me. While I fully appreciate that Tab's solution involves the least number of specification additions, I still would rather write this without the extra pair of parens and the `new` which was omitted, just to cut down on the noise and really reduce the number of reasons people have to use `Object` instead of a more suitable type. Consider embedding lists as keys in a map which compares keys by value: ``` let m = new Dict(#(1: "one", new List(#(1, 2)): "array of 1 and 2", null: "the null value")); ``` I think this just starts to look quite gnarly, and the fewer occurrences of `new` I see in declarative code the better. Re-consider my offered alternative, (putting `#{}` and `#[]` back on the table to visually distinguish abstract list and abstract mapping): ``` let m = Dict#{1: "one", List#[1, 2]: "array of 1 and 2", null: "the null value"}; let platonics = Set#["tetrahedron", "cube", "octahedron", "dodecahedron", "icosahedron"]; ``` I think it would also make sense to allow `...` to include the results of iteration over some other iterable. ``` let nums = [2, 3, 4]; let setOfNums = Set#[1, 2, 3, ...nums, ...range(20, 50)]; ``` Cheers On Sunday, 29 November 2015, Isiah Meadows <isiahmeadows at gmail.com> wrote: > With that syntax, I'm not even sure it's necessary. It's not much more > concise than a list of 2-tuples. Don't quite see the benefit the other than > a few characters. > > On Sat, Nov 28, 2015, 22:22 Tab Atkins Jr. <jackalmage at gmail.com> wrote: > >> On Thu, Oct 29, 2015 at 6:23 PM, Alexander Jones <alex at weej.com> wrote: >> > I don't think borrowing object notation is a good idea. What exactly >> does >> > >> > ``` >> > const myMap = Map#{ >> > get foo() { return 100; }, >> > set foo(v) {} >> > constructor() {} >> > }; >> > ``` >> > >> > mean? >> > >> > Honestly, a very significant portion of the use cases I have for *actual >> > maps* don't involve string keys. So to borrow object notation and have >> to >> > constantly write keys in [] is pretty naff: >> > >> > ``` >> > const describe = Dict#{ >> > [1]: "one", >> > [[1, 2]]: "array of 1 and 2", >> > [null]: "the null value", >> > }; // please no! >> > ``` >> > >> > If it makes people feel too weird to have comma separated, colon split >> > key-value pairs within curlies that *don't* parse like POJSOs, we could >> have >> > completely non-ambiguous parse with normal parentheses, I think? >> > >> > ``` >> > const describe = Dict#( >> > 1: "one", >> > [1, 2]: "array of 1 and 2", >> > null: "the null value", >> > ); >> > ``` >> > >> > That might limit confusion while giving a syntactically clean way to >> define >> > maps. Let's consider that a future mapping type like Dict compares >> > non-primitive keys by abstract value instead of by reference identity. >> There >> > are *tonnes* of nice use cases that open up that are taken for granted >> in >> > other languages and other classes like Immutable.Map - we're not there >> yet >> > with ES6 built-ins, so perhaps people might not yet appreciate the >> value of >> > this. >> > >> > To reiterate a previous point, object property access with a statically >> > defined string key is idiomatically written `obj.foo`, so it makes >> sense for >> > symmetry to have `foo` appear as a bareword in a literal defining `obj = >> > {foo: 42}`. For most mapping-type classes this symmetry simply does not >> > apply, and frankly neither should it. >> > >> > Also, I specifically suggested that the consumed value is an >> ArrayIterator >> > rather than an Array, because I feel having an intermediate Array >> around is >> > placing too high an importance on the humble Array. If the >> implementation >> > really wants an Array to work on internally, they can simply call >> > `Array.from` with little cost. But if they want an Immutable.List they >> can >> > have that instead without ever seeing an actual Array. (The >> Symbol.fromHash >> > method is just Symbol.literalOf as I called it - same thing, modulo >> > bikeshed.) >> >> I strongly agree with a lot of the points here, and think they suggest >> the OP's suggestion was generalized in slightly the wrong way. >> Producing a Map literal is indeed too specific to justify syntax, but >> what's suggested is not a special way of calling some constructors, >> but *a literal syntax for 2-value iterators*. >> >> We have a literal syntax for 1-value iterators: just use an Array. >> It's lightweight (2 chars + 1 char per item), and typos in the syntax >> are caught at compile time. Our existing literal syntax for 2-value >> iterators (an array of length-2 arrays) fails at both of these: it's >> heavyweight (4 chars + 4 chars per item), and typos in the syntax are >> only caught at runtime, when it's actually iterated over. >> >> Having a lightweight, compile-time-checked 2-value iterator literal >> that desugars to an N×2 Array (or ArrayIterator) fixes all these >> problems, and makes it easy to write Map literals, Immutable.Dict >> literals, or anything else. Using the hash-paren syntax suggested >> above: >> >> ``` >> let m = Map(#(1: "one", [1, 2]: "array of 1 and 2", null: "the null >> value")); >> ``` >> >> There's no need to invent a new function-calling syntax or add a new >> well-known symbol to anything. It Just Works™ as long as the function >> you pass it to expects a 2-value iterator. >> >> (From other languages, there doesn't appear to be any call for N×3 >> literals or anything higher >> >> ~TJ >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20151129/5440ceed/attachment-0001.html>
My one desire (perhaps not completely substantiated) would be that the “list” portion of the syntax exist outside of these expressions as well. That is to say, if:
new Dict#{a: b, c: d }
desugars to:
new Dict([[a,b], [c,d]])
Then I’d like/expect #{a: b, c: d} to also just desugar to [[a,b], [c,d]]. More than anything, I would just expect this to be the case if I ran into it in the wild. As such, perhaps one way to look at this is that what we actually want is a nice tuple syntax. Imagine if we had just a tuple syntax taht a->b desugars to [a,b]. Now, with no further changes, we get this “map
syntax” for free:
new Map([a->b, (4+5)->d, null->7])
That looks pretty good to me, and introduces a new operator that behaves the same everywhere, and has minimal requirements to “new” collection classes. Additionally, I would enjoy returning these as well when referring to key value pairs:
return (a->b) // sugar for return [a,b]
My one desire (perhaps not completely substantiated) would be that the “list” portion of the syntax exist outside of these expressions as well. That is to say, if: ``` new Dict#{a: b, c: d } ``` desugars to: ``` new Dict([[a,b], [c,d]]) ``` Then I’d like/expect #{a: b, c: d} to also just desugar to [[a,b], [c,d]]. More than anything, I would just expect this to be the case if I ran into it in the wild. As such, perhaps one way to look at this is that what we actually want is a nice tuple syntax. Imagine if we had just a tuple syntax taht a->b desugars to [a,b]. Now, with no further changes, we get this “map syntax” for free: ``` new Map([a->b, (4+5)->d, null->7]) ``` That looks pretty good to me, and introduces a new operator that behaves the same everywhere, and has minimal requirements to “new” collection classes. Additionally, I would enjoy returning these as well when referring to key value pairs: ``` return (a->b) // sugar for return [a,b] ``` -- Francisco Tolmasky www.tolmasky.com tolmasky at gmail.com -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20151129/aae3edbe/attachment.html>
I was actually talking about the syntax itself. I'd be fine with less verbose, extensible Map semantics.
I was actually talking about the syntax itself. I'd be fine with less verbose, extensible Map semantics. On Sun, Nov 29, 2015, 12:14 Alexander Jones <alex at weej.com> wrote: > I think you're overlooking the parse-time shape checking, Isiah, which in > the new world order of type inference and checking seems like a necessity > to me. > > While I fully appreciate that Tab's solution involves the least number of > specification additions, I still would rather write this without the extra > pair of parens and the `new` which was omitted, just to cut down on the > noise and really reduce the number of reasons people have to use `Object` > instead of a more suitable type. Consider embedding lists as keys in a map > which compares keys by value: > > ``` > let m = new Dict(#(1: "one", new List(#(1, 2)): "array of 1 and 2", null: > "the null value")); > ``` > > I think this just starts to look quite gnarly, and the fewer occurrences > of `new` I see in declarative code the better. > > Re-consider my offered alternative, (putting `#{}` and `#[]` back on the > table to visually distinguish abstract list and abstract mapping): > > ``` > let m = Dict#{1: "one", List#[1, 2]: "array of 1 and 2", null: "the null > value"}; > > let platonics = Set#["tetrahedron", "cube", "octahedron", "dodecahedron", > "icosahedron"]; > ``` > > I think it would also make sense to allow `...` to include the results of > iteration over some other iterable. > > ``` > let nums = [2, 3, 4]; > let setOfNums = Set#[1, 2, 3, ...nums, ...range(20, 50)]; > ``` > > Cheers > > > On Sunday, 29 November 2015, Isiah Meadows <isiahmeadows at gmail.com> wrote: > >> With that syntax, I'm not even sure it's necessary. It's not much more >> concise than a list of 2-tuples. Don't quite see the benefit the other than >> a few characters. >> >> On Sat, Nov 28, 2015, 22:22 Tab Atkins Jr. <jackalmage at gmail.com> wrote: >> >>> On Thu, Oct 29, 2015 at 6:23 PM, Alexander Jones <alex at weej.com> wrote: >>> > I don't think borrowing object notation is a good idea. What exactly >>> does >>> > >>> > ``` >>> > const myMap = Map#{ >>> > get foo() { return 100; }, >>> > set foo(v) {} >>> > constructor() {} >>> > }; >>> > ``` >>> > >>> > mean? >>> > >>> > Honestly, a very significant portion of the use cases I have for >>> *actual >>> > maps* don't involve string keys. So to borrow object notation and have >>> to >>> > constantly write keys in [] is pretty naff: >>> > >>> > ``` >>> > const describe = Dict#{ >>> > [1]: "one", >>> > [[1, 2]]: "array of 1 and 2", >>> > [null]: "the null value", >>> > }; // please no! >>> > ``` >>> > >>> > If it makes people feel too weird to have comma separated, colon split >>> > key-value pairs within curlies that *don't* parse like POJSOs, we >>> could have >>> > completely non-ambiguous parse with normal parentheses, I think? >>> > >>> > ``` >>> > const describe = Dict#( >>> > 1: "one", >>> > [1, 2]: "array of 1 and 2", >>> > null: "the null value", >>> > ); >>> > ``` >>> > >>> > That might limit confusion while giving a syntactically clean way to >>> define >>> > maps. Let's consider that a future mapping type like Dict compares >>> > non-primitive keys by abstract value instead of by reference identity. >>> There >>> > are *tonnes* of nice use cases that open up that are taken for granted >>> in >>> > other languages and other classes like Immutable.Map - we're not there >>> yet >>> > with ES6 built-ins, so perhaps people might not yet appreciate the >>> value of >>> > this. >>> > >>> > To reiterate a previous point, object property access with a statically >>> > defined string key is idiomatically written `obj.foo`, so it makes >>> sense for >>> > symmetry to have `foo` appear as a bareword in a literal defining `obj >>> = >>> > {foo: 42}`. For most mapping-type classes this symmetry simply does not >>> > apply, and frankly neither should it. >>> > >>> > Also, I specifically suggested that the consumed value is an >>> ArrayIterator >>> > rather than an Array, because I feel having an intermediate Array >>> around is >>> > placing too high an importance on the humble Array. If the >>> implementation >>> > really wants an Array to work on internally, they can simply call >>> > `Array.from` with little cost. But if they want an Immutable.List they >>> can >>> > have that instead without ever seeing an actual Array. (The >>> Symbol.fromHash >>> > method is just Symbol.literalOf as I called it - same thing, modulo >>> > bikeshed.) >>> >>> I strongly agree with a lot of the points here, and think they suggest >>> the OP's suggestion was generalized in slightly the wrong way. >>> Producing a Map literal is indeed too specific to justify syntax, but >>> what's suggested is not a special way of calling some constructors, >>> but *a literal syntax for 2-value iterators*. >>> >>> We have a literal syntax for 1-value iterators: just use an Array. >>> It's lightweight (2 chars + 1 char per item), and typos in the syntax >>> are caught at compile time. Our existing literal syntax for 2-value >>> iterators (an array of length-2 arrays) fails at both of these: it's >>> heavyweight (4 chars + 4 chars per item), and typos in the syntax are >>> only caught at runtime, when it's actually iterated over. >>> >>> Having a lightweight, compile-time-checked 2-value iterator literal >>> that desugars to an N×2 Array (or ArrayIterator) fixes all these >>> problems, and makes it easy to write Map literals, Immutable.Dict >>> literals, or anything else. Using the hash-paren syntax suggested >>> above: >>> >>> ``` >>> let m = Map(#(1: "one", [1, 2]: "array of 1 and 2", null: "the null >>> value")); >>> ``` >>> >>> There's no need to invent a new function-calling syntax or add a new >>> well-known symbol to anything. It Just Works™ as long as the function >>> you pass it to expects a 2-value iterator. >>> >>> (From other languages, there doesn't appear to be any call for N×3 >>> literals or anything higher >>> >>> ~TJ >>> >> -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20151130/39c4e413/attachment.html>
I like the idea of the #{} syntax working without a required type. But here's my opinions:
- It should automatically [[Construct]]. I don't see any other reason why it shouldn't.
- I don't like the idea of an
->
operator which does that. Also, isa -> b -> c
equivalent to[a, b, c]
or[a, [b, c]]
? I just don't like
it.
3. I can see why you want an untyped version to destructure into a list of
2-tuples, but I fear it would lead into the same pitfalls of the extreme
consistency in this
. Every ES5 function has its own this
, which led
people into problems when they forgot about it when using inner functions.
Forth is one of the simplest, most consistent languages out there (it's an
old concatenative, stack-based language, for those unfamiliar). But it's
easy to trip up if your stack has the wrong value, it leaves one too many
values on the stack, or you pass one too few values to it. And this fails
silently.
I like the idea of the #{} syntax working without a required type. But here's my opinions: 1. It should automatically [[Construct]]. I don't see any other reason why it shouldn't. 2. I don't like the idea of an `->` operator which does that. Also, is `a -> b -> c` equivalent to `[a, b, c]` or `[a, [b, c]]`? I just don't like it. 3. I can see why you want an untyped version to destructure into a list of 2-tuples, but I fear it would lead into the same pitfalls of the extreme consistency in `this`. Every ES5 function has its own `this`, which led people into problems when they forgot about it when using inner functions. Forth is one of the simplest, most consistent languages out there (it's an old concatenative, stack-based language, for those unfamiliar). But it's easy to trip up if your stack has the wrong value, it leaves one too many values on the stack, or you pass one too few values to it. And this fails silently. On Sun, Nov 29, 2015, 16:41 Francisco Tolmasky <tolmasky at gmail.com> wrote: > My one desire (perhaps not completely substantiated) would be that the > “list” portion of the syntax exist outside of these expressions as well. > That is to say, if: > > ``` > new Dict#{a: b, c: d } > ``` > > desugars to: > > ``` > new Dict([[a,b], [c,d]]) > ``` > > Then I’d like/expect #{a: b, c: d} to also just desugar to [[a,b], [c,d]]. > More than anything, I would just expect this to be the case if I ran into > it in the wild. As such, perhaps one way to look at this is that what we > actually want is a nice tuple syntax. Imagine if we had just a tuple syntax > taht a->b desugars to [a,b]. Now, with no further changes, we get this “map > syntax” for free: > > ``` > new Map([a->b, (4+5)->d, null->7]) > ``` > > That looks pretty good to me, and introduces a new operator that behaves > the same everywhere, and has minimal requirements to “new” collection > classes. Additionally, I would enjoy returning these as well when referring > to key value pairs: > > ``` > return (a->b) // sugar for return [a,b] > ``` > > -- > Francisco Tolmasky > www.tolmasky.com > tolmasky at gmail.com > _______________________________________________ > 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/20151130/8c218572/attachment-0001.html>
I'm using Maps a lot now and I was thinking why there is no "easy" way of declaring them like objects and arrays.
I'm sure I'm not the first one who came up with the idea of having Map literal declaration. There are many ways we can introduce new syntax for declaring Maps via a literal syntax such as:
or
and possibly many more.
I searched the discussions but couldn't find a topic on this. Have you discussed this before?