Andy Wardley writes: > Because Perl is a general purpose programming language. TT implements > a general purpose presentation language. A different kettle of fish > altogether.
These are the reserve words of TT: GET CALL SET DEFAULT INSERT INCLUDE PROCESS WRAPPER IF UNLESS ELSE ELSIF FOR FOREACH WHILE SWITCH CASE USE PLUGIN FILTER MACRO PERL RAWPERL BLOCK META TRY THROW CATCH FINAL NEXT LAST BREAK RETURN STOP CLEAR TO STEP AND OR NOT MOD DIV END Looks an awful lot like the same keywords in any general-purpose programming language. > It's like asking why XML has different syntax and semantics from > Perl. Well, if you read the XSLT spec and then look at an XSLT program, you'll see a lot of verbosity and a lot of general purpose constructs like variables, conditionals, and loops. I haven't done much with XSLT, but I do know you can get it in an infinite loop. That seems pretty general purpose to me. I think the rule is: if you can solve Towers of Hanoi in the language, its general purpose enough. True formatting languages, such as, Scribe do not contain general-purpose constructs, so you couldn't solve the Towers of Hanoi. HTML is another good example (ignoring <script>). > I find it easier to have a little language which is tailored to the task > at hand. Let's separate syntax from semantics. You can use Perl syntax very easily without adopting the semantics for the "little language" constructs. For example, here's a bOP configuration file: { 'Bivio::Ext::DBI' => { database => 'petdb', user => 'petuser', password => 'petpass', connection => 'Bivio::SQL::Connection::Postgres', }, 'Bivio::IO::ClassLoader' => { delegates => { 'Bivio::Agent::TaskId' => 'Bivio::PetShop::Agent::TaskId', 'Bivio::Agent::HTTP::Cookie' => 'Bivio::Delegate::PersistentCookie', 'Bivio::UI::HTML::FormErrors' => 'Bivio::PetShop::UI::FormErrors', 'Bivio::TypeError' => 'Bivio::PetShop::TypeError', 'Bivio::Auth::Support' => 'Bivio::Delegate::SimpleAuthSupport', }, maps => { Model => ['Bivio::PetShop::Model', 'Bivio::Biz::Model'], Type => [ 'Bivio::PetShop::Type', 'Bivio::Type'], HTMLWidget => ['Bivio::PetShop::Widget', 'Bivio::UI::HTML::Widget', 'Bivio::UI::Widget'], Facade => ['Bivio::PetShop::Facade'], Action => ['Bivio::PetShop::Action', 'Bivio::Biz::Action'], TestLanguage => ['Bivio::PetShop::Test'], }, }, 'Bivio::UI::Facade' => { default => 'PetShop', }, 'Bivio::UI::Text' => { http_host => 'petshop.bivio.biz', mail_host => 'bivio.biz', }, }; You could use XML, Lisp, or some other syntax for this. Since the implementation of the configuration parser is in Perl, we use eval as the config parser. When I program in Lisp, I use Lisp syntax for config and eval for the parser again. The syntax is different, but the semantics probably are the same. Perrin Harkins writes: > The thing that worries me about a widget approach is that I would have > the same problem I had with CGI.pm's HTML widgets way back: the > designers can't change the HTML easilly. Getting perl developers out of > the HTML business is my main reason for using templating. I think this is where our experience diverges. I have hired designers before and every time we had to recode the HTML and the JavaScript anyway. My approach is to apply the Once And Only Once principle, which simplifies design changes (discussed more below). Andy Wardley writes: > This is abstraction. Not to be confused with MVC which is one particular > architecture well suited to GUI applications. Blindly applying MVC without > understanding the real issues (abstraction of front/back ends, separation of > concerns, don't repeat yourself, etc.) is likely to build a system which is > highly fragmented. Maintenance becomes harder because everything is split > up into many different pieces and it becomes difficult to see the wood for > the trees. If you apply Once And Only Once extemely, you'll find that MVC is a nice fit for just about any information system. > Despite our best intentions, this web site doesn't neatly fall into > clearly defined chunks of model, application and view. Well, actually, > those parts do split down quite nicely. But then you look at localisation, > for example, and we find there is localisation required in the data backend, > localisation required in the applications and localisation required in the > templates. Thus, localisation is an aspect which cuts across the system. > By building a strict MVC we've fragmented localisation and have to trawl > through hundreds of different files to localise the site. To solve this problem, we added a letter. bOP is MVCF, where F stands for Facade. A Facade allows you to control icons, files, colors, fonts, text, and tasks. You can add other components, but we usually use text as a catch all, e.g. numeric formats. Facades can inherit from other facades and can be cloned from other facades. We use this to support different skins and co-brands. > Another example is that different countries running their localised versions > of this web site will want to change the URLs. Where the english version > uses /product/shirt/red.html, the french version should instead be > /produit/chemise/rouge.html, for example. A Facade is the first thing set in a request. You then know what tasks are available and what URLs map to them. Take a look at: http://petshop.bivio.biz/src?s=Bivio::PetShop::Facade::PetShop All the URLs for the site are contained in this file. Anybody rendering a URL, does it through Bivio::UI::Task. > to model in your system. Nowhere in MVC or any other Design Pattern does > it tell you to define all your URLs in one place in case you ever need to > change them en masse. You have to think of that all by yourself. I don't much buy into Design Patterns (in capitals). We call it MVC so that other people can understand what we are talking about. Unfortunately, the meaning of MVC (especially C) is up to individual (bad ;-) taste. There are some basic design rules. Eliminating redundancy is one of them. Another one is "pre-optimization is the root of all evil". You have to know these things if you're going to build complex systems. > Each of these elements can be "subclassed" to change one particular > aspect of the site. A simple bit of code weaves the 12 different aspects > together into one coherent data model which is the definitive reference > model for everything in the site. I don't see how it is an "Aspect" (in the capital A sense). It seems like a service module, which you had better use to maintain the Once And Only Once principle. It takes discipline to use abstractions properly. What I find is that unless you have designers who understand OAOO, you are going to have the same problems with your aspect infrastructure as with anything else. My experience maintaining Web applications is that it doesn't take very many people if you apply OAOO consistently. We don't have any designers on staff. We hire them to help with a redesign, and then code the ideas ourselves. The implementation of their ideas takes just a few days for the most complex changes. > In five years time, I'll probably be saying "Aspect Oriented Programming > isn't the answer by itself..." :-) I suspect you'll find AOP won't be in heavy use in five years except for debugging features. The magic of OO is hard enough to understand, and AOP is really magical. AOP also doesn't solve very many problems. What's interesting about this discussion to me is that I think the Model piece is the most complex part of bOP. It has taken as a long time to stabilize our FormModel class, for example. The SQL abstraction is limited and not as portable as we would like. Why is there so little discussion of the M in MVC? It's far from a trivial problem. Rob