[Added] D Mixin Templates

Moderator: GZDoom Developers

D Mixin Templates

Postby Major Cooke » Thu Oct 24, 2019 12:08 pm

There was discussion on discord about potential ability to have mixin templates.

In D they look like this:
Code: Select allExpand view
mixin template Foo()
{
    void func() { writeln("Foo.func()"); }
}

class Bar
{
    mixin Foo;
}

class Code : Bar
{
    override void func() { writeln("Code.func()"); }
}


And in ZScript they'd probably be like this (example by phantombeta):
Code: Select allExpand view
template mixin Foo {
    int phoo;
    Actor bar;
}

extend class Actor {
    mixin Foo;
}

extend class PSprite {
    mixin Foo;
}

extend class BaseStatusBar {
    mixin Foo;
}


Phantombeta said it's possible.
Last edited by Major Cooke on Thu Oct 24, 2019 12:21 pm, edited 2 times in total.
User avatar
Major Cooke
QZDoom Maintenance Team
 
Joined: 28 Jan 2007

Re: D Mixin Templates

Postby Graf Zahl » Thu Oct 24, 2019 12:12 pm

Possible, sure - but don't exer expect those mixin blocks to be accessible through generic object pointers. The only way this could possibly work would be to call a lookup function for each access to such a variable. You also need to find someone willing to code this...
User avatar
Graf Zahl
Lead GZDoom+Raze Developer
Lead GZDoom+Raze Developer
 
Joined: 19 Jul 2003
Location: Germany

Re: D Mixin Templates

Postby phantombeta » Thu Oct 24, 2019 12:17 pm

Graf Zahl wrote:Possible, sure - but don't exer expect those mixin blocks to be accessible through generic object pointers. The only way this could possibly work would be to call a lookup function for each access to such a variable. You also need to find someone willing to code this...

I'm the one who started discussion of such a feature in the Discord, and I'd be very much willing to code it :P (just as I would be very much willing to add a lot of stuff from D 👀)
Do note that the point of it is just to avoid code duplication. The actual replacement would be lexical/AST-level. Basically, kinda like a macro, but without the gross issues caused by macros being textual/token-level replacement.
User avatar
phantombeta
In the meadow of sinful thoughts, every flower's a perfect one
 
Joined: 02 May 2013
Location: Brazil, South America, Earth, Orion-Cygnus Arm, Milky Way
Discord: phantombeta#2461
Twitch ID: phantombeta_
Github ID: Doom2fan
Operating System: Windows 10/8.1/8/201x 64-bit
OS Test Version: No (Using Stable Public Version)
Graphics Processor: nVidia with Vulkan support

Re: D Mixin Templates

Postby Major Cooke » Thu Oct 24, 2019 12:21 pm

Graf Zahl wrote:don't exer expect those mixin blocks to be accessible through generic object pointers.


If you mean like foo.phoo and foo.bar, yeah, I would expect it just to be phoo and bar by themselves.
User avatar
Major Cooke
QZDoom Maintenance Team
 
Joined: 28 Jan 2007

Re: D Mixin Templates

Postby phantombeta » Thu Oct 24, 2019 1:23 pm

