December 10, 2018
On Monday, 10 December 2018 at 16:45:30 UTC, Steven Schveighoffer wrote:
> On 12/10/18 11:36 AM, Aliak wrote:
>> On Monday, 10 December 2018 at 16:27:03 UTC, Steven Schveighoffer wrote:
>>> On 12/10/18 11:11 AM, aliak wrote:
>>>> This is much better than having to mixin everywhere. A couple of things:
>>>>
>>>> 1) Can this be put in a module so that you don't have to mixin(enableInterpolation) but instead "import interp = std.interpolation;" or something similar?
>>>
>>> No, you need a local mixin. Doing that import just imports the *symbol* into your namespace, but it doesn't give access to your namespace to the symbol.
>>>
>> 
>> Au :(. Yeah that makes sense. Then Iā€™m not sure I see how this improves things if it has to be mixed in to every scope you want to use interpolation for. The sparseness of interpolation might just make mixin(Interp!ā€ā€)); more appealing.
>
> The benefit is that you only have to mixin once, whereas the usage does not require a mixin. It just goes next to your import statements.
>
> However, multiple scopes may make this less appealing, as you would have to mixin at any inner scope that has a variable you want to deal with.
>
> But I plan to write some string interpolation libraries based on this, would love to see a "better SQL" library for something like this.
>
> Not sure if it mitigates the need for an interpolation DIP, as clearly this is going to be compile-time intensive, where the cleverness is stomped on by memory usage and slow compile times.
>
> -Steve

It can also have some pretty unexpected results.  For example, having a variable reference an outerscope instance instead of the local one:

import std.stdio;
template somefun()
{
     auto iterpolate(string s)()
     {
         //do some parsing
         return mixin(s[1 .. $]);
     }
}

enum enableInterpolate = "mixin somefun A; alias interpolate = A.iterpolate;";

mixin(enableInterpolate);
enum a = 10;
enum msg = iterpolate!("$a");

void main()
{
    int a = 5;
    iterpolate!("$a").writeln;
}

This prints 10.
December 10, 2018
On Monday, 10 December 2018 at 16:45:30 UTC, Steven Schveighoffer wrote:
> The benefit is that you only have to mixin once, whereas the usage does not require a mixin. It just goes next to your import statements.

Once per *every* function you want to use it in. Not sure I see the benefit actually šŸ¤·ā€ā™‚ļø Jonathan also brings up a very good point. Hello bugs.

Cheers,
- Ali


December 10, 2018
I do not see any problem with add one line in every function. Right now I
do much more of this with imports so I can live with that.
And there is a easy solution to fix Jonathan issue. Just do not use it on
global scope. You can force it to be used only on function scope and so on.

But obviosly it is still a hack and workaround about something what should be in a language anyway.

On Mon, Dec 10, 2018 at 7:30 PM aliak via Digitalmars-d < digitalmars-d@puremagic.com> wrote:

> On Monday, 10 December 2018 at 16:45:30 UTC, Steven Schveighoffer wrote:
> > The benefit is that you only have to mixin once, whereas the usage does not require a mixin. It just goes next to your import statements.
>
> Once per *every* function you want to use it in. Not sure I see
> the benefit actually šŸ¤·ā€ā™‚ļø Jonathan also brings up a very good
> point. Hello bugs.
>
> Cheers,
> - Ali
>
>
>


December 10, 2018
On Monday, 10 December 2018 at 18:35:16 UTC, Daniel Kozak wrote:
> I do not see any problem with add one line in every function. Right now I
> do much more of this with imports so I can live with that.
> And there is a easy solution to fix Jonathan issue. Just do not use it on
> global scope. You can force it to be used only on function scope and so on.
>
> But obviosly it is still a hack and workaround about something what should be in a language anyway.
>
> On Mon, Dec 10, 2018 at 7:30 PM aliak via Digitalmars-d < digitalmars-d@puremagic.com> wrote:
>
>> On Monday, 10 December 2018 at 16:45:30 UTC, Steven Schveighoffer wrote:
>> > The benefit is that you only have to mixin once, whereas the usage does not require a mixin. It just goes next to your import statements.
>>
>> Once per *every* function you want to use it in. Not sure I see
>> the benefit actually šŸ¤·ā€ā™‚ļø Jonathan also brings up a very good
>> point. Hello bugs.
>>
>> Cheers,
>> - Ali

It's not just global scope, it's any outer scope. Examples:

class
{
    mixin(enableInterpolate); // BAD
    void foo()
    {
        interpolate!(...)
    }
}

void foo2()
{
    mixin(enableInterpolate); // BAD
    void inner_foo()
    {
        interpolate!(...)
    }
}

December 10, 2018
On 12/10/18 12:43 PM, Jonathan Marler wrote:

> It can also have some pretty unexpected results.Ā  For example, having a variable reference an outerscope instance instead of the local one:

Meh, I don't see this as really a problem or unexpected -- depending on how you look at the feature.

In general, anyone who wants to use this technique would know to mixin the string in the function they are going to use it.

