Wednesday, November 28, 2007

drop the superiority complex

I know, easier said than done, and I fall into this more than I should...

Neither career nor talents grant anyone the authority to degrade everyone else. On a website aimed toward computer technology professionals but on a non-tech topic, I just read an ugly comment stating (in different words) the unlikelihood of a previous commenter having anything valuable to say to "people who think for a living". I'm not surprised or bothered by attacks on basic credibility; disagreement without acrimony would be the real anomaly. What makes me cringe are the haughty assumptions behind the statement:
  1. People who work on computer technology think for a living.
  2. Others, like the statement's victim, don't think for a living.
  3. "Thinking for a living" is a qualification for having worthy opinions to express.
I won't deny that strong aptitude for logical/analytical thought, as used by people to successfully work with computer technology, is rather atypical. I won't deny that deep knowledge in a particular subject domain such as computer technology allows that person to not be as easily confused by casual problems in that domain. I even won't deny that the requisite intellectual capability should be an important factor in decisions for career and education.

However, people who don't fall into those categories can still make coherent, valid points. They may be smart, clever, and accomplished. Their problem-solving skills and ingenuity may be impressive. They may have a wealth of skills for human interaction (which would be foolish not to learn from). The striking creativity they may exhibit is partly why they want PCs at all. "Thinking for a living", as opposed to dumb repetitive labor like ditch-digging, encompasses many options beside working with computer technology.

I know people who either can't do my chosen career, or don't want to. That doesn't make them inferior. After all, the fact that I may not be able to succeed in their careers, or want to, doesn't make me inferior to them...

Friday, November 23, 2007

remembering Beast Wars

