Map shorthand

Discuss the future of the AutoHotkey language
tester
Posts: 84
Joined: 10 Jun 2021, 23:03

Re: Map shorthand

Post by tester » 16 Dec 2022, 03:05

Helgef wrote:

Code: Select all

[name : "Tedd", age : 37]
+1
lexikos wrote:It is unlikely that any "shorthand" syntax I add for Map will allow quote marks to be omitted.
+1
lexikos wrote:the main advantage of dedicated syntax (comparing the original Object() to {}) is the visual pairing.
This is very important for me over shortness. I hadn't been able to comprehend the rules of DllCall() parameters for a long time. When I finally understood that type-value pairs are passed in series, instead of a pleasant feeling of Eureka, I got a bit confused as to "why this is designed so?"; type-value pair relationships cannot be grasped at first glance. I concluded there was no choice but to do so within the already designed syntax when it was supported. But for Map(), there seems to be a room for dedicated syntax.
lexikos wrote: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.
I'm unable to grasp the logic in this part. Is it saying "[] and {} are already used so the suggested syntax, [ "foo": "bar" ] for Map( "foo", "bar" ), won't work"?
lexikos wrote:Associative arrays most often start out empty, so new syntax for an "associative array literal" seems unnecessary.
lexikos wrote:Do you regularly create associative arrays and need to populate them with a fixed list of key-value pairs at the point of creation?
I often encounter a need to do this for function or class method parameter values. For example,

Code: Select all

msgbox GetStringReplaced( "The quick-brown fox jumps over the lazy dog.", Map( "quick-brown", "slow-yellow", "lazy", "energetic" ), true )
GetStringReplaced( sHaystack, mReplacaments:=Map(), bCaseSense:=false, &iReplaced:=0, &iLimit:=-1 ) {
    for _sNeedle, _sReplacement in mReplacaments {
        sHaystack := StrReplace( sHaystack, _sNeedle, _sReplacement, bCaseSense, &_iReplacedNow, iLimit )
        iReplaced += _iReplacedNow
    }
    return sHaystack
}
And I hope there is a more visually intuitive way for Map( "quick-brown", "slow-yellow", "lazy", "energetic" ). My point is not shortness but visual paring, which is crucial to those who's native language isn't English.
lexikos wrote:2. That syntax was suggested by Helgef in the second post of this topic, and I already brought up one problem with it.
This must be a repeated request but I couldn't comprehend the reasoning of the addressed problem.

lexikos
Posts: 9811
Joined: 30 Sep 2013, 04:07
Contact:

Re: Map shorthand

Post by lexikos » 16 Dec 2022, 21:38

tester wrote:I'm unable to grasp the logic in this part.
Do you want x := [] to create an empty Array or an empty Map? It can't do both. Now it can't do the latter anyway, if we even wanted it to (despite using it for a long time to create arrays), because the behaviour for v2.x has been locked in. So [ "foo": "bar" ] would create a Map and [] would create an Array. Any special case for an empty map, like [:], wouldn't eliminate this oddity and wouldn't particularly be better than Map() anyway.

And what about cases like this?

Code: Select all

myMap := [
    ; "key": "value"  ; Temporarily commented out.
]

... which is crucial to those who's native language isn't English.
I don't see the connection between non-English languages and difficulty with the concept of pairing within a comma-delimited list, or the ability to visually identify pairs in such a list. I would think it is a subjective issue unrelated to language.

tester
Posts: 84
Joined: 10 Jun 2021, 23:03

Re: Map shorthand

Post by tester » 17 Dec 2022, 01:38

lexikos wrote:
16 Dec 2022, 21:38
Do you want x := [] to create an empty Array or an empty Map? It can't do both.
I got it now. Thank you for the explanation. That's a problem. There doesn't seem usable symbols left for associative arrays.
... which is crucial to those who's native language isn't English.
I don't see the connection between non-English languages and difficulty with the concept of pairing within a comma-delimited list, or the ability to visually identify pairs in such a list. I would think it is a subjective issue unrelated to language.
The term, Map, doesn't remind associative arrays or diagrams for those whose linguistic origin isn't Latin. When the term is unknown, they just observe the patterns in the code. Then, if the sets of characters are arranged in series, it's hard to imagine they have key-value relationships.

