On 09/05/2016 11:56 PM, ZombineDev wrote:
On Monday, 9 May 2016 at 11:20:00 UTC, rikki cattermole wrote:
On 09/05/2016 11:12 PM, ZombineDev wrote:
On Monday, 9 May 2016 at 10:33:27 UTC, rikki cattermole wrote:
I've done windowing and image libraries before.
You are correct, you do not need OOP.

But if you want to keep implementation nicely separated out from
usage, you really do. Which is a major part of my requirements.

Well, in my example above, everything is nicely separated, easy to use,
yet quite flexible. And still there is no Java-style OOP. Do you have
any examples, where the use of classic OOP would provide a strictly
superior design?

You're using templates. While this might be ok for image library.
I cannot use this for the windowing library. The implementation may
not be known and must be plugable at runtime.
The reality is, just because you say you know about something at
compile time doesn't mean the system that runs a program does.

I'm still not convinced. You have a fixed at CT number of
implementations. Even if you don't know at CT the actual platform that
will be used, you can still choose at RT the correct template. Example:

You do not.
Shared libraries remember them?

// platform name can be "X11", "mir", "Wayland", etc.
auto getPlatformWindow(CTArgs...)(string platformNameRTArg)
{
    switch (platformNameRTArg.toLower)
    {
        default:
             enforce(false, "Unknown platform: " ~ platformNameRTArg);

        foreach (platform; EnumMembers!Platform)
            case name.stringof:
                 // Use std.experiment.typecons.Wrap if you need a
common type.
                 return getWindow!(name, CTArgs);
    }
    assert (0);
}

Platform is undefined, did you mean IPlatform?

But that's besides the point. Even with OOP, your return type can be an
interface that has template parameters like allocators, policies, etc.
You're providing some the arguments at CT and the rest of the return
type is dynamically polymorphic. E.g.:

interface Window(Allocator, Policy);
Window!(Allocator, Policy) getWindow(alias allocator, Policy)(RunTimeArgs);

Sure you can, but now you have added another layer of indirection between implementation and usage because you can't use templated types in between.

My point is that there's no need for IAllocator, even if you want to use
OOP so badly.
But in most cases you will either write different code for different
platforms, making interfaces unnecessary, or you would be able to hide
the differences behind a struct.

And when the allocator and the other policies are template parameters
you will know at CT that your code is @nogc.

Again, no templates. You cannot initialize them at runtime, and since you won't know all implementations until it executes, well, you've got a problem.
Its a many to many problem. I faced this with Cmsed as well.

Reply via email to