On Tuesday, September 13, 2016 20:08:22 Patrick Schluter via Digitalmars-d- learn wrote: > On Tuesday, 13 September 2016 at 06:59:10 UTC, Jonathan M Davis > > wrote: > > On Tuesday, September 13, 2016 03:33:04 Ivy Encarnacion via > > > > Digitalmars-d- learn wrote: > > A pure function cannot call any function that is not pure [...] > > I've read that a lot but it's not true. A pure function can call > impure function. The restriction is, that the impure function > called within the pure function does not depend or mutate on > state existing outside of that function. If the called function > changes local variable, it has no bearing on outside the scope. > Here a contrived example in C. > > size_t strlen(const char *str); is pure. If I define it this way > for example: > > size_t my_strlen(const char *str) > { > char temp[50]; > > strlcpy(temp, str, sizeof temp); /* strlcpy is not pure as it > mutates something outside of its "scope" */ > > return strlen(str); > } > > That function is pure. There is no visible change outside of it. > > my_strlen and strlen have exactly the same properties.
That's because you're talking about functional purity and _not_ D's pure. If you want to talk about D's pure, you pretty much need to forget about functional purity. While D's pure allows you to get functional purity, it's actually something different. It would be far more accurate at this point if it were called something like @noglobal. Actual, functional purity really only comes into play when a pure function's parameters are immutable or implicitly convertible to immutable, at which point the compiler can guarantee that the same arguments to the function will result in the function returning the same result. Sometimes, pure functions whose parameters are immutable or implicitly convertible to immutable are referred to as strongly pure functions, whereas those whose parameters aren't are called weakly pure. So-called strongly pure functions are what you need if you want to talk about functional purity, whereas so-called weakly pure functions are still pure as far as D is concerned, because they don't violate the functional purity of a strongly pure function if they're called by it. Originally, for a function to be pure in D, it _had_ to have parameters which were immutable or implicitly convertible to immutable, which actually was functionally pure, but it was too restrictive to be useful, so pure was expanded to what it is now, which makes it so that it's not really about functional purity anymore even though it enables functional purity in a way that the compiler can detect it and optimize for it. But when a D programmer talks about a function that's imppure, they're generally not talking about functional purity but about whether it's marked with pure or inferred as pure by the compiler, and per that definition, the code that you have above _is_ pure. In a way, what you're trying to prove about impure in D is both right and wrong, because we're dealing with conflicting definitions of purity here. When discussing pure in D, if you want to talk about whether a function is functionally pure in the sense that one would normally talk about pure functions outside of D, then you need to clearly state that you're talking about functional purity and not about D's pure. When simply saying that something is pure or not, folks here are going to expect you to be talking about D's definition of purity. By the way, the only ways to get around pure are: 1. use debug blocks (where pure is ignored in order to facilite debugging). 2. use an extern(*) other than extern(D) so that the body of the function doesn't have to be marked pure like the prototype does (since other types of linkage don't actually use pure), allowing you to lie to the compiler. 3. use function pointers and cast an impure function pointer to a pure one and thereby lie to the compiler. So, there are a couple of ways to fool the compiler, but there's only one wayt that's sanctioned by it, and it's only intended for debugging purposes. - Jonathan M Davis