Clean Coding in Xojo: More tips from the community

Thanks. The article jogged a memory. In the early 1980s I would have been using assembly / MC and line numbered BASICs. SESE was a way to try to keep the spaghetti becoming tangled inside sub-routines. I also remember at what passed for college they tried to teach me Pascal and vaguely recollect functions that could only exit at the END FUNCTION statement - I could be imagining it though. It was a time share system that we got very little priority on. Waiting 24 hours to discover a syntax error soon drove me back to CBM, Apple and TRS BASICs.

1 Like

But you literally have put all the code into DoEverything.

Sort of, but its no longer a single block of code.

It also allows you to call one of the PerformLocalTask sub-methods with different parameters.

I was trying to prevent spaghetti becoming tangled inside sub-routines, by testing for error conditions and returning early.

You’re right about Pascal - it had no Return staement, by design. I just simulated that by putting a 999: label at the end, and doing GOTO 999 where otherwise I’d have had a Return. Only t ime I’ve used GOTO since stopping writing FORTRAN in 1978.

Totally depends on what is in those 3 methods. My general rule of thumb is that if a method has to be scrolled to see all the code. So smaller methods are easier to debug.

I recently came across at 2000 line method written by former colleague. It was clear after a few minutes of looking at it that it a) it was too complex (no left happy path) and b) it would benefit from making some smaller methods out of that monstrosity.

Write your code such that your future self (or the poor sap that has to work on your code) doesn’t want to invent a Time Machine to come back to kill you for writing this code!

4 Likes

Agreed.

One problem with splitting the method is that those new smaller methods become available to the rest of the class. Being able to have (private) sub-methods like Rick mentions would make code management much nicer.

Another reason for having long methods was to avoid the non-trivial overhead when calling other methods in a loop. More recent versions of Xojo appear to have made that better though.

Well, in my case I believe the original developer’s philosophy was why write 10 lines of code when 100 will do! Honestly, there’s reason to write a 2000 line method that had 20 levels of indentation from if then else, for and while loops. We didn’t care then, or now, about how efficient this code is. But is a huge PITA to work with, understand, and modify, and that IS something we care about.

Left happy path coding will make this method so much cleaner and easier to work with. But that’s an exercise for the future as we don’t have time to do it now.

2 Likes

This is absolutely the crucial point. I use the Quill editor in an HTMLViewer in an only partially successful attempt to have an editor that can export HTML. That is 12k lines of javascript and is, essentially, opaque. It seems to be a single function but may not be. It’s hard to tell, and even harder to understand.

i don´t care if it is 1 micro second faster.
I can remark a row, i can set a debug stop at this condition or write a remark at the end of the line or add a debug output. you know it was pseudo code.

1 Like

Declarations are typically at the top of a method and not in the visible area where the if then are placed.
I could use the ok variable multiple times if I have the need to do this.
I often set the value nearby the conditions.

that is great in java script, first it can access the variables from the scope one level up
and it encapsulate a set of methods.

Clipper too. But we are not talking about those kind of languages.

I do. We are different and that’s ok.

Until a few years ago, JavaScript didn’t support custom classes. But, you can “fake” a class-like object by having a single function with many nested functions and functions that act as properties. As a result, many JavaScripts libraries are written this way.

Edited for clarity.

1 Like

And these are all devoutly to be avoided.

Those writing such have clearly not been following this thread.

1 Like

I come from C#… obviously :)…

I had to look back in some ancient notes. Here is a single exit example in C. This is based on a coding standard I was subject to in the early 90s.

/* don't do this */
10  BOOL foo(void) {
20    ok : BOOL;
30    a_struct* temp;

40    temp = (a_struct*) malloc(sizeof(a_struct));
50    if (temp == NULL) return FALSE;

60    ok = bar(&temp);
70    if(! ok) return FALSE;

    /* do stuff with temp */

80    free(temp);
90    return TRUE;
    } 

The conditional return at line 70 will cause memory to leak. You might prevent the memory leak by duplicating the free() statement but the result is a malloc() with multiple free() statements which hard won experience tells me is worse than any problem returning early is likely to solve.

The solution was a potentially legitimate use of GOTO.

/* There can be only one. */
10  BOOL foo(void) {
20    BOOL ok = FALSE;
30    a_struct* temp = NULL;

40    temp = (a_struct*) malloc(sizeof(a_struct));
50    if (temp == NULL) goto end_function;

60    ok = bar(&temp);
70    if(! ok) goto end_function;

    /* do stuff with temp */

    end_function:
80    free(temp);
90    return ok;
    } 

What I remember of that Pascal compiler is, the main-frame was owned by G.E.C. and there were no line numbers or labels. It was the first time I had seen a procedural language. Too young for FORTRAN, too old for BBC Basic. I did eventually engage with Object Pascal but at 16 I was too impatient to wait on overnight compiler runs :smiley:

The trip down memory lane has reminded me how much we take modern language facilities for granted.

2 Likes

Do this, don’t use GOTOs, we’re not programming old versions of COBOL

bool foo(void) {

    bool ok  = false;
    a_struct* temp;

    temp = (a_struct*) malloc(sizeof(a_struct));

    // Explain here the condition bellow, store the result in ok too
    if (ok = (temp != NULL && bar(&temp))) {

        // do stuff with temp

    }

    free(temp);
    return ok;
} 

There are actually technical reasons to not use GoTo in Xojo. I heard it through the grapevine some time ago, so I wouldn’t want to misquote the problem. If you are interested in the technical details seek out Norman (and/or I think Bob?).

But yeah, it’s more than just the design concept, there are actual “you will cause problems” in Xojo.

Gotos in Xojo have issues when jumping from the inside of loops to the outside. I don’t remember the details, but I believe that in certain conditions leaks can occur.
Probably certain unwinds are skipped.