Getting started - D meta-program question

Justin Johansson no at spam.com
Sat Oct 3 23:08:22 PDT 2009


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



More information about the Digitalmars-d-learn mailing list