Having said that, I agree, at this point, it's better to be as is since there seem no appropriate characters for Map().

lexikos
Posts: 9811
Joined: 30 Sep 2013, 04:07
Contact:

Re: Map shorthand

Post by lexikos » 17 Dec 2022, 19:09

No one should be expected to guess what the code does based on visual patterns without having learned anything about the language or functions. Regardless of a person's native language, they will need to learn English-based names to use AutoHotkey, and they will need to learn what each function does and how its parameters are interpreted. The meaning of "Map" is not even immediately obvious to native English speakers; it was chosen because it is short.

Even if it was AssociativeArray(...) or 連想配列(...) or whatever the word is in one's native language, I would not be expecting anyone to know that it will accept a list of key-value pairs unless they have read the documentation.

Who is going to know what ["something": "something else"] means without first having learned it somewhere? If we choose some arbitrary combination of symbols, users will still need to know the name of the class.

Anyway, other ideas have been brought up here and elsewhere, that may be more widely useful or less problematic.

User avatar
RaptorX
Posts: 436
Joined: 06 Dec 2014, 14:27
Contact:

Re: Map shorthand

Post by RaptorX » 17 Dec 2022, 21:15

lexikos wrote:
17 Dec 2022, 19:09
No one should be expected to guess what the code does based on visual patterns without having learned anything about the language or functions. Regardless of a person's native language, they will need to learn English-based names to use AutoHotkey, and they will need to learn what each function does and how its parameters are interpreted. The meaning of "Map" is not even immediately obvious to native English speakers; it was chosen because it is short.

Even if it was AssociativeArray(...) or 連想配列(...) or whatever the word is in one's native language, I would not be expecting anyone to know that it will accept a list of key-value pairs unless they have read the documentation.
While I totally agree with the above I would slightly disagree with the statement below:
lexikos wrote:
17 Dec 2022, 19:09
Who is going to know what ["something": "something else"] means without first having learned it somewhere? If we choose some arbitrary combination of symbols, users will still need to know the name of the class.
Even if I dont understand exactly what is doing, I would assume that something and something else are directly related somehow.
That would be even more obvious if there are more items listed.

That is not the case for map(item1, item2, item3, item4) in which case I would assume I am listing some items with a general category and wouldnt guess that item1 and item2 are directly related in a way that item1 and item4 arent.

I do agree though that being able to do the following, helps a lot with that:

Code: Select all

myMap:= Map(
	"item1", "item2"
	"item3, "item4"
)
but not everyone does that, so reading someone elses code might not be as intuitive as in the [item1:item2] example.

Hopefully a better alternative might be found in the future of v2... :)
Projects:
AHK-ToolKit

lexikos
Posts: 9811
Joined: 30 Sep 2013, 04:07
Contact:

Re: Map shorthand

Post by lexikos » 17 Dec 2022, 22:12

If you can only see that the pairs are "related somehow", you still know next to nothing about what the code is doing. You still need to read the documentation to know that it's creating a Map, and how to use the Map. There is no way that any symbols we arbitrarily choose for creating a Map will intuitively convey these details. The documentation may even be harder to find because there's no keyword to search for. Giving an uneducated reader a slightly better chance at guessing what the code is doing is not even remotely important to me.
That is not the case for map(item1, item2, item3, item4) in which case I would assume I am listing some items with a general category and wouldnt guess that item1 and item2 are directly related in a way that item1 and item4 arent.
In complete isolation - or as an arbitrary example with no context whatsoever - the map has no meaning and merely having paired parameters is not going to be much use for understanding the code. In a real script, the keys of a Map have some commonality, and can often be distinguished from the values. One real example which recently came up in another topic: HTTP headers. It's fairly obvious which values are header names, and even more obvious when the Map is literally written within the parameter list of a function for making HTTP requests.


The only point so far that I agree with (as far as I can recall), and have therefore said very little about, is that being able to visually distinguish the pairs is beneficial.
lexikos wrote:
19 Aug 2019, 03:30
In my opinion, the main advantage of dedicated syntax (comparing the original Object() to {}) is the visual pairing.
But the degree of benefit is subjective, and to actually bring it about, I must decide upon and implement a specific syntax. Each idea has problems, or at the very least, a cost.

