why was LoopParse (no space) removed?

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

Re: why was LoopParse (no space) removed?

30 Dec 2017, 10:00

- Yes, just me, you're right on both counts.
- I like that we're trying to come up with a solution, at the moment we've got something that's improved the situation a bit, but AHK V1-ish, ambiguity-ish, quirky-syntax-ish dilemmas remain.
- I was trying to illustrate how they appear together in a list. But logically the 2nd list, would be more like yours. :(
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: why was LoopParse (no space) removed?

30 Dec 2017, 13:39

These are simply control flow statements which contains a space, it isn't harder to grasp than else if. Imho.

However, I'd like to see the removal of Files, Parse, Read and Reg, from the Parameters lists on their respective pages.

Cheers.
just me
Posts: 9423
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: why was LoopParse (no space) removed?

31 Dec 2017, 04:45

Helgef wrote:These are simply control flow statements which contains a space, it isn't harder to grasp than else if. Imho.
Good hint! Of course, v2 should implement ElseIf. ;)
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: why was LoopParse (no space) removed?

31 Dec 2017, 08:20

just me wrote:Of course, v2 should implement ElseIf. ;)
:D Happy new year!
just me
Posts: 9423
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: why was LoopParse (no space) removed?

01 Jan 2018, 06:55

Hi Helgef,
These are simply control flow statements which contains a space, it isn't harder to grasp than else if. Imho.
Else If ... is not a 'control flow statement which contains a space', it's a same line action.

Happy new year! :rainbow:
lexikos
Posts: 9553
Joined: 30 Sep 2013, 04:07
Contact:

Re: why was LoopParse (no space) removed?

01 Jan 2018, 08:21

@just me: If I change the implementation so that "else if" is its own statement, but the grammar for this statement allows or requires whitespace between the two words, how will you tell the difference?

For-in is a multi-word statement which has its own grammar, distinct from other statements.
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: why was LoopParse (no space) removed?

01 Jan 2018, 08:26

Technically that is correct :thumbup:. Which means else if is a little more complex than I argued, yet there are no problems grasping the concept, hence, my point stands. If you like, we can take the for-loop as an example instead, it is a control flow statement containing multiple keywords, spaces, optional parameters and comma, I don't think there is a general struggle with that either.

Cheers :rainbow:.
_3D_
Posts: 277
Joined: 29 Jan 2014, 14:40

Re: why was LoopParse (no space) removed?

01 Jan 2018, 08:29

loopParse vs loop "Parse"
There 2 main syntaxes for loop:

Code: Select all

loop [count] {				;loop "Count,"
} [until [expression]]
loop "loopCase" [param*] {	;loop "<Parse|Files|Read|Reg>,"
} [until [expression]]
in other words:

Code: Select all

loop "<Count|Parse|Files|Read|Reg>," [param*] { ;loop "Count," 10 == loop 10
} [until [expression]]
What alternatives are possible:
1. Keep simple syntax

Code: Select all

	loop [firstParam,] [param*] {
		;if firstParam is Integer - simple loop
		;if firstParam is String  - Parse|Files|Read|Reg loop in param[1], ...
	} [until [expression]]
2. Adding new reserved words but keep simple loop

Code: Select all

	loop [count] {			;firstParam is Integer
	} [until [expression]]
	loopParse [param*] {	;adding new reserved word
	} [until [expression]]
	loopFiles	- same as loopParse
	loopRead	- same as loopParse
	loopReg		- same as loopParse
I preffer 1.
loop "Parse" param or loop "Parse", param* (with or without comma)
As "Parse" is not the part of param* and just extend loop - comma not needed.

Code: Select all

loop "Parse" my_String, "|" { ; my favorite syntax 
	;action
}
AHKv2.0 alpha forever.
coffee
Posts: 133
Joined: 01 Apr 2017, 07:55

Re: why was LoopParse (no space) removed?

01 Jan 2018, 15:14

_3D_ wrote:loopParse vs loop "Parse"
There 2 main syntaxes for loop:

Code: Select all

loop [count] {				;loop "Count,"
} [until [expression]]
loop "loopCase" [param*] {	;loop "<Parse|Files|Read|Reg>,"
} [until [expression]]
in other words:

Code: Select all