By "Beast Wars" I mean the 1996-1999 CGI Transformers series, in which sentient robots transformed into animal forms (as the series continued, it incorporated various vehicle-inspired forms too). I know Beast Wars much better than the original cartoon series, which the summer Transformers movie was based on. After seeing that movie, I was compelled to peruse my Beast Wars DVDs and view some selected episodes. Here's why Beast Wars is still so good:
  • Memorable characters. I'm inclined to think this is common to all Transformers series. Admittedly, those looking for subtlety and balanced characterization should perhaps keep looking. Those who want to be entertained by a rich variety of strongly-defined personalities (so strongly-defined that it borders on overexaggeration) should be satisfied. Of course, defining characters, especially the minor ones, in broad, easily-grasped strokes is the norm for TV shows. Beast Wars had some great ones, and it seems unfair to only list seven: Optimus Primal the just leader, Megatron (different robot, same name) the megalomaniacal manipulator, Tarantalus the insane genius, Black Arachnia the slippery schemer, Rattrap the wisecracking infiltrator, Waspinator the bullied underling, Dinobot the conscientious warrior. The cast of the show changed incredibly often, yet each addition and subtraction made an impact, particularly in the second season.
  • Malevolent aliens. This element of the show is not as corny as it sounds; it acts more as a bubbling undercurrent of anxiety or a convenient plot driver/game-changer than a central focus. An advanced race of alien beings has an intense preexisting interest in the planet of the series' setting, and to them the crash-landed embattled transformers are an intolerable disruption. Yet the sophisticated alien race always acts indirectly through the use of proxy devices of incredible power (only at the very end do they send a single representative). The episodes that actually do revolve around the aliens' actions all have two-word titles starting with the letters "O" and "V". These episodes make up no more than a handful, but include the two episodes which make up the exhilarating cliffhanger finale of the first season.
  • Advanced but limited robots. Some fictional stories strive to be plausible by trying to match, or at least not massacre, the unwritten rules of reality: excessive coincidences can't happen, people can't act without motivation, human heroes and villains can't be entirely good or entirely bad. Other fictional stories are set in a fictional reality with a fictional set of rules, but the story must still be "plausible" to those rules. The Beast Wars "reality" has its own set. Although a transformer can be endlessly repaired from devastating injuries, its true mystical core, known as a spark, must not be lost, else it ceases to be the same animate object. Too much exposure to too much "energon" in its surroundings will cause it to overload and malfunction, but transforming to a beast form nullifies the effect. A transformer in suspended animation as a "protoform" is vulnerable to reprogramming even to the extent of changing allegiances. Transwarp technology operates through space and time. However, the attention to internal consistency is tempered by...
  • A sense of fun. Beast Wars was filled with humor. Robots that can take a beating are ideal for slapstick gags (arguably, the show takes this freedom too far on a few occasions). A few of the characters have bizarre and unique eccentricities, such as speech patterns or personality quirks, which are mined for amusement. For instance, one transformer has been damaged into confusing his consciousness with his ant form, so one of his titles for Megatron is "queen". The transformers' dialog is peppered with high- and lowbrow jokes, mostly at each others' expense. Between Rattrap, Dinobot, Megatron, and Black Arachnia, sarcasm isn't in short supply. When one transformer claims time spent in a secretive relationship with an enemy to be "scout patrol", Rattrap comments, "Find any new positions?"
  • Battles galore. As befits a show whose title contains "wars", almost every episode contains one or more conflicts. The most common type is shootouts, naturally, but the wily transformers on either side employ diverse strategies and tactics to try to gain a decisive advantage: hand-to-hand combat, communication jamming, viruses/"venom", ambushes, stalking, feints, double-crosses, gadgets made by Tarantalus, etc. Surprisingly, Megatron stages a fake "defeat" of his forces in one episode (so a spaceworthy craft will be forged by combining everyone's equipment), and calls a truce that lasts for a few episodes (so he can refocus his attention to the imminent threat from the aliens). It's probably unnecessary to note that these battles are bloodless, even in the minority of battles that happen while in beast form, however beheading and dismembering (and denting) are common results of warfare. In fact, if Waspinator wasn't so often assigned to collect up the pieces for later repair, he would have very few functioning comrades.
  • Connections to the original series. Foremost, that the transformers of this series are descendants of the original transformers, whose battles in the original series are collectively called the Great War. Autobots preceded the basically-decent maximals. Decepticons preceded the basically-aggressive predacons. Intriguingly, during the Beast Wars the maximals and predacons are officially at peace, although the maximals apparently exert greater control than the predacons. Megatron is a rogue who was openly pursuing resources for war, before the maximal research vessel was diverted from its mission to chase Megatron to the planet, ultimately causing each spacecraft to crash. To state more of the connections between Beast Wars and the original series would spoil too much, because over time the writers increasingly intertwined the two series.
  • Vintage CGI. You may think that a CGI TV series that started in 1996 wouldn't be as visually impressive now. You're right. Fortunately, the people who worked on the show were all-too-familiar with the limitations, which means they generally did what they could do well. They avoided (or perhaps cut in editing?) what they couldn't. Apart from a few often-used locations, the "sets" are minimal. The planet has life-forms that aren't usually seen, sometimes giving the impression that the transformers are the only objects in the world that move around. On the other hand, the "shots" are creative and effective in composition, angle, zoom, etc., conveying mood and expressing information such that viewers are neither confused nor bored. The transformers, thanks partly to astute body movements and voice acting, are more emotive than one might guess (really, their faces shouldn't be able to move as much as they do--this is an easy little detail to forget about). Each season's CGI noticeably improved on the previous'. Just as Toy Story (1995) benefited by rendering toys instead of people, Beast Wars rendered robots. Nevertheless, the unconvincing fur and hair textures on the beast forms are best ignored.
  • Not Beast Machines. This is an excellent reason to cover after CGI quality. Beast Machines was the series that followed Beast Wars. It was pretty, angst-y, stark, and altogether dazzling in design. It had a built-in audience of Beast Wars fans...who stopped watching. Beast Machines was just a drag. The comparison to Beast Wars was night and day, even in the literal sense of being much blacker. Beast Machines had the unintentional side effect of illustrating how special Beast Wars was.

Friday, November 16, 2007

has MVC in webapps been over-emphasized?

Most of the prior entries' titles don't contain a question mark. This one does, because I've become torn on this topic. As I understand it, MVC (Model-View-Controller) refers to the interface design principle of preserving code/implementation separation between the data (Model), the appearance or rendering (View), and the processing of user interactions (Controller). MVC in webapps typically means...
  • The Model is the data structures and data processing. Ultimately speaking, the Model consists of the information manipulation which is the prime purpose of the webapp, even if it merely accomplishes database lookup.
  • The View is the components, templates, and formatting code that somehow transforms the Model into Web-standard output to be sent to the client.
  • The Controller processes HTTP requests by running the relevant 'action' code, which interacts with the Model and the View. Part of the Controller is a pre-built framework, since the Controller's tasks, like parsing the URL, are so common from webapp to webapp.
Post-Struts, MVC may seem somewhat obvious. However, speaking as someone who has had the joy of rewriting an old webapp, no more than a jumble of .jsp and some simplistic "beans", to run on a properly-organized MVC framework, the benefit of MVC is palpable. I'm sure the difference shows itself just as strongly in, say, the comparison between Perl CGI scripts written before the Internet bubble and recent Perl modules that use Catalyst. (As an aside, I can't stop myself from remarking that well-written and quite-maintainable Perl does exist; I've seen it.)

Nevertheless, I wonder if the zeal for MVC has misled some people (me included) into the fool's bargain of trading a minor uptick in readability/propriety for a substantial drag in productivity. For instance, consider the many template solutions for implementing the View in JEE. Crossing borders: Web development strategies in dynamically typed languages serves as a minimal overview of some alternative ways. I firmly believe that embedding display-oriented, output-generation code into a template is better than trying to avoid it at all costs through "code-like" tags; markup is a dreadful programming language. Any CFML backers in the audience? I don't mind excellent component tag libraries that save time, but using a "foreach" tag in preference to a foreach statement just seems wonky.

Indeed, it is true that including code inside a template may make it harder to distinguish static from dynamic content, and the burden of switching between mental parsing of HTML and programming language X falls upon the reader. Developers won't mind much, but what about the guy with the Queer Eye for Visual Design, whose job is to make the pages look phat? In my experience, the workflow between graphic artist and web developer is never as easy as everyone wishes. Page templates don't round-trip well, no matter how the template was originally composed in the chosen View technology. A similar phenomenon arises for new output formats for the same data. When one wishes to produce a syndication feed in addition to a display page, the amount of intermingled code will seem like a minor concern relative to the scale of the entire template conversion.

Consider another example of possibly-overdone MVC practices, this time for the Model rather than the View. One Model approach that has grown in popularity is ActiveRecord. Recently my feed showed a kerfuffle over the question of whether or not ActiveRecord smells like OO spirit. The resulting rumble of the echo chamber stemmed more from confusion over definitions than irreconcilable differences, I think; in any case, I hope I grasp the main thrust of the original blog entry, despite the unfortunate choice of using data structures as a metaphor for ActiveRecord objects. Quick summary, with a preemptive apology if I mess this up:
  • In imperative-style programming, a program has a set of data structures of arbitrary complexity and a set of subroutines. The subroutines act on the data structures to get the work done.
  • In object-oriented-style programming, a program has a set of (reusable) objects. Objects are units having data structures and subroutines. As the program runs, objects send messages to get the work done. Objects don't interact or share data except by the messages. The advantage is that now a particular object's implementation can be anything, such as an instance of a descendant class, as long as the messages are still handled.
  • Since ActiveRecord objects represent a database record by freely exposing data, other code in the program can treat the ActiveRecord like an imperative data structure. To quote the blog: "Almost all ActiveRecord derivatives export the database columns through accessors and mutators. Indeed, the Active Record is meant to be used like a data structure." You know how people sometimes complain about objects having public "getters" and "setters" even when the getters/setters aren't strictly necessary for the object to fulfill its responsibility? Roughly the same complaint here.
  • The blog entry ends by reiterating that ActiveRecord is still a handy technique, as long as its messy lack of information hiding (leaky encapsulation) is isolated from other code to 1) avoid the creation of brittle dependencies on the associated table's schema, and 2) avoid the database design dictating the application design.
In my opinion, the real debate here is not if ActiveRecord objects break encapsulation and thereby aren't shining examples of OO (they do, so they aren't), but the degree to which anyone should care in any particular case. Rigidly-followed MVC, which aims to divide Model from View, would tend to encourage interfaces that prevent the Model data source, i.e. a database or remote service or file, from affecting the View. The result is layers of abstraction.

