Uh... destructors?

bearophile bearophileHUGS at lycos.com
Wed Feb 23 11:31:35 PST 2011


Steven Schveighoffer:

> That is allowed, and it's expected that a pure function can return  
> different references with identical calls.

A pointer and a "transparent reference" are two different things. That function returns a pointer, and a pointer is a value.
If you call a pure function with the same input you need to receive the same value. Otherwise it's not pure. If you mean something else, then you have redefined the meaning of "pure" so much that the word "pure" is the wrong one to use.


> pure functions are not necessarily @safe functions, you can access  
> pointers.

I know what I am currently able to do with pure functions in D. But here we are talking about what's the right/good way to design purity (or maybe we are even talking about what's the right way to modify D purity).

I presume you have understood what I have explained about transparent references.


> Pure functions are 100% about optimization.

Pure means first of all avoiding side effects. A pure function is not allowed to do some things, so both the programmer and the compiler are able to use such stronger constrains to perform some extra trasnformations normally not allowed on impure functions, and the resulting code is safer from certain kinds of bugs.


> An optimization should *never* be assumed.  That is, given  
> a pure function foo that returns a string, it should not be assumed that:
> 
> auto s = foo();
> auto s2 = foo();
> 
> is always factored into
> 
> auto s = foo();
> auto s2 = s;
> 
> It's an optimization, one which the compiler could or could not decide to  
> use.
> 
> However, it *should* be assumed that:
> 
> assert(s == s2);
> 
> That is, the values are the same.

I have suggested an extension of the type system that disallows statically code like:
assert(s.ptr == s2.ptr);

because this may break the transparent nature of references coming out of pure functions.


> What are your expectations for pure functions?

Allocating memory in a pure function is so useful that I expect D pure function to allow it. On the other hand I expect pure functions to behave deterministically, same input means same output. To solve this I have suggested di disallow reading the value of references/pointers coming out of pure functions.


> There is no such guarantee for weakly-pure functions.  There's not even  
> such a guarantee for strong-pure functions.

I know. This is something I'd like to add (well, I am not sure it's implementable, I am not sure it's a good idea, etc, so it's just an idea for now. And I don't think D will add it).


> To guarantee this would  
> require some sort of memoization, and require optimizations to be followed.

I think no memoization is needed, I think the only change needed is on the type system (so there are no effects on runtime. This type system just disallows some programs).

I may call them @transparent pointers/references, they are a supertype of normal ones:

class Foo() {}
pure @transparent(Foo) bar() {
  return new Foo();
}
Foo bar2() { // not pure
  return new Foo();
}
void main() {
  @transparent Foo f1 = bar(); // OK
  @transparent Foo f2 = bar2(); // OK
  Foo f3 = bar(); // not allowed, Foo is a subtype of @transparent(Foo)
}


On a @transparent Foo reference you are allowed to overwrite it, modify or use anything in the class itself, but you are statically allowed to use "is" operator on it, because it breaks its transparency (if you cast it to a pointer or not transparent, then you punch a hole in this type part of the type system).

Something similar is acceptable for struct pointers too, and arrays:

struct Spam() {}
@transparent Spam* bar3() {
  return new Spam();
}

struct Spam() {}
@transparent int[] bar4() {
  return new int[10];
}

Bye,
bearophile


More information about the Digitalmars-d mailing list