[fpc-devel] Design ideas ... [[Re: Attn: Sven Can not use "specialize" to resolve forward declaration]]

Martin Frb lazarus at mfriebe.de
Thu Dec 9 09:09:04 CET 2021

The below might read as if it belongs on the Lazarus list.
But this is not about Lazarus.

This is about a general design idea (pro and con), and the possibilities 
the language provides.
The example(s) just happen to be from Lazarus.

On 09/12/2021 07:59, Sven Barth via fpc-devel wrote:
> For interfaces you can use IInterface/IUnknown though that will work 
> only for COM interfaces. For raw interfaces there is no solution 
> currently.
> In my opinion you should rethink your code structure however. I don't 
> know right now what would be better, but as it is now it feels bad.

Well, ok, lets go fishing for ideas.
No rush, this is a loooong time think, no idea when I will really get to it.

Lazarus has a debugger frontend (currently more or less hardcode in the 
IDE), and several backends (gdb/lldb/fpdebug/....)

The currently provided "interface" (for implementing a backend, that the 
IDE can talk to) is just code taken from when we had only one backend.
However it is some elements, I like to keep. For different data elements 
(stack,watches,locals) a Monitor/Supplier relation exists.

The backend is the supplier. The frontend the monitor. One think they 
all have in common. They have a reference to each other.
For reasons outside this quest, the design should support multiple 
Montiors, hence "Add/RemoveMonitor"

The WatchesSupplier takes one or more WatchesMonitor. The WatchesMonitor 
has one WatcheSupplier.
On top of maintaining the relation, there will then be watches specific 

So far so good.
represents this idea.

Using interfaces also seems a good idea. It does put the least 
restrictions on both sides.
Especially each side can still choose it's own base classes.

One more consideration. New methods could be added later. Then all 
classes implementing the interface must implement them.
It would be nice, if a default could be automatically supplied. 
(if/where such a default exists, e.g. CanFeature = false)

Actually that is possible too. generics
type TWatchesSupplierDef<_Base> = generic class(_Base, IWatchesSupplier) 
... end; // having virtual methods for any method of the interface.

That still fulfils the initial requirements. Any implementer of the 
interface can just mix it into their class structure

Now that still works. the problem starts when you want to split the 
Inteface into a general base, and specifics for the watches/stack/locals.

At that point, the generic type restrictions no longer work.

Why splitting it? I could just repeat the 2 methods in the base? 
Couldn't I?
But, maintaining the list of monitors could be completely implemented in 
a generic (which later can be included in a monitor/supplier on a 
optional base).

So, if I do not want to duplicate that code, then I need such a baseclass.

Currently that means giving up on some of the param-type-restrictions.

Anyway that is the current background of what I am looking into.
> In my opinion you should rethink your code structure however. I don't 
> know right now what would be better, but as it is now it feels bad. 

Any better idea?

Btw, if that works, I have a feeling this could replace the LCL 
interfaces run-time created classes. Afaik it fulfils all the 
requirements that lead to the current situation.
- Being an interface
- having a default implementation
- allowing to mix default classes and specific classes into a new 
inheritance structure.

More information about the fpc-devel mailing list