Stories
Slash Boxes
Comments
NOTE: use Perl; is on undef hiatus. You can read content, but you can't post it. More info will be forthcoming forthcomingly.

All the Perl that's Practical to Extract and Report

use Perl Log In

Log In

[ Create a new account ]

ferreira (5993)

ferreira
  (email not shown publicly)
http://www.ferreira.triang.net/

Just another Brazilian Perl hacker.

Journal of ferreira (5993)

Tuesday October 24, 2006
12:29 PM

Fake Programmers

[ #31410 ]

I am convincing myself that fake programmers are not lazy. I think it applies to everyone that codes a piece of code such as:

  $body =~ s/%FIRSTNAME%/$firstname/;
  $body =~ s/%LASTNAME%/$lastname/;
  $body =~ s/%RECEPIENT%/$recipient/;
  $body =~ s/%VERB%/$verb/;
  $body =~ s/%PRODUCT%/$product/;

or

  int foo = rs.getInt("foo");
  String bar = rs.getString("bar");
  Date xyz = rs.getDate("xyz");

and do it over and over again. Abstractions like

  # $body = process_t($templ, \%fields);
  sub process_t {
      # generic code which does
      #    $body = $templ
      #    $body =~ s/%\U$fields{$k}%/$fields{$k}/;
      #    ...
  }

  # Map row = fetchRow( ResultSet rs );
  Map fetchRow( ResultSet rs ) {
      # generic code which fills
      #    a map with rs.getObject(col)
      # and returns it
  }

impose themselves to me. They could be much longer that one round of "brute force" programming, but once written and tested, they will not let you down and, after a couple of uses, they will be shorter, faster and more reliable. In the end, probably fake programers are not proud or impatient as well.

The Fine Print: The following comments are owned by whoever posted them. We are not responsible for them in any way.
 Full
 Abbreviated
 Hidden
More | Login | Reply
Loading... please wait.
  • You've illustrated one negative side of abstractions: the more you abstract, the easier it is to have tiny mistakes like the one in your regex example.

    Abstracted functions need better testing, and that can take longer. Some non-abstracting programmers write things in full *because* they are lazy.
    • I agree with you that abstraction is not everybody's choice. But they are useful: the mistake in the abstraction would soon be revealed and fixed and then new bugs can be found, but not the same. On contrary, one can keep making mistakes with cut-and-paste and editing and fixing one would not help with the others. Writing such things in full seem to me not real laziness.

      "Abstracted functions need better testing, and that can take longer." Yep, that's what I meant with "could be much longer that one round

    • Indirection is not Abstraction [zedshaw.com]. Let’s stamp out this meme.

      • Thank you so much for that link.

        The article helped convince me that the difference is that abstraction is designed to reduce complexity, whereas indirection is sometimes a neccessary way to implement abstraction. Indirection almost inherently involves *more* complexity, which is the reason that it is fundamentally different.
        • indirection is sometimes a neccessary way to implement abstraction.

          Argh! :-) No, that’s exactly what the rant is arguing against. Indirection is indirection. Indirection is not abstraction. Indirection trades simplicity for flexibility – it always increases complexity. Abstraction is the opposite direction: trading flexibility for simplicity.

          F.ex., Perl (largely) abstracts memory management away from the programmer.

          • [indirection] always increases complexity.

            Agreed, but abstraction may be combined with indirection and relieve some people from the additional complexity. Just to illustrate, I think DBI works a bit by indirection when it gives behavior for free to the database drivers (for example, fetchall_* methods) and when it delegates the specific bits to the drivers. It is sorta of abstract class and template methods. But that's happily transparent to the user. The complexity is there but relegated to the people

            • Yes. Zed makes this point in his article: you can sometimes make an interface both indirect as well as abstract. It just doesn’t usually work well, in which case you can (and, depending on the task, arguably should) wrap an abstract interface around the indirect one to reduce (some of the) undesirable complexity while retaining (some of the) the desirable flexibility.

              In the case of DBI, doing both works well because it’s inherently a factory-style API: you specify connection parameters to crea

          • What if the indirection is only an implementation detail?

            Let's say we have a complex and messy interface to something. If we wish to wrap an abstract interface around it, our implementation gluing the abstract interface to the more complex one almost neccessarily includes indirection. The trick is not exposing the indirection to the users of the abstract interface.

            I am not saying that indirection and abstraction are in any way the same thing. I am saying that they are often conflated because people use one
            • That does make more sense.

              I don’t know if I agree with that explanation for the conflation, though. Perl-land isn’t that big on deep class hierarchies and indirection in interfaces anyway, and your claim that indirection is usually employed as a means on a quest for abstraction may well hold.

              In contrast, indirection is almost a fetish in Java circles, where it’s rarely coupled with an abstraction. That’s what missing dynamism in the language does to you – forces you to rein

  • I agree with Juerd, there are disadvantages of abstractions, although I have other reasons I sometimes don't abstract. And that's flexibility.

    With the given code, it's easy to change one of cases, for instance I want to change it to:

        s/%FIRSTNAME%/$firstname/;
        s/%LASTNAME%|%CHRISTIANNAME%/$lastname/;
        s/%RECEPIENT%/$recipient/;
        s/%VERB%/$verb/i;
        s/%PRODUCT%/$product/;

    Not impossible to do if you have abstracted it out, but harder, and easier

    • The extension you proposed to the example will surely make harder the abstracted code. But I may propose other extensions that could be harder if you have redundant code. For example, suppose you are generating HTML and so you want to escape every interpolated value. An only change in process_t would do.

        $body =~ /%\U$k%/html_escape $fields{value}/e;

      And many many changes in the original code. After you cutted-and-pasted, it becomes messier to apply significant changes to the copied bits to keep the

  • Usually laziness is making a particular tradeoff to optimize work in one dimention, often by complicating work in another dimension. Assuming the goal is accomplished, there are more likely simply design tradeoffs that look like laziness if you try to measure it along a particular dimension.