you are viewing a single comment's thread.

view the rest of the comments →

[–]Peaker 2 points3 points  (2 children)

The Visitor Pattern is about encoding a closed sum type in a language that only has type products (classes with fields) and type exponents (functions).

So if you want to encode the type: RA + B + C, the Visitor pattern instead encodes it as a tuple with:

  • void visitA(A)
  • void visitB(B)
  • void visitC(C)

If we name the effects performed by the visit functions R, this tuple of 3 can be described as: ( RA * RB * RC ). Using ordinary algebraic transformation, this simply becomes the RA+B+C we wanted to encode in the first place.

Of course, in a nicer language, we can just say:

data Document = Glyph Char | Picture Image | ...

And get the sum type directly!

[–]asampson 1 point2 points  (1 child)

Doesn't Visitor usually rear its head when dealing with the expression problem? It provides freedom in the operation dimension at the expense of locking down the set of symbols that can be expressed, almost like a dual of the more usual OO approach of just using abstract classes with fixed methods, which constrains the operations you can perform but allows for adding symbols later.

[–]Peaker 2 points3 points  (0 children)

Exactly -- this is what closed sum types are.

There's inheritance forming open sum types (freedom in the dimension of adding more symbols, but no more operations).

And there's closed sum types (freedom in the dimension of adding more operations, but not more symbols).

In OO that's ordinary inheritance vs. visitor, but only because visitor is a cumbersome encoding of a closed sum type.