Amusing D facts: typesafe variadic arrays are lazy!
Jeremie Pelletier
jeremiep at gmail.com
Tue Oct 13 13:48:28 PDT 2009
Andrei Alexandrescu wrote:
> 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
I wouldn't mind lazy going away, its something that can be 100% covered
by delegates and closures, maybe keep lazy as a lazy way of writing a
delegate?
'lazy int foo' could semantically equivalent to 'scope int delegate()
foo'. It would get called as {return 1;} and evaluated as foo().
Jeremie
More information about the Digitalmars-d
mailing list