The easy way out would be to scrap it, no one will ever question why they cannot call their functions without (). With the current behaviour, there will be confusion, but the syntax can be convenient and people, including me, will always be confused about something. So I'm glad it is not up to me .

just me wrote:It would be interesting to hear why those who voted for 'keep' did it.

i initially was going to vote remove, but i hesitated, and chose not to vote. my reason was, there is definite value in keeping the historical "identity" of AHK. but, how much that value brings, in comparison to the headaches and confusion that the syntax causes, i cannot say.

The advantage is convenience, due to less typing, I cannot imagine any other reason (edit: I can respect the nostalgic arguments by guest3456, although, I do not suffer from nostaliga ). Maybe there are implementation benefits, performance? I will probably not use it for other things than debug-msgboxes and such. Eg,

Helgef wrote:The advantage is convenience, due to less typing, I cannot imagine any other reason (edit: I can respect the nostalgic arguments by guest3456, although, I do not suffer from nostaliga ).

upon further thought, since the "Command syntax" has changed so much, with all params now expressions (text is no longer literal and variables are no longer derefd with %%), it already looks nothing like in the past, so any and all nostalgic reasoning is pretty much gone. i voted remove.

Helgef wrote:And even those who doesn't want to use it, might eventually experince new bugs in their code,

Some of my concerns about keeping both notations are as follows:- Everything is doubled up in the documentation. What's the default notation, do we use the with/without parentheses version for this particular function.- Horrible scripts that interchange randomly between the 2 styles.- You write it without the parentheses, but then you need its return value so you have to add in the parentheses.- Everything looks better and cleaner with the parentheses.- I'd rather be going over people's scripts that used the parentheses style.- More consistency, less ambiguity.- With functions without parentheses being almost identical to functions with parentheses, it seems pointless to keep them both.- In a beginner tutorial, I can't see how I can rightly explain or justify why the no-parentheses style exists.- One subtle advantage of removing the no-parentheses style for functions is that it makes clear the distinction between functions and control flow statements, which is an important distinction. It was a revelation after many years to finally realise the exact distinction when trying to recreate the AHK commands as functions.- I don't know how severe this is, but I believe it hampers the maintenance and improvement of the AHK source code. I believe there were/are issues trying to create custom functions (with/without the same name as default functions) on-the-fly that had a command-style syntax equivalent that behaved in the same way. The problems associated with keeping the 2 notations may even be a key obstacle to AHK v2 being released, I'm not sure.- When AHK v3 comes around, we'll be thinking, finally time to get rid of the no-parentheses notation.

- My one and only argument in favour of keeping it might be for use with MsgBox, to save a bit of effort in typing. However it looks uglier without the parentheses, and all you need is a hotstring to save the effort in typing, and I would be using a hotstring anyway:

- The other point would be nostalgia for commands. But my nostalgia for commands requires the presence of initial commas. Anyhow, I have the memories, plus we can put a few old scripts that use commas into a picture frame. And besides, control flow statements and directives would remain command-like in appearance.- I think maybe some are reluctant to undo Chris's work, but I think that removing commands entirely will make things easier for newbies, in line with Chris's ethos. I found it odd that there were two styles when I first started using AutoHotkey, and I was already more used to the function style from Excel sheet functions, the commands concept was new to me.

I also use ()s for control flow statements and things like #If, unless nothing comes afterwards (in example: non-conditional else or "cleaning-out" #If (removing conditions that were set by another one)), because there is simply nothing to put inside.

g (37,38); accidental space, passes 38 as the first parameter, nothing elseg(37,38); does what you think

g (37,38) throws an error if the function requires more than one parameter.x := g (37,38) concatenates g and 38 regardless and will never throw an error, regardless of the outcome of this thread.My conclusion: This argument does not support your position very well.

We cannot use ternary or x && y at the beginning of a line without omitting spaces or enclosing in (),

This is a separate issue and may be solved without changing the syntax. Initially (in v1), commands had priority because they had known, fixed names; i.e. x ? y : z worked but MsgBox ? y : z gave you a MsgBox. In v2-alpha, user-defined commands were given priority over ternary for consistency with built-in commands. This is no longer necessary, because a valid expression cannot start with ? or &&; i.e. x && y and x ? y : z only have one valid interpretation each.

That was not an argument for my position, which I have neither decided nor stated, it was highligting a fact. The problem would obviously arise when the function is actually called, not when you get notified of a load time error pointing an arrow at the mistake.

No, only one interpretation implies a valid expression. The current interpretation is still valid. You can make the choise to interpret it as not being an invalid expression for the first parameter in a function call. Whatever you choose, the transformation of a function call with parentheses to one without, isn't invertible.

Actually, the controversy function-command exist mainly because of Autohotkey Classic. In fact, having two such different syntaxes gave rise to tremendous problems for beginners and to generate documentation.

In contrast, the specific case of the function calls without parentheses is trivial and easily understandable, even for beginners, provided they do not have the trauma of Authotkey Classic:No user commands. There are only functions. And if a line begins with a function call, the parentheses can be omitted:

MsgBox sin(x)MsgBox(sin(x))

That's all. I prefer the first call. I save writing and the code is clearer and nicer, at least as long as the text editors do not put the nested parentheses smaller.And, in any case, those extra parentheses only cause unnecessary noise. If you don't like the first notation use the second. Nobody prevents you. Do not force others to use your notation.In addition, the absence of parentheses shows that we want to make a procedure-call emphasizing the intention not to use the return value if it exists.

VBA also allows that and there is not so much controversy. Why? Because they do not start from the previous bad experience of Authotkey classic.

In Autohotkey, as in all languages, there are many cases in which things can be done in two ways and many people agree that this versatility compensates the inconvenience of making the language more complex. For example, the substitution of variables and expressions within a literal string is not strictly necessary (you can achieve the same by concatenating literals and expressions). The concept of substitution within a literal is much more complex than the case at hand and may confuse a novice who intends to write a literal message and encounters an unexpected substitution:

"You can write %(percent)"

But people still like this feature, and many languages have ended up including it because it makes life more comfortable and enjoyable for the writer-programmer and for the reader-programmer:

"Write a value between %(start) and %(end), please""Write a value between " . start . " and " . end . ", please"

If we suppress all (presumably) unnecessary characteristics we will remain with a rigid and boring language.

Many times people talk about syntactic sugar pejoratively without realizing that sugar sweetens the life of the programmer making their task more pleasant and enjoyable. This also increases productivity!

Helgef wrote:That was not an argument for my position, which I have neither decided nor stated, it was highligting a fact.

I misinterpreted your position, but the point I was trying to make had absolutely nothing to do with your position. Allow me to rephrase: The fact you have highlighted is of very little relevance. Anyone might eventually experience bugs in their code due to putting a space before the parentheses, regardless of whether function calls require them in all instances or not.

The problem would obviously arise when the function is actually called, not when you get notified of a load time error pointing an arrow at the mistake.

The problem "arises" when the program does not behave as expected, whether that is at load time, when the function is called, or at any other time when the effects of the mistake are actually felt. The solution is very easily found when load-time checking points out the error. In that case, the problem is less severe. There are effectively two problems:

g (37,38) written at the beginning of a line, currently interpreted as a call to g with one parameter. If g requires two parameters, the problem will be immediately pointed out.

g (37,38) written elsewhere, interpreted as concatenation. The problem will never be detected at load time; it may not be detected at all, and when its effects are felt, the cause may be hard to find.

Only #1 is relevant to this topic, but #2 is a larger problem and will remain a problem regardless of the outcome of this thread.

No, only one interpretation implies a valid expression. The current interpretation is still valid.

It is "valid" to interpret the code according to the rules even if the rules say the code can't run, and the rules can be whatever we like, so "valid" can mean anything. This makes discussion of validity (in this sense) pointless. If I say the rule is "parentheses may be omitted except where the first parameter begins with a binary operator", it is invalid to interpret x && y as a function call.

I was not talking of the act of interpreting, but the meaning being assigned. The current interpretation of x && y is x( && y), and x( && y) is invalid, therefore the current interpretation is invalid.

I have tried to put some more thoughts into the topic, specifically I wanted to come up with reasons to scrap it, so I don't regret saying I want to keep it. I'm still undecided but have questions, comments, opinions and things to note. In no particular order,

Code examplesI took a function from the gdip lib by tic, and converted it to the new syntax, so we can look at a real example, as opposed to just msgbox or x y,z examples. This function does many calls without retrieving the return values, I put all versions in one code box, I suggest you put them in your editor in different tabs and alternate between them.

Number 3 is not very nice in my opinion, number 4 is much better, I prefer number 2. What do you (all) think? I wonder if those who voted to keep, would use it like this? I wouldn't. In the next example, the functions are well known, which helps I think, and uses zero to one parameter,

I consider this mostly nice, eg, a::send "text", but a::b is a remapping, and a::b c is a function call. So there are some special cases, depending on the function name, and if passing parameters or not, to consider and document.

Omitting the first parameterI really do not like the call without parantheses when the first parameter is omitted,

I wonder if anyone likes this? In this context, f(,y) looks beautiful.

Variadic* callsNote, currently, variadic calls doesn't work, they should I guess, so either it is not yet implemented or maybe I missed a note about it in one of the pages. There are two errors, too few parameters, and missing operand,

lexikos wrote:The fact you have highlighted is of very little relevance.

I do not think a fact about the discussed topic is of very little relevance, even if it doesn't qualify as a stong argument, either for or against. Your addition about throwing an error highlights that the mistake sometimes is easy to spot, sometimes not.

The problem "arises" when the program does not behave as expectedAnyone might eventually experience bugs in their code due to putting a space before the parentheses

The novelty I tried to highlight is the case when the outcome of the old mistake is a function call, consequently, when you get unexpected results, the problem is more likely to appear to be related to the inners of the function, rather than at the place where it was called, making it more difficult to find. I consider it worth noting.

I was not talking of the act of interpreting, but the meaning being assigned.

That make sense, I should have figured, I apologise.

