java - Is skipping "accept" where type is known, a valid optimization for the Visitor pattern? -


consider following visitor simple language interpreter.

public interface visitor{     void visit( varstat vs);     void visit( ident i);     void visit( intliteral a);     void visit( sum s); } 

for completeness add code gives necessary implementation details (you can skip , read directly question).

public interface visitable{     void accept( visitor v); }  public class varstat implements visitable{     ident i;     exp   e;      public varstat(ident id, exp ex){         = id;         e = ex;     }      public ident getident() { return i; }     public exp getexp() { return e; }      @override     public void accept( visitor v){         v.visit( this);     } }  public interface exp extends visitable{  }  public class ident implements exp{     @override     public void accept( visitor v){         v.visit( this);     } } 

a var statement defined that:

varstat ::== var ident = exp; exp ::== exp + exp | intliteral | ident intliteral ::== [0-9]{0,8} ident ::== [a-za-z]+ 

a valid language instance

var x = x+y+4; 

an abstract way represent varstat node following:

.               _____varstat _____ .              /       /  | \     \  .             /       /   |  \     \   .            /       /    |   \     \ .         "var"   ident  "="  exp   ";" 

the question

the usual visitorpattern application be

void visit( varstat vs){      vs.getident().accept( this);      vs.getexp().accept( this);      //... } 

however, since know "ident" of type ident possible optimization is

void visit( varstat vs){       visit( vs.getident());      vs.getexp().accept( this);      //... } 

that skip 2 method calls improving performance (actually gives nice boost in scenario).

is considered design error lead future problems?

visitor complicated scaffold implement double-dispatch on languages java.

when deal leaf types, don't need double-dispatch; runtime type known @ compile time. dispatch leaf type directly not optimization, it's more out of principle.

of course, problem is, in future, leaf type may become super type. today's refactor tool in ides, not huge problem.

it better make simple design present's requirement, make complex design unknown future requirements.


in java 8, can implement double-dispatch syntax that's close real double-dispatch

final doubledispatch<root,void> dd = new doubledispatch<>();  dd.register(x.class, x-> {     x; compile time type x     return null; }); dd.register(y.class, y-> {     y; compile time type y     return null; }); // etc  ... dd.invoke( );    // ----  public class doubledispatch<t, r> {     public r invoke(t obj){...}      public <c extends t> void register(class<c> type, function<c,r> func){...} } 

see - java class.cast() , overload


Comments

Popular posts from this blog

c++ - Difference between pre and post decrement in recursive function argument -

php - Nothing but 'run(); ' when browsing to my local project, how do I fix this? -

php - How can I echo out this array? -