Thread overview
Making pure functions get dirty (D 2.0)
Feb 21, 2009
Burton Radons
Feb 21, 2009
Burton Radons
Feb 21, 2009
Burton Radons
February 21, 2009
I'm writing a general conversion template function a la:

  pure T convert (T, U) (const (U) value);

Sweet, and really handy for template errors because you can tell the user which number input it is that angered it. The problem is that if you're converting int to string there's allocations there that doesn't have to be there for many purposes (also I'm using it for error formatting, which isn't so good if what I'm telling the user is that there's no memory for allocations). So I thought I'd make it work like this:

  // May call write multiple times for arrays, each time builds onto the array.
  void convertInto (T, U, alias write) (const (T) value)
  {
    write ("You've bespoiled my honour, cur!\n");
  }

  void convertWith (T, U) (const (U) value, void delegate (T) write)
  {
    convertInto! (T, U, write) (value);
  }

  import std.stdio;
  void main ()
  {
    void write (string text) { writef (text); }
    convertWith! (string, string) ("Let's you and I spend a few moments alone without a chaperone, baby.\n", &write);
  }

Strangely enough this compiles but it doesn't actually DO anything (everything works, it's just that convertInto is not called at all); just taking the pure off fixes it. Obviously it shouldn't work, but what would I do to make an conditionally-pure function like this without code replication or mixin madness?

It feels like I'm missing some kind of "third way".
February 21, 2009
Burton Radons Wrote:

>   void convertInto (T, U, alias write) (const (T) value)

This should read "pure void". Everything I said about its behaviour is correct for my experiences.
February 21, 2009
Oh I see what's going on. pure functions get funky processing; if you don't actually use their return values they're not even compiled. Once you actually take the return value it'll complain about it whether it's a pure inner function in a pure outer function or anything else unless if it's a pure outer function which is perhaps the most useless thing you could have in this context.