scrap commands?

Discuss the future of the AutoHotkey language

Should command-like syntax for functions (functions without parentheses) be removed?

Remove the command-like syntax for functions.
26
72%
Keep the command-like syntax for functions.
10
28%
 
Total votes: 36
Helgef
Posts: 3301
Joined: 17 Jul 2016, 01:02
Contact:

Re: scrap commands?

14 Apr 2018, 03:26

Hello :wave:.
Seeing you replying to this topic today was almost a little spooky, for unknown reasons, I happened to think about this just today, I was thinking I would comeback and ask if variadic calls would be fixed, and then,
That was fixed in v2.0-a084.
I hadn't notice, thanks :thumbup: .
Side note: calls with zero parameters are where I most want to omit parentheses: ListVars, Pause, MsgBox, etc.
Zero or one definitely is my usual use-case for it, eg, detecthiddenwindows true is very convenient ;)
I see no reason to think the asterisk would terminate the parameter list.
Good.
Both of the above are method calls
I guess I was thinking of something (unusual) like this,

Code: Select all

obj.xyz
class obj {
	xyz[]{
		get{
			msgbox
		}
	}
}
obj.xyz() is always a method call, even if it might be implemented by calling a property function.
I see.
It won't force the user to write less readable code against their will
I agree that the unreadability argument is not very strong for this reason. Since last time, it turns out I do use this feature frequently, plain and simple, I do it when I like it.

Cheers.
KusochekDobra
Posts: 32
Joined: 25 Apr 2016, 18:00

Re: scrap commands?

14 Apr 2018, 10:45

For me, parentheses always describe the boundaries of priority, which always include something important.
Functions and methods always accept or NOT accept parameters - this is important!
Boolean operations decorated with round brackets are more pleasant to read. So they turn from a line of text into coded logic blocks, even if the block is only one. This does not carry an additional burden.
It is also important that, in parentheses, the operated part of the scenario is always semantically separated, from the operating part, like flies from cutlets. This is also important for beginners.
The text of the function call should be similar to the text, as the function itself is described. This introduces more consistency within the code. So, if we describe a function somewhere in the script, for example, like this:

Code: Select all

MyFunc() {
	; do something
}
Then we need to call it according to its full name, which contains parentheses MyFunc(). This also reminds us that this is more important than the name of the variable. Generally, parentheses are like punctuation marks, without them the sentences look confusing (eats shoots and leaves), but even when they are thoughtlessly many, one can lose the course of thought.
sirksel
Posts: 42
Joined: 12 Nov 2013, 23:48

Re: scrap commands?

15 Apr 2018, 14:08

I know I'm in the minority, but I VOTE FOR KEEPING the parens-optional syntax. As others have pointed out, msgbox x, or in my case, my slightly customized version mbx x is really nice and quick for debugging. Small point, I know.

For quick scripts with a lot of parameter-less calls, the () doesn't really add clarity. Helgef's example is a great one:

Code: Select all

run "notepad"
winWaitActive "ahk_class Notepad" 
send "hello"
sleep 1000
winClose
exitapp
In keyboard scripts for COM-object automation of applications where a lot of "actions" are defined and parameter-less (or even where single unenclosed parameters make linguistically intuitive expressions), things look very nice with parens-optional syntax... and can even approach the elegance of a domain-specific language:

Code: Select all

; example in Excel automation
select row
paste values
calculate
Also, for what it's worth, I teach a unit on Windows automation to non-programmers, and I've actually been using AHK v2 for that class. I've been told by students that the lack of parentheses (at least in the introductory scripts we write), makes the language seem less intimidating to them than other languages they've looked at in the past. Many of them had thought of coding as something that "techies or math majors" did and that they couldn't understand. This provides a gateway.

Lastly, I'd say parens-optional syntax was a good compromise for those who felt we lost something significant when v1-style command syntax was removed. I really miss command syntax when banging out a quick 10-line "batch file" to automate a one-off process in which 90% of what I'm writing is literal text and directory names with only a few %filename% interpolations. There was something very cool about the command syntax and not having to type quotes and parentheses around absolutely everything. It was quick and dirty, yet you still had the full power of AHK expressions, if you needed them. We lost that quote-less option, but we retained the parentheses-less option.