loop "<Count|Parse|Files|Read|Reg>," [param*] { ;loop "Count," 10 == loop 10
} [until [expression]]
What alternatives are possible:
1. Keep simple syntax

Code: Select all

	loop [firstParam,] [param*] {
		;if firstParam is Integer - simple loop
		;if firstParam is String  - Parse|Files|Read|Reg loop in param[1], ...
	} [until [expression]]
2. Adding new reserved words but keep simple loop

Code: Select all

	loop [count] {			;firstParam is Integer
	} [until [expression]]
	loopParse [param*] {	;adding new reserved word
	} [until [expression]]
	loopFiles	- same as loopParse
	loopRead	- same as loopParse
	loopReg		- same as loopParse
I preffer 1.
loop "Parse" param or loop "Parse", param* (with or without comma)
As "Parse" is not the part of param* and just extend loop - comma not needed.

Code: Select all

loop "Parse" my_String, "|" { ; my favorite syntax 
	;action
}
I liked it that way once, but I didnt understand what the parse word was supposed to be. It's not a good fit. These words are not strings, not supposed to be an expression. v2 has or should have clear delineation between something that is supposed to be a string and something that is supposed to be a keyword/statement of the language. Why would parse, reg, files need to be a string if it's not to be considered a parameter/argument or something to be evaluated from the user's point? Loop files is the entire name of the statement, it's not a regular loop with some parameter files added, it's a loop files, that's the name, all of it a name.
What's next?

Code: Select all

iwantfiles:="files"
Loop iwantfiles, filepath ; NO
Let's follow an example, think of goto and gosub, but imagine they are - go to "label" - and - go sub "label" -, now you are asking to make them - go "to" "label" - or - go "sub" "label" - and just me is asking for - goto "label" - and - gosub "label" - (none of these are actually real just in case).

(edit, this paragraph is more about the previous goto discussion). But then a label has more in common with a function (aside from all the other stuff like scope, args etc) than a string, you "jump" to that point in the script and come back if needed, looking like a function, so *to me* (or maybe anyone who knows what a label is), it should simply only be goto label or gosub label, as im calling the label out, it's a "label call", and if there is an emphasis that THEY ARE NOT FUNCTIONS and need evaluation with a parenthesis format, then goto ("label") or goto (var) can be used, but we have goto("label") that also works. Even in v1, goto label has never been similar to msgbox idontknowifthisisastringoralongassvariablename, but has been more similar to label() <- function. You don't call functions like "functioname"(param, param), but they have their own dynamic way of calling, which interestingly were more similar in v1 with goto %var% and %var%().
Goto label is a "static label call" like function() and goto("label")/goto(var) is a dynamic label call like... func("function").call() ? in format obviously. Label names are static jump point elements in script's body like functions are.

LoopFiles or Loop files, whatever is done, it shouldn't look like a string or something you will be evaluating at the higher autohotkey level. So Loop "files" is incorrect all the way from 0 to 10, because files is part of the name Like saying Loop"files". And if there's an emphasis on THEY ARE NOT FUNCTIONS, LoopFiles() shouldn't be made possible, i.e only LoopFiles path, "dfr", but maybe it will, I don't know. ;D
_3D_
Posts: 277
Joined: 29 Jan 2014, 14:40

Re: why was LoopParse (no space) removed?

01 Jan 2018, 17:10

Yes I understand.
If Parse is not an expression why don`t be reserved word concatenated to loop. In this case loop family will become with clear syntax:

Code: Select all

loop(count) {
}
loopParse(string, delimiters, omitchars) {
}
loopFiles(filepattern, mode) {
}
...
loop<Name>(param*) { ; Name:= ["", "Parse", "Files", "Read", "Reg"]
}
May be when () become mandatory for any.

Code: Select all

list:= [5, 6, 7]
for key, val in list ; the same no comma before and after in 
	msgBox(val)
AHKv2.0 alpha forever.
coffee
Posts: 133
Joined: 01 Apr 2017, 07:55

Re: why was LoopParse (no space) removed?

01 Jan 2018, 17:55

_3D_ wrote:Yes I understand.
If Parse is not an expression why don`t be reserved word concatenated to loop. In this case loop family will become with clear syntax:

Code: Select all

loop(count) {
}
loopParse(string, delimiters, omitchars) {
}
loopFiles(filepattern, mode) {
}
...
loop<Name>(param*) { ; Name:= ["", "Parse", "Files", "Read", "Reg"]
}
May be when () become mandatory for any.

