June 26, 2012
As delete and new / delete overloading is deprecated and it was recommeneded to write tempaltes to repalce these expressions I did so.

But now as everything starts to work out pretty nice I've walked into the 'purity' issue. Pure functions are only allowed to call other pure functions and as far as I know there is no way to make functions "trusted pure". But I would need to make certain functions "trused pure", espeically my new and delete replacements. Any suggestions how to do this?

Kind Regards
Benjamin Thaut
June 26, 2012
On 06/26/2012 05:59 PM, Benjamin Thaut wrote:
> As delete and new / delete overloading is deprecated and it was
> recommeneded to write tempaltes to repalce these expressions I did so.
>
> But now as everything starts to work out pretty nice I've walked into
> the 'purity' issue. Pure functions are only allowed to call other pure
> functions and as far as I know there is no way to make functions
> "trusted pure". But I would need to make certain functions "trused
> pure", espeically my new and delete replacements. Any suggestions how to
> do this?
>
> Kind Regards
> Benjamin Thaut

You can cast function pointers to pure, or mark extern(C) memory allocation functions as pure.
June 26, 2012
Am 26.06.2012 18:02, schrieb Timon Gehr:
> On 06/26/2012 05:59 PM, Benjamin Thaut wrote:
>> As delete and new / delete overloading is deprecated and it was
>> recommeneded to write tempaltes to repalce these expressions I did so.
>>
>> But now as everything starts to work out pretty nice I've walked into
>> the 'purity' issue. Pure functions are only allowed to call other pure
>> functions and as far as I know there is no way to make functions
>> "trusted pure". But I would need to make certain functions "trused
>> pure", espeically my new and delete replacements. Any suggestions how to
>> do this?
>>
>> Kind Regards
>> Benjamin Thaut
>
> You can cast function pointers to pure, or mark extern(C) memory
> allocation functions as pure.

extern(c) is not an options as there is a structure of various different allocators that implement a common interface which all is written in D.

Is the compiler smart enough to optimize away a function pointer I created localy just so I can cast it?

Kind Regards
Benjamin Thaut
June 26, 2012
On 06/26/2012 06:05 PM, Benjamin Thaut wrote:
> Am 26.06.2012 18:02, schrieb Timon Gehr:
>> On 06/26/2012 05:59 PM, Benjamin Thaut wrote:
>>> As delete and new / delete overloading is deprecated and it was
>>> recommeneded to write tempaltes to repalce these expressions I did so.
>>>
>>> But now as everything starts to work out pretty nice I've walked into
>>> the 'purity' issue. Pure functions are only allowed to call other pure
>>> functions and as far as I know there is no way to make functions
>>> "trusted pure". But I would need to make certain functions "trused
>>> pure", espeically my new and delete replacements. Any suggestions how to
>>> do this?
>>>
>>> Kind Regards
>>> Benjamin Thaut
>>
>> You can cast function pointers to pure, or mark extern(C) memory
>> allocation functions as pure.
>
> extern(c) is not an options as there is a structure of various different
> allocators that implement a common interface which all is written in D.
>
> Is the compiler smart enough to optimize away a function pointer I
> created localy just so I can cast it?
>
> Kind Regards
> Benjamin Thaut

You can examine the assembly code. DMD is perhaps not smart enough (it
is unable to inline directly called function literals, so I am not
optimistic.) LDC and GDC should certainly optimize it out.
June 26, 2012
Am 26.06.2012 18:44, schrieb Timon Gehr:
> On 06/26/2012 06:05 PM, Benjamin Thaut wrote:
>> Am 26.06.2012 18:02, schrieb Timon Gehr:
>>> On 06/26/2012 05:59 PM, Benjamin Thaut wrote:
>>>> As delete and new / delete overloading is deprecated and it was
>>>> recommeneded to write tempaltes to repalce these expressions I did so.
>>>>
>>>> But now as everything starts to work out pretty nice I've walked into
>>>> the 'purity' issue. Pure functions are only allowed to call other pure
>>>> functions and as far as I know there is no way to make functions
>>>> "trusted pure". But I would need to make certain functions "trused
>>>> pure", espeically my new and delete replacements. Any suggestions
>>>> how to
>>>> do this?
>>>>
>>>> Kind Regards
>>>> Benjamin Thaut
>>>
>>> You can cast function pointers to pure, or mark extern(C) memory
>>> allocation functions as pure.
>>
>> extern(c) is not an options as there is a structure of various different
>> allocators that implement a common interface which all is written in D.
>>
>> Is the compiler smart enough to optimize away a function pointer I
>> created localy just so I can cast it?
>>
>> Kind Regards
>> Benjamin Thaut
>
> You can examine the assembly code. DMD is perhaps not smart enough (it
> is unable to inline directly called function literals, so I am not
> optimistic.) LDC and GDC should certainly optimize it out.

The more I get into this, the more I get the feeling that all this "D can be used without a GC" is just a marketing trick to get C++ guys to use D.

I really like D because of a lot of nice features it has, but at the current rate I fear that the day I go back to c++ will come.
June 26, 2012
On Tue, 26 Jun 2012 12:05:55 -0400, Benjamin Thaut <code@benjamin-thaut.de> wrote:

> Am 26.06.2012 18:02, schrieb Timon Gehr:

>> You can cast function pointers to pure, or mark extern(C) memory
>> allocation functions as pure.
>
> extern(c) is not an options as there is a structure of various different allocators that implement a common interface which all is written in D.