Some of my other ideas, also presented in this topic, offer more flexibility and therefore higher potential benefit (though perhaps also higher cost to implement). Those are more interesting, but still lower priority than numerous other things I have planned.

tester
Posts: 84
Joined: 10 Jun 2021, 23:03

Re: Map shorthand

Post by tester » 18 Dec 2022, 01:09

lexikos wrote:
17 Dec 2022, 19:09
No one should be expected to guess what the code does based on visual patterns without having learned anything about the language or functions.
Some light users just want things to get done without completely understanding the details of the language, seen as copy-pasting pieces of code posted on forums. I'd guess most beginners start by doing it and after seeing the result, some start to think about why this works and doesn't then start learning. The learning curve should be kept moderate for them. They are the potential contributors or advertisers who contribute to expanding the user base. Visual intuitiveness can help reduce the steepness of the learning curve and the capability of letting the reader guess what it does is a crucial factor in understanding.
it was chosen because it is short.
It is a good choice, to be clear about my stance.
Even if it was AssociativeArray(...) or 連想配列(...) or whatever the word is in one's native language, I would not be expecting anyone to know that it will accept a list of key-value pairs unless they have read the documentation.
I agree. They have to read the documentation anyway to understand the code. I suppose you are assuming coders who write code from scratch. I assume those include copy-pasters who barely read and understand code but want to use code right away. They read code when pasted code doesn't work. When that happens, the code intelligibility determines whether they are going to be involved in coding.
Who is going to know what ["something": "something else"] means without first having learned it somewhere? If we choose some arbitrary combination of symbols, users will still need to know the name of the class.
The colon : is a symbol while Map is a word. Symbols are more widely known than words even outside programming fields and are easier to be recognized than words. Also, : resembles = so one can easily guess they are tied in some way. And as I already mentioned, the capability of being guessed from appearance is a crucial part of understanding. Cognitive load should be kept as low as possible in reading code.


If you can only see that the pairs are "related somehow", you still know next to nothing about what the code is doing.
There is no way that any symbols we arbitrarily choose for creating a Map will intuitively convey these details.
I'm not sure whether I can agree with it.

Code: Select all

Map( "yellow", "banana", "red", "apple", "pink", "peach" )

Code: Select all

[ 
    "yellow": "banana",
    "red": "apple",
    "pink": "peach",
]
To me, the latter is a way easier to guess what kind of data is collected. In this case, it is a list of fruits associated with color. It gives more hints to the reader than the former. The degree of intelligibility is not slight. My point here is that capability of being guessed is critical and shouldn't be downplayed. (To be clear, I'm not saying this particular syntax should be implemented now that I understand it won't work.)

lexikos
Posts: 9811
Joined: 30 Sep 2013, 04:07
Contact:

Re: Map shorthand

Post by lexikos » 18 Dec 2022, 01:33

Sure, they can guess some meaning from :, and they still won't know how to use the Map.

tester
Posts: 84
Joined: 10 Jun 2021, 23:03

Re: Map shorthand

Post by tester » 18 Dec 2022, 02:19

lexikos wrote:
18 Dec 2022, 01:33
Sure, they can guess some meaning from :, and they still won't know how to use the Map.
Assuming a code copy-paster tries to read code, the person doesn't necessarily have to know how to use the Map, but having a context of what kind of data is handled in advance to reading the documentation makes the learning process smoother.

guest3456
Posts: 3476
Joined: 09 Oct 2013, 10:31

Re: Map shorthand

Post by guest3456 » 18 Dec 2022, 19:12

tester wrote:
18 Dec 2022, 02:19
lexikos wrote:
18 Dec 2022, 01:33
Sure, they can guess some meaning from :, and they still won't know how to use the Map.
Assuming a code copy-paster tries to read code, the person doesn't necessarily have to know how to use the Map, but having a context of what kind of data is handled in advance to reading the documentation makes the learning process smoother.
+1


lexikos
Posts: 9811
Joined: 30 Sep 2013, 04:07
Contact:

Re: Map shorthand

Post by lexikos » 18 Dec 2022, 19:12

I wrote:Giving an uneducated reader a slightly better chance at guessing what the code is doing is not even remotely important to me.

tester
Posts: 84
Joined: 10 Jun 2021, 23:03

Re: Map shorthand

Post by tester » 19 Dec 2022, 00:15