Code: Select all

list:= [5, 6, 7]
for key, val in list ; the same no comma before and after in 
	msgBox(val)
I don't understand what you mean. But files/parse/reg have their own purpose to the interpreter, but not to the user like "k,v in obj" in for would for instance, they are just a plain word with no use other than to show it is a loop files, not a loop, that's the name of what "I intend to do".
I think it's done this way due to simplicity or speed? It uses loop keyword to check for these other four. Instead of checking whether the action is loop, loopparse, loopfiles, loopread, loopreg unconditionally, it checks whether its loop and consumes it, then does some checks to see whether it it can be any of these four, if they arent met then rolls the normal loop. I dont remember. If it isn't a loop, it's only 1 check, as opposed to 5.
coffee
Posts: 133
Joined: 01 Apr 2017, 07:55

Re: why was LoopParse (no space) removed?

01 Jan 2018, 19:23

Well i did a quick untested mockup and reverted the commit that removed loopfiles into the latest alpha version, I karate chopped the loop subtype block

Code: Select all

loopfiles a_scriptdir "\*", "df"
	msgbox(a_loopfilename)
loopfiles(a_scriptdir "\*", "df")
	msgbox(a_loopfilename)
Both seem to work fine but i dont know what other repercussions it may have on any other check. Loop files (separated) obviously doesnt work which would have been the point.
If action is loop, it doesnt check whether it may be one of the other four. But will always check for the joined names loopfiles...etc. I suppose keeping both is somewhat wasteful, but keeping one or the other not so much?
loopfiles (a_scriptdir "\*", "df") is not checked for which if i remember it was another reason why lexicos removed it. It does nothing, or maybe it will wipe your hard drive and install windows vista.

Basically the names on g_act and

Code: Select all

#ifdef CHOPCHOP
	else if (aActionType == ACT_LOOP)
	{
		LPTSTR cp = StrChrAny(action_args, EXPR_OPERAND_TERMINATORS);
		if (cp && cp > action_args && (IS_SPACE_OR_TAB(*cp) || *cp == g_delimiter))
		{
			LPTSTR next_nonspace = omit_leading_whitespace(cp);
			bool comma_was_used = *next_nonspace == g_delimiter;
			// Now cp points at the next character after the first word, while next_nonspace points
			// at the next non-whitespace character after that.  If comma_was_used, there is also
			// a comma and potentially more whitespace to skip if a valid loop keyword is used.
			TCHAR orig_char = *cp;
			*cp = '\0'; // Terminate the sub-command name.
			if (!_tcsicmp(_T("Files"), action_args))
				aActionType = ACT_LOOP_FILE;
			else if (!_tcsicmp(_T("Reg"), action_args))
				aActionType = ACT_LOOP_REG;
			else if (!_tcsicmp(_T("Read"), action_args))
				aActionType = ACT_LOOP_READ;
			else if (!_tcsicmp(_T("Parse"), action_args))
				aActionType = ACT_LOOP_PARSE;
			*cp = orig_char; // Undo the temporary termination.
			if (aActionType != ACT_LOOP) // Loop sub-type discovered above.
				// Set action_args to the start of the actual args, skipping the optional delimiter.
				action_args = comma_was_used ? omit_leading_whitespace(next_nonspace + 1) : next_nonspace;
			else if (comma_was_used)
				// This is a plain word or variable reference followed by a comma.  It could be a
				// multi-statement expression, but in this case the first sub-statement would have
				// no effect, so it's probably an error.
				return ScriptError(_T("Invalid loop type."), aLineText);
		}
	}
