Page 1 of 1

Many small functions vs. a few large functions

Posted: 07 May 2014, 11:50
by bobc119
I am sure it is personal preference, but I am curious if there are sort of standard common practices amongst programmers, that may be helpful to non-programmers like myself.

I am not a programmer, I have no formal or on the job training, or even any friends that write code. It seems AHK attracts many people like me.

Over the last year I have used AHK extensively, and after some time I found out that I should avoid global variables and use functions as much as possible. I recently started using VBA as well, and I'm running into these same questions. Does anyone know where a non-programmer can find these sorts of helpful guidelines (ie. avoid global variables) that may seem obvious to anyone that does it for a living?

I tend to write code like this:

Code: Select all

label:
Func()
return
where the one function may be a few hundred to a few thousand lines themselves. In my mind, this avoids global space as much as possible.
Is it better to instead split the function into many smaller functions, and call them from the label? VBA books seem to push this idea, that's where this question came from.

Also, quite often I'll use functions within other functions, which seems frowned upon for some reason:

Code: Select all

Func()
{
	if (AnotherFunc())
		AndAnotherFunc()
}
Is this bad for some reason?

Re: Many small functions vs. a few large functions

Posted: 07 May 2014, 12:01
by toralf
I guess you'll find a lot of "how to program" guidelines on the web.

At the end it is you that defines what is good/effective for your code.

You might consider
- readability/understandability (even after years of not working on it)
- maintability
- showing flow of data/actions
- sharing with other users the code
- working with other users on that code

Re: Many small functions vs. a few large functions

Posted: 07 May 2014, 13:36
by jballi
A few comments about calling functions within other functions. In this case, we're talking about AutoHotkey script functions, Ex: MyFunction(), not AutoHotkey system functions, Ex: Abs(Number).

In general, calling a function from another function is the way to go. Calling a properly designed, well written, and frequently called, function from within another function can save the developer a huge amount of development time and effort. If the function has a bug or needs an enhancement, fixing/changing the code in one place (in the original function) can potentially save the developer a lot of time and effort.

The only exception to this rule might be when the function is called from a time sensitive and/or response sensitive routine and the function is called within a hard loop. A "hard" loop is my way of saying a loop that is run for many (many) iterations. Every call to an AutoHotkey script function includes some pre-call and post-call overhead. It's not much so calling a function a few dozen, a few hundred, and in most cases, a few thousand times will not make much of difference. However, in a time/response sensitive routine that uses a hard loop, the extra overhead can be problematic. Putting the code directly in the routine instead of calling an external function will save the function overhead costs every time the code is performed.

Them be my thoughts...

Re: Many small functions vs. a few large functions

Posted: 12 May 2014, 12:06
by guest3456
bobc119 wrote:I am sure it is personal preference, but I am curious if there are sort of standard common practices amongst programmers, that may be helpful to non-programmers like myself.
everything is personal preference, but there good reasons as to why preferences have developed in certain ways ;)

one such set of standards that i like is here:
http://www.koonsolo.com/news/dewitters-tao-of-coding/

bobc119 wrote: where the one function may be a few hundred to a few thousand lines themselves. In my mind, this avoids global space as much as possible.
Is it better to instead split the function into many smaller functions, and call them from the label?
there are many reasons

1. its much harder to debug
2. its much harder to test
3. its much harder to maintain
4. you are probably repeating code

everyone falls in this trap and it takes conscious effort to keep refactoring the code. most of the time people won't worry about this, especially AHK scripters, because no one is testing their code. but when you have large codebases that you need to maintain, its a nightmare to try to read through a 1000 line function and then debug it. AHK scripts also don't write unit tests or use testing suites, so they aren't gonna bother. but when you have to maintain large commercial codebases you need to be able to know exactly where things are failling so you can fix bugs fast.

once you get into writing classes it is also important that each class adheres to the Single Responsibility Principle which will allow you to isolate variables similar to keeping the global namespace clean
bobc119 wrote: Also, quite often I'll use functions within other functions, which seems frowned upon for some reason
no, what you've shown is the exact way to keep the functions smaller by separating concerns
http://en.wikipedia.org/wiki/Separation_of_concerns

from the author of the Linux operating system:
https://www.kernel.org/doc/Documentation/CodingStyle wrote:
Chapter 6: Functions

Functions should be short and sweet, and do just one thing. They should
fit on one or two screenfuls of text (the ISO/ANSI screen size is 80x24,
as we all know), and do one thing and do that well.

The maximum length of a function is inversely proportional to the
complexity and indentation level of that function. So, if you have a
conceptually simple function that is just one long (but simple)
case-statement, where you have to do lots of small things for a lot of
different cases, it's OK to have a longer function.

However, if you have a complex function, and you suspect that a
less-than-gifted first-year high-school student might not even
understand what the function is all about, you should adhere to the
maximum limits all the more closely. Use helper functions with
descriptive names (you can ask the compiler to in-line them if you think
it's performance-critical, and it will probably do a better job of it
than you would have done).
heres an example exercise that i had done a while ago while i was learning to code in TDD style, where you write tests BEFORE you write the code (probably should watch in fullscreen):

https://www.youtube.com/watch?v=Fm2Q-lJPgSg&hd=1

you may think that video is trivial but test-first coding (TDD) has become very popular recently because you will have a test suite which can pinpoint any bugs as you go along. plus you will be constantly refactoring the code into smaller pieces so it is easy to maintain and read. you can see starting at 5:20 in the video when i break the code into smaller functions. notice that even if the new functions are only a few lines long, i have broken them out because the main function was no longer "only doing one single thing". so i refactor the code and split into new functions, with explicit names explaining the 'one thing' that the function is meant to do

