Programming/conversation design patterns and efficient structures all evolve quickly and naturally once you fully understand any language.
I derive this insight from how I learned and applied my most fluent language, English, which I use every day.
In order to write, read, and formulate meaningful English conversations I rely on a constantly accessible and vast database of English syntax and English vocabulary. Spellcheck is my only English IDE feature; I don't need to know how to spell all words I merely need to know that useful words exist, how to approximately construct such words, and where to use such words.
All higher level English design patterns, such as writing a novel, a short how-to guide, formulating an interview questionnaire, writing a blog post, writing a book review, etc. come naturally by seeing first how others use such patterns, and then making my own unique instances of these patterns using the same building blocks - the English language syntax and vocabulary. My theory is that AutoHotkey (and any other language) patterns can be instantiated much the same way.
In order to become fluent in AutoHotkey and create useful and advanced AutoHotkey conversations with computers I need to be able to have a deep understanding of the syntax and vocabulary of AutoHotkey, so much so that there are basically no major "what-ifs" or "vocabulary gaps" during coding that stop my flow of attention. After a coherent plan has been formulated, much like a coherent plan about what you want to say when writing a book or movie review, there should be almost no writers block when writing, but merely quickly refactoring/restructuring as I go along to optimize the conversation, only pausing to read/reread some code already written, just like when using English fluently.
Even when other people write poorly formatted or structured English, I can always decipher exactly what each word is, even if I don't derive the contextual meaning. Reading AutoHotkey code I cannot yet do this, even reading the documentation I cannot yet do this.
Therefore I will begin by systematically exploring the AutoHotkey syntax and vocabulary using commented tests written in AutoHotkey. It will be a slow process spanning over one or two months. I suspect that I will have to update, extend, restructure, and refactor the comments as well as the test code many times over this period.
Here is what I started with today. My systematic process is to copy pages or partial pages from the documentation into SciTE4AutoHotkey, break each concept down into its elemental parts, and tested each elemental part in order to link each concept in the documentation with a behavior I will come to expect. The collection of all of these concepts linked to all of these behaviors will result in an ever growing understanding of AutoHotkey.
I highlight each snippet in SciTE4AutoHotkey, right click, and "run selection" to test each block as I'm writing them.
Taken partially from: https://autohotkey.com/docs/Variables.htm
Code: Select all
;~ Variable types: AutoHotkey has no explicitly defined variable types. However, a variable containing only digits (with an optional decimal point) is automatically interpreted as a number when a math operation or comparison requires it. (To improve performance, numbers are cached internally to avoid conversions to/from strings.)
a := 5 ; the variable "a" contains only a digit, but is not interpreted to be a number yet
b := a + 5 ; the variable "a" is required for a math operation (a + 5) so it is interpreted to be a number type variable because it's used in a math operation on this line
msgbox % "b is equal to: " . b . "`nThis is because the variable ""a"" was interpreted as a number, and added to 5 (b := a + 5) to evaluate to 10."
if a = 5 ; the variable "a" is required for a comparison (if a = 5) on this line, since the variable "a" contains only digits, it is interpreted as a number
{
msgbox % "yes, the variable ""a"" is equal to 5!"
}
else
{
msgbox % "no, the variable ""a"" is not equal to 5!"
}
; Here is an example where a variable does not contain only digits, so it's not interpreted as a number type variable when used in math operations or comparisons.
a := 5grams ; the variable "a" contains contains a digit, but also non-digits : it is not interpreted yet
b := a + 5 ; the variable "a" is required for a math operation (a + 5) but "a" does not contain only digits, so it's not interpreted as a number, the math operation fails silently and "b" evaluates to nothing (empty)
if a = 5 ; the variable "a" is required for a comparison (if a = 5) on this line, since the variable "a" contains only digits, it is interpreted as a number
{
msgbox % "yes, the variable ""a"" is equal to 5!"
}
else
{
msgbox % "no, the variable ""a"" is not equal to 5!"
}
;~ Variable scope and declarations: With the exception of local variables in functions, all variables are global; that is, their contents may be read or altered by any part of the script.
a := "test"
gosub MyLabel
return
MyLabel:
msgbox % a ; the variable "a" is found because variables created outside functions are accessible everywhere in the script except inside functions.
return
;~ To access variables created outside functions and use them inside functions they must be declared global variables outside of functions.
global a := "test"
msgbox % myFunction()
myFunction() {
b := a . " worked"
return b
}
;~ Alternatively, functions themselves can be declared global so that they can use variables created outside of functions.
a := "test"
msgbox % myFunction()
myFunction() {
global ; this function is declared a global function by placing "global" on the first line inside of the function
b := a . " worked"
return b
}
;~ Except where noted on the functions page, variables do not need to be declared;
;~ Variables come into existence simply by using them (and each variable starts off empty/blank).
if (a = "") ; the variable "a" comes into existence simply by using it in a comparison
if b = ; the variable "b" comes into existence simply by using it in a comparison
c := ; the variable "c" comes into existence simply by using it when you assign it (even assign it to contain nothing as in this example)
msgbox % "a: " . a . "`nb: " . b . "`nc: " . c . "`nThe variables came into existence, but their contents starts off empty/blank."
;~ Variable names: Variable names are not case sensitive (for example, CurrentDate is the same as currentdate).
CurrentDate := "December 5th, 1805"
currentdate := "January 6th, 1906" ; The currentdate is the same as CurrentDate, so CurrentDate/currentdate both contain "January 6th, 1906" on the second line.
msgbox % "currentdate: " . currentdate . "`nCurrentDate: " . CurrentDate . "`ncURRENTdATE: " . cURRENTdATE
;~ Variable names may be up to 253 characters long and may consist of letters, numbers and the following punctuation: # _ @ $
abc := "test 1"
123 := "test 2"
#a# := "test 3"
_b_ := "test 4"
@c@ := "test 5"
$d$ := "test 6"
msgbox abc: %abc% `n123: %123% `n#a#: %#a#% `n_b_: %_b_% `n@c@: %@c@% `n$d$: %$d$%