AHK v2 and strings

Discuss the future of the AutoHotkey language
User avatar
jeeswg
Posts: 4783
Joined: 19 Dec 2016, 01:58
Location: UK

AHK v2 and strings

09 Sep 2017, 01:07

==================================================

AHK V2 AND STRINGS:

==================================================

INTRODUCTION:

suggestions:
- 'CdLn' custom function for preparing command line parameters
- Deref function restored as a built-in function or as a custom function
- one-line 'continuation sections' (AHK v1/v2 compatible), code name 'Verbatim'
- Format function to accept variable names inside the FormatStr parameter

issues:
- Format doesn't handle variable names
- handling paths with hardcoded 'A_'/environment variables: e.g. '%AppData%\MyDir'
- improved readability gained in certain circumstances by using %%
- inconvenience of 4-line continuation sections for assigning 1 line of text
- a custom Deref function cannot identify escaped (i.e. literal) % signs
- a custom Deref function cannot distinguish between local/global variables
- a Deref function could support objects as well as variables
- %% is not just an AHK thing, it's a Windows thing

characters:
- " - paths use double quotes a lot
- % - paths use percent signs a lot (environment variables)
- {} - Send/SendInput use curly braces a lot
- () - functions use parentheses a lot
- " - functions use double quotes a lot
- , - functions use commas a lot
- " and ' - handling strings that contain both " and '

==================================================

BENEFITS OF %%:

- %% is not just an AHK thing, it's a Windows thing, people are tempted to keep it not just because they're used to it, but because it's a common notation used by Windows for paths.

- %% can be used to improve readability:

Code: [Select all] [Expand] [Download] GeSHi © Codebox Plus



- %% may appear in path names in selected text, and can be useful for storing paths in ini files:

Code: [Select all] [Download] GeSHi © Codebox Plus

%A_Desktop%\MyFile.txt
%A_ScriptDir%\MyFile.txt
%vDirLogs%\MyFile.txt
%A_ScriptDir%\MyLog %A_YYYY%-%A_MM%.txt
C:\Users\%username%\AppData\Roaming\Microsoft\Windows\Recent

This highlights the importance of having a Deref function that can handle % signs.

- Although for simple paths, environment variables do not always aid readability particularly:
vPath := Deref("%A_Desktop%\MyFile.txt")
versus:
vPath := A_Desktop "\MyFile.txt"

It is better, in an ini file, to store:
'%A_Desktop%\MyFile.txt'
versus:
'A_Desktop "\MyFile.txt"'
And it is easier to copy/paste/modify strings back and forth between Explorer and the AHK editor, if they are stored in a form that is closer to the original paths. It is also easier to manipulate and perform text operations on the environment variable form.

- The %% notation doesn't just have to be used for variables:
var := Deref("text%var%text")
it could be extended to handle objects e.g.:
var := Deref("text%obj.key%text")

- When considering notation for dereferencing:
{} - Send/SendInput use curly braces a lot
() - functions use parentheses a lot
% - % is a character that is used very rarely and is quite bold and easy to identify

==================================================

BENEFITS OF AN (AMENDED) DEREF FUNCTION:

- The Deref function traditionally used `% to specify a literal percent sign, I am not necessarily against that, but my instinct is to not use such special handling, I would rather just do this:

Code: [Select all] [Download] GeSHi © Codebox Plus

vNum := 20, vPct := "%"
MsgBox, % Deref("roughly %vNum%%vPct% of AutoHotkey users")

Note: if there was no built-in Deref function, I would have to use such a workaround anyhow.

- The Deref function could be made to handle objects:

Code: [Select all] [Download] GeSHi © Codebox Plus

obj := {key:20}, vPct := "%"
MsgBox, % Deref("roughly %obj.key%%vPct% of AutoHotkey users")

Note: a custom Deref couldn't distinguish between local/global variables. I would have to use a workaround such as this:

Code: [Select all] [Download] GeSHi © Codebox Plus

obj := {num:20, pct:"%"}
MsgBox, % Deref("roughly %obj.num%%obj.pct% of AutoHotkey users", obj)


- There is the option that %% could return a literal %, but I would be careful before settling on what %% could be used for, if anything.

- A Deref function could have a parameter with special options, e.g. to prefer environment variables where they exist, to use environment variables as a backup if no variable is found, and to change which character is used to do the dereferencing.

==================================================

ISSUES WITH COMMAND LINE PARAMETERS AND DOUBLE QUOTES:

I had thought that maybe bringing `" into AHK v1, if possible, could be a fix for string issues relating to double quotes in AHK v1/v2, but after considering many possible solutions for this issue, I don't think it would be a good solution ...

Examples of some of the possibilities re. command line parameters:

