No struct extending?

Steve Horne stephenwantshornenospam100 at aol.com
Mon Sep 11 10:06:16 PDT 2006


On Mon, 11 Sep 2006 15:45:19 +0300, Georg Wrede
<georg.wrede at nospam.org> wrote:

>I suspect this is a perfect case of the Square Triangle. Happens to me 
>too. The solution sought being just a notch off the problem, concepts 
>fighting for neurons, and the goal but a mirage, elusive and yet so 
>tempting.

Hopefully. I mentioned elsewhere that I'm chasing my own tail,
refactoring to try to get my interface use patterns to be sane. Not
familiar enough yet with having that tool, and not having multiple
inheritance. Doesn't mean D is bad. Just means the paradigms need to
shift around a bit yet before they stabilise.

>Anyway, as I understood it, you have struct instances (from somewhere, 
>like a C library routine or a file

No. I need struct instances.

The posts have created a bit of haze, since I have covered a bunch of
vaguely related issues, but I have one specific application in mind
right now which is why I kept going on about branch nodes and leaf
nodes.

I'm working on a multiway tree container library. The tree has to be
able to live in a disk file. Think of it as a database index. Since
the basic data structure is essentially a B+ tree, there are two types
of nodes - branch and leaf - which share some fields in common.

As far as disk blocks are concerned, each block holds one node and in
effect uses a union. When a node is read back from the disk, fields in
the common part are used to determine the node type.

It's an everyday kind of pattern when dealing with file formats and
network protocols, as well. Families of block types. Families of
message types. There are applications where remoting features can
remove the need (server side objects and the like), but someone still
has to implement the remoting protocols that achieve this.

So I'm building from scratch, but I still have a family of structs
that have to be structs. It may seem inappropriate in that there is an
apparent polymorphic type, but the compiler cannot resolve the
polymorphism for me.

The 'struct extending' title comes via two routes. The lesser route is
that the leaf nodes and branch nodes are both extensions of the core
node. But the more important route came from the idea of using of a
mix-in layers pattern to 'compose' the functionality I want.

"Mix-in layers" is a template pattern. You basically add features one
at a time to what you need. You get to say what requirements you have,
and you don't get the overhead from features you don't need. Third
parties can even create their own mix-in layers to add support for new
features, without needing to start from scratch.

The requirements crosscut multiple classes etc. So, in principle, you
get to order a library with the options you want - "gimme a multiway
tree with ordered keys and efficient subscripting support, hold the
non-key data and persistable intelligent iterators. Here's an
interface you can use to shove the nodes into a disk file, but there's
more than one tree sharing space in the file so I'll handle the free
list." kind of thing.

There are a few papers available on mix-in layers in C++ - google for
Yannis Smaragdakis and Don Batory. They're a lot easier in D because
the template support is better.

Crosscutting features seem to be a big thing at the moment - aspect
orientation is another expression of this, and there are versions of
Java and C++ with aspect support.

>One could use a concoction of templates, mixins, unions and inheritance 
>to create a module (or a library) which then lets one handle the 
>situation simply and cleanly in main code.

Overkill. All the struct layouts are known in advance, and the
polymorphism is resolved using ordinary data fields in the common
part. All I need is a set of small access functions...

int Get_Branch_XXX (s_Node_Base* p_Node)
{
  if (Is_Branch (p_Node))
  {
    return (cast(s_Node_Branch*) p_Node).m_XXX;
  }

  throw new Exception ("XXX not available for this node.");
}

Even that's overkill. I'd rather do a one-shot check-and-cast pointer
type conversion in most core functions, so the checks don't repeat.

Actually, just realised I'm being stupid. Will post the 'easy way'
solution separately, once I've checked whether it works.

>Now, the issues of machine word width and endianness, only exist when 
>carrying the data (or porting the program) between different 
>architectures.

Yes, but it is a potential issue for me, and an awkward one, since
code can be compiled for multiple platforms and files exchanged
between platforms, but my library is inherently generic. It can handle
fields that it puts in the nodes (size, flags, child pointers etc) but
it doesn't necessarily understand much more about key or data items
than how to copy and compare them.

It's a 'once the thing works on one platform I'll deal with this' kind
of issue. I might even delegate the responsibility to users, along
with the 'make sure you only store plain-old-data' thing. Probably
I'll have some kind of callbacks called when nodes are read or
written, though - kind of 'I don't know how to fix your data, but
endian fixes and conversions are needed now'.

> As to the data, simply exactly specifying the record 
>layout takes care of both word size and endianness.

No it doesn't, since there is no pre-existing import/export to
delegate this task to. I'm writing a low level library, not using a
pre-existing one. Any bit twiddling needed is my responsibility, not
someone elses.

>Implementation I'd start with simple textbook OO.

Yes. That's what I want to do. I just _CANNOT_ use compiler-managed
polymorphism for this.

Handling the polymorphism has to be my responsibility rather than the
compilers, otherwise I'd just use classes. But in principle,
inheritance can be useful even without polymorphism. Just as
encapsulation can be useful without polymorphism or else why do D
structs support methods?

>Clear, concise and KISS. Oh, and way more robust and maintainable.

If only it was relevant to the job ;-)

-- 
Remove 'wants' and 'nospam' from e-mail.



More information about the Digitalmars-d mailing list