December 20, 2011
On Tuesday, 20 December 2011 at 11:17:32 UTC, Froglegs wrote:
>
>> The class will still have a vptr. The vtable will contain only the type info.
>
> No way to disable type info(like in most C++ compilers you can disable RTTI)? I get that GC might want it, but if I disable GC why would I want type info?

It's used for casts and other language/library features depending on typeid.

There's also the standard Object virtual methods: toString (used e.g. when passing objects to writeln), toHash, opEquals, opCmp (used in associative arrays, array sorting).

December 20, 2011
On Tuesday, 20 December 2011 at 11:17:32 UTC, Froglegs wrote:
> The array concatenation requiring GC I get, but why does a delegate require it?
>
> This link says D allocates closures on the heap
>
> http://en.wikipedia.org/wiki/Anonymous_function#D
>
> I don't really get why, C++ lambda works well(aside from broken lack of template lambda's) and do not require heap usage, even binding it to std::function can generally avoid it if it doesn't exceed the  SBO size

C++ "closures" do not allow you to maintain a reference to the context after the function containing said context returns. Instead, C++ allows you to choose between copying the variables into the lambda instance, or referencing them (the references may not "escape"). The compiler may or may not enforce correct uses of reference captures. In contrast, D's approach is both intuitive (does not copy variables) and safe (conservatively allocates on the heap), with the downside of requiring the context to be garbage-collected.
December 20, 2011
> C++ "closures" do not allow you to maintain a reference to the context after the function containing said context returns. Instead, C++ allows you to choose between copying the variables into the lambda instance, or referencing them (the references may not "escape"). The compiler may or may not enforce correct uses of reference captures. In contrast, D's approach is both intuitive (does not copy variables) and safe (conservatively allocates on the heap), with the downside of requiring the context to be garbage-collected.

Ah, makes sense now, thanks.

Still it seems like a case of "you pay for what you don't use", and seems like a real downer for adopting D since you loose the ability to use lambda's without having the GC shoved down your throat(wouldn't be so bad if the D GC was known for performance, but everything I've read indicates it is quite slow).



December 20, 2011
Froglegs:

> Still it seems like a case of "you pay for what you don't use",

That's a design rule for C++, but D is a bit different :-)
Often in D there are ways to not pay what you don't use, but you have to ask for them. If you don't ask for those ways, you usually need to pay a little, and you get a program that's safer or more easy to debug.

So for D the rule is more like "Safety on default, and unsafe (and cheap) on request".


> and seems like a real downer for adopting D since you loose the ability to use lambda's without having the GC shoved down your throat

In theory in D there is a way to use (at the usage site) static delegates, that don't allocate a closure on the heap. I don't know if now this feature is fully correctly implemented, but if not it's planned.

Bye,
bearophile
December 20, 2011
On 12/20/11 5:17 AM, Froglegs wrote:
> The array concatenation requiring GC I get, but why does a delegate
> require it?
>
> This link says D allocates closures on the heap
>
> http://en.wikipedia.org/wiki/Anonymous_function#D
>
> I don't really get why, C++ lambda works well(aside from broken lack of
> template lambda's) and do not require heap usage, even binding it to
> std::function can generally avoid it if it doesn't exceed the SBO size

Well another way of putting it is std::function MUST do heap allocation if environment size exceeds the SBO size. It's the same thing here.

Just like C++ lambdas, D lambdas and local functions don't need heap allocation unless they escape their scope.


Andrei
December 20, 2011
On 12/20/11 5:56 AM, Froglegs wrote:
>
>> C++ "closures" do not allow you to maintain a reference to the context
>> after the function containing said context returns. Instead, C++
>> allows you to choose between copying the variables into the lambda
>> instance, or referencing them (the references may not "escape"). The
>> compiler may or may not enforce correct uses of reference captures. In
>> contrast, D's approach is both intuitive (does not copy variables) and
>> safe (conservatively allocates on the heap), with the downside of
>> requiring the context to be garbage-collected.
>
> Ah, makes sense now, thanks.
>
> Still it seems like a case of "you pay for what you don't use", and
> seems like a real downer for adopting D since you loose the ability to
> use lambda's without having the GC shoved down your throat(wouldn't be
> so bad if the D GC was known for performance, but everything I've read
> indicates it is quite slow).

D's pass-down lambdas do not need memory allocation. As far as I remember none of std.algorithm's use of lambda allocates memory.

Andrei
December 20, 2011
> D's pass-down lambdas do not need memory allocation. As far as I remember none of std.algorithm's use of lambda allocates memory.
>
> Andrei

Oh cool, I like that
December 20, 2011
Le 20/12/2011 14:08, Andrei Alexandrescu a écrit :
> On 12/20/11 5:56 AM, Froglegs wrote:
>>
>>> C++ "closures" do not allow you to maintain a reference to the context
>>> after the function containing said context returns. Instead, C++
>>> allows you to choose between copying the variables into the lambda
>>> instance, or referencing them (the references may not "escape"). The
>>> compiler may or may not enforce correct uses of reference captures. In
>>> contrast, D's approach is both intuitive (does not copy variables) and
>>> safe (conservatively allocates on the heap), with the downside of
>>> requiring the context to be garbage-collected.
>>
>> Ah, makes sense now, thanks.
>>
>> Still it seems like a case of "you pay for what you don't use", and
>> seems like a real downer for adopting D since you loose the ability to
>> use lambda's without having the GC shoved down your throat(wouldn't be
>> so bad if the D GC was known for performance, but everything I've read
>> indicates it is quite slow).
>
> D's pass-down lambdas do not need memory allocation. As far as I
> remember none of std.algorithm's use of lambda allocates memory.
>
> Andrei

Is the compiler able to ensure that and do not allocate on the heap ?
December 20, 2011
On 12/20/11 7:41 AM, deadalnix wrote:
>> D's pass-down lambdas do not need memory allocation. As far as I
>> remember none of std.algorithm's use of lambda allocates memory.
>>
>> Andrei
>
> Is the compiler able to ensure that and do not allocate on the heap ?

Yes, to the best of my knowledge it's pretty much cut and dried.

Andrei
December 20, 2011
> The array concatenation requiring GC I get, but why does a delegate require it?

If you really want a stack allocated delegate, you could use something like:

import std.stdio, std.traits;

struct DelegateWrapper(alias fun, Args...)
{
    Args args;
    private auto f(ParameterTypeTuple!fun[Args.length..$] otherArgs)
    {
        return fun(args, otherArgs);
    }
    auto dg()
    {
        return &f;
    }
}

auto delegateWrapper(alias fun, A...)(A a)
{
    return DelegateWrapper!(fun,A)(a);
}

void main()
{
    static test (int a, int b, int c)
    {
        writeln(a, b, c);
    }
    auto b = delegateWrapper!(test)(1,2);

    b.dg()(3);
}