Code: [Select all] [Expand] [Download] GeSHi © Codebox Plus


Code: [Select all] [Expand] [Download] GeSHi © Codebox Plus


Code: [Select all] [Download] GeSHi © Codebox Plus

;suggestion:
Verbatim, vOpt, vTarget, "%vPathExe%" "%vPath%" ;AHK v1/v2
Run(vTarget)


==================================================

BENEFITS OF A ONE-LINE CONTINUATION SECTION:

i.e. a special 'Verbatim' command:

- the inconvenience of 4-line continuation sections for assigning 1 line of text

- the avoidance of extra quote or escape characters that make text less readable
" - paths use double quotes a lot
" - functions use double quotes a lot
" and ' - single/double quotes can merge together appearance-wise, i.e. they can look unclear in many fonts, making it hard to distinguish between the characters

- text can be maintained in its original form, which is useful for copy and paste

- the convenience of special options such as an environment variable mode, so you could just use %username% instead of %A_UserName% etc

- useful for AHK v1 forwards compatibility to AHK v2, if the command was to have the same behaviour in both versions

==================================================

FORMAT FUNCTION:

- Format doesn't handle variable names (at present)

- Send/SendInput use curly braces a lot, but so does Format, this again suggests the potential usefulness of the Deref function.

- Here's how I might use Format to do a particular task from earlier. Also, if Format could handle variable names, or objects/keys, one idea might be:

Code: [Select all] [Download] GeSHi © Codebox Plus

vNum := 20, obj := {key:20}
MsgBox, % Format("roughly {}% of AutoHotkey users", vNum)
MsgBox, % Format("roughly {1:i}% of AutoHotkey users", vNum)
MsgBox, % Format("roughly {vNum:i}% of AutoHotkey users")
MsgBox, % Format("roughly {obj.key:i}% of AutoHotkey users")

;if there was the potential for any number versus variable name clashes, unlikely since in AHK v2, variable names can't begin with a digit, you could put the variable name in brackets:
MsgBox, % Format("roughly {(vNum):i}% of AutoHotkey users")


Thanks for reading.
HotKeyIt
Posts: 1664
Joined: 29 Sep 2013, 18:35
Contact:

Re: AHK v2 and strings

09 Sep 2017, 02:48

With regards to deref function, take a look at macro functions in AHK_H v2:

Code: [Select all] [Expand] [Download] GeSHi © Codebox Plus

User avatar
jeeswg
Posts: 4783
Joined: 19 Dec 2016, 01:58
Location: UK

Re: AHK v2 and strings

09 Sep 2017, 03:04

Thank you HotKeyIt, I'm not quite sure how a macro function differs from a normal function, or if this addresses any of the issues where I said that a built-in Deref function could have capabilities that a custom Deref function couldn't have e.g. escaped % and local/global variable handling. I will check the AHK_H help.

Re. attempts at a custom Deref function, I've found three variations from searching txt file backups of my posts:
objects: define succinctly, retrieve dynamically - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=5&t=33530&p=155519#p155519
objects: define succinctly, retrieve dynamically - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=5&t=33530&p=156575#p156575
Re: v2.0-a079-be5df98 - Loop statements - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=37&t=32941&p=153249#p153249
HotKeyIt
Posts: 1664
Joined: 29 Sep 2013, 18:35
Contact:

Re: AHK v2 and strings

09 Sep 2017, 04:08

Correct, macro function will use callers scope except for parameters, those will be local, see: Macro functions
User avatar
jeeswg
Posts: 4783
Joined: 19 Dec 2016, 01:58
Location: UK

Re: AHK v2 and strings

09 Sep 2017, 20:08

I searched here for 'macro', and it turns out they're very new (09 Jul 2017, 2 months ago):
AutoHotkey Community - Search
https://autohotkey.com/boards/search.php?st=0&sk=t&sd=d&sr=posts&author_id=60
[AHK_H v2] Macro functions - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=65&t=34227

Functions
https://hotkeyit.github.io/v2/docs/Functions.htm#Macro

Macro will use caller's scope for all variables except for parameters, function parameters will be resolved to local variables.
Dynamic variable references will also use caller's scope.

Global and static variables are not supported in macros.


This is very interesting, and I had been wondering which commands/functions can't be recreated via standard functions due to scope issues (and for any other reasons generally). I can think of:
- Deref
- RegExMatch: variable mode
- StringSplit
- SysGet: Monitor subcommand
- WinGet: ControlList/ControlListHwnd/List subcommands

Also, I think SubStr has to be a variadic function for example.

Also, I'm curious as to whether you had any particular need to pursue the macro function functionality, interestingly you cite Deref itself as an example at the webpage. Cheers.
_3D_
Posts: 182
Joined: 29 Jan 2014, 14:40

