Amusing D facts: typesafe variadic arrays are lazy!

Andrei Alexandrescu SeeWebsiteForEmail at erdani.org
Tue Oct 13 13:39:13 PDT 2009


Jeremie Pelletier wrote:
> 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

I think that's sensible, and thanks all for revealing reasons for assert 
to stay in the language.

As far as lazy goes, I think the lazy variadic functions are a 
compelling feature that renders lazy unnecessary. I plan to put no 
reference to lazy in TDPL. (Before someone else leaves the group: I just 
talked to Walter and he approved that.)


Andrei



More information about the Digitalmars-d mailing list