HN is not tied to one presentation model.
It will support normal console/terminal applications, so text output remains available where that is appropriate. HN itself is Unicode-oriented, so console applications are not limited to traditional ASCII/codepage assumptions.
For business applications, a major focus is HTML-based user interfaces, particularly through the planned HarbourNova Web Framework. HN will also have an official FastCGI contrib, making it suitable for high-performance server-side web applications behind standard web servers.
There will also be WebView support, allowing an HN desktop application to use modern HTML/CSS/JavaScript for its user interface while still behaving like a locally installed application. This provides a practical bridge between native desktop applications and web-based UI development without forcing everything to run as a remote web application.
HN is also designed so that more traditional native graphical interfaces can be supported, but a particular cross-platform desktop GUI toolkit is not being built into the core language.
A later release is planned to go further with a visual form builder, including visual inheritance. The intention is that developers will be able to design forms visually, derive new forms from existing ones, and inherit and refine their UI structure and behavior rather than repeatedly rebuilding similar screens.
The development environment itself is graphical as well: the HN VS Code extension provides project, language and debugging integration, while DataWharf provides visual database/schema management.
So the short answer is: Unicode console applications, HTML/web applications through FastCGI and the HarbourNova Web Framework, desktop applications using WebView, and later a visual form-building environment with inheritance.
Hi Francesco,
Thank you for the thoughtful message. I actually share part of your concern about fragmentation.
The Harbour community is relatively small, and creating another language inevitably risks dividing attention. That is something I have considered carefully. On the other hand, I think trying to make these changes directly inside Harbour would create a different and potentially worse division, because many of the changes intentionally break with existing behavior.
Harbour has an important role as a highly compatible continuation of the Clipper/xBase tradition. Existing applications depend on that compatibility. I don't think it would be appropriate to ask Harbour to abandon it.
HN therefore takes a different approach: preserve the parts of the xBase/Harbour programming model that remain productive, but allow the language, compiler, runtime, datatype system and tooling to evolve without requiring compatibility with every historical decision.
So I don't see HN as "the new Harbour" or something Harbour developers should be expected to move to. They are different projects with different goals. If HN eventually proves useful enough that some Harbour developers want to use it, great. If an existing Harbour application is working well, there may be no reason to move it at all.
At the same time, I don't want HN to be designed only for existing Harbour developers.
A significant part of the design review is looking at capabilities that have proven useful in languages such as Python, Go, Java, C#, Rust and others, and considering how those ideas can fit naturally into an xBase-style language rather than simply copying their syntax.
This is particularly true in areas such as classes, typing, collections, error handling, concurrency and multithreading. For example, HN's class model is being reviewed against capabilities that developers from mainstream object-oriented languages would expect, while the concurrency design takes ideas from newer structured-concurrency and message-passing models.
The objective is to keep the directness that makes xBase productive for business and database applications, but make HN less unfamiliar to somebody coming from Python, C#, Java, Go or Rust.
I hope that eventually this works in both directions: Harbour/xBase developers should feel at home, while developers from other ecosystems should see concepts they recognize rather than viewing HN as an isolated historical language family.
Regarding implementation, yes, there is considerably more than a feature list now. Some features are still approved designs, but others are already implemented and tested.
The two items you mentioned are good examples.
Named parameters are implemented at compiler level. They are not implemented by passing a dictionary of names and values at runtime. For a statically known function or method, the compiler knows its signature, including parameter names, required/default parameters, reference parameters and type contracts.
For example, arguments can be supplied positionally and then by name, and named arguments can appear in a different order. The compiler binds them to the correct formal parameters while still evaluating the expressions exactly once and in their original left-to-right source order. The callee receives the canonical parameter layout and also enforces the declared contract.
This works not only for HN APIs but for user-defined functions across separate .hnp source files, and the same callable/signature infrastructure is used for methods.
Classes are also compiler-owned rather than primarily preprocessor constructs. A class has one authoritative structural declaration containing its properties, method signatures, visibility, inheritance information, etc. Method implementations can then be in that declaration for short methods, or independently implemented in one or several other .hnp files.
The compiler and build system understand those relationships. A change to the implementation of one method need not cause everything using the class to be rebuilt, while a change to the class layout or public contract invalidates the appropriate dependent code.
That compiler knowledge also gives us opportunities later to optimize statically known method calls and property access more aggressively than would be possible if the compiler knew very little about the class. I am being careful not to claim performance improvements before they are benchmarked, but the architecture is deliberately being designed to make such optimization possible.
Another major change is the API model.
HN is not simply retaining every historical Harbour API name and adding more names beside them. The intent is that, where practical, one semantic action has one canonical HN API.
Over time Harbour accumulated APIs with overlapping purposes or slightly different semantics—for example things such as AINS() and HB_AINS(). Experienced Harbour programmers learn those distinctions, but they increase the amount of historical knowledge needed to write code.
They also make automated code generation more difficult. An AI coding agent may know that several functions appear to perform approximately the same task without reliably understanding which historical variant should be used in a particular situation.
HN APIs are therefore being reviewed and redesigned rather than mechanically renamed. Public HN functions use a consistent hn_ namespace, and their signatures, parameter names, types and documentation come from machine-readable definitions shared by the compiler and development tools.
My hope is that this will benefit both humans and future coding agents: fewer overlapping choices, clearer contracts, better diagnostics and less historical ambiguity.
That is particularly important because I think xBase still has an advantage that is sometimes underestimated: it grew up around data and databases. HN is trying to retain that strength while incorporating ideas that have developed elsewhere over the last several decades.
Ultimately I would like a developer—or an AI development agent—to find it especially straightforward to build a database-oriented business application in HN.
There is already a substantial automated test suite around the compiler/runtime work. One accepted Windows/MSVC checkpoint was 170 suites / 2,662 tests with zero failures, and there are additional focused compiler/build/class tests that are not simply added to that number.
You are also correct about the repositories.
The public repositories visible at the moment are not representative of the current HN development tree. Active development is presently being done privately while some fairly fundamental architecture, repository organization and tooling work is still changing.
The intention is not to keep HN closed. HN will be released under GPLv3, and the public projects will be under:
https://github.com/harbournova/
There will eventually be several related repositories/projects there, including the compiler/runtime and its matching VS Code extension, the HarbourNova Web Framework, DataWharf, and other components.
I want the compiler and VS Code extension versions to remain coordinated because the editor understands compiler metadata, APIs, signatures, classes, named parameters, debugging information, etc. I don't want the IDE support to become an unrelated project that gradually drifts away from the language.
Interoperability and migration are also important parts of the longer-term plan.
There will be a Harbour-to-HN converter, and I also intend to develop Visual FoxPro-to-HN and Python-to-HN conversion tooling.
I don't expect those converters to magically translate 100% of every application. That would be an unrealistic promise, especially for large applications or code that depends on runtime behavior specific to the original language.
The intended model is closer to:
convert everything that can be converted with confidence, and produce a detailed exception/report for everything requiring developer attention.
That report should identify unsupported constructs, ambiguous conversions and behavioral differences rather than silently generating questionable code.
Python is particularly interesting because I would eventually like conversion and interoperability to work in both directions.
If useful portions of Python packages can be converted to HN, and the resulting HN functionality can also be called back from Python through a clean embedding interface, that could make it easier for developers outside the xBase community to experiment with HN without having to move an entire application to it.
I don't expect arbitrary Python packages to be converted automatically—Python's dynamic nature makes that unrealistic—but a useful subset, combined with generated wrappers and clear exception reports, could still cover a significant amount of practical code.
More generally, HN is being designed so that other languages can call HN without knowing about its internal VM stack, using a defined foreign-language interface. C is the natural base interface, with bindings for languages such as Python and potentially Rust, C#, JavaScript and others.
Another longer-term objective is PostgreSQL integration. PostgreSQL is already the primary database target for HN's datatype and cursor design, and I intend to investigate HN as a supported PostgreSQL procedural/backend language as the HN module/runtime model matures.
Being able to execute appropriate HN routines close to the database would fit naturally with the project's database-oriented focus, although that is clearly a later feature rather than something I would claim exists today.
The project is also being developed somewhat differently from a traditional compiler project. I make the architecture and language decisions and review the results, while almost all implementation is AI-assisted. Because of that, I have put a lot of emphasis on specifications, automated testing and recorded acceptance evidence. Documentation is being developed together with the features rather than being postponed until the end.
When the repositories become public, I actually think some of the most valuable contributions will initially be review and testing, not necessarily writing large amounts of code. Experienced Harbour/xBase developers finding semantic problems, migration cases, missing business-language capabilities or flaws in the documentation would be extremely useful.
And thanks for the FoxScript link. I took a look at it after your message. It is definitely relevant and interesting, particularly the way the project documents its compiler/runtime architecture and keeps the editor connected to the same compiler used by the runtime.
Its objective is quite different from HN—FoxScript is deliberately pursuing very high Visual FoxPro compatibility, whereas HN deliberately allows semantic changes—but there are certainly implementation ideas and lessons worth studying.
I don't expect everyone in the Harbour community to agree with the HN direction. At this point I mainly want to make the design and the working implementation visible enough that people can evaluate it on technical merits.
If there is enough interest when the public repositories are ready, I would also be happy to organize an online meeting and demonstrate some of the parts that are already working, including the compiler, named parameters, classes, build system and VS Code debugger.
Thanks again for taking the time to look at it.
Eric
Hello Marcos,
Thank you again for taking the time to think through HN at this level. These are exactly the kinds of questions I hope experienced Harbour developers will ask, because they force a distinction between what belongs in the language/runtime, what belongs in official HN packages, and what should remain the responsibility of the surrounding deployment ecosystem.
I will try to answer each point separately and also distinguish current direction from features that are not implemented yet.
1. Microservices, APIs and front endsFor the first release I am not planning a special "microservices runtime." Microservices are primarily an application/deployment architecture, and HN does not need a new execution model simply to expose an HTTP API.
The initial server-side model will primarily use an official FastCGI contrib. For API-only applications there is no requirement to use the HarbourNova Web Framework; HNWF is more relevant when building complete web applications and their UI infrastructure.
I actually think persistent FastCGI processes are a very good fit for many business applications because the process can remain alive across requests and retain resources such as database connection pools instead of reconnecting for every request. That is particularly useful for the type of database-oriented software HN targets.
A React, Vue, Angular, Blazor or other front end would simply communicate with HN through normal web protocols. REST/JSON will be the obvious initial model. SSE is already part of the design direction for server-to-browser events and progress reporting. WebSockets can be added where bidirectional persistent communication actually requires them. GraphQL is possible, but I do not currently consider it a first-release priority.
One clarification concerning OpenAPI: the hn_ API catalog describes HN language/runtime APIs, not an application's HTTP endpoints, so I would not generate an application's OpenAPI document directly from those definitions.
I do, however, like the idea of explicit machine-readable service/route contracts. Once that part of HNWF/API development is defined, generating OpenAPI from those contracts would be a logical feature. It would follow the same general philosophy already used elsewhere in HN: define something once and derive compiler/editor/documentation artifacts from that definition rather than maintaining several independent descriptions.
HN can certainly be used to implement microservices, but optimizing specifically for very large microservice/serverless installations will probably come after the initial release.
2. Virtualization, containers and elastic deploymentContainers are one of the primary deployment targets. Docker/OCI containers are a natural fit for HN because the end result is a native application with its runtime and required libraries rather than an application requiring a large external managed-runtime installation.
HN still has runtime/VM machinery internally, so I would not describe it as having no VM at all, but deployment is based on native binaries rather than requiring something analogous to a Java or .NET runtime installation on the target machine.
The build/project design already distinguishes the target operating system from its execution environment. For example, Linux is the platform, while Docker, Podman, a Kubernetes pod or a bare server can be deployment environments.
I expect us eventually to provide example Docker images and container deployment configurations. Kubernetes examples also make sense. I am less certain that HN itself needs to maintain something such as an official Helm chart, because that becomes application-architecture specific very quickly. I would rather provide good examples and composable building blocks than pretend there is one correct Kubernetes deployment.
Serverless is interesting but probably later. For example, an AWS Lambda adapter could potentially invoke HN through the planned C/embedding interface. Similar adapters could be produced for other platforms.
The important point is that HN should not architect itself around AWS, Azure, Docker or Kubernetes. A hypervisor, container runtime or microVM is simply an environment in which the native application executes.
3. Building an ERP or HIS on AWS/AzureHN is not being designed specifically for AWS or Azure. I want the first architecture to be vendor independent.
An HN application should be able to connect through normal encrypted network connections to PostgreSQL whether that PostgreSQL instance is self-hosted, Amazon RDS/Aurora, Azure Database for PostgreSQL or another compatible service.
For things such as object storage, cloud queues, identity services and vendor-specific monitoring, I expect a combination of:
HN contrib packages;
standard HTTP/service APIs;
native libraries;
and Python interoperability where that is the practical solution.
Python interoperability is strategically useful here because enormous amounts of cloud integration already exist in Python. HN does not need to reproduce every AWS or Azure SDK before somebody can use those services.
If HN becomes widely used, native HN packages for the most important services would make sense.
For an ERP or HIS, HN should provide a strong language/runtime, database model, schema management, transactions, concurrency, web/API support, diagnostics and security building blocks. Cloud architecture and regulatory compliance remain larger application/deployment responsibilities. I would not claim, for example, that using HN by itself makes an application HIPAA compliant.
4. Multiple databases, local querying and real-time informationYes, multiple simultaneous database connections, including connections to different backend types, are part of the direction.
I would not call different SQL engines completely "transparent," because pretending PostgreSQL, SQL Server, Oracle, SQLite, DuckDB, etc. have identical semantics eventually causes problems. Backend-specific capabilities should remain visible when they matter.
What HN can provide is a common Cursor boundary.
HN's own Cursor storage is an in-memory typed record store capable of representing the HN datatype system. Query results from different backends can therefore be materialized into HN Cursors and subsequently processed consistently.
I also plan to support DuckDB as a receiving/query engine, and there is a larger planned HN local SQL engine inspired in part by the convenience VFP developers had when querying local cursors.
The goal is to be able to retrieve data from several sources, materialize working sets locally, and then perform joins, filtering, grouping, aggregation and additional queries without repeatedly going back to the remote servers.
The native local SQL engine will not initially attempt to duplicate every feature of PostgreSQL or other enterprise databases. Its purpose is high-performance local data processing integrated closely with HN Cursors.
An especially useful capability I want to investigate is allowing appropriate HN functions in the current scope to participate as functions callable by local SQL, providing some of the convenience of stored/user functions without requiring everything to live on the remote database server.
This is a substantial amount of work. I expect significant portions of it before HN 1.0, but probably after the first Alpha/Beta preview rather than before anyone can begin experimenting with HN.
For real-time presentation, SSE is already the preferred simple model for one-way browser progress and event updates. WebSockets can be supported for applications that genuinely require bidirectional persistent communication.
Background work is being designed separately from HTTP request handling: durable job state can live in PostgreSQL while workers perform the long operation and an SSE/event layer reports progress. Message brokers/queues can also be integrated, but I don't intend to make a specific broker mandatory for ordinary HN applications.
5. End-to-end encryption, secrets and securitySecurity is an area where I specifically do not want HN inventing its own cryptographic algorithms.
The accepted direction includes an official TLS/SSL package using established, reviewed cryptographic implementations. The current candidate design uses a Rust interoperability layer with OpenSSL initially. HTTP/client packages would consume that rather than each implementing their own TLS behavior.
Hashing, signing, certificate handling, symmetric and asymmetric encryption should similarly be exposed through HN-owned APIs backed by established cryptographic libraries, not newly invented HN cryptography.
Secret management is a somewhat different concern. HN applications should not encourage embedding secrets in source files or project manifests. Deployments should be able to obtain secrets from the environment appropriate to them: container secrets, mounted secret files, Kubernetes secret mechanisms, cloud secret stores, operating-system facilities, etc. Generic HN interfaces or contrib adapters can sit above those mechanisms.
TLS termination may occur in a reverse proxy/web server or inside an HN service depending on the deployment. If an application requires true application-level end-to-end encryption beyond transport TLS, that should also be possible through the crypto packages.
The exact public crypto/security API surface is not frozen yet, and this is an area where external security review will be important before calling it production-ready.
6. Artificial intelligenceYes, I expect AI integration to be important, but I don't think OpenAI, Gemini or another provider should become a dependency of the HN language itself.
An HN application should be able to call hosted AI APIs through HTTP just as applications written in other languages do. Local models can be reached through their HTTP/native interfaces, and the Python interoperability layer gives us another route into the existing AI/ML ecosystem.
Provider-specific HN contrib packages may eventually make these integrations more convenient.
There is also a second AI question that I consider particularly important: how well AI coding agents can understand HN itself.
A considerable part of HN's architecture already helps with this deliberately.
Public APIs have canonical names and machine-readable signatures. The compiler has a canonical datatype registry. Parameters, named arguments, nullability/type contracts, diagnostics and source locations are represented as structured information rather than existing only as prose documentation.
The VS Code/VSCodium tooling consumes those same authorities.
One reason I have been simplifying the API surface is exactly this problem. If one operation has several historical functions that are almost—but not quite—the same, a human has to remember those distinctions and an AI agent can choose the wrong one just as easily.
My preference is therefore one clear canonical API for one semantic operation whenever practical.
I hope this makes HN unusually approachable both for humans and future coding agents. AI support inside the IDE can then be built on real compiler/API metadata instead of asking a model to infer everything from source examples.
Given that nearly all HN implementation itself is currently AI-assisted, making the language friendly to AI development is not an abstract consideration.
7. Migration of real large applicationsI definitely do not want hnconvert to produce questionable output silently and report success.
The converter already has the concept of structured reports and source locations. The intended end state is that conversion problems can identify the original file and source span and, where available, the function/class/method context and the reason developer review is required.
So the model is approximately:
convert what can be converted deterministically;
identify changed semantics explicitly;
flag ambiguous or unsupported constructs;
provide file/line/context information;
produce a report of remaining manual work;
validate the converted application with tests.
The goal is not "100% automatic conversion." It is maximizing the portion that can be converted safely while making the remainder measurable and manageable.
I don't currently want a broad runtime "Harbour compatibility mode" that silently restores old semantics, because that would eventually reproduce the compatibility constraints HN is intentionally escaping.
There may be carefully bounded migration/compatibility facilities where useful, but semantic differences should remain visible.
Module-by-module migration is desirable, especially for large systems, but there is an important distinction: I am not promising that arbitrary Harbour and HN object modules can simply be mixed in the same executable.
Practical staged migration may use well-defined C/foreign interfaces, processes/services, database boundaries, or specific migration bridges. The converter and build tooling should help determine which boundaries are safe.
The same philosophy will apply to the planned VFP-to-HN and Python-to-HN converters.
Python conversion in particular will never convert every Python package automatically because Python permits extremely dynamic behavior. But if a useful majority of a package can be translated and the converter produces a good exception report for what remains, that can still be very valuable.
An additional goal is that converted HN functionality can then be exposed back to Python through the HN embedding interface. That could create a useful two-way migration/interoperability path rather than requiring an all-or-nothing language switch.
8. Status, Alpha/Beta, repositories and contributionMy current thinking is to have a small closed Alpha/Beta group before the general release, probably consisting initially of developers who are genuinely interested in testing the language and challenging the design.
One reason for keeping that group relatively small initially is that I do not want to declare language features permanently frozen too early. Until HN 1.0 there needs to be room to correct a bad decision when actual use shows a problem.
Alpha/Beta users should have direct input on features and priorities. I expect real application experience to affect the roadmap.
Initially, governance will continue to be led by me directly. If the community eventually becomes large enough that this is no longer practical, then the governance model can evolve.
I have some experience with that side as well. I was a lead board member of the San Diego FoxPro Developers User Group for more than twenty years and have participated in other nonprofit organizations.
For larger design changes I want to establish HNEPs — HarbourNova Enhancement Proposals, similar in purpose to Python's PEP process. That gives important changes a persistent specification, discussion history and decision rather than allowing language design to emerge only from message-board conversations.
I expect most core implementation to remain AI-assisted under controlled design/review/testing. Traditional contributors may be particularly useful for contrib packages.
But I see enormous value in contributions through:
independent testing;
design review;
documentation review;
migration cases;
additional platform validation;
examples;
translations/localization;
and community support.
I would especially welcome future help managing discussion groups and other community infrastructure. I have already reserved HN groups on Google and Facebook.
9. Development toolsVS Code and VSCodium are the target IDEs.
The existing extension already has a working debugging foundation including launch/attach, breakpoints, stepping, stack/locals, Watch/evaluation and language/API integration. The current build/editor work is making the compiler, hnmake, debugger and extension share one consistent project/build context.
The roadmap includes increasingly compiler-backed:
completion;
signature/named-parameter help;
navigation;
diagnostics;
API documentation;
project editing;
build/run/debug integration;
and static/semantic analysis.
The API documentation is already intended to be available directly inside the extension rather than requiring the developer to constantly leave the editor.
Refactoring support can grow once the compiler-backed semantic model is mature enough to perform changes safely.
Git itself is already handled well by VS Code/VSCodium, so I don't see a reason to create an HN-specific Git implementation.
Test Explorer and coverage integration are desirable, but I don't want to promise that every testing UI feature will make the first preview. The underlying HNTest/testing contracts come first.
A modern profiler is also now planned for late HN 1.0 development, with profiling compiled out when disabled and visualization through a VS Code/VSCodium WebView—for example statistics, call trees/flame graphs, timelines and source navigation.
A dedicated REPL and full HN formatter are lower priorities and may come after the first release if necessary.
I currently have no plans to develop dedicated JetBrains, Neovim or Emacs integrations. If the community eventually wants to build them, compiler protocols and machine-readable metadata should make that more practical, but I don't want to dilute the initial tooling effort across many editors.
10. License, sustainability and enterprise supportThe sustainability model I have in mind is closer to the community-oriented Python/PostgreSQL model than to a vendor-controlled commercial language.
HN is currently self-funded by me. The HarbourNova trademark application is pending.
The HN project itself is intended to use GPLv3, with the appropriate runtime/application exception so developers can build commercial and closed-source applications without their application automatically becoming GPL simply because it uses HN.
I do not currently plan a separate proprietary "commercial edition" of HN or an open-core model where important language features are kept behind a commercial license.
If HN becomes widely used, I would certainly be open to sponsorship, financial support and companies providing professional/enterprise services around it. That does not require the language to become dependent upon a particular vendor.
I would actually prefer an ecosystem where multiple companies and developers can provide support.
International participation is also important to me. One of the earliest HN language features I worked on was Unicode support at the source-code level, not merely Unicode strings. Function, class, method and variable identifiers can therefore be written using non-English characters.
That was intentional: I don't want HN to assume that software development happens only in English-speaking countries.
11. Testing, quality and CIYes. The tests and testing framework will be part of the repositories, not private acceptance artifacts that users are asked to trust.
The currently quoted Windows/MSVC acceptance checkpoint of 170 suites / 2,662 passing tests is one recorded baseline. As development continues there are also many focused compiler/build/application tests around individual features.
When the source becomes public, I expect CI results and the tests that produced them to be visible as well.
Windows/MSVC is currently the strongest validated platform, but Linux is a required supported platform, not just an experiment.
macOS and ARM will require additional hardware/platform expertise, and I will probably need community help there. I would rather state that openly than claim validation on machines/configurations that have not actually been tested.
Database testing will include real PostgreSQL integration, with controlled test schemas and test data—not merely mocks of database calls. DataWharf's schema definitions can participate in creating and validating those database fixtures.
Over time I want the release matrix to make it obvious which compiler/OS/database combinations actually passed the release gates.
12. Community, documentation and trainingDocumentation is being treated as part of development rather than something to write after the compiler is complete.
Almost every significant architectural decision has a design record, and public APIs are derived from structured catalog information. My intention is to publish that as an online, searchable/queryable documentation system, in the same general spirit as the new harbour.wiki.
The same API documentation will also be available from inside the VS Code/VSCodium extension.
I expect to add:
tutorials;
migration guides;
complete examples;
reference applications;
architecture explanations;
and probably YouTube videos/demonstrations.
Formal courses may come later depending on demand.
Regarding Harbour and HN communities, I hope they can coexist without hostility.
HN exists specifically so Harbour itself does not have to change its compatibility mission. There will certainly be ideas or implementations that can travel in either direction where licensing and architecture allow it.
HN-original code will be GPLv3, so if portions of that code are incorporated into another project, the applicable GPLv3 licensing requirements need to be respected. The runtime/application exception is intended to protect developers writing applications; it should not be assumed to relicense copied HN source code.
Out of respect for the Harbour group, I only intend to post occasional major HN announcements here rather than turn the Harbour list into the HN development forum.
I hope we can start moving detailed HN discussions soon to:
https://groups.google.com/g/harbournova-users
The official web site will be:
Finally, thank you very much for your offer to help. That is genuinely appreciated.
As we approach Alpha/Beta, developers who understand real Harbour/xBase business applications will be particularly valuable because they can identify problems that language/compiler tests alone will never find.
And yes, I think we should arrange a meeting soon. It would probably be much easier to demonstrate the pieces that are already working—compiler features, named parameters, classes, hnmake, VS Code/VSCodium debugging, etc.—than to keep describing all of them only through long messages.
Best regards,
Eric
Hi Luigi,
Thank you again for the questions and for taking the time to draw the architecture diagram. These are useful points, and your examples help make the architectural questions much more concrete.
Before answering, one clarification about the source code you mentioned.
The current HarbourNova development source has not yet been published publicly. Therefore, if you saw extensive hb_..., codepage and GT handling in a repository, I suspect you were looking at Harbour/Harbour Legacy source, or at older/public material based on the Harbour codebase, rather than the current HN development tree.
HN still uses portions of Harbour internally as transitional compiler/runtime infrastructure, but the presence of that code should not be interpreted as the intended HN public architecture. HN is progressively defining its own runtime types, APIs, compiler semantics and tooling.
In principle, I agree.
HN does not intend to reimplement the entire Unicode ecosystem internally. ICU is already part of the intended direction for advanced Unicode services such as language-aware collation, normalization and other locale-sensitive Unicode operations.
The important distinction is between HN language semantics and the implementation provider.
HN must first define exactly what Text, comparison, sorting, character length, code points, grapheme clusters, etc. mean. ICU can then implement appropriate portions of that contract.
HN's normal string model is deliberately different from Harbour's historical codepage model:
Text = Unicode text
Raw = arbitrary binary bytes
A normal HN Text value is Unicode. Codepages do not determine normal string semantics.
Legacy codepages are instead treated as boundary concerns:
A future codepage-import contrib/tool may use libiconv or another established conversion library if that proves to be the best implementation choice.
Collation
For collation, we are also taking significant guidance from the way modern PostgreSQL handles the problem.
The important separation is:
Encoding = how the Text is represented
Collation = how Text is ordered or compared for a language or locale
A Text value should not permanently carry a locale inside itself.
For example, UTF-8 tells us how characters are encoded. It does not tell us how characters such as é, e and É should sort for French, Hungarian, Swedish or another language.
HN's collation support is primarily intended for HN in-memory processing, for example:
When the work is performed by PostgreSQL or another SQL backend, the database backend owns the collation semantics.
So conceptually:
PostgreSQL table/index
→ PostgreSQL collation
→ PostgreSQL collation-aware indexes
HN in-memory Cursor
→ HN collation
→ eventually ICU-backed
HN Text encoding
→ independent of both
HN should not try to duplicate PostgreSQL's index/collation behavior on the client and pretend it is identical.
That is especially important because PostgreSQL can build indexes according to a selected collation and tracks the collation provider/version. If the backend owns an index, then the backend must also own the rules under which that index was created and searched.
So yes: ICU fits the HN design, and PostgreSQL's modern separation of encoding, collation and indexed database behavior is an important reference model for us.
I would not, however, make HN Text simply an alias for something such as icu::UnicodeString. The HN language needs its own semantic contract independent of whichever implementation library happens to provide part of it.
I should clarify the HN direction here.
HN is not planning to carry all of Harbour's historical GT implementations forward as part of the core runtime.
Harbour's GT system is very capable and made a lot of sense for Harbour's compatibility goals.
HN's goals are different.
Traditional screen-coordinate programming such as:
@ ... SAY
@ ... GET
READ
SAVE SCREEN
RESTORE SCREEN
SET COLOR
and the traditional full-screen GT APIs may still be useful for migrating older applications, but I do not want that architecture to determine the core HN user-interface model.
If there is enough demand, I expect a Classic UI contrib could provide that type of functionality and could use appropriate terminal backends such as ncursesw or PDCurses.
That would remain optional.
The primary HN desktop direction is instead:
HN application/business logic
→ HN UI / Web Components
→ HN Desktop Host
→ platform WebView
The expected default renderer family is approximately:
Windows → WebView2
macOS → WKWebView/WebKit
Linux → WebKitGTK
That also means much of the same UI can operate in a normal browser.
Later, probably as a V2-generation capability, I want a visual Form/Class Designer inspired by the productive ideas in Visual FoxPro, but targeting the HN UI model rather than reproducing the VFP runtime.
I expect useful concepts such as:
The designer itself will probably be web-based.
WebView remains the preferred cross-platform rendering model.
If there is substantial community demand for native platform controls, that could eventually become a separate contrib renderer/backend. However, I do not want to reverse the current architecture and require HN itself to maintain independent Windows, GTK and macOS widget implementations.
The application design should remain renderer-neutral enough that an optional native-controls contrib could be developed later without redesigning the business application model.
So I like the abstraction idea in your diagram, but I would separate the architecture roughly like this:
HN application
For Text/Data:
HN application
→ HN Text/Data semantics
→ ICU when advanced Unicode services are needed
For UI:
HN application
→ HN UI / Web Components
→ HN Desktop Host
→ WebView2 / WKWebView / WebKitGTK
Optional later:
→ Classic UI contrib
→ Native-control contrib
4.1. Class property initialization and shared objects
This is a very good example, and this issue has already been reviewed explicitly.
Consider conceptually:
CLASS TSample
PROPERTY Object := MyObject()
ENDCLASS
HN's intended semantics are that MyObject() is evaluated separately for each new TSample instance.
It is not evaluated once when the class definition is initialized and then reused by every instance.
So:
oA := TSample()
oB := TSample()
would normally mean that:
oA:Object is not the same object instance as oB:Object
assuming that MyObject() creates a new object each time.
The same principle applies to mutable collection literals.
For example:
CLASS Customer
PROPERTY Tags Array := {}
ENDCLASS
Then:
oA := Customer()
oB := Customer()
oA:Tags:Add( "VIP" )
must not cause oB:Tags to suddenly contain "VIP".
Each construction evaluates the initializer separately.
HN's approved initialization sequence is approximately:
base-class property initializers
→ base constructor body
→ derived-class property initializers
→ derived constructor body
all operating on the same newly created object.
There is one important distinction.
If an initializer deliberately calls something such as:
PROPERTY Cache := GetGlobalCache()
and GetGlobalCache() intentionally returns an existing shared object, HN should not secretly clone it.
So the language distinguishes fresh construction from intentional sharing.
Class-wide state is also different. HN uses the CLASS PROPERTY concept for storage that intentionally belongs to the class rather than to each object instance.
4.2. IsDerivedFrom() versus ClassName()
I agree with you that these are different operations.
ClassName() answers approximately:
"What is the name of this object's class?"
An inheritance query answers:
"Is this object an instance of this class, or of one of its descendants?"
Those should not be implemented by comparing strings.
HN's compiler-native class model records actual class identity and inheritance relationships. Those relationships can therefore be queried using class metadata rather than doing something fragile such as comparing ClassName(oObject) with a string.
I have not finalized whether the public HN API will literally be called hn_IsDerivedFrom(), hn_IsKindOf(), or something else.
HN APIs are being systematically redesigned rather than automatically preserving every Harbour API name.
But yes, I agree that an inheritance-aware query is useful and should exist separately from a class-name query.
HN API naming
One of the general HN design rules is that all normal public HN core APIs will use the hn_ prefix.
For example:
hn_Something()
rather than accumulating several historical naming conventions.
The goal is that HN has one clearly identified core API namespace and, where practical, one canonical API for one semantic operation.
Compiler syntax and compiler-owned constructs are a different category. Keywords or special compiler constructs do not need the hn_ prefix because they are not ordinary runtime API functions.
4.3. Calling a parent implementation
HN already has an approved SUPER direction.
Conceptually:
SUPER:DoSomething()
from a derived method means:
"Invoke the inherited implementation on this same object."
Suppose we have:
A
→ B
→ C
and C:DoSomething() contains:
SUPER:DoSomething()
The natural meaning is to invoke the inherited implementation through B.
That is different from explicitly naming A, because that could mean:
"Skip B and invoke A directly."
Those are potentially different operations.
SUPER also has the benefit that a class does not unnecessarily hard-code the identity of its immediate parent.
For example, if the hierarchy changes from:
A
→ C
to:
A
→ B
→ C
a SUPER call in C can continue to mean "my immediate inherited implementation."
So I think SUPER is the better normal mechanism.
Whether HN should additionally support explicit named-ancestor qualification in specialized cases is still something we can discuss before the syntax is permanently frozen.
Imported libraries and namespaces
HN is also being designed so that imported libraries do not have to dump every public symbol into one global namespace.
Imported HN libraries will support qualified access using consumer-selected library aliases/namespaces.
Conceptually, a project might import a library using the local name:
Accounting
and then use:
Accounting.CalculateTax()
Accounting.Invoice()
Accounting.Invoice:Create()
Another application could import exactly the same library using a different local alias if that name fits the application better.
This also allows different libraries to expose similarly named classes or functions without creating global collisions.
For example:
Sales.Customer()
Accounting.Customer()
CRM.Customer()
could represent three different public classes.
The exact final import syntax is still being specified, but the important design decision is that HN will support qualified namespaces/aliases for imported libraries rather than forcing all public library symbols into one flat global namespace.
This is separate from the hn_ rule.
The hn_ prefix is reserved for canonical HN core APIs.
Imported application libraries and contrib libraries can instead be accessed through their qualified library namespace/alias.
C++ could certainly be useful for individual components, and I am not opposed to using it when there is a concrete benefit.
However, I currently prefer to keep the main HN compiler/runtime core primarily in C.
The advantages are architectural:
It also makes the future HN embedding API easier to expose to languages such as:
because almost every language ecosystem knows how to call a C ABI.
That does not mean every HN component must be written in C.
Quite the opposite.
HN is intended to support Rust-authored contribs and selected components through a stable C ABI.
Conceptually:
HN
→ stable C ABI
→ C module
HN
→ stable C ABI
→ Rust module
HN
→ stable C ABI
→ C++ wrapper
A Rust contrib could compile as a native library and expose C-compatible entry points.
That lets us use Rust's memory-safety and modern library ecosystem where appropriate without rewriting the VM/compiler/runtime around Rust.
Security-sensitive, cryptographic or networking packages are particularly interesting candidates for that approach.
Similarly, if ICU or another useful library has C++ interfaces internally, an HN wrapper can isolate that implementation behind a stable HN/C boundary.
From the HN developer's perspective, the implementation language should normally be irrelevant.
For example:
hn_SomeFunction()
could internally be implemented using C, Rust, C++, or an external system library as long as it obeys the same HN contract.
That is one reason the API definitions, datatypes, errors, ownership rules and documentation are being specified independently from their implementation language.
One final clarification about the HN repositories and discussions
Since you mentioned examining source code, I want to emphasize again that the current HN development tree has not yet been made public.
I do plan to begin publishing much more precise language and architecture specifications for interested developers fairly soon.
The dedicated discussion group is:
https://groups.google.com/g/harbournova-users
Anyone interested can request access now.
Before HN 1.0 I intend to keep that group private. During Alpha/Beta development some specifications may still change significantly, and I would prefer that experimental proposals and design discussions not be mistaken for final language behavior.
Once HN 1.0 is released, the intention is for that group to become public.
I very much welcome this kind of technical review before then. Questions about Unicode architecture, class initialization, inheritance, external libraries and implementation-language boundaries are exactly the kinds of things that are useful to challenge before the language is frozen.
Thanks again for taking the time to review the ideas and send detailed suggestions.
Best regards,
Eric
