You Know the Problem with Programming Forums…?

November 03, 2025

 

Logo

You know the problem with programming forums?

It’s not the questions. It’s not even the bugs. It’s the people.

Everywhere you go, there’s a small but mighty group of seasoned coders who really get it — the ones who’ve wrestled with obscure compiler errors, traced logic bugs through 200 lines of nested loops, and still have the mental energy left to explain it to someone else (usually with more patience than the situation deserves).

These are the quiet heroes of the community — they drop by, solve your issue with a three-line code sample, and vanish into the digital mist like some kind of stack-trace samurai.

And then… there’s the other group.

The overconfident few who, thanks to the magic of the Dunning–Kruger effect, have somehow achieved total certainty with only partial understanding. They appear out of nowhere, ready to tell you how your code should work — and they’ll do it with such conviction that you start questioning your own sanity.

It’s a fascinating phenomenon:

The less someone knows, the more aggressively they’ll argue about it.

They’ll cite “best practices” they half-remember, invent terminology mid-sentence, and copy–paste code that looks like it was written during a caffeine overdose at 3 a.m. in 1998.

And because confidence sounds like competence online, the myth spreads faster than a memory leak in an infinite loop.

Meanwhile, the real experts quietly bow out of the conversation, sensing that no amount of logic will change the outcome. They’ve seen it before. They know the cycle: ask → argue → ego → silence → repeat.

Now don’t get me wrong — every programmer starts somewhere, and we’ve all been wrong (some of us spectacularly so). But there’s a big difference between learning and lecturing. The first builds communities. The second just fills them with noise.

Maybe the cure is humility — or at least a sense of humour about how we’re all wrong sometimes. If we could just admit that once in a while, maybe the next generation of coders wouldn’t have to scroll through ten paragraphs of “expert advice” before finding the one post that actually fixes the problem.

Until then, I’ll be here, sipping coffee, watching the cycle repeat — and quietly hoping someone, somewhere, finally invents a compiler for forum advice.

Let’s Write a Lexer in PlayBASIC

October 12, 2025

 

Logo

Introduction

Welcome back, PlayBASIC coders!

In this live session, I set out to build something every programming language and tool needs — a lexer (or lexical scanner). If you’ve never written one before, don’t worry — this guide walks through the whole process step by step.

A lexer’s job is simple: it scans through a piece of text and classifies groups of characters into meaningful types — things like words, numbers, and whitespace. These little building blocks are called tokens, and they form the foundation for everything that comes next in a compiler or interpreter.

So, let’s dive in and build one from scratch in PlayBASIC.


Starting with a Simple String

We begin with a test string — just a small bit of text containing words, spaces, and a number:

s$ = "   1212123323      This is a message number"
Print s$

This gives us something to analyze. The plan is to loop through this string character by character, figure out what each character represents, and then group similar characters together.

In PlayBASIC, strings are 1-indexed, which means the first character is at position 1 (not 0 like in some other languages). So our loop will run from 1 to the length of the string.


Stepping Through Characters

The core of our lexer is a simple `For/Next` loop that moves through each character:

For lp = 1 To Len(s$)
    ThisCHR = Mid(s$, lp)
Next

At this stage, we’re just reading characters — no classification yet.

The next question is: how do we know what type of character we’re looking at?


Detecting Alphabetical Characters

We start by figuring out if a character is alphabetical. The simplest way is by comparing ASCII values:

If ThisCHR >= Asc("A") And ThisCHR <= Asc("Z")
    ; Uppercase
EndIf

If ThisCHR >= Asc("a") And ThisCHR <= Asc("z")
    ; Lowercase
EndIf

That works, but it’s messy to write out in full every time. So let’s clean it up by rolling it into a helper function:

Function IsAlphaCHR(ThisCHR)
    State = (ThisCHR >= Asc("a") And ThisCHR <= Asc("z")) Or _
            (ThisCHR >= Asc("A") And ThisCHR <= Asc("Z"))
EndFunction State

Now we can simply check:

If IsAlphaCHR(ThisCHR)
    Print Chr$(ThisCHR)