extern(C) does not mean implemented in C, it just means C linkage.  You can use arrays, classes, etc. in extern(C) functions.  UFCS makes this really easy too:

myalloc.d:

interface Allocator
{
   void * _alloc(size_t size);
}

extern(C) void *alloc(Allocator a, size_t size) pure;

allocimpl.d:
import myalloc;

extern(C) void *alloc(Allocator a) // pure
{
   return a._alloc(size)
}

mallocer.d:

public import myalloc;
import std.c.stdlib;

// sample allocator
class Mallocer : Allocator
{
   void *_alloc(size_t size) { return malloc(size);}
}

main.d:

import mallocer;

void foo(Allocator a) pure
{
   a.alloc(200);
   //a._alloc(200); // fails as expected
}

void main()
{
   foo(new Mallocer);
}

-Steve
June 26, 2012
On Tuesday, 26 June 2012 at 16:52:48 UTC, Benjamin Thaut wrote:
> Am 26.06.2012 18:44, schrieb Timon Gehr:
>> On 06/26/2012 06:05 PM, Benjamin Thaut wrote:
>>> Is the compiler smart enough to optimize away a function pointer I
>>> created localy just so I can cast it?
>>> […]
>>
>> You can examine the assembly code. DMD is perhaps not smart enough (it
>> is unable to inline directly called function literals, so I am not
>> optimistic.) LDC and GDC should certainly optimize it out.
>
> The more I get into this, the more I get the feeling that all this "D can be used without a GC" is just a marketing trick to get C++ guys to use D.

This has nothing to do with the GC, just with the compiler turning an indirect jump to a statically known address into a direct one. Every decent compiler should optimize it away, and even if it doesn't, it still won't kill you in 99.9% of the use cases.

David
June 26, 2012
Am 26.06.2012 19:23, schrieb David Nadlinger:
> On Tuesday, 26 June 2012 at 16:52:48 UTC, Benjamin Thaut wrote:
>> Am 26.06.2012 18:44, schrieb Timon Gehr:
>>> On 06/26/2012 06:05 PM, Benjamin Thaut wrote:
>>>> Is the compiler smart enough to optimize away a function pointer I
>>>> created localy just so I can cast it?
>>>> […]
>>>
>>> You can examine the assembly code. DMD is perhaps not smart enough (it
>>> is unable to inline directly called function literals, so I am not
>>> optimistic.) LDC and GDC should certainly optimize it out.
>>
>> The more I get into this, the more I get the feeling that all this "D
>> can be used without a GC" is just a marketing trick to get C++ guys to
>> use D.
>
> This has nothing to do with the GC, just with the compiler turning an
> indirect jump to a statically known address into a direct one. Every
> decent compiler should optimize it away, and even if it doesn't, it
> still won't kill you in 99.9% of the use cases.
>
> David

I'm not talking about the optimization here. I'm talking about not beeing able to do a propper replacement for new / delete with the features the language currently has.
June 26, 2012
Am 26.06.2012 19:19, schrieb Steven Schveighoffer:
> On Tue, 26 Jun 2012 12:05:55 -0400, Benjamin Thaut
> <code@benjamin-thaut.de> wrote:
>
>> Am 26.06.2012 18:02, schrieb Timon Gehr:
>
>>> You can cast function pointers to pure, or mark extern(C) memory
>>> allocation functions as pure.
>>
>> extern(c) is not an options as there is a structure of various
>> different allocators that implement a common interface which all is
>> written in D.
>
> extern(C) does not mean implemented in C, it just means C linkage. You
> can use arrays, classes, etc. in extern(C) functions. UFCS makes this
> really easy too:
>
> myalloc.d:
>
> interface Allocator
> {
> void * _alloc(size_t size);
> }
>
> extern(C) void *alloc(Allocator a, size_t size) pure;
>
> allocimpl.d:
> import myalloc;
>
> extern(C) void *alloc(Allocator a) // pure
> {
> return a._alloc(size)
> }
>
> mallocer.d:
>
> public import myalloc;
> import std.c.stdlib;
>
> // sample allocator
> class Mallocer : Allocator
> {
> void *_alloc(size_t size) { return malloc(size);}
> }
>
> main.d:
>
> import mallocer;
>
> void foo(Allocator a) pure
> {
> a.alloc(200);
> //a._alloc(200); // fails as expected
> }
>
> void main()
> {
> foo(new Mallocer);
> }
>
> -Steve

Thanks this works, but it seems to be a very ugly hack just to work around the type system. Also I have templated allocator functions I can not use this trick on. This is going to be a lot of work to get done properly, so I just ignore pure for now I think.
June 26, 2012
On Tuesday, June 26, 2012 20:08:14 Benjamin Thaut wrote:
> Thanks this works, but it seems to be a very ugly hack just to work around the type system. Also I have templated allocator functions I can not use this trick on. This is going to be a lot of work to get done properly, so I just ignore pure for now I think.

Note that since telling the compiler something is pure when it doesn't think so _is_ forcing the type system, it's not entirely unreasonable that it not be super-easy to do. However, it would definitely be nice if it were a lot easier than it is.

You could try std.traits.SetFunctionAttributes (it was recently added and is not in 2.59 IIRC). David Nadlinger created it specifically for being able to create easily add function attributes such as pure to a function. I haven't messed around with it yet, but it looks very easy to use.

- Jonathan M Davis
« First   ‹ Prev
1 2
Top | Discussion index | About this forum | D home