#endif
	switch (aActionType)
	{
	case ACT_LOOP:
	case ACT_LOOP_FILE:
	case ACT_LOOP_REG:
	case ACT_LOOP_READ:
	case ACT_LOOP_PARSE:
	case ACT_GOTO:
	case ACT_GOSUB:
		if (end_marker && *end_marker == '(')
		{
			LPTSTR last_char = end_marker + _tcslen(end_marker) - 1;
			if (*last_char == ')')
			{
				// Remove the parentheses (and possible open brace) and trailing space.
				ASSERT(action_args == end_marker);
				++action_args;
				last_char = omit_trailing_whitespace(end_marker, last_char - 1);
				last_char[1] = '\0';
				// Treat this like a function call: all parameters are sub-expressions.
				all_args_are_expressions = true;
			}
		}
		break;
edit yolo
Winging it and adding

Code: Select all

if (end_marker && ((*end_marker == '(') || IS_SPACE_OR_TAB(*end_marker)))
To the condition seems to have made loopfiles (path, mode) do something at least.

You could stylize your loops like a header

Code: Select all

LoopFiles																		(a_scriptdir "\*", "df")
totally worth it.
coffee
Posts: 133
Joined: 01 Apr 2017, 07:55

Re: why was LoopParse (no space) removed?

02 Jan 2018, 01:18

Ah I see, none of these should have even been called that in the first place *from my perspective*, using the loop keyword. They all do different things, calling a different function. For and while could have also been handled by that block, and checked only when the users type loop in a line, saving these two extra checks. For what it's worth, they could have been called

Code: Select all

loop for k, v in objectexpr
; or
loop object k, v in objexpr
;or
loop array k,v in objexpr

loop while expr
Using for and while as keywords, and handled the same way as parse, files, reg, read keywords. All under one loop action umbrella. But for and while were given their own separate handling (implemented later? problems for that one keyword? who knows). Even though parse, files, reg are also their own separate thing.

Code: Select all

; Instead of Loop Files/LoopFiles
FileLoop pathExpr, modeExpr ; Fitting with its own file category
FilesLoop pathExpr, modeExpr
FileBrowser pathExpr, modeExpr
FileSystemBrowser pathExpr, modeExpr
FileSystemLoop pathExpr, modeExpr

;Instead of Loop Read
FileContentLoop fileExpr, outExpr
FileReadLoop fileExpr, outExpr ; Fitting with its own file category
FileReadLines fileExpr, outExpr ;after the now defunct FileReadLine as that is exactly what the loop is doing.

;Instead of Loop Reg
RegLoop keyExpr, modeExpr ; Fitting with its own registry category
RegBrowser keyExpr, modeExpr
RegistryLoop keyExpr, modeExpr

;Instead of Loop Parse, all looking nice
ParseLoop strExpr, delimExpr, omitExpr
StrParseLoop strExpr, delimExpr, omitExpr
StrLoop strExpr, delimExpr, omitExpr
StrParse strExpr, delimExpr, omitExpr

All a bit more fitting starting with the word that they actually belong to/or more descriptive, where they will be applying the iteration to.
Even as LoopType, they should be their own entry.

You wouldn't use a Move action then Dir and File keywords to then switch around calling their own thing, they are separate.

Code: Select all

Move Dir source, target
Move File source, target
;???????????

;or
Read file
;and
Read Ini
Beri interesting mon.
_3D_
Posts: 277
Joined: 29 Jan 2014, 14:40

Re: why was LoopParse (no space) removed?

02 Jan 2018, 04:44

Probably "loop" is just word for human reading mean: next will looped.
Alternatively:

Code: Select all

repeat(count) { ;loop count times
}
parse(string, ...) { ;loop in string
}
files(pattern, ...) { ;loop in matched file names
}
read(input, ...) { ;loop in input file lines
}
There is reason comma after modifier "Parse" to be omitted due to loop and "Parse" made new one command loopParse :lol:
Probably in the future will see loop Parse, OR loopParse.
AHKv2.0 alpha forever.
guest3456
Posts: 3454
Joined: 09 Oct 2013, 10:31

Re: why was LoopParse (no space) removed?

02 Jan 2018, 10:09

good stuff coffee

zcooler
Posts: 455
Joined: 11 Jan 2014, 04:59

Re: why was LoopParse (no space) removed?

02 Jan 2018, 11:27

The best proposal yet :thumbup: ...but would require large rewrites of the documentation ;)
User avatar
nnnik
Posts: 4500
Joined: 30 Sep 2013, 01:01
Location: Germany

Re: why was LoopParse (no space) removed?

02 Jan 2018, 11:39

@coffee I like the idea of renaming them - if I have to give up on removing them
For the ParseLoop I would suggest the name StrSplitLoop - to mark the correlation between its functionality and strSplit
Recommends AHK Studio
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: why was LoopParse (no space) removed?

02 Jan 2018, 17:27