EndIf

That already gives us all the letters from our string — but one at a time.

To make it more useful, we’ll start grouping consecutive letters into words.


Grouping Characters into Words

Instead of reacting to each character individually, we look ahead to find where a run of letters ends. This is done with a nested loop:

If IsAlphaCHR(ThisCHR)
    For ChrLP = lp To Len(s$)
        If Not IsAlphaCHR(Mid(s$, ChrLP)) Then Exit
        EndPOS = ChrLP
    Next
    ThisWord$ = Mid$(s$, lp, (EndPOS - lp) + 1)
    Print "Word: " + ThisWord$
    lp = EndPOS
EndIf

Now our lexer can detect whole words — groups of letters treated as a single unit.

That’s the first real step toward tokenization.


Detecting Whitespace

The next type of token is whitespace — spaces and tabs.

We’ll build another helper function:

Function IsWhiteSpace(ThisCHR)
    State = (ThisCHR = Asc(" ")) Or (ThisCHR = 9)
EndFunction State

Then use the same nested-loop pattern:

If IsWhiteSpace(ThisCHR)
    For ChrLP = lp To Len(s$)
        If Not IsWhiteSpace(Mid(s$, ChrLP)) Then Exit
        EndPOS = ChrLP
    Next
    WhiteSpace$ = Mid$(s$, lp, (EndPOS - lp) + 1)
    Print "White Space: " + Str$(Len(WhiteSpace$))
    lp = EndPOS
EndIf

Now we can clearly see which parts of the string are spaces and how many characters each whitespace block contains.


Detecting Numbers

Finally, let’s detect numeric characters using another helper:

Function IsNumericCHR(ThisCHR)
    State = (ThisCHR >= Asc("0")) And (ThisCHR <= Asc("9"))
EndFunction State

And apply it just like before:

If IsNumericCHR(ThisCHR)
    For ChrLP = lp To Len(s$)
        If Not IsNumericCHR(Mid(s$, ChrLP)) Then Exit
        EndPOS = ChrLP
    Next
    Number$ = Mid$(s$, lp, (EndPOS - lp) + 1)
    Print "Number: " + Number$
    lp = EndPOS
EndIf

Now we can identify three types of tokens:

Words (alphabetical groups)

Whitespace (spaces and tabs)

Numbers (digits)


Defining a Token Structure

Up to this point, our program just prints what it finds.

Let’s store these tokens properly by defining a typed array.

Type tToken
    TokenType
    Value$
    Position
EndType
Dim Tokens(1000) As tToken

We’ll also define some constants for readability:

Constant TokenTYPE_WORD        = 1
Constant TokenTYPE_NUMERIC     = 2
Constant TokenTYPE_WHITESPACE  = 4

As we detect tokens, we add them to the array:

Tokens(TokenCount).TokenType = TokenTYPE_WORD
Tokens(TokenCount).Value$    = ThisWord$
TokenCount++

Do the same for whitespace and numbers, and our lexer now builds a real list of tokens as it runs.


Displaying Tokens by Type

To visualize the result, we can print each token in a different colour:

For lp = 0 To TokenCount - 1
    Select Tokens(lp).TokenType
        Case TokenTYPE_WORD:       c = $00FF00 ; green
        Case TokenTYPE_NUMERIC:    c = $0000FF ; blue
        Case TokenTYPE_WHITESPACE: c = $000000 ; black
        Default:                   c = $FF0000
    EndSelect

    Ink c
    Print Tokens(lp).Value$
Next

When we run this version, we see numbers printed in blue, words in green, and whitespace appearing as black gaps — exactly how a simple syntax highlighter or compiler front-end might visualize tokenized text.


Wrapping Up

And that’s it — our first lexer!

It reads through a line of text, classifies what it finds, and records each token type for later use.

The same process underpins many systems:

Compilers use it as the first step in parsing code.

Adventure games might use it to process typed player commands.

Expression evaluators or script interpreters rely on it to break down formulas and logic.

The big takeaway? A lexer doesn’t have to be complicated.

