title: Generalisation of Visitor Pattern is impossible?
body: <p><strong>Is there a way of full generalistation of visitor pattern?</strong></p>
  
  <p>I concluded that fully generising Visitor pattern is impossible in JAVA if I want also generalise the return value. Only possible to make generic either the Visitor/Visitable or the ReturnValue.</p>
  
  <hr>
  
  <p><strong>Example1 - Return value is generic but the Visitor/Visitable is not:</strong></p>
  
  <pre><code>public abstract class PaymentType { //Visitable
      public abstract &lt;T&gt; T accept(PaymentTypeVisitor&lt;T&gt; visitor);
  }
  public interface PaymentTypeVisitor&lt;T&gt; {
      public T visit(CommissionedPaymentType commissionedPaymentType);
      public T visit(SalariedPaymentType salariedPaymentType);
      public T visit(HourlyPaymentType hourlyPaymentType);
  }
  </code></pre>
  
  <p><strong>Example2 - Visitor/Visitable is generic, but the return value is not (unsafe generic):</strong></p>
  
  <pre><code>public interface Visitor&lt;V extends Visitor&lt;V, A&gt;, A extends Visitable&lt;V, A&gt;&gt; {
  }
  public interface Visitable&lt;V extends Visitor&lt;V, A&gt;, A extends Visitable&lt;V, A&gt;&gt; {
      public abstract &lt;R&gt; R accept(V visitor); //Unsafe generic
  }
  </code></pre>
  
  <p>_</p>
  
  <pre><code>public interface AddEmployeeError extends Error, Visitable&lt;AddEmployeeErrorVisitor, AddEmployeeError&gt; {
  
  }
  public interface AddEmployeeErrorVisitor extends Visitor&lt;AddEmployeeErrorVisitor, AddEmployeeError&gt; {
      //Unsafe generics
      &lt;R&gt; R visit(IdAlreadyExistsValidationError idAlreadyExistsValidationError);
      &lt;R&gt; R visit(NameAlreadyExistsValidationError nameAlreadyExistsValidationError);
  }
  </code></pre>
  
  <p>_</p>
  
  <pre><code>public class AddEmployeeUseCaseValidationErrorFormatter implements AddEmployeeErrorVisitor {
      @Override
      protected String format(AddEmployeeError error) {
          return error.accept(this);
      }
  
      //Unsafe return type
      @Override
      public String visit(IdAlreadyExistsValidationError idAlreadyExistsValidationError) {
          return String.format("%s already owns this id!", idAlreadyExistsValidationError.nameOfExistingUser);
      }
  
      //Unsafe return type
      @Override
      public String visit(NameAlreadyExistsValidationError nameAlreadyExistsValidationError) {
          return String.format("Name already exists with id: %s", nameAlreadyExistsValidationError.idOfExistingUser);
      }
  
  }
  </code></pre>
  
  <p>I found this case here: <a href="http://musingsofaprogrammingaddict.blogspot.fr/2009/01/visitor-pattern-generic-and-still-type.html" rel="nofollow">http://musingsofaprogrammingaddict.blogspot.fr/2009/01/visitor-pattern-generic-and-still-type.html</a></p>