In contrast, I'm steadily less convinced of the need for doing that. The number of times I've 1) completely swapped out the Model data source, or 2) significantly tweaked the Model without also somehow exposing that tweak in the View, is minuscule. Similarly, the majority of webapps I work on are almost all View, anyway. Therefore, as long as the View is separate from the Model, meaning no program entity executing both Model and View responsibilities, inserting an abstraction or indirection layer between the two probably is unnecessary extra work and complexity. When the coupling chiefly consists of feeding a dynamic data structure, like a list of hashes of Objects, into the View, the weakness of the contract implies that the Model could change in numerous ways without breaking the call--the parameter is its own abstraction layer. Of course, that flexibility comes at the cost of the View needing to "know" more about its argument to successfully use it. That information has in effect shifted from the call to the body of the call.

Lastly, after retooling in ASP.Net, the importance of a separate Controller has also decreased for me. I can appreciate the necessity of subtler URL-to-code mapping, and the capability to configure it on the application level in addition to the web server level. Yet the concept of each dynamic server page consisting of a page template and an event-driven code-behind class is breathtakingly simple and potent as a unifying principle. Moreover, the very loose MVC enforcement in ASP.Net (although explicit MVC is coming) is counterbalanced by the strong focus on components. To be reusable across Views, components must be not tied too closely to a specific Model or Controller. The Controller code for handling a post-back or other events is assigned to the relevant individual components as delegates. The, the Model may be the weak point, until the .Net Entity Framework comes around. As with any other webapp framework, developers should have the discipline to separate out the bulk of the nitty-gritty information processing from the page when it makes sense--fortunately, if that code is to be reused in multiple pages, the awkwardness acts as a nudge.