If the parens-optional syntax is not limiting other features, I'd definitely say keep it. To me, just because a feature CAN be abused, or if used improperly, CAN create ugly code, isn't a reason to necessarily remove the feature. The same could be said about the multi-statement comma or the fact that assignments can be embedded within expressions. I'm sure we've all seen code where these get abused and lead to less clear code, but I think (I certainly hope!) at least most of us would agree they should not be removed for that reason alone. Python, for example, doesn't allow assignment within expressions -- largely for this reason -- but there isn't a day that goes by when I wish they hadn't made that call...
iseahound
Posts: 355
Joined: 13 Aug 2016, 21:04
GitHub: iseahound

Keep commands, make them better

16 Apr 2018, 17:11

Even I used to assume commands and functions to be equivalent when they are not.

Code: Select all

Run, "notepad.exe"
Run("notepad.exe")            ; What is this returning?
You can't force Run() to return say a success/fail value, because Run() doesn't even check if the value you input properly ran. It sort of delegates the action to a windows cmd prompt, and moves on to the next line of code. But what is Run, "notepad.exe" returning? Imagine if you could assign a variable to capture this return value. Well it would return some value with an empty type. It's important to remember that every value belongs to a type. When a function is "void" it returns an empty value. But if it refuses to return anything, it's returning an empty type. Empty value != empty type. An empty type is also known as the bottom type. And the bottom type is equivalent to falsity in logic via the Curry Howard correspondence. Now it's plainly obvious why Run() cannot exist. It's because there's no way for AutoHotkey to verify that Run("notepad.exe") did anything in the first place. Maybe the user deleted notepad.exe. You want AutoHotkey to check for that? It would do things outside the scope of the language.

In Rust there is the idea of a macro, or a function with the ! exclamation point at the end. These functions return an empty type. println!() is the finest example of that, since there's no way for Rust to verify that the user even has a command prompt. println!() doesn't return anything useful to the programmer, so the ! denotes empty return type.
User avatar
kczx3
Posts: 691
Joined: 06 Oct 2015, 21:39

Re: scrap commands?

16 Apr 2018, 19:23

I feel that parenthesis should be mandatory. Nearly every editor out there has an autocomplete feature that will automatically place the close parenthesis after typing the open one. And since everything is expression syntax now, you would simply continue typing your parameter list in the same manner as you would if parenthesis weren’t required. To me, the parenthesis are what signify that the following are parameters and are passed to the function. It’s less obvious to me that that is the case when using command syntax.
User avatar
jeeswg
Posts: 5415
Joined: 19 Dec 2016, 01:58
Location: UK

Re: scrap commands?

16 Apr 2018, 21:18

