Map shorthand

Discuss the future of the AutoHotkey language
User avatar
kczx3
Posts: 1640
Joined: 06 Oct 2015, 21:39

Map shorthand

18 Aug 2019, 09:41

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
]
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: Map shorthand

18 Aug 2019, 11:09

Hi.
Perhaps something like {name, "Tedd", age, 37} or [name : "Tedd", age : 37]. I think map() is pretty short though.

Cheers.
User avatar
kczx3
Posts: 1640
Joined: 06 Oct 2015, 21:39

Re: Map shorthand

18 Aug 2019, 12:14

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.
swagfag
Posts: 6222
Joined: 11 Jan 2017, 17:59

Re: Map shorthand

18 Aug 2019, 18:03

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

Code: Select all

myMap := [
    name => "Tedd"
]
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"?
User avatar
kczx3
Posts: 1640
Joined: 06 Oct 2015, 21:39

Re: Map shorthand

18 Aug 2019, 18:55

Good point
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: Map shorthand

18 Aug 2019, 23:49

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*)*)
}
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
lexikos
Posts: 9554
Joined: 30 Sep 2013, 04:07
Contact:

Re: Map shorthand

19 Aug 2019, 03:30

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.
User avatar
kczx3
Posts: 1640
Joined: 06 Oct 2015, 21:39

Re: Map shorthand

19 Aug 2019, 07:04

I see. So same as object literals except for using square brackets. I think that'd look nice.
swagfag
Posts: 6222
Joined: 11 Jan 2017, 17:59

Re: Map shorthand

20 Aug 2019, 06:37

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
User avatar
kczx3
Posts: 1640
Joined: 06 Oct 2015, 21:39

Re: Map shorthand

20 Aug 2019, 07:32

Valid point. Most people are going to use Map now instead of Object. And the class syntax is much more intuitive to me.
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: Map shorthand

20 Aug 2019, 08:15

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.
User avatar
kczx3
Posts: 1640
Joined: 06 Oct 2015, 21:39

Re: Map shorthand

20 Aug 2019, 08:36

Helgef wrote:
20 Aug 2019, 08:15
Perhaps with local classes, {} would see much less use as shorthand objects.
Forgot about that.
User avatar
nnnik
Posts: 4500
Joined: 30 Sep 2013, 01:01
Location: Germany

Re: Map shorthand

20 Aug 2019, 10:04

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

Code: Select all

obj := object()
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
Recommends AHK Studio
swagfag
Posts: 6222
Joined: 11 Jan 2017, 17:59

Re: Map shorthand

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
User avatar
nnnik
Posts: 4500
Joined: 30 Sep 2013, 01:01
Location: Germany

Re: Map shorthand

20 Aug 2019, 10:25

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
:oops:
Recommends AHK Studio
lexikos
Posts: 9554
Joined: 30 Sep 2013, 04:07
Contact:

Re: Map shorthand

21 Aug 2019, 03:52

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
User avatar
nnnik
Posts: 4500
Joined: 30 Sep 2013, 01:01
Location: Germany

Re: Map shorthand

21 Aug 2019, 05:57

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?
Recommends AHK Studio
swagfag
Posts: 6222
Joined: 11 Jan 2017, 17:59

Re: Map shorthand

21 Aug 2019, 10:10

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
}
User avatar
kczx3
Posts: 1640
Joined: 06 Oct 2015, 21:39

Re: Map shorthand

21 Aug 2019, 10:30

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.
swagfag
Posts: 6222
Joined: 11 Jan 2017, 17:59

Re: Map shorthand

21 Aug 2019, 11:16

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'})

Return to “AutoHotkey Development”

Who is online

Users browsing this forum: lexikos and 34 guests