This simple approach — scanning text, detecting groups, and tagging them — is the heart of it. Once you understand that, you can expand it to handle symbols, punctuation, operators, and beyond.

If you’d like to see more about extending this lexer or turning it into a parser, let me know in the comments — or check out the full live session on YouTube.

Links:

  • PlayBASIC,com
  • Learn to basic game programming (on Amazon)
  • Learn to code for beginners (on Amazon)




  • The NDIS Rollercoaster: One Man’s Fight for Mobility, Dignity, and Fairness

    September 16, 2025

     

    Logo

    The NDIS Rollercoaster: One Man’s Fight for Mobility, Dignity, and Fairness

    A friend of mine is a brain cancer survivor. Twice in his twenties he fought off cancer, and the second time cost him an eye and the life skills most of us take for granted. After surgery, he had to relearn everything—walking, talking, motor skills. It took years of determination, rehab, and grit to claw his way back to independence.

    He’s lived with the impact of those battles ever since. But now, with age taking its toll, the old injuries and fatigue are catching up. Everyday tasks are harder, and walking is becoming more of a struggle. Eventually, he did what anyone in his situation should be able to do: applied for NDIS support.

    The first time, he was rejected. The message? You’re not sick enough.

    It took persistence, multiple applications, and more years of struggle before he was finally accepted. But even then, qualifying doesn’t mean you get help straight away. The NDIS approval and the funding are two separate processes. He waited almost another year for an actual support package.

    So when his coordinator raised the idea of a mobility scooter — a tool to help him stay independent as walking became more difficult—it finally felt like a practical step in the right direction.


    The Scooter Trial

    I tagged along to the scooter trial. His package coordinator and an occupational therapist (OT) were there, helping him test different models. The session was positive. Smiles all round. He found a medium-sized scooter that was practical, safe, and portable. About $5,000 —just 10% of his $50,000 annual package.

    He’s still mobile today, but walking has always been difficult, and age is making it worse. The scooter wasn’t about giving up—it was about ensuring a smooth transition as his mobility inevitably declines. A simple, practical step to safeguard his freedom and independence for the years ahead.

    A week later, he told me NDIS had knocked back the request.

    Strange, right? Funded to $50K, yet a life - changing mobility aid worth a fraction of that was deemed too much.

    We joked maybe it was just a game of persistence—put in the request every six months until someone says yes. “Pester power.”


    The Bizarre Twist

    Then it got weird.

    Despite the knock-back, his OT booked a home scooter trial. He didn’t request it. He didn’t want it. He’d already said it was pointless without funding.

    But they brought it anyway.

    Weeks later, when I caught up with him, he was frustrated and confused. His OT had called to say he couldn’t work with him anymore—the OT’s $6,000 allocation (part of the $50K) was already used up within six months.

    Something didn’t add up.


    Following the Money

    He called his coordinator to review the accounts. What he found was staggering.

  • An invoice of over $1,000 for that unnecessary home scooter trial which he never asked for.
  • A long list of inflated service charges.
  • And, the kicker: every chat with his coordinator was being billed at $200 per hour—more if they had to “research” something on his behalf.
  • All while the scooter that could change his daily life was deemed unaffordable.


    The Bigger Picture

    This isn’t just about one man’s scooter. It’s about systemic waste and misplaced priorities.

    NDIS participants are treated like line items on an invoice. Providers drain budgets with endless admin, trials, and “consultations”—while the actual supports that improve quality of life get delayed or denied.

    It’s a cruel irony: the system spends thousands on bureaucracy and box-ticking, but when it comes to something as tangible as mobility, independence, or dignity—the answer is "no."


    Closing Point

    The NDIS was supposed to be about empowerment, choice, and support. Instead, it often feels like a tangled bureaucracy designed to wear people down until they stop asking for help

    My friend doesn’t want charity. He doesn’t want luxuries. He wants what the scheme was built for—a fair go, a chance to live with dignity, and the freedom to get around without begging for scraps from his own package.

    The tragedy is that his story isn’t unique.

    And unless the system changes, thousands more Australians with disability will continue to be robbed—of their time, their money, and their independence—by the very program meant to help them.