Just for brainstorming for future considerations, what about <>?

Code: Select all

myMap := <>
myMap := <"foo": "bar">
doSomething( myMap:=<> ) {
   for _k, _v in myMap {
       ; doing something
   }
}

User avatar
DrReflex
Posts: 45
Joined: 25 May 2015, 02:57
Location: Greer, SC

Re: Map shorthand

Post by DrReflex » 26 Nov 2024, 04:02

PLEASE RECONSIDER ADDING A SHORTHAND FOR MAP LITERALS

*** The point of SHORTHAND is to eliminate unnecessary strokes while preserving (or enhancing) readability. ***

CREATION LIMITS (There is no shorthand for maps)
  • Array(), Array.Call(), and [] can be used to create an Array
  • Object(), Object.Call() and {} can be used to create an Object
  • ONLY Map(), and Map.Call() can be used to create a Map
POPULATION LIMITS (There is no shorthand for map literals AND there are no functions for object literals)
  • Array(), Array.Call(), and [] can be used to populate an Array with literal elements at the time of creation
  • ONLY Map() and Map.Call() can be used to populate a Map with literal Key:element pairs at the time of creation
  • ONLY {} can be used to populate an Object with literal parameter:element pairs at the time of creation
MY WISH LIST:
1. My first wish is for a shorthand for Maps. I favor:

mMap := [:] ;where [:] is equivalent to Map() and to Map.Call()

mMap := [key1:value1,Key2:value2,...,keyN:valueN]

JUSTIFICATION: Using the same (reference:element) pair formatting for both Maps and Objects is intuitive and helps separate Map and Object pairs from the sequence of elements only seen in Arrays. Commas in Map statements are no longer ambiguous. With the new shorthand, commas would only separate entries in Arrays, Maps, and Objects. Using square brackets to denote Arrays and Maps further separates them from the base Objects. Finally, because this is shorthand, there is no need for the double quotes to enclose each map key. The double quotes are assumed and KeyVariables are entered by enclosing them in percent signs (%KeyVariable%) similar to PropertyVariables in Objects. This formatting consistency makes variable entries standout. The effect is to eliminate unnecessary keystrokes while enhancing readability.

Because there is currently no Map Shorthand, it could be implemented without affecting existing code.

2. My second wish is for Object() and Object.Call() to support object literals identical to the {} shorthand. This is of a much lower priority.

User avatar
RaptorX
Posts: 436
Joined: 06 Dec 2014, 14:27
Contact:

Re: Map shorthand

Post by RaptorX » 26 Nov 2024, 15:43

I agree with everything you were saying and I even like the [:] syntax, which lexikos himself mentioned a while back as a possible shorthand that he might consider, or that someone mentioned and he explain some issues with it (i think, i cant remember now).

But i definitelly dont agree with this part:
DrReflex wrote:
26 Nov 2024, 04:02
Finally, because this is shorthand, there is no need for the double quotes to enclose each map key. The double quotes are assumed and KeyVariables are entered by enclosing them in percent signs (%KeyVariable%) similar to PropertyVariables in Objects.
Percent signs for variables are closer to v1 syntax and we moved away from that. I for one dont miss it one bit.
Having quotes or single quotes for text literals is:
1) more intuitive
2) more common (other languages are like that too)...

having expressions are a blessing for complex operations. This syntax is just fine:

Code: Select all

headers := [
	'accept':        '*/*',
	'Authorization': 'Bearer ' key,
	'Organization':  orgID ?? '',
	'Project':       projID ?? ''
]
Projects:
AHK-ToolKit

Qriist
Posts: 161
Joined: 11 Sep 2016, 04:02

Re: Map shorthand

Post by Qriist » 02 Dec 2024, 15:40

lexikos wrote:
16 Dec 2022, 21:38
Do you want x := [] to create an empty Array or an empty Map?
DrReflex wrote:
26 Nov 2024, 04:02
PLEASE RECONSIDER ADDING A SHORTHAND FOR MAP LITERALS

I realize this may not be the most practical solution to shorthand a Map(), but since we're out of standard keyboard characters... why not simply use nonstandard characters? Some unused ASCII characters and many extended Unicode characters have left/right interpretations that can be typed out on the keyboard via ALT+####.

Some possibilities I found:

Code: Select all

