August 01, 2018
On 8/1/18 3:59 AM, Shachar Shemesh wrote:
> Thank you! Finally!
> 
> Let me just state, for the record, that having *yet another* syntax special case is just appalling.

The lazy variadic thing is a distinction between specifying variadic lazy parameters and a lazy variadic array. The distinction is so miniscule, but necessary to have a disambiguous syntax.

But I had actually thought for a while, that you could simply specify a delegate, and it would be treated as a lazy parameter, which would probably solve your problem. I really think this syntax should be available.

> With that said, I was hoping that specifying it explicitly as a delegate would allow me to scope it. Apparently, that doesn't work :-(
> 

I guess you mean you can't scope the delegates? I'm surprised if that doesn't work.

-Steve
August 01, 2018
On 01/08/18 17:13, Steven Schveighoffer wrote:
> On 8/1/18 3:59 AM, Shachar Shemesh wrote:
>> Thank you! Finally!
>>
>> Let me just state, for the record, that having *yet another* syntax special case is just appalling.
> 
> The lazy variadic thing is a distinction between specifying variadic lazy parameters and a lazy variadic array. The distinction is so miniscule, but necessary to have a disambiguous syntax.
> 
> But I had actually thought for a while, that you could simply specify a delegate, and it would be treated as a lazy parameter, which would probably solve your problem. I really think this syntax should be available.
> 
>> With that said, I was hoping that specifying it explicitly as a delegate would allow me to scope it. Apparently, that doesn't work :-(
>>
> 
> I guess you mean you can't scope the delegates? I'm surprised if that doesn't work.
> 
> -Steve



import std.string;

alias Dg = string delegate() @nogc nothrow;

void myAssert(bool cond, scope Dg[1] msg_dg ...) @nogc nothrow
{
    import core.stdc.stdio;
    if (!cond)
    {
        string msg = msg_dg[0]();
        printf("%*s\n", msg.length, msg.ptr);
    }
}

void main() @nogc {
    string msg = "Hello";
    myAssert(true, msg); // <- errors on this line
}

It errors out: complains it needs to allocate main's frame on the GC, but main is @nogc. The same happens if I move the scope to the alias.
August 01, 2018
On 1 August 2018 at 18:52, Shachar Shemesh via Digitalmars-d <digitalmars-d@puremagic.com> wrote:
> On 01/08/18 17:13, Steven Schveighoffer wrote:
>>
>> On 8/1/18 3:59 AM, Shachar Shemesh wrote:
>>>
>>> Thank you! Finally!
>>>
>>> Let me just state, for the record, that having *yet another* syntax special case is just appalling.
>>
>>
>> The lazy variadic thing is a distinction between specifying variadic lazy parameters and a lazy variadic array. The distinction is so miniscule, but necessary to have a disambiguous syntax.
>>
>> But I had actually thought for a while, that you could simply specify a delegate, and it would be treated as a lazy parameter, which would probably solve your problem. I really think this syntax should be available.
>>
>>> With that said, I was hoping that specifying it explicitly as a delegate would allow me to scope it. Apparently, that doesn't work :-(
>>>
>>
>> I guess you mean you can't scope the delegates? I'm surprised if that doesn't work.
>>
>> -Steve
>
>
>
>
> import std.string;
>
> alias Dg = string delegate() @nogc nothrow;
>
> void myAssert(bool cond, scope Dg[1] msg_dg ...) @nogc nothrow
> {
>     import core.stdc.stdio;
>     if (!cond)
>     {
>         string msg = msg_dg[0]();
>         printf("%*s\n", msg.length, msg.ptr);
>     }
> }
>
> void main() @nogc {
>     string msg = "Hello";
>     myAssert(true, msg); // <- errors on this line
> }
>
> It errors out: complains it needs to allocate main's frame on the GC, but main is @nogc. The same happens if I move the scope to the alias.

My first thought was to have a look at enforce(), but on closer observation it is neither @nogc or nothrow.

Maybe you should raise a bug report?

It's certainly worth an attempt to bridge these two features together. I think it makes sense enough that lazy parameters should infer attributes from the function, and that it should be an error to pass a parameter that does not meet those constraints.

i.e:
---
// Signatures.
void myAssert(bool cond, lazy string msg) @nogc nothrow;
string mayAlloc() nothrow;
string mayThrow() @nogc;

// Code
myAssert(cond, mayAlloc());    // violates @nogc
myAssert(cond, mayThrow());    // violates nothrow
---

Iain.
August 02, 2018
On 01/08/18 17:13, Steven Schveighoffer wrote:
> The lazy variadic thing is a distinction between specifying variadic lazy parameters and a lazy variadic array.

I have now read that sentence 4 times, and I still have no idea what it means.

Can you give examples of both?