- From using AHK v2, MsgBox without parentheses or some alternative like 'Print', would be useful.
- I also think that var `= literal text, or some equivalent, would be very useful.

- If the command style was kept, I would like:
- A mode to warn of any command-style uses, so that you could remove all of them.
- Command-style could only be used at the start of a line, and not with multi-statements. So no 'MsgBox, MsgBox', but 'MsgBox(), MsgBox()' would be possible. This would not be allowed: 'Func(Cmd Arg1 Arg2)'.
- The documentation would always use parentheses style. Apart from one page to demonstrate command-style notation. Consistency is needed, and since some functions *require* function-style, to retrieve a return value, it makes sense for them all to use function-style.
- Something like 'A_ReturnValue' would make sense for commands, to retrieve the return value for the last command. [EDIT: I remembered, either this is needed, or a return parameter is needed after every command name, although you would even need 'Sleep RetValue, 1000' in that case. Perhaps 'RetValue := Cmd Arg1, Arg2', but this would interfere with 'var := value'. Again, another reason I was against commands.][EDIT 2: I remembered again, the idea where, in custom functions, using 'return' at any point within the function resulted in an output parameter being added to the command version.]

- Concerns that I mentioned previously:
scrap commands? - AutoHotkey Community
https://autohotkey.com/boards/viewtopic ... 55#p183855
- Also, with commands it's less clear what is happening when you omit the first parameter.
- Also, it's easier to search for 'Func(' than 'Func ', where you might have false positives. And if you always use 'Func(', then 'Func(' will find all occurrences. Also, don't underestimate the benefits of easy text replacement.

- @iseahound: Any function lacking an obvious return value, could return 1/a blank string/0. Often a function's return value should be the inverse of what it puts into ErrorLevel.
Last edited by jeeswg on 17 Apr 2018, 02:13, edited 1 time in total.
iseahound
Posts: 355
Joined: 13 Aug 2016, 21:04
GitHub: iseahound

Re: scrap commands?

17 Apr 2018, 01:57

If you force functions that return "undefined" to return something like 0, empty string, or 1, it would be absurd.
Absurdity ⊥ (contradiction) has no proof; a proof of ¬A is a construction which transforms any hypothetical proof of A into a proof of a contradiction
User avatar
nnnik
Posts: 3527
Joined: 30 Sep 2013, 01:01
Location: Germany

Re: scrap commands?

17 Apr 2018, 02:10

No that would mean that "" fulfills the role of undefined.
Informatics is not mathematics - while informatics use mathematics it is not bound to mathematic laws within its own principles.
In informatics there is encoding - that means that a specific meaning is encoded using a specific binary data combination.
That assignment is something people agreed on. If we all agree that 65 means A then it is A. If we all agree that an empty string in this case means undefined then its undefined.
Applying your law we would have never achieved anything in informatics.
Recommends AHK Studio
User avatar
jeeswg
Posts: 5415
Joined: 19 Dec 2016, 01:58
Location: UK

Re: scrap commands?

17 Apr 2018, 02:22

- @iseahound: My intention was that every function should return a value, even if the value does not give you useful information. It could be 1, so that if Func() would always work, or it could be a blank string, to indicate undefined.
- @nnnik: iseahound's recommendations above probably sound to you, a bit like how some of your recommendations sound to me, if you know what I mean. I'm all for high standards and going by conventions, but are we making things complex beyond what they are?
- @iseahound: (I've written plenty of quick-and-dirty custom functions where I didn't bother to specify a return value. Return values aren't always important. Although if you make a proper function library it's good to decide upon some consistent principles.)
- @nnnik: (I'm impressed that your thinking is flexible/practical, and not only confined to notions of Platonic ideals etc.)
User avatar
nnnik
Posts: 3527
Joined: 30 Sep 2013, 01:01
Location: Germany

Re: scrap commands?

17 Apr 2018, 02:44

No towards me he sounded a lot like you - as in he has no idea what he is talking about.
Recommends AHK Studio
iseahound
Posts: 355
Joined: 13 Aug 2016, 21:04
GitHub: iseahound

Re: scrap commands?

17 Apr 2018, 03:06

Other than a desire to return something, what purpose would returning "" serve? You speak of informatics, so explain what information can be retrieved from "". Does it mean the function completed? Did it fail?

Code: Select all

if !Run("Notepad.exe")
   throw "error" ; not even useful for error handling.
User avatar
jeeswg
Posts: 5415
Joined: 19 Dec 2016, 01:58
Location: UK

Re: scrap commands?

17 Apr 2018, 03:19

- @iseahound: Run could return a value that is equivalent to UseErrorLevel: 1 if the launch succeeds, 0 if it fails.
- I'd figure out a specific return value for each individual function. Generally 0 or a blank string for failure, success otherwise.
- IIRC correctly the return values for new AHK v2 functions will be reviewed at some point, and if you notice any problems, you could make some suggestions.
- Btw re. nulls I had thought that perhaps AutoHotkey built-in functions could allow ComObjMissing to let you specify a parameter to use the default value. (This works with Excel COM object methods for example.) Or just for a handful of awkward parameters.
iseahound
Posts: 355
Joined: 13 Aug 2016, 21:04
GitHub: iseahound

Re: scrap commands?

17 Apr 2018, 03:51

Thanks, jeeswg. But it's important to just accept that AutoHotkey shouldn't have to prove that it's working. Sure even the Click command could have a return value, where AutoHotkey actually checks if the mouse was clicked after the Click command was sent. But at some point AutoHotkey will be proving that its code is consistent. It's okay to have functions that simply don't return.

@nnnik, I'm using abstract programming to formulate my arguments. That is, type theory/category theory/intuitionisic type theory. Sometimes it's easier to think from a different perspective. I think Rust does a good job of differentiating between functions that return, and those that don't. By adding an exclamation point! as in println!()
User avatar
nnnik
Posts: 3527
Joined: 30 Sep 2013, 01:01
Location: Germany

Re: scrap commands?

17 Apr 2018, 11:36

I dont understand why you see a need to differentiate between functions that return something and functions that return nothing ( same thing for methods ).
Thats just meaningless extra work either you return something or you dont - either you call the function with the intent for it to return something or you dont.
What it returns specifically and what that exactly means is up to the function.
There are simply more meaningful things you could add to the language.

Also I just guessed where that law you mentioned comes from I didn't really bother to look it up.
However my final judgement doesn't change - the law doesn't apply in this context.

Also the obvious return parameter for Run is the PID or 0 if it fails.
Recommends AHK Studio
guest3456
Posts: 2464
Joined: 09 Oct 2013, 10:31

Re: scrap commands?

17 Apr 2018, 11:38

nnnik wrote:Thats just meaningless extra work either you return something or you dont - either you call the function with the intent for it to return something or you dont.
good point

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

Re: scrap commands?

17 Apr 2018, 12:09

@nnnik: I would like the Run function to output a PID, but what would you output for the situation below? -1 perhaps?
Run[Wait]
https://autohotkey.com/docs/commands/Run.htm
The name of the variable in which to store the newly launched program's unique Process ID (PID). The variable will be made blank if the PID could not be determined, which usually happens if a system verb, document, or shortcut is launched rather than a direct executable file.
[EDIT:] There is success/failure, and PID available/unavailable. For this reason, I'm quite happy with the Run function as it is.
Last edited by jeeswg on 17 Apr 2018, 15:00, edited 1 time in total.
User avatar
nnnik
Posts: 3527
Joined: 30 Sep 2013, 01:01
Location: Germany

Re: scrap commands?

17 Apr 2018, 13:42

OK then lets use throw.
The return value is 0 for undefined ( in the cases you mentioned above ) any return value >0 is a defined PID and if it fails it will throw an exception.
Recommends AHK Studio
iseahound
Posts: 355
Joined: 13 Aug 2016, 21:04
GitHub: iseahound

Re: scrap commands?

17 Apr 2018, 20:26

nnnik wrote:... differentiate between functions that return something and functions that return nothing ...
To clarify: between functions that return nothing and functions that don't return. "Don't return" is really a euphemism for "never returns" as in there is no way to know...

Code: Select all

foo() { 
    return foo()
}
Obvious examples are WinWait, Untitled - Notepad

Code: Select all

WinWait("notepad.exe")

WinWait(title) {
    if (hwnd := WinExist(title))
        return hwnd
    else
        return WinWait(title)
}
User avatar
nnnik
Posts: 3527
Joined: 30 Sep 2013, 01:01
Location: Germany

Re: scrap commands?

18 Apr 2018, 02:29

Your code with the infinite recursion would cause a crash of the program - do you mean by adding the ! you can mark a function that is buggy and might cause the program to get shut down?
Well I know that you mean functions with infinite recursion - if you ask me thats a bad programming practice but well.
Recommends AHK Studio
User avatar
jeeswg
Posts: 5415
Joined: 19 Dec 2016, 01:58
Location: UK

Re: scrap commands?

18 Apr 2018, 03:02

I'm not sure where this conversation is going, anyway, here are the AHK v2 backports I currently have for AHK v1, to give some idea of what the AHK v2 functions are doing. (Note: my WinWait function returns an hWnd, something that AHK v2 doesn't currently do.)

Code: Select all

Run(Target, WorkingDir:="", Options:="", ByRef OutputVarPID:="")
{
    Run %Target%, %WorkingDir%, %Options%, OutputVarPID
    if InStr(Options, "UseErrorLevel")
        return !ErrorLevel
}
WinWait(WinTitle:="", WinText:="", Seconds:="", ExcludeTitle:="", ExcludeText:="")
{
    WinWait %WinTitle%, %WinText%, %Seconds%, %ExcludeTitle%, %ExcludeText%
    return ErrorLevel ? 0 : WinExist()
}

Return to “AutoHotkey v2 Development”

Who is online

Users browsing this forum: No registered users and 8 guests