Re: AHK v2 and strings

10 Sep 2017, 03:46

Probably this is for ahk_h not for v2 due to v2 now havent deref and macro.
AHKv2.0 use the future now.
HotKeyIt
Posts: 1664
Joined: 29 Sep 2013, 18:35
Contact:

Re: AHK v2 and strings

10 Sep 2017, 04:16

I had the idea long ago when I reused same code in various places in a script. Gosub and functions were not very convenient because you would need to use global variables or pass a lot of variables to the function.
When deref was removed in v2, I thought it is now time to build such macro feature.
User avatar
jeeswg
Posts: 4783
Joined: 19 Dec 2016, 01:58
Location: UK

Re: AHK v2 and strings

10 Sep 2017, 04:44

@_3D_: AHK v1 has Transform's Deref subcommand, and initially AHK v2 did have a Deref function. Although my instinct would be that escaping `% be removed, I could probably work around it whether it was kept or removed.

If possible I would recreate the Deref function myself, but in this case an effective cloned custom function is not possible due to scope issues.

In temporary and permanent scripts in AHK v1 I like to present paths like this:
vPath = %A_Desktop%\MyFile %A_Now%.txt
For AHK v2 I would like to do this, which used to be possible:
vPath := Deref("%A_Desktop%\MyFile %A_Now%.txt")

I do not like this, even though it's shorter:
vPath := A_Desktop "\MyFile " A_Now ".txt"

@HotKeyIt: Interesting, cheers.
_3D_
Posts: 182
Joined: 29 Jan 2014, 14:40

Re: AHK v2 and strings

10 Sep 2017, 09:04

Changes sins 2.079 https://autohotkey.com/boards/search.php?author_id=77&sr=posts
Yep sintax:= "`% variable + 1000" removed from v2
still valid val:= var "string" / val:= %var%
not valid val:= "%var%" / % var "string"
In other words v2 can`t transfer variables inside the strings more.
Deref https://autohotkey.com/boards/viewtopic.php?f=37&t=36434
AHKv2.0 use the future now.
User avatar
jeeswg
Posts: 4783
Joined: 19 Dec 2016, 01:58
Location: UK

Re: AHK v2 and strings

30 Sep 2017, 05:55

For a Verbatim 'command', some options would be:
- e1: dereference any environment variables before other variables
- e2: dereference any normal variables first, if the contents are blank, check if an environment variable exists
- d%: use % as the dereference character for variables and obj.key, you can specify any character e.g. d| to use pipe, perhaps d by itself would default to d%
- d{}, d(), d[], d`s, d`t, d09, d32: some special delimiter options for brackets/spaces/tabs
- note: e1 and e2 would assume a delimiter of % if not specified
- `: to make ` literal (in this sense Verbatim is not literal by default)
- C: to allow semicolon comments
- % / , / Q / Join: wouldn't be necessary (cf. continuation sections)
- LTrim / LTrim0 / RTrim0: wouldn't be necessary, the string starts at the first non-whitespace character, and ends at the last non-whitespace character: use `s / `t / A_Space / A_Tab for leading/trailing whitespace

Verbatim would be a good substitute for 'var = value', which is one relic of AHK v1 that I believe had some advantages, including for handling command line parameters and text with single and/or double quotes. I also like to be able to create literal comma-separated lists that don't end with a ".

AutoHotkey Scripts and Macros
https://autohotkey.com/docs/Scripts.htm#continuation
AutoHotkey Scripts and Macros
https://lexikos.github.io/v2/docs/Scripts.htm#continuation

==================================================

For double quotes "" is quite good, and adds compatibility with Excel (and AHK v1) and possibly other languages. I'm not sure if it's possible to have both "" and `" in AHK v2.

Code: [Select all] [Download] GeSHi © Codebox Plus

MsgBox, % StrLen("a""a") ;AHK v1
;=LEN("a""a") ;Excel
return