Shachar
August 02, 2018
On 8/1/18 10:14 PM, Shachar Shemesh wrote:
> On 01/08/18 17:13, Steven Schveighoffer wrote:
>> The lazy variadic thing is a distinction between specifying variadic lazy parameters and a lazy variadic array.
> 
> I have now read that sentence 4 times, and I still have no idea what it means.
> 
> Can you give examples of both?

import std.stdio;

// lazy variadic array
void foo(lazy int[] arr...)
{
  writeln(arr[0]);
  writeln(arr[1]);
  writeln(arr[2]);
}

// variadic lazy paramters
void bar(int delegate()[] items...)
{
   writeln(items[0]());
   writeln(items[1]());
   writeln(items[2]());
}

int param(int x)
{
    writeln("param ", x);
    return x;
}

void main()
{
    foo(param(0), param(1), param(2));
    bar(param(0), param(1), param(2));
}

output:

param 0
param 1
param 2
0
param 0
param 1
param 2
1
param 0
param 1
param 2
2
param 0
0
param 1
1
param 2
2

So in the first case, the ENTIRE array is evaluated lazily, and then an element selected. In the second case, each item is evaluated when used.

-Steve
August 02, 2018
On Wednesday, 1 August 2018 at 20:32:11 UTC, Iain Buclaw wrote:
> On 1 August 2018 at 18:52, Shachar Shemesh via Digitalmars-d <digitalmars-d@puremagic.com> wrote:
>> [...]
>
> My first thought was to have a look at enforce(), but on closer observation it is neither @nogc or nothrow.
>
> Maybe you should raise a bug report?
>
> It's certainly worth an attempt to bridge these two features together. I think it makes sense enough that lazy parameters should infer attributes from the function, and that it should be an error to pass a parameter that does not meet those constraints.
>
> i.e:
> ---
> // Signatures.
> void myAssert(bool cond, lazy string msg) @nogc nothrow;
> string mayAlloc() nothrow;
> string mayThrow() @nogc;
>
> // Code
> myAssert(cond, mayAlloc());    // violates @nogc
> myAssert(cond, mayThrow());    // violates nothrow
> ---
>
> Iain.

Isn't this https://issues.dlang.org/show_bug.cgi?id=12647?
August 03, 2018
On 2 August 2018 at 16:14, Seb via Digitalmars-d <digitalmars-d@puremagic.com> wrote:
> On Wednesday, 1 August 2018 at 20:32:11 UTC, Iain Buclaw wrote:
>>
>> On 1 August 2018 at 18:52, Shachar Shemesh via Digitalmars-d <digitalmars-d@puremagic.com> wrote:
>>>
>>> [...]
>>
>>
>> My first thought was to have a look at enforce(), but on closer observation it is neither @nogc or nothrow.
>>
>> Maybe you should raise a bug report?
>>
>> It's certainly worth an attempt to bridge these two features together. I think it makes sense enough that lazy parameters should infer attributes from the function, and that it should be an error to pass a parameter that does not meet those constraints.
>>
>> i.e:
>> ---
>> // Signatures.
>> void myAssert(bool cond, lazy string msg) @nogc nothrow;
>> string mayAlloc() nothrow;
>> string mayThrow() @nogc;
>>
>> // Code
>> myAssert(cond, mayAlloc());    // violates @nogc
>> myAssert(cond, mayThrow());    // violates nothrow
>> ---
>>
>> Iain.
>
>
> Isn't this https://issues.dlang.org/show_bug.cgi?id=12647?

Seems so, good to know.  I'll bookmark it for when I get time to do other things.

Iain.
August 04, 2018
On 2018-08-02 13:33, Steven Schveighoffer wrote:

> // variadic lazy paramters
> void bar(int delegate()[] items...)
> {
>     writeln(items[0]());
>     writeln(items[1]());
>     writeln(items[2]());
> }

I'm surprised that this doesn't need to be called with a delegate syntax, i.e.

bar({ return 0; });

-- 
/Jacob Carlborg
August 04, 2018
On 2018-08-02 13:33, Steven Schveighoffer wrote:

> // variadic lazy paramters
> void bar(int delegate()[] items...)
> {
>     writeln(items[0]());
>     writeln(items[1]());
>     writeln(items[2]());
> }

Adding @nogc to this example works.

-- 
/Jacob Carlborg
August 04, 2018
On 8/4/18 3:07 PM, Jacob Carlborg wrote:
> On 2018-08-02 13:33, Steven Schveighoffer wrote:
> 
>> // variadic lazy paramters
>> void bar(int delegate()[] items...)
>> {
>>     writeln(items[0]());
>>     writeln(items[1]());
>>     writeln(items[2]());
>> }
> 
> I'm surprised that this doesn't need to be called with a delegate syntax, i.e.
> 
> bar({ return 0; });
> 

See one of the earlier posts, it's a lazy variadic function. A little-known D feature.

-Steve