Where are we with thoughts on string interpolation and mixins?

aliak something at something.com
Tue Nov 20 09:19:41 UTC 2018


Hello,

I do a lot of work with mixins. But, it's usually very hard to 
read, and therefore reason about, and therefor review, and 
therefor maintain. So I'm wondering what people's thoughts are on 
how we can improve the experience of using mixins.

I'm thinking two things:
1) String interpolation
2) mixin syntax (this is not as big a deal as 1 IMO)

I was triggered by this in rust: 
https://github.com/bodil/typed-html - not completely relevant but 
it made me think: "oh, that's really nice and readable" and then 
I thought of D mixins and felt sad.

I'm referring to (this is plucked form random projects on github) 
code like this:

template MPQ_F_GET(char[] type, char[] name, char[] name2 = name) 
{
     const char[] MPQ_F_GET = type ~ " " ~ name2 ~ "() { " ~
             type ~ " ret; " ~
             "file_" ~ name ~ "(am, fileno, &ret); " ~
             "return ret;" ~
         "}";
}

Which, frankly, I had no idea what it was doing till I 
transformed it to this:

template MPQ_F_GET(char[] type, char[] name, char[] name2 = name) 
{
     const char[] MPQ_F_GET = q{
         $type $name2() {
             $type ret;
             file_$name(am, fileno, &ret);
             return ret;
         }
     };
}

Then I realized, ok, it's creating a function. Before that, I 
didn't see the "()" because it was hidden in noise. I was 
confused about "ret" because I assumed the mixin was generated 
from the template parameters. And I had no idea "file_" ~ name ~ 
"(am, fileno, &ret); " ~ was a function call O_o. Here's another 
one:

private char[] bindCode( char[] symbol ) {
    return symbol ~ " = cast( typeof( " ~ symbol ~
       " ) )m_sLibrary.getSymbol( `" ~ symbol ~ "` );";
}

As opposed to:

private char[] bindCode( char[] symbol ) {
    return q{
        $symbol = 
cast(typeof($symbol)m_sLibrary.getSymbol($symbol);
    };
}

And here's a one liner:

mixin("self."~option.VarName ~ " = " ~ "assumedValue.to!bool;");

mixin("self.${option.VarName} = ${assumedValue.to!bool};");

I've found that you waste A LOT of time just trying to figure out 
where ~ and " or ` go when you're writing a mixin. And don't even 
get me started on this pattern: `"` ~var ~ `";`; The number of 
times I've had a bug there and been thinking ... "why does this 
not compile" ... "ooooh a missing semicolon"...

This:

`"`~x`"~`~"` ~var ~ `";`;

As opposed to this:

`"$x" ~= "$var"`;

The difference to someone coming from interpolated strings land 
is quite significant. For people used to mixins, it's maybe less 
so? I'm not sure. I feel the pain everytime I try and mixin some 
code.

And I feel like this is almost like asking people to move to a 
ranged for loop because the C for(;;) is just inferior in 
readability, maintainability, debuggability, and reviewability 
... which is basically time, money, sanity, developer 
satisfaction, etc, etc. But at the same time, the C for-loop 
works "just fine".

I tried to rewrite this one as well [0], because I think that 
could look/read much better with interpolated string, but I 
couldn't understand it because there was just too much noise and 
my head hurt and I gave up and I threw my mac out the window and 
then I dissolved in to the virtual ether and wrote this post in 
my now new binary, and starved, form.

If it makes a difference at all as well, I've gotten this look at 
work 🤨when I say, yeah, there's no string interpolation in this 
language. And also "how old is this language?"

Ok, so now for the mixin syntax:

mixin(function("blah"));

What're thoughts on something like template mixin syntax so that 
we can get rid of those extra parens?:

mixin function("blah");

I couldn't really think of anything other than that or to allow 
for a trailing mixin decleration, i.e.: function("blah").mixin;

Thoughts?

Cheers,
- Ali

PS: I know that there're dub packages, but they a) they add yet 
another layer of indent, yet another set of parens or a bang, b) 
more uses of mixin (i.e. - mixin(mixin s!`"$x" ~= "$var"`"); - 
erm, I'm not even sure if that'd work, and c) take up a symbol 
which adds the friction of having to alias it away to something 
both nice, and unoccupied in your that particular file. Which 
also, btw, adds a maintainability nightmare and a code review 
nightmare - "wait what, interpolation is 'i' here but 'interp' in 
this file? And 's' in this other file??? - no thanks". Plus, 
dependencies for quick scripts are just overkill, and then you 
just go and use python instead.

PPS: I also believe that string interpolation was one of the top 
requested things in the survey this year? I may be misremembering 
though.

[0]: 
https://github.com/atilaneves/unencumbered/blob/7ecc9a811268edd6170bd294ac846d4da72acc8a/source/cucumber/reflection.d#L86





More information about the Digitalmars-d mailing list