Daniel Keep Wrote:

> Justin Johansson wrote:
> > There was mention** on the general discussion group that the D 
> > foreach_reverse
> > language construct could be replaced (emulated?) with a (D) meta-program.
> > 
> > ** "Even a novice programmer can write a meta-program to replace
> > foreach_reverse without any runtime performance hit."
> > 
> >    
> > http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D&article_id=97362
> >   
> > As I'm less than a novice with the D meta-programming facilities (at this 
> > stage of my journey into D),
> > if someone would kindly show me the D meta-program solution to do this,
> > I'd really appreciate the enlightenment.
> > 
> > Thanks again.
> 
> Short answer: you can't.
> 
> Long answer: you can, provided you aren't trying to reverse an opApply,
> which is patently impossible.
> 
> As for the "meta-program", I would suspect whoever said that was talking
> about writing a templated type or function to handle it.  You would need
> to use template specialisation or static ifs to switch on what type
> you've been given to reverse.
> 
> http://digitalmars.com/d/1.0/template.html
> 
> http://digitalmars.com/d/1.0/version.html#staticif

Thanks for your answer, Daniel.  I thought the original post was a bit of a red 
herring but
thought I'd ask about it anyway.  Good thing I did as you motivated me to delve 
into the
subject just after reading your reply.

Just now I've written a bit of CS101 play around code (shown below) for 
constructing a
singly-linked list of numbers (Conslist idiom).  As the code seems to work, it 
looks like
I've cut my first teeth on "D meta programming".

I'm sure there's lots to learn though .. especially looking though some of that 
std.functional
stuff.

If you have any comments / suggestions for improvement about this code, I'd 
graciously accept the same.
It's just a tutorial exercise for learning the D way of doing things.


class List
{
   List next;
   int data;

   this( int data) {
      this.next = null;
      this.data = data;
   }

   static List opCall() {
      return cast(List) null;
   }

   static List opCall( int data) {
      return new List( data);
   }

   static List cons( int data, List list) {
      auto newList = List( data);
      newList.next = list;
      return newList;
   }

   int opApply( int delegate( ref int data) dg) {
      auto result = 0;
      auto list = this;

      while ( list !is null) {
         if ((result = dg( list.data)) != 0)
            break;

         list = list.next;
      }

      return result;
   }

}


void printdata( int data) {
   writef( " %d", data);
}


void print( List list) {
   writef( "(");

   if (list !is null) {
      foreach ( x; list) {
         printdata( x);
      }
   }

   writef( ")");
}


void println( List list) {
   print( list);
   writefln();
}


List list(A...)( A args) {
   static if (A.length == 0) {
      return List();
   }

   else {
      return List.cons( args[0], list( args[1..$]));
   }
}


void main() {
   auto l0 = list();
   println( l0);
   
   auto l1 = list( 10);
   println( l1);
   
   auto l2 = list( 10, 20);
   println( l2);
   
   auto l3 = list( 10, 20, 30);
   println( l3);
   
}


Outputs:

()
( 10)
( 10 20)
( 10 20 30)

Thanks again, Justin

Reply via email to