The practical upshot is to use MVC to separate the concerns of the webapp, while ensuring that separation is proportionate to the gain.

Wednesday, November 14, 2007

another case of unintentionally funny

I've stumbled on another unintentional funny from somewhere on the Web. This is a concluding analysis after converting a function to be truly tail-recursive:
Comparing those two the first one increases the stack to a point until it starts to pop the stack. The tail recursive version does not use the stack to keep a “memory” what it has still to do, but calculates the result imediatly. Comparing the source though, in my view the tail recursive version takes all beaty out of the recursive implementation. It nearly looks iterative.

Hmm...tail recursion making a recursive function "nearly look" iterative. Go figure.

(What makes this funny, of course, is the fact that in situations without mutable variables, tail-recursive functions are the way to achieve iteration. And converting recursion into iteration through an explicit stack is another well-known technique...)

Tuesday, November 06, 2007

DIY expletives

I was about to apologize for writing something self-indulgent, but then I remembered this is a blog. Moving along...

I've fallen into the habit of saying DIY (do-it-yourself) expletives. Making up expletives isn't difficult. With practice, driven by the frustrations of everyday life, the original sound combinations just flow off the lips like, uh, spittle. Observe these helpful tips, which are more guidelines than rules:
  • Keep each individual "word" short. Expletives beyond two syllables can be unwieldy and unsatisfying. The goal is acting as an embodiment of anger and rage--emotions of violent aggression.
  • The limitation on the length and complexity of each word doesn't apply to the "sentence" as a whole. Speaking multiple words in rapid succession is great for overall effect, even more so in situations when loudness is prohibited.
  • To start a "word", I like to use the consonants k, t, d, m, s. To a lesser degree I also sprinkle in usage of p, h, b, n, g (hard or soft pronunciation, but more often hard), and f. More complicated consonantal sounds can be handy for adding flavor, such as "st","ch", "sp". By all means include gutturals, if you can without hurting yourself or working too hard.
  • I like to use the vowel sounds "ah", "oo", "oh". Other vowel sounds can help to break up monotony, perhaps in the middle or end of a statement, but in any case shouldn't draw attention too far away from the consonants. Following up a vowel sound with another vowel sound ("oo-ee" for example) is probably not conducive to maintaining peppy rhythm and tempo.
  • "Words" with multiple syllables (not more than two or three per word, recall!) are simply constructed by combining monosyllabic words.
  • Emphasize whichever syllable you like. Variety is what I prefer.
  • The last tip is counterintuitive: don't let the preceding tips slow you down or stop you from creating a word that feels right. Practice and developing the habit are more important.
Some quick examples:
  • "Mah-TOO-choh!"
  • "Fah soo poh NOOST!"
  • "KOH-dahb hoom BAYSH-tah!"
I'm not absolutely sure what led me to start muttering violent gibberish, but I suspect my Star Wars and Firefly DVDs deserve some of the blame.