@ juan, hello.

the specific case of the function calls without parentheses is trivial and easily understandable, even for beginners [...] if a line begins with a function call, the parentheses can be omitted [...] That's all.

might not be trivial and easily understandable, I would probably have a hard time getting used to that too. I do not think the sweet taste of AHK is greatly affected by the presence or absence of this syntax.

Some commands have not been fully converted. Defining a function with the same name as one of these commands currently overrides the command only for the function() style of calling; i.e. if parentheses are omitted, the original command is called.

- Interesting, 80% in favour of scrapping the command-style notation for functions.- I'm partially sympathetic to the idea of MsgBox having 2 styles. However, I have an alternative idea.- I would make MsgBox function-only, like all of the other functions. But I would have a special 'Print' function, that would allow you to omit parentheses. The Print function would be an alternate name for MsgBox, but could be set to do something else, like run ToolTip, or a custom function that prints to a console window. E.g. see:AHK Console - AutoHotkey Communityhttps://autohotkey.com/boards/viewtopic.php?f=5&t=37043&p=170789#p170789- I like the idea of separating MsgBox and Print, so that you know that when you see MsgBox, that that's a part of the script proper, whereas Print implies debugging. It also makes it easier to find lines related to debugging in big scripts.

PHP has a print statement, which is not a function but can be called with or without parentheses (functions in PHP require parentheses).

Perl has a print function and allows parentheses to be omitted from function calls.

I think there's something wrong about the idea of making print a statement (presupposing that functions require parentheses and statements do not), but then allowing it to be redefined. Either we have one statement that can be redefined, unlike every other statement (or one function that doesn't require parentheses, unlike every other function), or we use a less obvious method to define what happens (like a built-in variable).

Helgef wrote:Currently, a::func makes the hotkey call func, even though func isn't at the beginning of a line,

Any statement can be recognized to the right of a:: (but won't necessarily form a valid program). "At the beginning of the line" is easier to grasp without any previous knowledge/reading, but function call statements are really allowed anywhere that allows a statement, as mentioned in the current documentation.

but a::b is a remapping, and a::b c is a function call. So there are some special cases, depending on the function name, and if passing parameters or not, to consider and document.

This is due to the similarity between the remapping syntax and hotkeys. It causes ambiguity in v1 and is likely to continue to cause ambiguity regardless of the outcome of this thread. For instance, a::return is interpreted as a return statement, since that's the most useful interpretation and most likely what the user wants, but a::^return and a::enter are remappings.

However, return is probably the most benign example, being a control flow statement commonly used as such, rarely used as a key name, and also redundant (we could remove it in favour of Enter). There are other key names that seem more likely to be used as user-defined functions, like Launch_Mail.

Currently (and in v1.0), Pause is specifically excluded from remapping to allow the command to be called. If parentheses are required for calling Pause(), this exclusion can be removed.

Side note: calls with zero parameters are where I most want to omit parentheses: ListVars, Pause, MsgBox, etc. By default, Pause() requires 40% more key-presses than Pause.

Note, currently, variadic calls doesn't work,

That was fixed in v2.0-a084.

However, it touches on another point of potential ambiguity. The current implementation of line continuation requires the next line to start with an operator, but it could be possible to "continue" by ending a line with a binary operator. Since * is also a binary operator, Fn array* would be ambiguous. If parentheses are required, there's no question of which way to interpret the asterisk.

On the other hand, implementing this type of continuation would prevent any future use of current operator symbols as postfix operators (like the variadic call operator, written after its input). There's also the option of changing the variadic operator (e.g. ...).

This would also affect commas. Multi-statement comma is technically a binary operator.

I see no reason to think the asterisk would terminate the parameter list. f p*, (expr) is equivalent to f(p*, (expr)), which is not supported right now but logically should be.

More generally, a user might think that f p, (expr) would be evaluated as (f p), (expr), or even that x := f p will call function f. Many things can be misunderstood if the user lacks requisite experience and knowledge. In this case, it shouldn't be hard to pick up on how function call statements work vs. auto-concat, even if the user doesn't read the documentation. The current documentation (written after your post), uses the phrase "the remainder of the line is taken as the function's parameter list". There's also "Line breaks generally act as a statement seperator, terminating the previous function call or other statement."

I really do not like the notation for method calls, there is already some awkwardness in that parentheses can be used with properties, eg,

Both of the above are method calls, just as they would be function calls if you removed obj.. x := obj.xyz is not a method call, just as x := xyz is not a function call.

Re "parentheses can be used with properties": obj.xyz() is always a method call, even if it might be implemented by calling a property function. That will always be possible via meta-functions. It's currently possible by default for class-defined properties and some built-in properties, but that will change (as I've indicated in v2-thoughts).

But I agree that method call statements can be awkward.

[Example] might not be trivial and easily understandable,

I think the main argument for parentheses being optional is that omitting them can make the code more readable. It won't force the user to write less readable code against their will. I suppose that your example was written for the express purpose of demonstrating code you consider unreadable, so did it help you to achieve your goal, and if so, how can that be a bad thing?