Re: v2.0-a079-be5df98 - Loop statements

Discuss the future of the AutoHotkey language
just me
Posts: 9424
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: v2.0-a079-be5df98 - Loop statements

11 Jun 2017, 02:56

Hi lexikos,

that's actually a 'big bang' (and a big source of motivation for me ;)).

Must have been really much work, thank you!
Last edited by just me on 19 Jun 2017, 03:02, edited 1 time in total.
User avatar
runie
Posts: 304
Joined: 03 May 2014, 14:50
Contact:

Re: Re: v2.0-a079-be5df98

11 Jun 2017, 05:09

Seconded, this looks very cool :bravo:
just me
Posts: 9424
Joined: 02 Oct 2013, 08:51
Location: Germany

Loop statements

11 Jun 2017, 16:00

In this version AHK v2alpha raises an error for:

Code: Select all

Loop, Rows
Line Text: Loop, Rows {
Error: Function calls require a space or "(". Use comma only between parameters.
On the other hand

Code: Select all

Loop Parse, "ABC"
   MsgBox(A_Index . ": " . A_LoopField)

Loop Files, A_WinDir . "\Web\Wallpaper\*.jpg", "FR"
   MsgBox(A_Index . ": " . A_LoopFileFullPath)
Until (A_Index = 3)
both raises errors respectively do nothing without the comma after Parse or Files. Since the 'command syntax' has been removed, I don't understand the state of Parse and Files. Are they parameters? Then they should be "strings". If not, they should be part or the name of the command, e.g. Loop-Parse, LoopParse, Loop-Files, LoopFiles.
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: Re: v2.0-a079-be5df98

11 Jun 2017, 16:08

Rather good. :clap: :bravo: (I always get nervous whenever AHK v2 gets changed.)

- removing 'AutoDeref' (my term, i.e. 'auto deref within strings') (although Deref for %var% variables within strings can be achieved with a custom function)
- `s like `t (cf. A_Space and A_Tab)
- FileRead first n bytes RAW
- et al. (including many features that had been previously announced)

Link:
AutoHotkey v2 alpha (UPDATES) - AutoHotkey Community
https://autohotkey.com/boards/viewtopic ... 36#p153136

I have done some tests and made some comments for anyone interested:

Code: Select all

#SingleInstance force
return

;==================================================

;variable names

;q::
a := 1
b := 2
c := 3
var1 := "A"
var2 := "B"
var3 := "C"
MsgBox(var%a%) ;still works as normal
return

;==================================================

;expressions within strings (variable names)

;it seems that 'AutoDeref' as I call it,
;which wasn't present in AHK v1 has been removed,
;and that so has the AHK v2 Deref function
;which was equivalent to 'Transform, var, Deref',
;however I believe that a Deref is still potentially useful,
;although you must be aware that my function
;refers to global variables

;q::
a := 1
b := 2
c := 3
vText1 := "a%a%b%b%c%c%"
vText2 := JEE_Deref(vText1)
MsgBox(vText1 "`r`n" vText2) ;a%a%b%b%c%c% a1b2c3

;I always like to be able to write paths/command lines
;in a form ready for copy and paste to Explorer

username := A_UserName
vPath1 := "C:\Users\%username%\Desktop"
vPath2 := JEE_Deref(vPath1)
MsgBox(vPath1 "`r`n" vPath2)
return

;==================================================

;expressions within strings (mathematics)

;q::
vText := "a%1+1%b"
MsgBox(vText) ;a%1+1%b
return

;==================================================

;`s within strings

;I can't tell you how happy I am to see `s in AutoHotkey!

;q::
vText := "a`sb`sc" "`r`n" "a`s`sb`s`sc" "`r`n" "a `s b `s c" "`r`n" "a `s`s b `s`s c" "`r`n" "a`s`s`s`s b`s`s`s`s c"
MsgBox(vText)
return

;==================================================

;`s hotstrings

;:?*:abc`s:: ;didn't work
;:?*:abc`t::
;:?*:abcd::
MsgBox(A_ThisHotkey)
return

;:?*:abcd1::qwe`srty`s ;didn't work
;:?*:abcd2::qwe`trty`t
;:?*:abcd3::qwe rty `

;another character with hotstring issues is ':' (colon)

;possibly A_DQ, A_DQuote or something similar would be good for " (double quote)

;==================================================

;new-style commands:
;Cmd Arg1, Arg2, Arg3 (correct)
;Cmd, Arg1, Arg2, Arg3 (incorrect)

;note: is the style that uses omission of the first comma common?
;i.e. present in some well-known programming language(s)?
;I noticed that Coco's functions used this style

;q::
;MsgBox, "hello" ;didn't work (as expected)
;MsgBox, vText ;didn't work (as expected)
vText := "hello world"
MsgBox "hello"
MsgBox vText
return

;==================================================

;FileRead/FileAppend (CRLF/LF and RAW)
;really nice to be able to do raw read,
;and specify the number of bytes

;q::
vText := "a`r`nb`r`nc`r`nd`r`ne"
;vText := "a`nb`nc`nd`ne"
vPath := A_Desktop "\z test " A_Now ".txt"
vPath2 := JEE_Deref("%A_Desktop%\z test %A_Now%.txt")
MsgBox(vPath "`r`n" vPath2)
;MsgBox(vText)
FileAppend(vText, vPath)
;cf. AHK v1, * needed to prevent lone LFs to CRLFs
;FileAppend, % vText, % "*" vPath
vText := ""
vText := FileRead(vPath)
StrReplace(vText, "`r`n", "`r`n", vCount1)
StrReplace(vText, "`n", "`n", vCount2)
MsgBox(vCount1 "`r`n" vCount2 "`r`n" vText)

vText := FileRead(vPath, "m7") ;get the first 7 bytes
MsgBox(vText)

vData := FileRead(A_AhkPath, "m25 RAW")
vOutput := ""
Loop 25
{
	vNum := NumGet(vData, A_Index-1, "UChar")
	vNum := vNum ? vNum : 32
	vOutput .= Chr(vNum)
}
MsgBox(vOutput)
return

;FileAppend
;https://autohotkey.com/docs/commands/FileAppend.htm

;FileAppend
;https://lexikos.github.io/v2/docs/commands/FileAppend.htm

;==================================================

;'RegCreateKey'

;Apologies if I've missed something, but I still
;can't see some kind of 'RegCreateKey' possibility,
;to create a key without creating a value
;(a workaround being: RegWrite, to create a value and a key,
;RegDelete to delete the value)

;RegWrite
;https://lexikos.github.io/v2/docs/commands/RegWrite.htm

;create empty registry key - AutoHotkey Community
;https://autohotkey.com/boards/viewtopic.php?f=5&t=26245

;==================================================

;'RegMoveKey'

;Btw would a 'RegMoveKey'/'RegRenameKey' be straightforward,
;or would it involve cloning and deleting the original key,
;RegEdit makes renaming a registry key look quite easy

;==================================================

;Deref function and new-style commands

;note: at present, I believe, the new Loop syntax,
;does not make two-way compatibility possible,
;essentially I think allowing '% expression' for all parameters
;in AHK v2 would be a good solution for this
;people can argue over how important two-way compatibility is,
;I say it's always worthwhile

;note: this function cannot distinguish between
;normal percent signs and escaped percent signs

;note: a more advanced second Deref function might be possible,
;if strings could be executed as code dynamically, perhaps,
;but this is not a priority for me

JEE_Deref(vText)
{
	global
	vOutput := ""
	Loop Parse, vText, "%"
		vOutput .= (A_Index & 1) ? A_LoopField : %A_LoopField%
	return vOutput
}

;==================================================
Last edited by jeeswg on 11 Jun 2017, 17:18, edited 5 times in total.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: Re: v2.0-a079-be5df98

11 Jun 2017, 16:23

Diligent work. :salute:
Spoiler
guest3456
Posts: 3454
Joined: 09 Oct 2013, 10:31

Re: Re: v2.0-a079-be5df98

11 Jun 2017, 18:15

are there no commas allowed after a Command name anymore? what is this

coffee
Posts: 133
Joined: 01 Apr 2017, 07:55

Re: Loop statements

11 Jun 2017, 22:56

just me wrote:Then they should be "strings". If not, they should be part or the name of the command, e.g. Loop-Parse, LoopParse, Loop-Files, LoopFiles.
LoopFiles() used to exist along with the other versions, looked clean, I thought it was the clear choice onwards. I wonder what happened :(
The chimera supports OTB though, like LoopVariant(), so I guess it kept the flexibility.

superlate edit

Code: Select all

files:=5

Loop files ; Loop(files) -> also works, simple count
	msgbox(a_index)

Loop files, "V:\Movies Unwatched\*.mp4" { ; works fine, but doesnt follow the rest of the syntax rules
; Loop files("params") or Loop(files, "params") or Loop("files", "params") is not possible
	msgbox(a_loopfilename)
	msgbox(a_LoopFileExt)
}

; LoopType "params" -or- Loop "type", "params" would be much less ambiguous
; Following Loop(count), as functions style: LoopType("params") -or- Loop("type", "params")
; and would maintain consistency by working like Loop(count) or by making Loop a multipurposed loop command(?)
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: Re: v2.0-a079-be5df98 - Loop statements

23 Jun 2017, 01:47

@guest3456
I noticed you stating that your Gdip conversion can no longer be two-way compatible, is that solely because of:

v2-changes
https://autohotkey.com/v2/v2-changes.htm
•There is no percent-space prefix to force an expression.
or are there other reasons?

I would have thought that if a function syntax version of Loop was added to AHK v1 and AHK v2, and that if you use function versions of commands, then two-way compatibility would still be possible? Or are there further complications?

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

@coffee
LoopFiles() does look pretty cool, plus it's cleaner, hmm. Plus as you imply, 'Loop' by itself could then be an unambiguous 'loop n times' control flow statement.

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

@Helgef
Cheers, I wasn't sure if you meant Lexikos and/or me, cheers anyhow.

Yeah just testing whether to use all `s, and/or a regular space at the beginning/end, re. clarity.

Code: Select all

;all equivalent:
vText := "a`s`s`sb`s`s`sc" ;preferable?
vText := "a`s`s b`s`s c" ;perhaps a bit confusing
vText := "a `s`sb `s`sc" ;perhaps a bit confusing
vText := "a `s b `s c" ;perhaps a bit confusing (in some fonts, the gap here: 'a `s', can look like 2 literal spaces)
vText := "a`s`s`s" "b`s`s`s" "c" ;alternative

vText := StrReplace(vText, "`s`s", " ")
vText := StrReplace(vText, A_Space A_Space, " ")
==================================================
•There is no comma between the function name and parameters, so MouseGetPos(, y) = MouseGetPos , y (x is omitted). A space or tab is required for clarity.
This is a *big* change. To force the comma behaviour, I had been thinking that AHK should recommend one approach over the other. 'Sleep 10' v. 'Sleep, 10'. There's a nice symmetry in 'it's just the function syntax minus the (round) brackets'. (I'll have to do so much conversion...) [EDIT:] (Actually I won't, because I was converting everything to function syntax anyway.)

[post 1200]
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: 9553
Joined: 30 Sep 2013, 04:07
Contact:

Re: Re: v2.0-a079-be5df98 - Loop statements

23 Jun 2017, 21:52

I simplified the concept of "command" to "just a function or method call without parentheses (at the start of a line)".

Loop is not a function, therefore Loop x and Loop Parse, y are not commands.

Control flow statements were and are necessarily grammatically separate to "commands"/function calls. Function calls do not support or have any use for OTB, or attaching a statement or block. Function calls strictly take a list of parameters, while control flow statements can and do have more specific, more expressive syntax. For instance, for x, y in obj is more flexible (, y can be optional while still requiring obj) and easier to understand than for x, y, obj. Control flow statements aren't simple functions, and there's little reason to pretend that they are.

Parse, Read, etc. are not parameters any more than Loop or in are parameters. There is dubious benefit to requiring quote marks or allowing variables/expressions for the sub-command. (As for requiring, allowing or not allowing the comma, I had deferred thinking about it as I was losing interest and approaching the end of the weekend. It is in my notes to revisit.)

LoopParse() etc. were labelled "experimental" from the start. I added them as an obvious method of giving authors a way to use expression syntax uniformly across the entire script (avoiding commands and the % prefix), but that's been superseded. It seemed obvious because it looks like a function call. On the other hand, it looks like a function call or definition, but is neither. I decided that the original "sub-command" approach was clearer. It goes without saying that any statement beginning with "Loop " (with space) is a loop statement, whereas the same can't be said for any statement/function name beginning with "Loop" (without space).

One (perhaps contrived) drawback of the function-like syntax is that typos may go undetected:

Code: Select all

Looparse(x, y) {
    ; this doesn't raise an error.
}
I continue to consider replacing Loop Parse etc. and A_Loop variables with enumerators and enumerated objects, like for x in string.substrings(",") or for file in files("*") ... path := file.FullPath. The main deterrents are performance (objects and dynamic calls such as string.substrings() are slower and have more memory overhead), and increased complexity for Loop Files/Reg (they are currently implemented with simple recursion, but enumerators require an iterative approach).
just me
Posts: 9424
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Re: v2.0-a079-be5df98 - Loop statements

24 Jun 2017, 02:48

Personally, I'm not interested in using 'function syntax' in control statements. I was simply suprised that the concept of 'sub-commands' (keywords) was preserved for Loop statements, requiring a comma after the keyword whereas the original command (Loop) doesn't accept a comma any more. What would be the drawback of distinct commands like LoopParse, LoopFiles, etc. following the same 'comma rules' in your opinion?
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: Re: v2.0-a079-be5df98 - Loop statements

22 Jul 2017, 19:58

COMMAS

I've thought about command notation, and I think that:
Cmd, Param1, Param2
is more elegant, and easier to read, than:
Cmd Param1, Param2
especially when you have very complicated parameters:
MyCommand, 1 + MyFunc(2 - 3 * 4 / 5), Param2
MyCommand 1 + MyFunc(2 - 3 * 4 / 5), Param2
Sometimes it's even hard to tell when the command name ends and the first parameter begins. I tend to only omit the comma for something simple like 'Sleep 1000', or 'SendInput a'.

There is the issue, that choosing one of forcing comma, or forcing no comma, would lead to greater consistency in scripts; and that forcing comma, means typing an extra character; but (a) I don't mind two methods personally, (b) if I had to pick one method, it would definitely be the force comma method.

The changes being made in AHK v2, are making AutoHotkey a more elegant language generally, and I think this is a good argument for either 'force comma' or 'prefer comma'.

LOOPS

I would advocate for 5 loop 'commands/functions': Loop LoopFiles LoopParse LoopRead LoopReg. This is consistent with splitting up ControlXXX, DriveXXX, Menu(?), Process, SysGet and WinXXX, and is nicer to read in both command and function syntax, and gets rid of the 'weird parameter with no double quotes' issue. Also it makes it easier to refer to things, and to be simultaneously more concise and precise: 'use a parsing loop' v. 'use LoopParse'.

If there is no function-style syntax for the 5 Loop control flow statements, then one would need to have force expression available, in order to have AHK v1 and AHK v2 be two-way compatible. At the moment I know of no other obstacle to two-way compatibility, and there were no obstacles until force expression was done away with. So in my view this argues in favour of a function-style syntax to be available for Loop, but also to allow force expression for Loop, in the meantime, in AHK v2 alpha, until such a syntax is available. It is very useful to have two-way compatibility *as you convert your scripts*, in the back and forth process.

Interested to hear plans for in/contains. Thanks for reading.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
just me
Posts: 9424
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Re: v2.0-a079-be5df98 - Loop statements

23 Jul 2017, 03:51

jeeswg wrote:If there is no function-style syntax for the 5 Loop control flow statements, then one would need to have force expression available, in order to have AHK v1 and AHK v2 be two-way compatible. At the moment I know of no other obstacle to two-way compatibility, and there were no obstacles until force expression was done away with. So in my view this argues in favour of a function-style syntax to be available for Loop, but also to allow force expression for Loop, in the meantime, in AHK v2 alpha, until such a syntax is available. It is very useful to have two-way compatibility *as you convert your scripts*, in the back and forth process
The 'traditional' syntax has been eliminated with v2.0-a079-be5df98. So there is no need nor would it make sense to force an expression.
User avatar
derz00
Posts: 497
Joined: 02 Feb 2016, 17:54
Location: Middle of the round cube
Contact:

Re: Re: v2.0-a079-be5df98 - Loop statements

23 Jul 2017, 08:25

@jeeswg if you don't like the looks of no comma, use Cmd(param1, param2)

It looks nice to me. You don't need to use the extra feature of omitting the parentheses.
try it and see
...
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: Re: v2.0-a079-be5df98 - Loop statements

23 Jul 2017, 11:49

Yes just me, your comment makes sense. It is unfortunate that (what I call) 'expression AutoDeref', and 'force expression', were removed in the same update. If 'AutoDeref' had been removed in one update, and 'force expression' in a later update, I would then have a very useful version for transitioning from AHK v1 to AHK v2.
- I know it's an unusual request, to temporarily restore i.e. allow 'force expression' just for Loop (until/unless there is a function-syntax version of Loop in AHK v1/v2), but if relatively easy to implement, it would be a smart move. I say this as someone who's maybe a little more proactive and realistic about conversion, than other people who just go with the flow. If I see something that will benefit AHK, I will say it.
- For various reasons, theoretically, I would have removed 'force expression', in the very last update to AHK v2 alpha, however, there may be other considerations that I was unaware of.

derz00, what you say is true, however, unfortunately I will be looking at other people's code from time to time. It actually makes me hazy sometimes to read code like that, where I can't readily visually distinguish between command name and parameter 1. Plus if no initial comma mode is forced, I can't even then correct/repair the code by adding in commas, unless there was a directive to allow initial commas. I gave it the benefit of the doubt initially, but through experience I now know where I stand.
- In theory, I liked the idea of the function/command symmetry, of commands as 'functions without parentheses'. I see that each has disadvantages: force no comma (quite serious readability issues), force comma (a bit pedantic for use with one short parameter), allow both (inconsistency amongst scripts). I would go with force comma, or allow both, as the least worst options.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
guest3456
Posts: 3454
Joined: 09 Oct 2013, 10:31

Re: Re: v2.0-a079-be5df98 - Loop statements

23 Jul 2017, 12:31

i too dislike the removal of the first comma for the 'command' syntax

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

Re: Re: v2.0-a079-be5df98 - Loop statements

13 Aug 2017, 08:56

Since I don't use the 'no initial comma' style usually, I haven't necessarily become aware of all the problems involved with using it. However, I was using this style to match Coco's code in AHK v2 functions for AHK v1, and noticed a further issue, things become ambiguous when the first parameter is blank:

Code: Select all

;no initial comma (more ambiguity)
Cmd Arg1, Arg2
Cmd , Arg2

;initial comma (clearer)
Cmd, Arg1, Arg2
Cmd,, Arg2
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: Re: v2.0-a079-be5df98 - Loop statements

15 Aug 2017, 17:58

@ jeeswg. I fail to understand what is ambiguous.
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: Re: v2.0-a079-be5df98 - Loop statements

15 Aug 2017, 18:18

Although in computing, you shouldn't necessarily expect anything to be immediately apparent or intuitive* **. I would argue that one of the notations in the example above, is more intuitive than the other, re. omitting the first parameter. Even after I worked out that it must be correct, 'Cmd , Arg2', I was still unsure. Looking at it now, 'Cmd , Arg2', it still doesn't inspire confidence, and leaves one uncertain.

What is ambiguous here? To someone who's never programmed before (or experts unfamiliar with such a notation):

Code: Select all

Cmd , Arg
Is that a blank parameter and a nonblank parameter, or just one nonblank parameter?

*Although you should be careful about breaking the principle of least astonishment.

**The mouse isn't even immediately intuitive to a first-time user:
Jef Raskin on "Intuitive Interfaces"
http://www.asktog.com/papers/raskinintuit.html
Last edited by jeeswg on 15 Aug 2017, 18:52, edited 1 time in total.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: Re: v2.0-a079-be5df98 - Loop statements

15 Aug 2017, 18:38

Someone how have never programmed should read the manual, you are biased from earlier experiences. Preferences aside, there is no ambiguity.
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: Re: v2.0-a079-be5df98 - Loop statements

15 Aug 2017, 18:47

'Although in computing, you shouldn't necessarily expect anything to be immediately apparent or intuitive' = you should always read the manual.

Of the two examples I posted above, I regard one set as being clearer than the other. No person should claim to be objective, but I did *try* to be objective, I did explore the advantages/disadvantages of both notations. Perhaps my preference is for the less ambiguous option.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA

Return to “AutoHotkey Development”

Who is online

Users browsing this forum: No registered users and 39 guests