Thread overview
purity question
May 28, 2017
Brad Roberts
May 29, 2017
Era Scarecrow
May 29, 2017
Era Scarecrow
May 29, 2017
Seb
May 28, 2017
Is there a mechanism for declaring something pure when it's built from parts which individually aren't?

string foo(string s)
{
    // do something arbitrarily complex with s that doesn't touch globals or change global state except possibly state of the heap or gc
    return s;
}
May 29, 2017
On Sunday, 28 May 2017 at 23:49:16 UTC, Brad Roberts wrote:
>     // do something arbitrarily complex with s that doesn't touch globals or change global state except possibly state of the heap or gc

 Sounds like the basic definition of pure to me; At least in regards to D. Memory allocation which is a system call, doesn't actually break purity. Then again if you were worried about not using the gc, there's the newer nogc property.

[quote]
 TDPL pg. 165: 5.11.1 Pure functions

 In D, a function is considered pure if returning a result is it's only effect and the result depends only on the function's arguments.
[/quote]
May 29, 2017
On Monday, 29 May 2017 at 01:12:53 UTC, Era Scarecrow wrote:
> ...

 Hmm didn't notice the post had split. Otherwise i wouldn't have replied... That and thinking about the GC state (outside of allocating memory)...
May 29, 2017
On Sunday, 28 May 2017 at 23:49:16 UTC, Brad Roberts wrote:
> Is there a mechanism for declaring something pure when it's built from parts which individually aren't?
>
> string foo(string s)
> {
>     // do something arbitrarily complex with s that doesn't touch globals or change global state except possibly state of the heap or gc
>     return s;
> }

Ali has answered this two years ago:

http://www.digitalmars.com/d/archives/digitalmars/D/learn/using_memset_withing_a_pure_function_74629.html#N74631

Copying for convenience:


If you want to live dangerously, you can use assumePure, which is found
in one of the unittest blocks of std.traits:

import std.traits;

auto assumePure(T)(T t)
if (isFunctionPointer!T || isDelegate!T)
{
     enum attrs = functionAttributes!T | FunctionAttribute.pure_;
     return cast(SetFunctionAttributes!(T, functionLinkage!T, attrs)) t;
}

int i = 0;

void foo()
{
     ++i;    // foo accesses mutable module-level data
}

void bar() pure
{
     auto pureFoo = assumePure(&foo);
     pureFoo();    // <-- pure function is calling impure function
}

void main()
{
     assert(i == 0);
     bar();
     assert(i == 1);    // mutation through a pure function
}

It also came up in other discussions (the keyword is `assumePure`), e.g.
- http://forum.dlang.org/post/hpxxghbiomtitrmwendu@forum.dlang.org
- http://forum.dlang.org/post/nfhqvffqtkfsxjewgeix@forum.dlang.org