document updated 16 years ago, on Feb 15, 2008
Treatise on a more consistent AutoHotkey language syntax
Treatise on a more consistent AutoHotkey language syntax
ToDo
- Include solid examples for the "bad" cases.
- Where possible, try to propose solid examples of improved syntax.
- Post a reference to this (or possibly a shortened version) to the AHK forums.
- Move this to DNewcum.com, since it's relatively cogent.
The AutoHotkey's syntax is unusual or confusing at some points. This document attempts to pinpoint the issues, determine the root causes, and propose changes that attempt to make the language more consistent and thus easier to learn and use.
There are two common problems with AutoHotkey's current syntax:
- The language has a long history, and has expanded a lot since it began. While retaining backwards compatibility is a good thing, not enough effort has been made to deprecate older / more primitive constructs, and move the language as a whole towards a more constitent syntax.
- (more specifically) The same operation (eg. variable interpolation, or string literals) sometimes has two completely different syntaxes, and the programmer must determine which is the correct one to use in each context (when writing), and determine which of two possible meanings is correct (when reading).
Specific problems:
- The syntax for three basic features varies based on context, making the language very unintuitive for the beginner. I find myself often needing to try two or three different possible versions sometimes, because each of these features need to be written different ways based on context:
- String literals — sometimes you have to put them in quotes, sometimes you don't. This confusion often results in passing variable names as string literals, when you meant the variable to be interpolated.
- Variable interpolation — sometimes you have to surround the variable with percent signs, sometimes you don't. Sometimes you have to surround an if-expression ni parantheses, sometimes you don't. This is a second feature that often results in passing a string literal containing the variable name, when you were trying to pass the variable's value. The manual explains the need for this as being a way to cobble together array functionality. Recommendation: Implement genuine array syntax, which will then allow variable interpolation to have a consistent syntax. If passing-variable-names-as-literals is still needed, provide a separate syntax for that, and MAKE ITS SYNTAX BE CONSTISTENT AND CLEARLY DIFFERENT from more frequently used operations.
- Pass by reference — The only way to pass-by-reference is to send a string literal containing the variable's name. (for examples, serch for OutputVar in the manual) However, this creates confusing syntax, similar to the above. (somewhat more nitpicky, perl considers stringliterals-as-references to be strongly deprecated) Recommendation: Implement a unique syntax for pass-by-reference (eg. "&" as in C). (This change is optional, as it would reduce the need for the above two syntax quirks, however, the above two recommendations can be implemented while still retaining literals-as-references).
- Functions (and scoping / local variables) were added in April 2005, which is relatively late in the language's development. As a result, string-manipulation commands often have two forms (eg. an older one: StringMid, and a newer one: SubStr). String-manipulation is MUCH easier when the modified string can be returned from the function, since that allows chaining multiple commands on one line, and also means you don't have to come up with arbitrary names for the intermediate temporary variables. However, return values weren't originally possible, so older versions use the OutputVar pattern.
- Proper arrays still aren't implemented. Sometimes they're implemented as separate variables, whose names differ by a numerical suffix, other times they're implemented as one string literal with internal delimeters (see example#3, sorting filenames). Recommendation: implement proper arrays.