;MsgBox(StrLen("a`"a")) ;AHK v2
User avatar
jeeswg
Posts: 4783
Joined: 19 Dec 2016, 01:58
Location: UK

Re: AHK v2 and strings

10 Apr 2018, 18:45

- I was thinking about simpler alternatives to some of these ideas that might be popular.
- I decided that two things were really important: maintaining 'var = value' in some form, and maintaining the equivalent of %var% in continuation sections.

VAR = VALUE / VERBATIM TEXT
- For 'var = value':

Code: [Select all] [Download] GeSHi © Codebox Plus

var `= value
;or a different operator, or:
Verbatim var, value
;or Verbatim/Assign/Literal/Text/another name:
Verbatim var, options, value ;where options is hardcoded
;or something quite different
- I've removed the options parameter. For anything fancy, a continuation section could be used.
- I know that having both single and double quotes to mark the start/end of a string gets us pretty close to having verbatim one-liners. However, I think it's worth it to know that you can simply paste the text in, and it will work without problems. E.g. when writing quick code. Also, you have the advantage of not needing to add trailing/leading quotes. And you can define variables 'lazily' initially, but then use a parser to tidy up the definitions later. I think that convenience/ease-of-use is a key principle of AutoHotkey.
- Also, sometimes text contains both single quotes and double quotes. And sometimes the quotes blur with the start/end text, making it less readable. E.g. to specify a single/double quote by itself you need: "'" or '"', which aren't great. Neither are Chr(39) or Chr(34).
- Also, IMO it's the mark of a good programming language to have good verbatim text support. And if *all* languages could be relied upon to support this, that would be greatly beneficial.
- And yes, two-way compatibility is a good reason.
- Note: I would suppose that since such text would be interpreted literally, and if no options parameter were allowed, you could not write comments on such a line, i.e. ' ;', would be interpreted literally. Which I'm OK with. It's possible that the 'command' would be sufficiently useful, or perhaps better, without the options parameter. Continuation sections would still be available for anything fancy.

'DEREFERENCE' TEXT
- E.g. it's been mentioned before that something like this would be useful:
vText := "Hello {Name}"
- I do not think that the syntax of AutoHotkey should be changed. However, having a function that can parse text like this would be a good thing.
- The Format function could accept an associative array for example:
MsgBox, % Format("Hello {Name}", {Name: "My Name"})
- Also, the Format function by default uses { and }, I think it would be good to be able to change these characters temporarily. Perhaps via an 'A_' variable, that takes a string 2 characters in length, either that must be different, or possibly where they can be the same.
- Potentially you could have {1.key1} and {2.key1}, the first would get 'key1' from the object in the first parameter, and the second would get 'key1' from the object in the second parameter. ('key1' by itself/any non-integer might mean get 'key1' from the object in the first parameter, and '1'/any integer might mean get the text of the string in the first/nth parameter, as it does now.)

A_COMMA
As AutoHotkey becomes more function-y, with the move to all expression-style parameters. At least A_Comma could be useful, I know that I would use it occasionally. Other candidate characters are parentheses and single/double quotes (A_SQ/A_DQ).

Code: [Select all] [Download] GeSHi © Codebox Plus

vText := StrReplace(vText, ", ", ",")
vText := StrReplace(vText, A_Comma " ", A_Comma)
vText := StrReplace(vText, A_Comma A_Space, A_Comma)

CONTINUATION SECTIONS
- I think it would be good to have a two-way compatible way to write multi-line verbatim text in both AHK v1/v2. Potential obstacles are AHK v1 handling ", and the choice of a letter to indicate the setting (perhaps V).

OTHER POINTS
- The CdLn function is nice, although if it wasn't built-in, I wouldn't mind.
- I've accepted that Deref might not be added in, and I can create my own custom function, that is almost as good.
- I do think that something like DerefEnv would be useful for lines like vPath := "C:\Users\%username%", to prepare the sort of text that the Run dialog supports, however, I could create my own function for this also.

Thanks for reading.

[EDIT:] Being able to switch code from var = value to var `= value (with possibly a few edits being required), or having a Format function that can handle %% instead of {}, and that can take an object (associative array), are very useful for simple manual conversions of old files, and avoiding suddenly adding new bugs to scripts.
User avatar
jeeswg
Posts: 4783
Joined: 19 Dec 2016, 01:58
Location: UK

Re: AHK v2 and strings

06 May 2018, 09:47

VAR = VALUE (NOT VERBATIM)

Code: [Select all] [Download] GeSHi © Codebox Plus

var = value ;AHK v1
var `= value ;AHK v1/v2 ;same as 'var = value' except that perhaps %var% is not dereferenced
`s could be made available in AHK v1 for var `= value
'var `= value' would be verbatim apart from `, and comment handling

CONTINUATION SECTIONS (AND VERBATIM)
For verbatim text perhaps a two-way compatible V verbatim mode e.g. '(V Join`r`n':
This works in AHK v2 at the moment, but % and " are problems in AHK v1.

Code: [Select all] [Expand] [Download] GeSHi © Codebox Plus

User avatar
jeeswg
Posts: 4783
Joined: 19 Dec 2016, 01:58
Location: UK

Re: AHK v2 and strings

14 May 2018, 18:47

I wanted to create a quick list of paths in a continuation section, where the paths were written in expression style. It took me a little while to figure out.

Code: [Select all] [Expand] [Download] GeSHi © Codebox Plus


Return to “AutoHotkey v2 Development”

Who is online

Users browsing this forum: No registered users and 2 guests