your personal AutoHotkey style guide

Discuss Autohotkey related topics here. Not a place to share code.
Forum rules
Discuss Autohotkey related topics here. Not a place to share code.
john_c
Posts: 255
Joined: 05 May 2017, 13:19

Re: your personal AutoHotkey style guide

22 Jul 2019, 10:30

From my PM conversation with Flipeador:

Me:
In your Ahk2Exe on GitHub you sometimes use something like

Code: Select all

; https://github.com/flipeador/Ahk2Exe/blob/master/Ahk2Exe.ahk#L457
if (Var != "")
but sometimes

Code: Select all

----
; https://github.com/flipeador/Ahk2Exe/blob/master/Ahk2Exe.ahk#L546
if (Var)
Could you explain, is there any difference between them? And why you use slightly unusual if (Var != "") instead of if (Var)?
Flipeador:
In AutoHotkey it is true that an empty string is interpreted as FALSE, but for me this is not appropriate. So, if a function returns an empty string to indicate error, I prefer to use if (var == ""), it's more explicit and clear. On the other hand, if the function returns zero in case of error, I use if (var == 0) or if (!var). Also AHK interprets a number in a string just like a pure number, which I disagree with as well (when used with if strnum == num). I never handle an empty string as FALSE.

This is true on v2.0-a103-56441b52:

Code: Select all

MsgBox "0x00009" == 9
Last edited by john_c on 11 Sep 2019, 22:03, edited 1 time in total.
john_c
Posts: 255
Joined: 05 May 2017, 13:19

Re: your personal AutoHotkey style guide

22 Jul 2019, 15:25

@jeeswg
If/else styles, any opinions?

Code: Select all

func()
{
    if (...)
        return True
    else
        return False
}

Code: Select all

func()
{
    if (...)
        return True
    return False
}
See here:

https://softwareengineering.stackexchange.com/questions/157407/best-practice-on-if-return
User avatar
jeeswg
Posts: 6648
Joined: 19 Dec 2016, 01:58
Location: UK

Re: your personal AutoHotkey style guide

31 Aug 2019, 17:06

HUNGARIAN NOTATION
aeiklmr wrote: This is strange. I am Hungarian and did a very similar thing, but I've never heard about this thing before. :shifty:
@aeiklmr: Hehe, it's funny when things like that happen. Hungarian notation is great. Apparently 'English muffins' are a thing.

NOT ENDING FUNCTIONS WITH IF/ELSE
@john_c: Great addition. Thanks.

Code: Select all

;NO (but logical):
func()
{
	if cond
		return 1
	else
		return 0
}

;YES (probably better overall):
func()
{
	if cond
		return 1
	return 0
}
DLLCALL (AND QUOTES)
Since AHK v2 'Disabled unquoted arg and return types for DllCall', I've revised how I do DllCall.
Using DllCall for dll functions:

Code: Select all

;notes from my JEE_TidyDllCall function:
;[YES, include name] n: always include dll name (else omit comctl32/gdi32/kernel32/user32)
;[NO, i.e. omit .dll] x: always include .dll e.g. 'DllName.dll\Func' (else 'DllName\Func')
;[NO, i.e. omit Int] r: always include return type (else omit Int)
;[YES, use pairs] p: use pair style e.g. 'T1,A1, T2,A2' (else 'T1, A1, T2, A2')
;[YES, use quotes, was no] q: use quotes style e.g. "Int" (else Int)
;[YES, use *, was no] s: use star style e.g. Int* (else IntP)

;before: I omitted quotes for brevity
;after: changed to use quotes because:
;AutoHotkey v2 alpha (UPDATES) - Page 3 - AutoHotkey Community
;https://autohotkey.com/boards/viewtopic.php?f=37&t=2120&p=275703#p275703
;'Disabled unquoted arg and return types for DllCall.'

;before: I used XXXP style for brevity
;after: since now using quotes, XXX*/XXXP are of equal length,
;and XXX* is more standard than XXXP

;YES:
;MB_OK := 0x0
DllCall("user32\MessageBox", "Ptr",0, "Str","text", "Str","title", "UInt",0x0)

;NO (opposite):
;MB_OK := 0x0
DllCall("MessageBox", Ptr, 0, Str, "text", Str, "title", UInt, 0x0)
DLLCALL AND INTERFACES
Using DllCall for interface methods:
The key point is that I now always include 'interface::method' as a comment.
Adding in the comments to my main scripts/libs, was a lot of work, but very worthwhile.

Code: Select all

;CM_ENUM_VISIBLE := 0x2
vCountCol := 0
DllCall(NumGet(NumGet(pCM+0)+5*A_PtrSize), "Ptr",pCM, "UInt",0x2, "UInt*",vCountCol) ;IColumnManager::GetColumnCount

;or, if using a VTable function:
;CM_ENUM_VISIBLE := 0x2
vCountCol := 0
DllCall(VTable(pCM, 5), "Ptr",pCM, "UInt",0x2, "UInt*",vCountCol) ;IColumnManager::GetColumnCount
VTable(ptr, n)
{
	return NumGet(NumGet(ptr+0), n*A_PtrSize)
}
FILEAPPEND
FileAppend, I always use 3 parameters for clarity:

Code: Select all

