Page 1 of 4
Map shorthand
Posted: 18 Aug 2019, 09:41
by kczx3
Any consideration to implementing a shorthand for initializing a Map?
You could borrow syntax from PHP maybe.
Code: Select all
myMap := [
"name" => "Tedd",
"age" => 34
]
Re: Map shorthand
Posted: 18 Aug 2019, 11:09
by Helgef
Hi.
Perhaps something like {name, "Tedd", age, 37} or [name : "Tedd", age : 37]. I think map() is pretty short though.
Cheers.
Re: Map shorthand
Posted: 18 Aug 2019, 12:14
by kczx3
Agreed, though I definitely prefer the literal notation. I like your second suggestion best actually. Since objects and arrays are unique now, I think that would work.
Re: Map shorthand
Posted: 18 Aug 2019, 18:03
by swagfag
something visually distinguishing is needed to
tie keys to values and separate pairs from one another, thats for sure
Code: Select all
myMap := [
"name" => "Tedd",
"age" => 34
]
i dont think this could work
did i define a
Map with 1 key(the
value of
name) paired to
"Tedd" or did i define an
Array with a one argument lambda returning
"Tedd"?
Re: Map shorthand
Posted: 18 Aug 2019, 18:55
by kczx3
Good point
Re: Map shorthand
Posted: 18 Aug 2019, 23:49
by jeeswg
For readability and avoiding pressing " too many times:
Code: Select all
oMap := StrSplitMap("key1,value1,key2,value2,key3,value3", ",")
oMap := StrSplitMap("1,1,2,2,3,3", ",")
oMap := StrSplitMap("1.0,1.0,2.0,2.0,3.0,3.0", ",")
vOutput := ""
for vKey, vValue in oMap
vOutput .= vKey " " vValue " " Type(vKey) " " Type(vValue) "`r`n"
Clipboard := vOutput
MsgBox(vOutput)
return
;StrSplitToMap
StrSplitMap(oParams*)
{
oArray := StrSplit(oParams*)
for vKey, vValue in oArray
{
if (vValue is "Integer")
oArray[vKey] := Integer(vValue)
else if (vValue is "Float") && !(A_Index & 1)
oArray[vKey] := Float(vValue)
}
return Map(oArray*)
}
;StrSplitToMapSimple
StrSplitMapSimple(oParams*)
{
return Map(StrSplit(oParams*)*)
}
Re: Map shorthand
Posted: 19 Aug 2019, 03:30
by lexikos
It is unlikely that any "shorthand" syntax I add for Map will allow quote marks to be omitted. Object notation allows it because they are "properties", and the usual syntax for accessing them does not use quote marks. (Now it makes more sense to require the quote marks to be omitted for properties.) Map, on the other hand, always requires quote marks around literal keys.
["a" => "b"] becomes longer than Map("a", "b") once you write more than three key-value pairs, or sooner if you use spaces around the delimiter.
In my opinion, the main advantage of dedicated syntax (comparing the original Object() to {}) is the visual pairing. We are already using : for this purpose, so it seems like the logical choice. It is also reminiscent of assignment. One problem is that [] creates an empty Array and {} creates an empty Object, so overloading based on whether there are key-value pairs vs. just values would not completely work.
Re: Map shorthand
Posted: 19 Aug 2019, 07:04
by kczx3
I see. So same as object literals except for using square brackets. I think that'd look nice.
Re: Map shorthand
Posted: 20 Aug 2019, 06:37
by swagfag
what about taking
{} away from
Object and giving it to
Map.
Code: Select all
myMap := {
name: "Tedd",
age: 34
}
or quoted, optionally
if u want variables:
Code: Select all
myMap := {
(name): "Tedd",
(age): 34
}
if u want to make objects, use the
Object(params*) constructor
i imagine, more often than not ud want to use maps. but how often would u need to make objects? and wouldnt the preferred best practice in this case be to declare a class, rather than cobbling props and methods together
Re: Map shorthand
Posted: 20 Aug 2019, 07:32
by kczx3
Valid point. Most people are going to use Map now instead of Object. And the class syntax is much more intuitive to me.
Re: Map shorthand
Posted: 20 Aug 2019, 08:15
by Helgef
I'm not sure about that, I'd rather see extended shorthand syntax for objects to allow method definitions, eg { m() => expr, prop : val }. Perhaps with local classes, {} would see much less use as shorthand objects.
Cheers.
Re: Map shorthand
Posted: 20 Aug 2019, 08:36
by kczx3
Helgef wrote: ↑20 Aug 2019, 08:15
Perhaps with
local classes,
{} would see much less use as shorthand objects.
Forgot about that.
Re: Map shorthand
Posted: 20 Aug 2019, 10:04
by nnnik
Regardless in the end having an expression as key is inevitable.
Code: Select all
myMap := {
name: "Tedd",
age: 34
}
^ this syntax conceals the fact that keys can be any kind of expression/value.
A map that is intended to map value a to value as a general purpose dictionary should not have some sort of bias towards strings.
I thought you disliked the command syntax swagfag. Or is the usage of () over %% enough to conceal the fact that we are essentially continuing the legacy of legacy syntax in v2 with this shorthand?
We will end up with all sorts of strange situations and many problems where some keys cannot be used because they resemble an expression too much or have to be escaped with ` or similar again.
I feel that we should free ourselves as much as possible from that weight in v2:
Code: Select all
arr := {("(key)"):value} ;marvelous :)
arr := {%"%key%"%} ;even better :D
I think in the end
would be enough of a shorthand to create a new object. (unless I missed something and that got removed)
We will also have a highly similar notation to JSON which would make the transition for many people from the developer scene a lot easier.
Just my 2 cents.
Cheers
Re: Map shorthand
Posted: 20 Aug 2019, 10:21
by swagfag
no, not at all. which is why i bothered enough to add:
swagfag wrote: ↑20 Aug 2019, 06:37
or quoted, optionally
Re: Map shorthand
Posted: 20 Aug 2019, 10:25
by nnnik
swagfag wrote: ↑20 Aug 2019, 10:21
no, not at all. which is why i bothered enough to add:
swagfag wrote: ↑20 Aug 2019, 06:37
or quoted, optionally
Re: Map shorthand
Posted: 21 Aug 2019, 03:52
by lexikos
lexikos wrote: ↑19 Aug 2019, 03:30
It is unlikely that any "shorthand" syntax I add for Map will allow quote marks to be omitted.
lexikos wrote:
{a: b, c: d} is most often used to create ad-hoc objects with known properties, so these should be properties.
...
Associative arrays most often start out empty, so new syntax for an "associative array literal" seems unnecessary. The primary advantage of
{x: y} is that the property names do not need to be quoted - this is consistent with
obj.x and not with
obj["x"]. On the other hand, the current rules also allow
{"x": y} and any other expression which isn't a plain variable. Perhaps properties can require a
literal_identifier: or
%variable_identifier%: while array elements require
[index]:.
https://github.com/Lexikos/Object.ahk
Re: Map shorthand
Posted: 21 Aug 2019, 05:57
by nnnik
I never create objects ad-hoc with known properties.
I use objects mostly for lookup tables - which sometimes contain objects as key.
From what I understood from this topic a few users dont use {} for quick anonymous creation either.
Simply put I define all my classes explicitly.
Defining an object with {} that contains methods is awkward and using actual property syntax is not possible afaics.
On the other hand the {} syntax is qualified to quickly create a map with initialized data.
Could you please reconsider?
Re: Map shorthand
Posted: 21 Aug 2019, 10:10
by swagfag
not claiming to have a firm grasp on this prototypal inheritance thing, but i wouldnt normally create ad-hoc objects either. whats the point, really? the only reason i can think of, is if u needed an object and not leak it to users by confining it to a given scope. but if that were the case, whats the point of having the shorthand syntax? if u only needed it for its properties, to use it as a faux-map, u could have just used a
Map instead. if u wanted to use it as a class, then ud have to additionally
.DefineProp() and
.DefineMethod() a bunch of times, which kinda defeats the point of the shorthand syntax imo.
if u take
{} away, then defining such a thing becomes somewhat verbose, ex:
Code: Select all
adHoc := Object('dumbProp', 'plainString')
adHoc.DefineProp('smartProp', Object('get', this => "Today's date is " FormatTime(A_Now, 'MM/dd/yyyy'),
'set', (this, value) => MsgBox('Immutable property')))
adHoc.DefineMethod('printProps', Func('printProps'))
printProps(this) {
for name, value in this.OwnProps()
MsgBox name ": " value
}
versus
Code: Select all
adHoc := {dumbProp: 'plainString'}
adHoc.DefineProp('smartProp', {get: this => "Today's date is " FormatTime(A_Now, 'MM/dd/yyyy'),
set: (this, value) => MsgBox('Immutable property')})
adHoc.DefineMethod('printProps', Func('printProps'))
printProps(this) {
for name, value in this.OwnProps()
MsgBox name ": " value
}
Re: Map shorthand
Posted: 21 Aug 2019, 10:30
by kczx3
Apparently I started something here.
I want to make it clear that my intention was not to say that I'm not happy with the recent changes. They are an awesome addition to the language and I very much look forward to using them.
My thinking is along the lines of nnnik I believe. I don't think that anyone really creates an ad-hoc object using {} where they define methods and whatnot for it to then be instantiated using new. Most often they are just to create dictionaries, and in my case, usually small ones with only a few keys.
If I really want an object to have more than very limited functionality, I would define a class and I think having an explicit/verbose syntax for that is warranted.
Re: Map shorthand
Posted: 21 Aug 2019, 11:16
by swagfag
i doubt its anybody's intention to rip on the update. its a dope af update, after all. we're just talking
and just now ive figured that if u were to give
{} to
Map, u could have
.DefineProp() accept a map instead:
adHoc.DefineProp('smartProp', {'get': theGetterFunc, 'set': theSetterFunc}), so the only difference to how it is currently are the quotes.
that still leaves us with "what to do about
adHoc := Object('dumbProp', 'plainString')?" - u could have a
.DefineProp(MapOfDumbProps) single-arg overload that accepts a map for setting "plain" properties
Code: Select all
adHoc := Object()
adHoc.DefineProp({'dumbProp': 'plainString'})