Showing posts with label visitor pattern. Show all posts
Showing posts with label visitor pattern. Show all posts

Tuesday, June 27, 2006

Revisiting Visitor

I was looking for another approach to implement parsing expressions and came across Visitors in JSR 269 and "The Expression Problem Revisited", "The expression problem (aka the extensibility problem) refers to a fundamental dilemma of programming: Can your application be structured in such a way that both the data model and the set of virtual operations over it can be extended without the need to modify existing code, without the need for code repetition and without runtime type errors."

"All proposals that we know of take as a starting point either a data-centered approach, making it hard to add new operations, or an operation-centered (visitor-based) approach, making it equally hard to add new data types."

"Despite its simplicity, this trick is one of the major contributions of this paper, because it finally moves the visitor-based approach to the expression problem into the realm of static type safety...[it] divides the node classes of the different phases into separate, incompatible families, each characterized, in the form of a type parameter, by the specific brand of Visitor they are capable of accepting."

To put it another way, this enables you to define what implementation of Visitor you wish to use when you construct your visitable classes (at compile time, not runtime) - a pretty neat trick.

Via, why Visitors?.

Update: I've started using these ideas in JRDF to implement the SPARQL query layer and see what practical benefits are.

Friday, April 21, 2006

I Object

A response to some points in, The perils of avoiding heresy (or "What are Design Patterns") and Visitor Pattern and Trees Considered Harmful.

""21 reasons C++ sucks; 1 embarassment; and an Abstract Syntax Tree"...So if the book is predominately a catalogue of unfortunately necessary kludges around the semantic weaknesses of mainstream OO-languages, why do I still highly recommend it to new programmers?"

Design patterns are not reliant on OO, Java, C++ or any particular language or programming paradigm. It's not even reliant on Computer Science. The source of design patterns comes from architecture (Christopher Alexander) and is used in diverse areas such as dating. Grady Booch's Handbook lists 1000s of patterns, so many reasons OO-languages suck.

"Singleton. This is a global variable."

So variables and objects are not the same thing - variables lack behaviour (amongst other things). The Singleton pattern as implemented by IoC containers like Spring, Yan, PicoContainer all use Singleton as configuration on a plain Java object - so again it's not necessarily a concept in code at all.

"In a language with first-class constructors, the Factory Method Pattern consists of factory = MyClass.constructor"

This just shows a misunderstanding of the the Factory pattern - its intention is to decouple object instantiation, especially at runtime. In languages that have first-class constructors, like Ruby, you still use the Factory pattern.

An interesting discussion, Factory and Singleton are false Design Patterns?.

So the old chestnut, the visitor. "The visitor pattern is kludge used by programmers in a language that doesn't support multiple-dispatch to provide themselves with a static version of double-dispatch."

This I agree with. But the rest seems simply a rant against OO.

So Wikipedia says, "...visitor design pattern is a way of separating an algorithm from an object structure. A practical result of this separation is the ability to add new operations to existing object structures without modifying those structures."

So there's no need for multiple if-then-elses or case statements which is what happened in Python as there is no switch statement.

The Visitor pattern is not the ultimate answer to writing a compiler. It's very straight-forward for small languages, simple languages, languages where you might find changing the code and the syntax independently, etc. Having written a C compiler using SableCC I have seen the issue of breaking encapsulation - in fact most compiler implementations I've seen tend to create global state of one sort or another anyway.

The main issue with compiler compilers that I tried before SableCC (which uses the Visitor pattern) is the combination of grammar and Java code. I have similar problems with PL/SQL, JSPs, etc. This combination is also detrimental to tools like debuggers, IDEs etc. (the work that goes into JSP support in IDEs is a good example of how hard it is).

I can't think of a successful combination of the two styles, declarative and imperitive. To me it seems to always end in very poor, unmaintainable code. And through the eyes of a lemming it's much poorer than sticking within the OO paradigm.

A better article is, Translators Should Use Tree Grammars. At the end of article the author writes, "...aspect-oriented specifications as long as we are thinking about putting actions outside of the grammar. Action execution is just an aspect and each phase would be an aspect." which seems very similar to the way things like transactions and context have been implemented in Spring. It might well be that combining AOP and OOP will provide a clean solution to writing compilers.