I'm not saying the proposed DMD update and DIP isn't worth it, as even with the better call syntax, this is going to tax the CTFE engine hard, compared to what the compiler deals with (and that code already is there). But it's worth exploring how far we can get with this idea, to see the limitations and benefits. Maybe it solidifies the position that we need it in the language instead of the library.

-Steve
December 10, 2018
On Mon, Dec 10, 2018 at 01:44:48PM -0500, Steven Schveighoffer via Digitalmars-d wrote:
> On 12/10/18 12:43 PM, Jonathan Marler wrote:
> 
> > It can also have some pretty unexpected results.Ā  For example, having a variable reference an outerscope instance instead of the local one:
> 
> Meh, I don't see this as really a problem or unexpected -- depending on how you look at the feature.
> 
> In general, anyone who wants to use this technique would know to mixin the string in the function they are going to use it.
> 
> I'm not saying the proposed DMD update and DIP isn't worth it, as even with the better call syntax, this is going to tax the CTFE engine hard, compared to what the compiler deals with (and that code already is there). But it's worth exploring how far we can get with this idea, to see the limitations and benefits. Maybe it solidifies the position that we need it in the language instead of the library.
[...]

Yes, pushing the limits of the current language will give us more solid arguments to convince W&A that language support is necessary.  Otherwise there's a risk they will consider library solutions "good enough".


T

-- 
People tell me that I'm skeptical, but I don't believe them.
December 10, 2018
On Monday, 10 December 2018 at 18:44:48 UTC, Steven Schveighoffer wrote:
> On 12/10/18 12:43 PM, Jonathan Marler wrote:
>
>> It can also have some pretty unexpected results.Ā  For example, having a variable reference an outerscope instance instead of the local one:
>
> Meh, I don't see this as really a problem or unexpected -- depending on how you look at the feature.
>
> In general, anyone who wants to use this technique would know to mixin the string in the function they are going to use it.
>
> I'm not saying the proposed DMD update and DIP isn't worth it, as even with the better call syntax, this is going to tax the CTFE engine hard, compared to what the compiler deals with (and that code already is there). But it's worth exploring how far we can get with this idea, to see the limitations and benefits. Maybe it solidifies the position that we need it in the language instead of the library.
>
> -Steve

Yeah I agree we should explore this and try to find other options besides the new string literal syntax.  But for me, this is reason enough not to use this technique in my code.  It means that at any point when I see the "interpolate!(...)" call, I have to follow it back up to where mixin(enableInterpolate) appears and make sure it's in my scope and not an outer one.  That's worse than making sure to free memory/resources every time you allocate them, and the amount of bugs that causes is bad enough.  Any time your code depends on other code outside of itself you introduce more technical debt from the mental burden it takes to verify that code upon reading. Sometimes you can prevent that, but in this case I'd rather not use interpolation at all then introduce this kind of technical debt.
December 10, 2018
On Mon, Dec 10, 2018 at 7:40 PM Jonathan Marler via Digitalmars-d < digitalmars-d@puremagic.com> wrote:

>
>
> It's not just global scope, it's any outer scope. Examples:
>
> class
> {
>      mixin(enableInterpolate); // BAD
>      void foo()
>      {
>          interpolate!(...)
>      }
> }
>
> void foo2()
> {
>      mixin(enableInterpolate); // BAD
>      void inner_foo()
>      {
>          interpolate!(...)
>      }
> }
>
> You can fix this too
 https://gist.github.com/run-dlang/b797fd9e1d4993aeafcdb3d0523ef465


December 10, 2018
On Monday, 10 December 2018 at 19:04:21 UTC, Daniel Kozak wrote:
> On Mon, Dec 10, 2018 at 7:40 PM Jonathan Marler via Digitalmars-d < digitalmars-d@puremagic.com> wrote:
>
>>
>>
>> It's not just global scope, it's any outer scope. Examples:
>>
>> class
>> {
>>      mixin(enableInterpolate); // BAD
>>      void foo()
>>      {
>>          interpolate!(...)
>>      }
>> }
>>
>> void foo2()
>> {
>>      mixin(enableInterpolate); // BAD
>>      void inner_foo()
>>      {
>>          interpolate!(...)
>>      }
>> }
>>
>> You can fix this too
>  https://gist.github.com/run-dlang/b797fd9e1d4993aeafcdb3d0523ef465

Yes that does mitigate the issue.  It's a clever idea overall (someone else had something similar too).  Not as elegant as the string literal syntax but it's clever.  Would I use it in my code?  Not by default, but if I had a case where string interpolation was very beneficial (i.e. code generation) then I might use it.
December 10, 2018
On Mon, 10 Dec 2018 19:35:16 +0100, Daniel Kozak wrote:
> I do not see any problem with add one line in every function.

One line in every scope, rather:

    void foo()
    {
      mixin(interpSupport);
      {
        auto i = 10;
        // doesn't work
        writeln(interp!"i is $i");
      }
    }