std.patterns: it was about time

Ary Borenszweig ary at esperanto.org.ar
Sun Feb 1 07:43:33 PST 2009


Andrei Alexandrescu escribió:
> In wake of the increasing power of templates in D2, I am starting the 
> std.patterns module, which is to contain boilerplate for a number of 
> common design patterns (as in the GoF book). For now I'm adding a 
> Visitor implementation, which was lying in my codebase for a while.
> 
> http://ssli.ee.washington.edu/~aalexand/d/web/phobos/std_patterns.html
> http://ssli.ee.washington.edu/~aalexand/d/web/phobos/std_patterns.d
> 
> Comments and suggestions are as always welcome.

It's nice to implement patterns with mixins, like Singleton in my video.

But that way of the visitor pattern seems pretty useless. I used that 
pattern a lot in Descent for the AST of the D language (and also in 
other projects). Each node of the AST has children, so for example:

---
class BinaryExp {

   Exp leftOperand;
   Exp rightOperand;
   Op operator;

   void accept(ASTVisitor visitor) {
     boolean visitChildren = visitor.visit(this);
     if (visitChildren) {
       if (leftOperand != null) leftOperand.accept(visitor);
       if (rightOperand != null) rightOperand.accept(visitor);
     }
     visitor.endVisit(this);
   }

}
---

Major differces with what you have are:
  1. Two methods: visit and endVisit. This allows you to know when the 
visitor enters a node and exits it. This is useful for algorithms with 
stacks: Say you want to print the AST back to a string with nice 
formatting. Whenever you enter a WhileStatement you increment the 
indentation, and when you exit it, you decrease it.
  2. visit returns true if the visitor wants to visit the node's 
children, false otherwise. This allows you to skip entire nodes upon a 
condition or depending on the visitor logic.
  3. The children of a node are visited automatically by that node (if 
desired by the visitor).

When it says "Essentially the Visitor pattern offers a means to add new 
methods to a class hierarchy without touching the hierarchy", I think it 
doesn't means a hierarchy of classes, but a conceptual hierarchy, like 
an AST or a Car with it's parts, where there are some things that 
contain other things.

Here's the ASTVisitor in JDT: 
http://help.eclipse.org/help32/index.jsp?topic=/org.eclipse.jdt.doc.isv/reference/api/org/eclipse/jdt/core/dom/ASTVisitor.html

So maybe the visitor pattern should be implemented like this:

---
class BinaryExp {

   Exp leftOperand;
   Exp rightOperand;

   mixin MakeVisitable!(leftOperand, rightOperand);

}
---

Also, since you normally write visitors for the same conceptual 
hierarchy, you'd like to do something like this:

---
auto expHierarchy = VisitorHierarchy!(BinaryExp, PrefixExp, Number, 
Parenthesis);

class Calculator : Visitor!(expHierarchy) {

   // ...

}
---

And the Visitor should be an abstract class where every visit method 
returns true by default. In that way you can extend it and overrite just 
the methods you need in your visitor.

Well... just thoughts. There are a lots of ways to implement this 
pattern, but I find this one the most useful.



More information about the Digitalmars-d mailing list