Amusing D facts: typesafe variadic arrays are lazy!

Jeremie Pelletier jeremiep at gmail.com
Tue Oct 13 12:36:55 PDT 2009


Leandro Lucarella wrote:
> Andrei Alexandrescu, el 13 de octubre a las 10:30 me escribiste:
>> downs wrote:
>>> Did you know the following code compiles?
>>>
>>>> module test;
>>>>
>>>> import std.stdio;
>>>>
>>>> void Assert(bool cond, string delegate()[] dgs...) {
>>>>  debug if (!cond) {
>>>>    string str;
>>>>    foreach (dg; dgs) str ~= dg();
>>>>    throw new Exception(str);
>>>>  }
>>>> }
>>>>
>>>> void main() {
>>>>  Assert(false, "O hai thar! ");
>>>> }
>>>
>>> It's true! :)
>> Gosh!!! What's happening over here? I even tried this:
>>
>> import std.stdio;
>>
>> void Assert(bool cond, string delegate()[] dgs...) {
>>     if (!cond) {
>>         string str;
>>         foreach (dg; dgs) str ~= dg();
>>         throw new Exception(str);
>>     }
>> }
>>
>> string fun(string a, string b) {
>>     writeln("Concatenating...");
>>     return a ~ b;
>> }
>>
>> void main() {
>>     Assert(true, fun("O hai thar! ", "wyda"));
>>     Assert(false, fun("O hai thar! ", "wyda"));
>> }
>>
>> This example only prints "Concatenatning..." once, meaning that fun
>> is also lazified!!!
>>
>> This is very exciting! The fact that this little anomaly hasn't
>> caused trouble is a good sign it could actually replace lazy!
> 
> What is the relation between assert and pure/nothrow? Is assert allowed?
> I think it should be, since an assert is expressing a very essential
> property of the software, it can't happen in a normal flow of the program.
> 
> If this is the case, I guess assert should be kept as a language construct
> so it can be always be used in pure/nothrow functions.
> 

It works for the reason you said, assertions either guard against an 
unreachable code path or invalid values. AssertError throwables aren't 
meant to be recovered from (as should any Error) so they're perfectly 
fine in pure or nothrow contexts.

I often use assert(0) to mark unreachable paths, and the compiler don't 
warn me that some paths of a function have no return value. For that 
reason I also want assert() to stay a compiler intrinsic, especially 
since having assert() as a library routine and static assert() as a 
compiler feature sounds weird.

Jeremie



More information about the Digitalmars-d mailing list