vba

Sub vs. Function without a return value


What is the sense of a subroutine (Sub)? Why not use a Function without a return value?


Edit

What I mean is, why does the keyword Sub exist? I can use Function without declaring a return value and have the same, no?


Solution

  • Because it clarifies the intent.

    A Function clearly says "I'll have something for you when I return". The expectation is that a Function returns something, because that's what functions are meant to do.

    A Sub clearly says "I'm doing something that you should expect to just eventually succeed". The expectation is that a Sub executes an action, alters some state, causes some side effects.

    A Function that would be named DoSomething, is just as confusing as a Sub that would be named GetFoo: the intent is obscured, the very nature of the procedure conflicts with how it's advertised. I expect DoSomething to either succeed at doing something, or throw some error. Similarly, I expect GetFoo to, well, get me a Foo.


    Because a non-returning function makes no sense.

    In several programming languages, a Function (or semantically similar construct) that doesn't return a value in all code paths, can't even be compiled. Using a Function-without-a-return-value for everything in VBA sounds very much like abusing the language, just because VBA won't complain about it. As common wisdom tells us, it's not because we can, that we should.

    Why return void, when you can return a bool everywhere, and not assign it?

    public bool DoSomething()
    {
        // do stuff...
        // ...and don't assign the return value.
        // woopsie, doesn't compile.
    }
    

    A VBA Sub procedure is like a C# void method: it's explicit about its non-returning nature, and that's a good thing.


    Because static code analysis tools will complain.

    The VBA compiler will notoriously not care if you write code where it's never clear whether your non-returning of an implicit return value is intentional or not.

    When you do mean to return a value - and forget, because bugs happen all the time - how can you be sure that this one is legitimately non-returning, and that other one isn't? Without combing through the code and fully understanding everything it does and why, you can't tell. If you're lucky, you're looking at small, specialized functions that obviously do one thing, and do it well. Otherwise, you need to waste your time understanding what's going on, just to be sure of something that should already be obvious.

    Static code analysis tools like Rubberduck (I maintain that project) will flag these functions, since they are potential bugs hiding in your code base, waiting to bite you:

    Rubberduck code inspection results