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


Reply via email to