foo := Map()
foo := ‹›    ;ALT-0139 / ALT-0155
foo := «»    ;0171 / 0187
foo := ⁅⁆    ;2045 / 2046
foo := ⦕⦖    ;2995 / 2996
foo := ﴾﴿    ;FD3E / FD3F   ...lol
The main trick, I think, would be to find a character pair that is obviously "encapsulating" the data and is numerically easy to remember.

I believe either the quill brackets (2045/2046) or the arc brackets (2995/2996) fit that criteria:

Code: Select all

foo := ⁅"jankKey":"junkValue"⁆
foo := ⦕"jankKey":"junkValue"⦖
...with perhaps the quill brackets edging out an aesthetic victory.

Probably not worth the effort, but it's an idea all the same.

User avatar
DrReflex
Posts: 45
Joined: 25 May 2015, 02:57
Location: Greer, SC

Re: Map shorthand

Post by DrReflex » 02 Jan 2025, 03:45

1. Map and Array are both derived from object.
2. Object shorthand is {parameter1:value1,parameter2:value2, ... , parameterN,valueN}
3. Array shorthand is [value1,value2, ..., valueN]

THE OBVIOUS SHORTHAND FOR MAPS WOULD BE:
mVar := [key1:value1,key2:value2, ... , keyN,valueN]

NOTES:
1. ADDING QUOTES AROUND EACH "KEY" WOULD NOT REPRESENT A SHORTHAND. SHORTHAND WOULD DEMAND ELIMINATION OF THESE SURPERFLUOUS CHARACTERS. LET THE COMPUTER ADD THEM.
2. USE ANOTHER CONTROL CHARACTER TO DESIGNATE A VARIABLE KEY OR VALUE. POSSIBLY "&". WE ALREADY USE IT TO PASS VARIABLE VALUES IN FUNCTIONS.
EXAMPLE: mVar := [&VarKey1:&VarValue1,&VarKey2:&VarValue2}
3. THE USE OF THE COLON ":" TO SEPARATE THE "Key" FROM THE "Value" AND THE USE OF THE COMMA "," TO SEPARATE "Key:Value" PAIRS IN MAP - IS CONSISTENT WITH -
SIMILAR USE OF THE COLON ":" TO SEPARATE THE "Parameter" FROM THE "Value" AND THE USE OF THE COMMA "," TO SEPARATE "parameter:value" PAIRS IN OBJECT.
THE COLON ALSO SERVES TO DISTINQUISH MAP SHORTHAND [:,:, ..., :] ENTRIES FROM ARRAY {,, ..., } ENTRIES.

User avatar
Chunjee
Posts: 1650
Joined: 18 Apr 2014, 19:05
Contact:

Re: Map shorthand

Post by Chunjee » 02 Jan 2025, 13:46

DrReflex wrote:
02 Jan 2025, 03:45
mVar := [key1:value1,key2:value2, ... , keyN,valueN]
I like this idea

Descolada
Posts: 1494
Joined: 23 Dec 2021, 02:30

Re: Map shorthand

Post by Descolada » 03 Jan 2025, 02:00

I also support the [key1:value1, key2:value2] syntax, but both key and value would have to be expressions for it to be useful, meaning quotes couldn't be omitted if creating a key/value for a string literal. Ternary else part should take precedence so [a ? "a" : "b": "value"] would use key "b" if a is false (or just require parenthesis if key/values is not an identifier, member/item access, or literal?).
It'd also be nice to somehow define the case-sensitivity of the map during the creation as well...

iPhilip
Posts: 865
Joined: 02 Oct 2013, 12:21

Re: Map shorthand

Post by iPhilip » 09 Jan 2025, 23:39

Descolada wrote:
03 Jan 2025, 02:00
I also support the [key1:value1, key2:value2] syntax, but both key and value would have to be expressions for it to be useful, meaning quotes couldn't be omitted if creating a key/value for a string literal. Ternary else part should take precedence so [a ? "a" : "b": "value"] would use key "b" if a is false (or just require parenthesis if key/values is not an identifier, member/item access, or literal?).
It'd also be nice to somehow define the case-sensitivity of the map during the creation as well...
:thumbup:
Windows 10 Pro (64 bit) - AutoHotkey v2.0+ (Unicode 64-bit)

Post Reply

Return to “AutoHotkey Development”