pure or not pure?

Koroskin Denis 2korden+dmd at gmail.com
Fri Apr 11 12:21:42 PDT 2008


On Thu, 10 Apr 2008 21:41:15 +0400, Janice Caron <caron800 at googlemail.com>  
wrote:

> On 10/04/2008, Koroskin Denis <2korden+dmd at gmail.com> wrote:
>>  OK, new is 'special', but what about malloc or my own allocator? (I  
>> happen
>> to work in a gamedev and we never use new nor malloc).
>>  I don't see how
>>
>>  special extern(C) void* malloc(size_t size);
>>
>>  differs from:
>>
>>  void* my_malloc(size_t size)
>>  {
>>    return malloc(size);
>>  }
>>
>>  and why can't it be 'special' too.
>
> Because you're modifying global state.
>
> One of the reasons why new is special is because you never have to
> delete (because the garbage collector takes care of it). This is
> directly comparable to, for example, Haskell, where new "things" are
> created all the time, and are never freed. It's built into the system.
> More - it /is/ the system. That's the status of new. It's the de facto
> heap allocation method in D.
>
> If you want to use custom allocators, there's nothing to stop you, but
> that doesn't change the fact that the minute you modify global state,
> you have a function that isn't pure.
>
> I think you're worrying too much. There should never be a need to call
> malloc and free inside a pure function. If you need a function that
> does impure stuff, just write the function anyway, and don't call it
> pure.

Well, I don't distinguish between new and malloc. They both are impure and
/shouldn't/ be callable from pure functions. In fact, there is a solution:
inew (for short, or new invariant(T) from accu-functional).

Obviously enough, new can't be pure:

T t1 = new T();
T t2 = new T();

Since it can't be rewritten to:

T t1 = new T();
T t2 = t1;

However, inew /is/ pure:

T t1 = inew T();
T t2 = t1;

Is this the key!?

Yet, there is one more exception: rand(). I believe Haskell /has/ random  
numbers,
therefore it should be callable from pure functions, isn't it?

Other solution could be to introduce some 'uncachable' keyword, so that we  
could declare:

uncachable int rand();
uncachable void* malloc(size_t size);

> [snip]
> I should have added: /neither/ of those functions is pure.
>
> In fact, I strongly doubt that any function declared extern(C) will be
> pure, for the simple and obvious reason that C doesn't have the "pure"
> keyword. :-)

Agreed, C doesn't but pure and impure follow the same calling convention
(I hope), so there is no difference between two from linker's point of  
view.

Can't see why isalpha/isdigit/tolower/etc. can't be declared pure:

extern "C" {
    pure int isalpha(int c);
    pure int isdigit(int c);
    pure int tolower(int c);
}



More information about the Digitalmars-d mailing list