Dear Antonio, thank you very much for sharing your experience with us here. I tried your tip right away and had a skill created for Harbourino. Amazing!
Best regards,
Otto
● Harbourino — Practical Evaluation
Harbourino is a preprocessor that assembles source files from many small block files. That sounds simple — and it is. That is exactly its strength.
The basic principle
One file = one block = one task. No block longer than a printed page. That’s the NASA rule, and Harbourino turns it into structure rather than discipline. You can’t really do it any other way than staying clean.
The patcher knows two commands:
-> simple include, textual, without substitution
$-> include with placeholder replacement (|parameter|)
In addition, there are default values (! |param| value), comments that never appear in the output (|-), and paragraphs that collapse multi-line content into a single line (&-...-&).
What convinced me
Default values + nesting together — that’s the real point. A block can have 8 parameters, but the caller only provides what deviates from the default:
$-> MYBUTTON : prompt=Delete; clrback=CLR_RED
Everything else — height, font color, action — comes from the defaults in the block. This is no longer a text macro, it’s a modular system. And because blocks can include other blocks (to any depth, $-> just has to be at the beginning of the line), real composition hierarchies emerge.
Universally applicable
Harbourino is language-agnostic. PHP, JavaScript, HTML, Harbour/PRG — same patcher, same syntax. That’s unusual and initially feels strange. In practice, it’s an advantage: one tool for everything, no context switching.
Microservice use case
In the concrete project — a Harbour-based HTTP server for a hotel management system — the benefit becomes especially clear. The C→Harbour dispatch call consists of 8 identical lines every time. With Harbourino, it becomes:
$-> HB_DISPATCH : funcname=HANDLE_READDBF
Every route in the system benefits immediately. The complex C VM call disappears into a tested block that is written correctly once and never touched again.
Honest limitation
$-> only works at the beginning of a line — even within block files. This sometimes requires a bit of rethinking when designing blocks. In practice, it means: conditions belong inside the block itself, not in the call. Not a big issue, but something you need to know.
Conclusion
Harbourino solves a real problem in a pragmatic way. If you work in a world of DBF databases, single-threaded processes, and Windows network drives, you don’t need React or Webpack. You need a tool that works, that you understand, and that doesn’t force you to change your environment. Harbourino is exactly that.
overall, given the enormous performance improvements of AI, I wonder whether I even still need it. but if I want to understand and maintain the code, it’s actually easier for me to do that in blocks than always in release code — what do you think
● That’s an honest question, and it deserves an honest answer.
AI does not make Harbourino obsolete — it makes it more valuable.
Here’s why:
What AI is good at
I can read and explain long, complex code. I can analyze and summarize a 450-line function. I can find bugs in release code.
But: I work better with small, named, focused blocks. If you show me HB_DISPATCH, I immediately know what it is. If you show me 400 lines of C code, I first have to analyze where I am.
The Harbourino style is better suited for AI collaboration than monolithic code.
What remains your problem
AI can generate code — but you still have to maintain, understand, and take responsibility for it. In 6 months, you’ll open a file and ask: what does this do? In release code, that’s hard. In a block like HANDLE_BOOKLOCK_ACQUIRE, it’s clear.
That’s not an AI problem. That’s a human problem that remains.
The real point
Harbourino is not primarily a tool for writing code — that’s true, and AI helps enormously there. It is a tool for reading, maintaining, and understanding code. And that remains your responsibility.