PhobosV3+ Fundamental Elements

Richard Andrew Cattermole (Rikki) richard at cattermole.co.nz
Thu Aug 27 22:39:04 UTC 2026


The following document is a collaboration between Adam Wilson and 
Richard (Rikki) Andrew Cattermole.

The PhobosV3+ work, is comprised of multiple components.
The first of these is ``based``, this is a low level component 
that comprises of target specific elements to druntime, druntime 
is the platform specific elements and may contain target 
independent code.

The PhobosV2 replacement elements comprises of a base library, 
and auxiliary libraries built on top.

```
GUI toolkit         |       web service framework
--------------------------------------------------
             Event loop/windowing
--------------------------------------------------
               PhobosV3 base
--------------------------------------------------
                  druntime
--------------------------------------------------
                   based
```

Each of the auxiliary libraries are shipped as a shared library 
and D files suitable for importation using ``-extI`` switch.
The base library will be shipped as both a shared library and a 
static library, along with the D files suitable for importation 
using both ``-extI`` and ``-I``.
You will not need to deal with this, compiler support will exist 
to aid and automate both the linking against these libraries 
(including dependencies), as well as picking the right import 
switch to use.

This is a non-negotiable aspect of the design, PhobosV3+ is 
designed to have a very large scope, and be a batteries inclusive 
standard library that solves all resonably common problems. This 
cannot fit inside a single shared library nor should it. Most 
people will not need access to most of what will be on offer for 
every program. This is a standard approach to the problem in 
application VM's such as .net.

One of the key design elements that is wanted, is to remove the 
requirement for templates where possible. Templates are 
expensive, especially if they are not needed to solve a problem.

A notable example of this is the dispatch and handling of 
formatting to a string. There is unfortunately only one really 
good solution that has been come up with to date, and that is a 
single type that can be used for composition. It is also 
important for use cases like pretty printing to support removal 
of text, not just appending. The solution to this is to introduce 
a string builder, similar to C#'s that is not templated.

To format a type using such a string builder would require the 
following signature for the hook method:

```d
struct Type {
	void toString(scope StringBuilder) scope const;
}
```

This can then be taken as a pointer to with the usage of a 
delegate to get a templateless dispatch call that doesn't care 
about the types involves. The alternative to this is to use D 
style variadics, and lean heavily into TypeInfo and reflection 
capabilities. Luckily we are missing the reflection capabilities 
to do this. A way to solve this would be added, a new function 
pointer that each TypeInfo would store, this function would take 
the value and do whatever reflection required to print it. 
Absolutely horrid compared to this much simpler approach.

The string builder will need to be in druntime not based as it 
will be using the GC for memory management, but this leads to 
another set of problems, what to do about classes?

The ``Object`` root class is not the future for D, BUT we don't 
have to break the world to resolve this problem. Instead we can 
introduce a new feature called custom root classes. This will 
allow us to define a new root class that can be swapped to being 
the default in an edition.

What do I mean by 'swap to'? Two things, first the default parent 
for classes will change to this new root class; second interfaces 
will gain a class parent and the default will be the new one. But 
you can change it like you could with the class.

```d
class MyRoot : void {
	// Look its completely empty!
	// No monitor, no methods, nothing!
}

interface MyInterface : MyRoot {
}

interface AnotherInterface : Object {
}
```

The current thinking would suggest that a new default root class 
should appear similar to:

```d
class RootClass : void {
	// No monitor
	void toString(scope StringBuilder) scope const {}
	ulong toHash() const => 0
	int opCmp(scope const RootClass) scope const => 0;
}
```

But it won't be the only root class, PhobosV3+ will have more 
than just this one.

In multithreading scenarios you will likely want one with a 
monitor, and a message passing one specifically for windowing.

None of this is final, but it has been the general direction that 
me and Adam have come up with over the last couple of years.

I'd like to thank monkyyy for giving me the motivation to get 
this previously WIP article out.



More information about the Digitalmars-d mailing list