FileAppend,, % vPath, CP1252 ;create an empty 0-byte file
FileAppend, % vOutput "`r`n", % "*" vPath, UTF-8 ;create/append to a text file
BRACES: MINIMUM/OPTIMUM/MAXIMUM
Braces(/indentation):
Before: use the minimum number of braces.
After: always use braces apart from for one-liners.
Adding in the braces to my main scripts/libs, was a lot of work, but very worthwhile.
Basically I searched for two consecutive lines starting with control flow statements that affect indentation (note: 'else XXX' and 'try XXX' one-liners do not affect indentation):
vIsMatch := !RegExMatch(vTemp, "i)^(else[ `t]|try[ `t])") && RegExMatch(vTemp, "i)^(else|if|Loop|while|catch|finally|for[ `t]|try)")
[note: 'FormatTime', false positive for 'for']

Code: Select all

;==================================================

;before:
Loop 3
	if cond
	{
		action1()
		action2()
		action3()
	}

after:
Loop 3
{
	if cond
	{
		action1()
		action2()
		action3()
	}
}

;==================================================

;before:
Loop 3
	if cond
		action()

;after:
Loop 3
{
	if cond
		action()
}

;==================================================

;before:
Loop 3
	if cond1
		Loop 3
			if cond2
				action()

;after:
Loop 3
{
	if cond1
	{
		Loop 3
		{
			if cond2
				action()
		}
	}
}

;==================================================

;before:
Loop 3
	if cond1
		action1()
	else if cond2
		action2()
	else if cond3
		action3()
	else
		action4()

;after:
Loop 3
{
	if cond1
		action1()
	else if cond2
		action2()
	else if cond3
		action3()
	else
		action4()
}

;==================================================
[EDIT:] Updated vIsMatch RegEx line.
Last edited by jeeswg on 15 Sep 2019, 10:14, edited 1 time in total.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
User avatar
Chunjee
Posts: 121
Joined: 18 Apr 2014, 19:05
GitHub: Chunjee

Re: your personal AutoHotkey style guide

09 Sep 2019, 22:10

jeeswg wrote:
31 Aug 2019, 17:06
Braces(/indentation):
Before: use the minimum number of braces.
After: always use braces apart from for one-liners.
My homie :thumbup: :thumbup: :thumbup:
User avatar
jeeswg
Posts: 6648
Joined: 19 Dec 2016, 01:58
Location: UK

Re: your personal AutoHotkey style guide

15 Sep 2019, 10:21

@Chunjee: Hehe. Thanks. I've seen the idea of *always* using braces (including for one-liners) discussed. My idea is to 'almost always' use braces, with the exception of one-liners, a sort of halfway house, but I don't recall seeing that approach discussed anywhere, have you? Are you using the same principles as me, or something slightly different? Thanks.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
User avatar
Chunjee
Posts: 121
Joined: 18 Apr 2014, 19:05
GitHub: Chunjee

Re: your personal AutoHotkey style guide

15 Sep 2019, 11:22

Wish I could find it again but some article I read a while back convinced me that code comprehension was much more valuable than neat tricks and clever code. The basic argument being that when working with a group, or even a later version or yourself; being able to quickly understand what is going on an why is more valuable than using hacks to get it done in less lines. For this reason, I like very straightforward solutions, even if they are a few milliseconds slower. I don't really care that something is faster for the CPU if it takes me 10 mins to figureout what is going on when I open it again a year from now.

Other inspirations:
https://12factor.net/
https://www.zenprogrammer.org/en/10-rules-of-a-zen-programmer.html


Overall I would say that I like your style and principles a lot. They mirror what I've come to know on my own or through other sources. Perhaps we are on different paths to the same truths.
User avatar
nnnik
Posts: 4242
Joined: 30 Sep 2013, 01:01
Location: Germany

Re: your personal AutoHotkey style guide

15 Sep 2019, 11:51

Which brings us back to the discussion of practices.
Something that I do regularily or many others do regularily might be completely foreign to other people.
No member will ever be able to completely understand all other peoples styles - a rule for good practices probably can only be enforced by the developers themselves simply by going in one direction and disregarding the other.
Though in general its a waste of time to worry about Allman vs. K&R because it matters very little in practice.
A real argument for K&R is that many advanced languages force you or advise to use it.
Going with K&R would make it easier for those to swap languages back and forth.
Same goes for most other considerations in this topic.
Recommends AHK Studio
SOTE
Posts: 736
Joined: 15 Jun 2015, 06:21

Re: your personal AutoHotkey style guide

16 Sep 2019, 05:38

jeeswg wrote:
15 Sep 2019, 10:21
@Chunjee: Hehe. Thanks. I've seen the idea of *always* using braces (including for one-liners) discussed. My idea is to 'almost always' use braces, with the exception of one-liners, a sort of halfway house, but I don't recall seeing that approach discussed anywhere, have you? Are you using the same principles as me, or something slightly different? Thanks.
I'm on the side of always use braces (and indentation), because I'm not concerned about typing speed as much as I rather always be able to clearly see and understand what the code is doing. When it comes to indentation, prefer tabs, as spaces can create more of a mess or confusion. Especially when it comes to troubleshooting or coming back weeks or months later to review or update code. A lot of styles create a big mess of squashed together or convoluted code, where the programmer is trying to impress people that are not there or make themselves feel more clever with the way that the code "looks" (form over function), but this can cause unnecessary errors or makes it hard for others (or even themselves later on) to read.

Also, when it comes to other programming languages, one should be careful with assuming that C style or C family languages rule all. In languages like Object Pascal, Lua, and Python (for example) how they are written is a bit different. And these are reasonably popular languages. With Object Pascal, using braces all of the time (from the C family language), even for one-liners can arguably make "translating" between languages easier. As it's easier to identify blocks of code or nested loops. But, Object Pascal does allow you to omit "Begin" and "End" (equivalent to { }) for one-liners, like you can do in C family languages.

Return to “General Discussion”

Who is online

Users browsing this forum: No registered users and 1 guest