- @coffee: Some history, in case it explains any of how the source code is laid out:
AHK v1.0 had Loop Count/Files (old style)/Parse/Read/Reg (old style) and while.
AHK v1.1 introduced Loop Files (new style)/Loop Reg (new style) and for.
- So, what is your conclusion re. whether you have 1 Loop CFS (control flow statement) with 5 'subcommands' or 5 LoopXXX CFSs, does it really make a difference performance-wise?

- One reason why I'd prefer LoopXXX, is that you can see at a glance that's it's a loop.
- Cf. all the FileXXX functions, and a proposed 'FileLoop', blurring into each other.
- Also, for/loop/while are words that are well understood, and it makes sense to have these words at the front of the CFS names.
- To whoever suggested 'StrSplitLoop', I can't argue against that on purely logical grounds, but I can argue against that on aesthetic grounds.

Code: Select all

LoopParse vText, "`n", "`r" ;the most consistent with AHK v2 functions
LoopParse, vText, "`n", "`r" ;the most elegant
Loop "Parse", vText, "`n", "`r" ;also consistent with AHK v2 functions (but wrong, and users will make this mistake, and it takes a paragraph or two to explain)
Loop Parse vText, "`n", "`r" ;confusing: comma or no comma
Loop Parse, vText, "`n", "`r" ;confusing: comma or no comma

LoopParse(vText, "`n", "`r") ;of the function possibilities, best of the bunch
Loop("Parse", vText, "`n", "`r") ;unsettling
Loop(Parse, vText, "`n", "`r") ;even more unsettling than 'Loop("Parse", ...', a strong argument against 'Loop Parse'

;in use:
LoopParse vText, "`n", "`r"
{
	vTemp := A_LoopField
}

;if we bring back initial commas (very nice, I wish AHK v2 could look this nice, very satisfying to look at):
LoopParse, vText, "`n", "`r"
{
	vTemp := A_LoopField
}

Code: Select all

;inconsistent: 'param 1' is either a variable or a 'subcommand'
Loop var
Loop Files var
Loop Reg var
Loop Parse var
Loop Read var

;a solution:
Loop var
LoopFiles var
LoopReg var
LoopParse var
LoopRead var

;an alternative (undesirable) solution:
Loop Count var
Loop Files var
Loop Reg var
Loop Parse var
Loop Read var
- Of 'Loop XXX'. Is that a two-word entity, or a one-word entity with 'subcommands'?
- There aren't any other two-word entities (i.e. command/function/directive/CFS names) in AutoHotkey, why should Loop be special?
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: why was LoopParse (no space) removed?

06 Jan 2018, 04:08

The several varieties of Loop are first and foremost loop statements. "Loop" establishes the context for the following line or block of code, and is easier to recognize at the start of the line. Frankly, I think moving "Loop" to the end of the name or removing it is a terrible suggestion, unless you're talking about creating a function which returns an enumerator (for for). Instead of seeing at a glance that this is a loop, the reader must be trained to recognize each name. It is also a bigger departure from v1, without sufficient reason.

As far as I am concerned, the only compelling point I have read regarding the name of the loop statement or its use of commas was only mentioned in passing: Loop Parse "ABC" would "do nothing without the comma after Parse". Omitting the comma when one is required has worse consequences than specifying a comma when one is prohibited (the script silently failing vs. the error being reported). Therefore, I've changed it to allow there to be no comma.

Having no particularly good reasons for allowing a comma here may mean this leads to removing the comma entirely, or maybe not. I chose not to remove it right now (forcing users, including myself, to update scripts) because - aside from my personal preference - I have not completely discounted the possibility of replacing Loop Files/Parse/Read/Reg with enumerators. I don't believe the current syntax is a problem that needs solving, so even if the enumerators will be implemented, they might not be in v2.0. If v2.0 is to include every possible improvement which supersedes existing syntax or functionality, it will be perpetually in alpha (like it has been), and v2.0 will never be released.
guest3456
Posts: 3454
Joined: 09 Oct 2013, 10:31

Re: why was LoopParse (no space) removed?

07 Jan 2018, 06:44

i just kind of see it in the same vein as the sub-commands which are now removed and split into their own commands. and thats what the oneword LoopParse resembled. it just makes more sense imo


Return to “AutoHotkey Development”

Who is online

Users browsing this forum: No registered users and 52 guests