Re: Many small functions vs. a few large functions

Posted: 30 May 2014, 23:07
by bobc119
Thank you all for great answers!

I wish there were some sort of 6 month tutorial. I spent the first six months writing little hotkeys, and then all of a sudden my scripts started to get huge and complex. and trying to find bugs a year later takes days each.
one such set of standards that i like is here:
http://www.koonsolo.com/news/dewitters-tao-of-coding/
I really like that style. It has improved my own comprehension (of my own code) greatly.

Since I read guest3456's post and watched the video, I've made a strong effort to constantly keep my functions focused on one idea, and also give them appropriate names ( with verbs ). And in the last few weeks it has completely changed the way I write code. One of the first things I noticed is I now create functions knowing ahead of time that I will be using it shortly in multiple other functions, and I end up building it with that intention. Combining this with giving each function a clear purpose has saved me a lot of repeat coding that in the past I would have done.

Re: Many small functions vs. a few large functions

Posted: 21 Jul 2014, 19:45
by fischgeek
It's usually best practice to keep functions down to about 20 lines of code. Anything more than that there's probably room for optimization.

Re: Many small functions vs. a few large functions

Posted: 22 Jul 2014, 01:14
by vasili111
bobc119 wrote: I tend to write code like this:

Code: Select all

label:
Func()
return
In my personal opinion you should not use label for calling function. Just call function from any place you want to call. I am not against Goto and Gosub, I think they are useful some time. But I don't think that they are useful for calling functions. I mean that instead Goto, label in your code for calling Func(), just use Func() instead of Goto, label.

Personally I prefer to put all code whenever it is possible (not every code can be putted inside function in AutoHotkey). And I like to break my code in to little functions and avoid to make big ones.



Also I like idea of TDD. As guest3456 mentioned before it is good idea to writes test first before your code whenever it is possible. It is very useful when you are writing big script. TDD is especially useful with interpreted languages, because in comparison to compiled languages, code is checked only when it is executed.

Re: Many small functions vs. a few large functions

Posted: 22 Jul 2014, 05:03
by Nextron
vasili111 wrote:
bobc119 wrote: In my personal opinion you should not use label for calling function. Just call function from any place you want to call. I am not against Goto and Gosub, I think they are useful some time. But I don't think that they are useful for calling functions. I mean that instead Goto, label in your code for calling Func(), just use Func() instead of Goto, label.
I think bobc119 does it that way out of necessity. I don't like it but do it too. Gui event, timers or menus all point to labels, not functions.

Re: Many small functions vs. a few large functions

Posted: 22 Jul 2014, 08:47
by tank
It is worth mentioning that functions and classes also serve the purpos of encapsulating. not just the code but the memory as well.
variables created in global space allocate and stay reserved for the life of the script. created within a function exist only while that bit of code is executing,classes further encapsulate this process reducing the need for unique function names and variables making code easier to read within a context. but remember you wouldnt define a class with a function to encapsulate msgbox. Your going to have to put thought into what your doing and why and then and only then can you decide what level of encapsulation actually makes sense

Re: Many small functions vs. a few large functions

Posted: 22 Jul 2014, 11:21
by joedf
Good point on the memory/encapsulation there! Global vars.... I always forget a few after writing long scripts and always end up with at least 30 different variables when it would possible to use only half as many... :P

Re: Many small functions vs. a few large functions

Posted: 23 Jul 2014, 21:26
by bobc119
Nextron wrote: I think bobc119 does it that way out of necessity. I don't like it but do it too. Gui event, timers or menus all point to labels, not functions.
yeah exactly. Most of my functions run from hotkeys or buttons.
fischgeek wrote:It's usually best practice to keep functions down to about 20 lines of code.
Wish I had learned that earlier. When I asked this question, I was in the middle of a function that was over 2000 lines.

But now, sometimes I feel like I write incredibly tangled webs of small functions that are almost harder to follow.

Re: Many small functions vs. a few large functions

Posted: 23 Jul 2014, 21:34
by tank
Your application should have a logical flow and function names should be self documenting. ArrayToHTML_Table() is far more meaningful than table() as an example. But perhaps googlesearchresultstoarray() while descriptive is far too specific a function. Finding ways to write functions with utility in mind is a skill many programers overlook.

Re: Many small functions vs. a few large functions

Posted: 23 Jul 2014, 21:39
by joedf
+1 Naming functions appropriately is very important.

Re: Many small functions vs. a few large functions

Posted: 24 Jul 2014, 00:29
by vasili111
bobc119
If you need to write big scripts especially with complex logics, I suggest you to look at DRAKON-AutoHotkey ( http://ahkscript.org/boards/viewtopic.php?f=6&t=3108 ). DRAKON system makes very complex logic easy to implement and understand even for non programmer. DRAKON-AutoHotkey makes possible to use DRAKON with AutoHotkey - generate AutoHotkey code from DRAKON diagrams.

Re: Many small functions vs. a few large functions

Posted: 08 Apr 2015, 19:24
by guest3456
just found this and i love the idea and will be implementing it:
http://pear.php.net/manual/en/rfc.cs-enhancements.splitlongstatements.php wrote: When the if clause is really long enough to be split, it might be better to simplify it. In such cases, you could express conditions as variables an compare them in the if() condition. This has the benefit of "naming" and splitting the condition sets into smaller, better understandable chunks:

Code: Select all

<?php

$is_foo = ($condition1 || $condition2);
$is_bar = ($condition3 && $condtion4);
if ($is_foo && $is_bar) {
    // ....
}
?>