Oh yeah: Graf, would you be opposed to adding templates? Even just class templates would be quite useful. Wouldn't be too useful for arrays and maps, unfortunately (since those have to map to the internal TArray template), but still pretty useful for mods and libraries.
I have some idea on how they could be added (I think it'd be somewhat similar to how mixins would be done), and I would be very much willing to add them too.
User avatar
phantombeta
In the meadow of sinful thoughts, every flower's a perfect one
 
Joined: 02 May 2013
Location: Brazil, South America, Earth, Orion-Cygnus Arm, Milky Way
Discord: phantombeta#2461
Twitch ID: phantombeta_
Github ID: Doom2fan
Operating System: Windows 10/8.1/8/201x 64-bit
OS Test Version: No (Using Stable Public Version)
Graphics Processor: nVidia with Vulkan support

Re: D Mixin Templates

Postby Graf Zahl » Thu Oct 24, 2019 1:53 pm

If you think you can pull it off, go ahead.
User avatar
Graf Zahl
Lead GZDoom+Raze Developer
Lead GZDoom+Raze Developer
 
Joined: 19 Jul 2003
Location: Germany

Re: D Mixin Templates

Postby Gez » Fri Oct 25, 2019 1:30 am

Major Cooke wrote:There was discussion on discord about potential ability to have mixin templates.

In D they look like this:
Code: Select allExpand view
mixin template Foo()
{
    void func() { writeln("Foo.func()"); }
}

class Bar
{
    mixin Foo;
}

class Code : Bar
{
    override void func() { writeln("Code.func()"); }
}



What if:

Code: Select allExpand view
mixin template Foo()
{
    void func() { writeln("Foo.func()"); }
}

mixin template Bar()
{
    void func() { writeln("Bar.func()"); }
}

class Baz
{
    mixin Foo;
    mixin Bar;
}


:?:
Gez
 
 
 
Joined: 06 Jul 2007

Re: D Mixin Templates

Postby Major Cooke » Fri Oct 25, 2019 5:36 am

That would also be the point of it.
User avatar
Major Cooke
QZDoom Maintenance Team
 
Joined: 28 Jan 2007

Re: D Mixin Templates

Postby phantombeta » Fri Oct 25, 2019 5:45 am

No, that's a compile-time error. Remember, you'd access them as "Baz.func()", so it can't work like that.
Thst reminds me, ZScript (correctly) errors out if you redefine something in the same class it was defined in, but if you try it from inheriting classes, it silently lets you redefine things. This seems to be a quirk of how the compiler resolves inheritance, and IIRC there's a bug report of this that shows it working in some very specific cases
User avatar
phantombeta
In the meadow of sinful thoughts, every flower's a perfect one
 
Joined: 02 May 2013
Location: Brazil, South America, Earth, Orion-Cygnus Arm, Milky Way
Discord: phantombeta#2461
Twitch ID: phantombeta_
Github ID: Doom2fan
Operating System: Windows 10/8.1/8/201x 64-bit
OS Test Version: No (Using Stable Public Version)
Graphics Processor: nVidia with Vulkan support

Re: D Mixin Templates

Postby phantombeta » Fri Oct 25, 2019 7:27 am

Ugh, I may have severely underestimated how much of a pain it'd be to add this to the Lemon file. Ughhhhhhh.
*headdesks*

Also, one thing I forgot is that, unlike D, there's lots of things you can put into class bodies that you can't put into function bodies and vice versa. So this needs slightly different syntax.
The syntax should be something like this:
Code: Select allExpand view
// Can be present in classes, structs and functions, less specialized, only allows things all three of those can do.
mixin Foo {
    int foo;
    int bar = 1; // Syntax error. Classes and structs can't initialize things like this.
    void func () { [...] } // Syntax error. Methods can't be nested.
}

// Can be present in classes and structs. More specialized, allows everything both structs and classes can do.
mixin type Bar {
    // Allowed:
    int foo;
    void func () { [...] }
    enum blah { fuck = 1 }
    const A_Number = 1337;
}

// Can only be used in class bodies
mixin class Bar {
    int foo;
    int bar = 0; // Syntax error. Classes can't initialize variables like this.
}

and so on.
Or we could do something like checking if the mixin can be used in that context, but that basically requires manually checking for syntax errors after the parsing is already done.
User avatar
phantombeta
In the meadow of sinful thoughts, every flower's a perfect one
 
Joined: 02 May 2013
Location: Brazil, South America, Earth, Orion-Cygnus Arm, Milky Way
Discord: phantombeta#2461
Twitch ID: phantombeta_
Github ID: Doom2fan
Operating System: Windows 10/8.1/8/201x 64-bit
OS Test Version: No (Using Stable Public Version)
Graphics Processor: nVidia with Vulkan support

Re: D Mixin Templates

Postby Graf Zahl » Fri Oct 25, 2019 7:34 am

What do you want to do with mixins in functions? Those are ten times more complicated than structs or classes. You also cannot initialize class members in the class body, there is no backing implementation for that. Keep it simple at first, if you want too much at once it won't end well.
User avatar
Graf Zahl
Lead GZDoom+Raze Developer
Lead GZDoom+Raze Developer
 
Joined: 19 Jul 2003
Location: Germany

Re: D Mixin Templates

Postby phantombeta » Fri Nov 01, 2019 3:46 pm

Added for classes. Can be easily extended to structs with just some copy-paste work, but I can't be bothered - ZScript structs are so janky and full of bugs that I'd say they're not that useful in 99% of the cases where you'd want to use a struct.
Example code:
Code: Select allExpand view
version "4.2"

class TestActor1 : Actor {
    int foo;
    mixin ItBeAMixin;
    int bar;

    override void Tick () {
        foo++;
        bar = EnumConst_C;
        Console.Printf ("foo: %d, margarine: %d, bar: %d, actorPtr: %d", foo, ICantBelieveItsNotButter, bar, !!actorPtr);
    }
}

class TestActor2 : Actor {
    int foo;
    int bar;
    mixin ItBeAMixin;

    default {
        +TestActor2.FLAGGY
    }

    states {
    Spawn:
        BAL1 A 1;
        loop;
    }

    override void PostBeginPlay () {
        Super.PostBeginPlay ();
        bar = 1;
        actorPtr = self;
    }

    override void Tick () {
        foo = EnumConst_B;
        bar *= 2;
        Console.Printf ("foo: %d, margarine: %d, bar: %d, actorPtr: %d", foo, ICantBelieveItsNotButter, bar, !!actorPtr);
    }
}

mixin class ItBeAMixin {
    enum ItsAnEnum {
        EnumConst_A,
        EnumConst_B,
        EnumConst_C,
    };

    Actor actorPtr;
    int ICantBelieveItsNotButter;

    flagdef FLAGGY: ICantBelieveItsNotButter, 0;

    default {
        +SOLID
        +ISMONSTER
        // Can't set FLAGGY here, as it'll have the class' identifier and we can't know that in advance.
    }

    states {
    Spawn:
        TROO A 1;
        loop;
    }
}


Graf Zahl wrote:What do you want to do with mixins in functions? Those are ten times more complicated than structs or classes.

Mixins could be useful for functions too. For example, if you have a long loop that's the same in two different functions, but can't be moved to a third function for some reason.

Graf Zahl wrote:You also cannot initialize class members in the class body, there is no backing implementation for that. Keep it simple at first, if you want too much at once it won't end well.

Hm? As the comments in the example code say, that would be a syntax error if used for anything other than a "mixin function" block.

By the way... Wow. There's a TON of places to change if you want to add new tokens to the parser. I feel like stuff like that should be documented somewhere...
User avatar
phantombeta
In the meadow of sinful thoughts, every flower's a perfect one
 
Joined: 02 May 2013
Location: Brazil, South America, Earth, Orion-Cygnus Arm, Milky Way
Discord: phantombeta#2461
Twitch ID: phantombeta_
Github ID: Doom2fan
Operating System: Windows 10/8.1/8/201x 64-bit
OS Test Version: No (Using Stable Public Version)
Graphics Processor: nVidia with Vulkan support


Return to Closed Feature Suggestions

Who is online

Users browsing this forum: No registered users and 0 guests