David Cantrell wrote: > > On Wed, Oct 30, 2002 at 01:09:51PM +0000, Tim Sweetman wrote: > > David Cantrell wrote: > > > On Wed, Oct 30, 2002 at 10:26:41AM +0000, Andy Wardley wrote: > > > > PHP is, or should be, a quick hack language. The fundamental feature > > > > of embedding application code directly in presentation markup is the > > > > biggest no-no there is. It leads to a poor (or non-existant) separation > > > > of concerns, typified by spaghetti code programs that are all but impossible > > > > to read, understand, extend and maintain. > > > Unreadable spaghetti is a function of the programmer, not (generally) of > > > the language. > > <reductio ad="absurdum"> > > ... so we might as well all program in COBOL. > > </reductio> > > There are, of course, other reasons for rejecting languages. Some of which > apply to PHP. Some of which apply to perl, TT, COBOL and any other flavour > of the week. > > Remember, all software sucks*. But to say that "embedding application code > in markup leads to a poor (or non-existant) seperation of concerned, > typified by spaghetti code" is to talk bollocks. Yes, there are *some* > languages which might be said to encourage spaghetti. Assemblers do, as do > many dialects of BASIC. But I see nothing inherent in embedding code in > markup that would encourage it**. Therefore, when you *do* come across such > 'orribleness, and especially if it's in a language where spaghetti can be > easily avoided then the programmer is most definitely to blame. > > * - and absolutism in software sucks absolutely? > ** - depending on the lnaguage, of course. Embedded perl is fine, embedded > Sparc assembler would suck.
Languages (amongst other things) should make it easy to do the right thing. For spaghetti avoidance, "the right thing" tends to constitute nonspaghetti; separating stuff out; abstraction layers; passing the right data, and just the right data, to another part of the system through a comprehensible interface. # example with HTML::Template (not tried, so for example only) $template->param($foo->RetrieveSomeDBStuff()); $template->param("my_name_is", $slimshady->random_nym); print $template->output; # example using trivial-templates-by-variable-substitution my %data = $foo->RetrieveSomeDBStuff(); my $name = $slimshady->random_nym; print " My name is (!) my name is (!) my name is (!) $name Average expletives per song: $data{rude_words_per_song} Disturbed teenage fans: $data{disturbed_teenage_fans} ..."; Firstly: "Trivial templates by variable substitution" is not an intuitive thing to do. I'm doing it here, because DC did it earlier, because in a sense it removes content from presentation. However, a bunch of variables isn't something that you can (without heavy wizardry) simply pass somewhere else. You could pass each variable individually: my ($width, $height, $iq, $motherfuckers_per_second, $foo, $bar, $blarch) = $slimshady->vital_stats; ... but that's a good way to get confused, it wrong, or RSI. Secondly: Except for trivial amounts of data, slinging data around in hashes, hash references, list references etc is good for this sort of application. You can then say things like print Dumper(\%page_data) or $template->param(%page_data) "Trivial templates by variable substitution" does not make this particularly easy. Templating systems (well, TT and H::T) _do_. "TtbVS" makes using globals for everything _very_ easy. Use them here, use them there. Look, the data transfers over, simple... Templating systems work well with interfaces that pass data. Interpolation works well with everything sitting in variables. The latter is more conducive to spaghetti code. Therefore, templating systems (used like this) discourage spaghetti code. (Natch, this relies on this kind of structure suiting your problem, and your programmers - not to mention relying on spaghetti code actually being a bad solution for this problem and these programmers, which seems dangerous to assume. FWIW, _entirely_ unidirectional data flow from code to template is often difficult or stupid. Should I throw all the scalar data on slim shady that I have into the template, in case it turns out to be needed? Should I list fields in the template somewhere? Should I allow the template to go SlimShady.name?) Separating templates out also means it's easier to change appearance without changing functionality. It reduces friction between specialised graphic designers and coders. It keeps dreamweaver and emacs relatively happy. It makes it easier to grep your source without running into fragments of HTML-or-whatever. All of which are good things in general, rather than spaghetti avoidance features in particular, and which go away if you start having Perl-like bits in your templates. > I fail to see the point of [magimix] analogy. If you disagree with me, say > so, and tell us why you think I'm talking arse. OK. You maintain that: > *any* templating > language is code embedded in presentation Loosely speaking, when we talk about code, we mean stuff that can do some of these: 1. implement an arbitrary algorithm 2. loop for an arbitrary period. Perhaps forever. Perhaps not. 3. perhaps do IO, perhaps system calls. 4. perhaps invoke your methods elsewhere within your system. The situation is somewhat blurred by data like PostScript, which behaves somewhat like a language. A language that does things in a sandbox, also, can be treated more cavalierly. Data will just _sit_ there. If I have _code_ in my templates, I might have to worry about whether its logic has been tested. Does it have randomness in it? Has that been thought of? Does it call my methods? Is there something in one of my templates which calls the ->die_motherfucker() method, because I'm about to deimplement that in Slim::Shady? Do I have millenium, or indeed January, bugs? H::T's constructs do not, unless I'm missing some key ones, constitute "code" by these, or other similar, criteria. A good language makes it easy to do what you're trying to do. OO languages make certain kinds of useful encapsulation easy; this makes spaghetti code less desirable, therefore less likely to happen. Making spaghetti code easy, making structure difficult, and taking bloody ages to write and debug are all bad features in a language. Cheers Tim