On Wed, 23 Feb 2011 16:40:22 -0500, bearophile <bearophileh...@lycos.com> wrote:

Steven Schveighoffer:

That's not what your example showed.  It showed comparing two allocated
pointers *outside* a pure function, and expected them to be equal. I see
that as disallowing all pointer comparisons.

My first examples were not so good, I am sorry :-) Thank you for not ignoring my posts despite that.

The idea was that if you allocate memory inside a pure function, then the result of this memory allocation is a @transparent pointer/reference. And that a @transparent pointer/reference can't be read (but you are allowed to dereference it, overwrite it, etc).

So this is OK, because the transparency of the pointer is respected:

pure @transparent(int*) foo() {
  return new int; // allocates just one int on the heap
}
void main() {
  @transparent int* i = foo(); // OK
  *i = 10; // OK
}

@transparent has little value outside a pure function, because the compiler does not expect to be able to perform pure optimizations on normal functions. Right now, the only drawback you have shown of being able to compare such references is when that comparison is used as the return value for a pure function. We can't continue to enforce the @transparent rules when they don't prevent problems, or else the language becomes too burdensome.

It also has some unpleasant effects.  For example, the object equality
operator does this:

bool opEquals(Object o1, Object o2)
{
   if(o1 is o2)
     return true;
   ...
}

So this optimization would be unavailable inside pure functions, no?  Or
require a dangerous cast?


Ick.
You can't give a @transparent Object to function that expects an Object, because transparent references disallow something that you are allowed to do on a not transparent reference/pointer:


pure @transparent Object foo() {
  return new Object();
}
void opEquals(Object o1, Object o2) {}
void main() {
  @transparent Object o = foo();
  opEquals(o, o); // not allowed
}

Once a reference gets out of a pure function, I think it should implicitly cast to a non-transparent reference, or else you have a huge mess. I would not like to define @transparent versions of all functions.

The question is, shouldn't you be able to compare two objects inside a pure function? I would think so. Note that the comparison inside opEquals does not alter purity, it's just an optimization.

Then again, I don't think opEquals would be callable inside a pure function, since it's not pure itself.

Would something like o is null be allowed?

Would it be enough to just require this type of restriction in pure @safe
functions?

I don't know.

Currently @safe is a wrong name, it means means @memorySafe. So I think that currently "@memorySafe" and "pure" are almost orthogonal concepts.

@safe is supposed to prevent using pointers. But then again, the definition is a moving target. I have a vague memory that really only pointer arithmetic is disallowed, comparison is allowed.

-Steve

Reply via email to