Map literal
Isiah Meadows
isiahmeadows at gmail.com
Thu Oct 29 22:51:07 UTC 2015
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>
More information about the es-discuss
mailing list