Beefy Boxes and Bandwidth Generously Provided by pair Networks
P is for Practical
 
PerlMonks  

Re: Would you use 'goto' here?

by clintp (Curate)
on Dec 06, 2001 at 06:17 UTC ( [id://129833]=note: print w/replies, xml ) Need Help??


in reply to Would you use 'goto' here?

Personally, I have no problems with it. (As a matter of fact, I posted something in the Snippets section earlier today that used the "magical" goto.)

The overall taboo associated with an unconditional jump instruction (goto) is just plain silly. If a tool is available, by all means use it if it does the job well. Sure with TMTOWTDI means that we probably don't need goto in Perl. We could also get away without grep, map, foreach, my, local, readline, for, and hashes if those suddenly became taboo also.

As for the criticism that a later programmer might not understand the code: limiting yourself to widely-known and well-used syntax is the antithesis of Perl programming and I want no part of it. goto is well documented, and it quite plainly states what the goto & statement does. Just because this isn't what OTHER languages do with goto isn't a reason to avoid it. Other languages might use "write" as the standard output statement -- perl doesn't. <>'s are exclusively comparison operators in some other languages -- that doesn't mean we should avoid them in Perl.

Replies are listed 'Best First'.
Re: Re: Would you use 'goto' here?
by perrin (Chancellor) on Dec 06, 2001 at 11:53 UTC
    As for the criticism that a later programmer might not understand the code: limiting yourself to widely-known and well-used syntax is the antithesis of Perl programming and I want no part of it.

    But using obscure syntax when obvious and well-known syntax (a subroutine call) exists is the antithesis of maintainable code. There are so many ways to do things in Perl that you have to choose what you want to optimize for. Ovid says he wants to optimize for clarity and maintainability. That sometimes means doing things in a simpler way and avoiding cool but obscure (though documented) tricks like this.

      No. No. NO. NO. NO!

      A language has a certain syntax. Knowing that syntax is the responsability of the person who says "I know language XXX". It is not my responsability to make sure that I dumb down my code for your inability or unwillingness to keep your end of the bargain!

      I'm currently in a shop where use of $_, map, and grep is nominally discouraged. Why? Because others might not understand the code later down the line. (Yet, this place uses the most complex regexes I've ever seen, making me go to my book over and over.)

      If I was in C, would you discourage bit-masking? What about pointer arithmetic? Yes, they can cause problems, but they're a feature, not an 'oops'!

      Let me take another tack. Let's say you told me "I can read English". So, I write you a letter in English. No problems, right? Well, you start complaining about my use of the words with more than 6 letters. They're too difficult. You've never seen them. You don't like them. (And, yes, I've received this complaint before!) Should I not use a standard part of the language you have said you speak solely because you don't want to make good your assertion?!?

      I didn't think so.

      ------
      We are the carpenters and bricklayers of the Information Age.

      Don't go borrowing trouble. For programmers, this means Worry only about what you need to implement.

        Since I'm willing to bet your paycheck that I have a few more years in the software industry that you, allow me to point something out:

        A software shop does not want to have to hire the top 5% of the skill pool just to do code base maintainence when you leave. You also don't probably don't want to spend the rest of your work career at that company maintaining a project you wrote 5 years ago.

        To this end, it's well and fine to use out-of-idiom methods when absolutely necessary, but not just because you can, or because they're cute. An *experienced* programmer recognizes when to write for efficiency (and saving .0001 CPU seconds off a job that runs once a week hardly qualifies), and when to write for maintainability.

        Some languages support the ability to write obfusicated code more than others. Perl outshines C in this respect, since Perl is a richer and more complex language. If the next guy that comes along to make some changes to your code has to track you down across the country to ask about how something what was done, that doesn't necessarily make him stupid. It may make him less skilled, but it's also a reflection on your inability to write for maintainability.

        Try getting involved in code reviews. If you have 5 people on the team, odds are they will not all have the same skill levels. If 2 or more agree that your code is obtuse, perhaps you should consider your style.

        The inability to write for maintainability costs a company money. You may have saved 10 minutes thinking about how to do it, but if it took 3 days for someone else to figure out it's supposed to work, you've burdened the company with your 'coolness'.

        Let me take another tack. Let's say you told me "I can read English". So, I write you a letter in English. No problems, right? Well, you start complaining about my use of the words with more than 6 letters. They're too difficult. You've never seen them. You don't like them. (And, yes, I've received this complaint before!) Should I not use a standard part of the language you have said you speak solely because you don't want to make good your assertion?!?

        This is a bad assertion, by the way. There are plenty of phrases I can write that will send you to a dictionary to figure out what I mean. Unless your goal is to complicate communication, there's no point in using obscure words. If you're trying to be understood, you don't use words that only see print when a new dictionary is released.

        A whole armamentarium of devices to create an illusion of real life -- Kenneth Rexroth

        --Chris

        e-mail jcwren

        Let me point to the discussion at Operator Precedence and specifically my comments therein. I'm all for using the best tool for the job, but if you are writing code that others are going to see, you need to try to keep it as reasonably understandable as possible. What's 'reasonably'? Well, that definition's going to vary, particularly with perl.

        In the Big 3 languages, C, C++, and Java, these are typically taught to CS students, and there's a few key textbooks that are used for this; in addition, these languages don't offer the richness that Perl or other scripting languages have in terms of builtin functions, syntax, etc. Thus, if I was in a shop that used the Big 3, I'd know where to expect the 'reasonably understood' level to be at. As an example, I'd expect someone to understand a massively deep inheritence structure in C++; however, I would expect that someone might have trouble with C++ templates, and would effort myself to write more comments in that area.

        Perl, since it doesn't have a standard teaching path, is much different. (While we believe that at least one school does teach it, based on the massive duplication of the finite automata question, this is only one of thousands). Based on what I read on NGs, here, and elsewhere, the most common learning path of perl is what is in 'Learning Perl', and possibly what is out of 'Programming Perl'. I don't have the former book in front of me, but I don't recall a lot of advanced topics coming up in it, things like map and grep, for example; instead, my reading of the book was more focused on doing direct input and output from a script (actually using perl as the expanded acronym implies). Thus, if we assume a perl shop has, at *best* that common knowledge from 'Learning Perl', then we are drastically restricting what we can do with the language, unfortunately. This may be one reason why dc's shop highly discourages these idioms.

        Now, if I were in charge of such a shop, would I stop at that point? Probably not; sure, I know those coming in would be at a disadvantage, but that's why you train employees. Teach them the advanced features of perl (IF NEEDED!!) by either an in-house trainer, or someone from outside. Get them immersed in existing code that may use the advanced features. This way, you don't have your hands tied by limiting yourself to a subset of features.

        Of course, I would still discourage the use of advanced features that are not intuitively obvious. Map and grep , for example, are very simple to understand once you know they are there and seen them in use a few times. But Ovid's non-standard goto example, or using some of the code that pops up from Golf solutions, would be questionable because of it's readibility. If someone did determine that they just had to use an advanced feature to get the job done right, I wouldn't discourage it, but I would strongly encourage excessive commenting of the code around it. For example, in Ovid's case, if a comment such as 'In this form of goto (to a sub reference), the calling stack immediately switches to that code' preceded the questionable line, then I'd be more comfortable with that code (though as others have pointed out, the programming logic can be replaced by other code bits that are much more readable).

        So to get back to the point at hand, I would never encourage dumbing down code to a very basic level; I'd determine where a reasonable level would be, and try to take all advantages of that level. However, commentings would be very important here, and I would strive to make my programs as readable as possible without the comments in the first place. The right combination of readable code and commenting will make even the most complex pieces of perl code understandable by all levels of programmers.

        -----------------------------------------------------
        Dr. Michael K. Neylon - mneylon-pm@masemware.com || "You've left the lens cap of your mind on again, Pinky" - The Brain
        "I can see my house from here!"
        It's not what you know, but knowing how to find it if you don't know that's important

        I'm currently in a shop where use of $_, map, and grep is nominally discouraged. Why? Because others might not understand the code later down the line.

        Those are often-abused features of Perl. I've seen crazy things done with map when much simpler stuff would have worked. I would definitely encourage people to think twice before choosing them, but I wouldn't ban them. Sometimes they are the best thing to use.

        A lot of this comes down to knowing what the shared level of knowledge you can expect from your team is. When I worked at eToys, we wanted to use mod_perl and OO code extensively for a new version of our system. To that end, I taught a brief class on mod_perl fundamentals, and we hired merlyn and TheDamian to help our team with OO and some of the tricky but useful Perl idioms. We gave everyone a copy of the Effective Perl and OO Perl books. That gave us a higher baseline than most Perl development groups, and freed us to use some trickier stuff.

        Even so, any time I used something a bit unusual like a hash slice, I would document it carefully. Sure, you can look it up, but you have to spot it in the first place and you have to have some idea of what you're looking up to know where to find it.

        Your English analogy is actually pretty good because I think it makes my point. When writing English for fun or for an audience of serious readers, you can use some wild and obtuse stuff. People have often "hacked" English for artistic purposes and created great things. However, if you were writing for a newspaper you would be expected to use a subset of English that supports the business goal of the newspaper, i.e. being clear and easy to understand for the average reader. Newspapers have extensive style guides on how you should use English in their papers. Perl shops tend to be less prescriptive about it and assume that you will exercise some common sense. Since most places have bug fixes and enhancements as major goals for their projects, writing code that the available pool of programmers can maintain is an implicit rule.

        Here's my take on this:

        I'm currently filling the role of quasi-lead for a Perl-powered web application. Due to the nature of our customers this web application is frequently in heavy development and we often find ourselves developing faster than we would like.

        It is my _preference_ that our team be explicit and as clear as possible about the way they are accomplishing tasks. This practice extends beyond the way we solve problems in our Perl-codebase. I typically encourage the guys to solve as they see fit but I am constantly reminding them to "keep it simple."

        $_, map and grep are among some of the cool features of Perl. They have their place and are often useful in reducing the number of lines of code required to complete a particular task (among other things). The problem with them is that they are _not_, in my experience, easy to understand. There are often much more simple ways of expressing concepts and those that are clearer are less likely to cause confusion.

        And productivity, in my current job (and frankly, in most of my previous jobs), is closely linked with effective communication. When I code I am more concerned with readability from the perspective of others than I am about how quickly I can express myself or how Perlish I can be. I have managed to learn that viewing a problem from the perspective of another person can often grant me a better understanding of the problem domain and solution.

        Cheers,

        Matt

      I couldn't possibly disagree more.

      Just so everyone understands that you're not just afraid of goto, let's take a look at a few pieces of syntax:

      • while(<FH>) assignment to $_
      • { local $/; $a=<SLURP>; }
      • sub cntr { my $r=0; return sub { $r++ }; }
      • $a="aaaa"; $a++
      • map {...} sort {...} map {... }
      • grep { s/foo/bar/ } @arr
      • *copy=\$original;
      Are these pieces of code obscure (though documented) tricks? Arguably, to someone new to Perl they're all tricks. Most of these can't be attempted (in their current form) in C, Shell, Java, Pascal, REXX, FORTRAN, or Basic without throwing a lot more code at the problem. So a programmer with 25 years of fairly broad experience could claim that these are all witchcraft of the worst sort and insist you avoid them. (All of these have an alternate "workaround" in Perl that could be used for "clarity.")

      But, in fact, they're all fairly idiomatic and common Perl. One programmer's "trick" is another programmer's tool. When does a "trick" become an idiom?

      I'd use any of them in a heartbeat if it was the appropriate tool for the job. I would hope you would too. Coding for clarity is one thing, wearing shackles is quite another. If the syntax is there, documented, and not deprecated -- use it.

      Those that fear and are unable to deal with large languages should stick to C.

        I figured it would be a controversial comment, but since this is one of the most fundamental issues when using Perl I wanted to bring it up and see what others think.

        To me the most interesting thing you say here is this: But, in fact, they're all fairly idiomatic and common Perl.

        That is the key difference. Common idioms that are widely recommended in books, on mailing lists, and sites like this one, are fair game in my opinion. If someone doesn't know how to slurp a file, he should learn. On the other hand, goto is not common or recommended (though not deprecated in this form). The comment from tilly that inspired this thread basically said that he could imagine a situation where he might want to use goto, but it had never happened and he didn't think it ever would.

        Remember, the only advantage that goto has in this situation is that it replaces the current sub in the call stack so that you can't tell it wasn't called directly in the first place. I consider this a disadvantage in most circumstances since it will make things more confusing to debug.


        Just as a note,

        It seems to me that the grep example shouldn't be used anyway, because you're modifying $_ en passent. This can lead to all kinds of problems, not the least of which is a lower level programmer misunderstanding why this is bad.

        Doing that in two lines seems to be a bit better, if more verbose:

        s/foo/bar foreach @arr; return grep { /bar/ } @arr;
        jynx

        update: excuse my slow thinking

        i first thought that clintp was demonstrating canonical use of grep, which is documented, but difficult to understand at first (akin to canonical use of map). i feel sheepish. It now behooves me to think that he was in fact directing his snippet at what i was trying to point out: a subtle feature that is documented and so able to be understood (and used in production code).

        i feel there is still a point to be made however. While most of his other code snippets could be discovered plainly from documentation, this example is a bit more insidious. The student learning grep will probably not "get" what is being said in the documentation about this feature (i know i didn't the first few times through it). More to the point, while clintp's example is fine, a learning student would probably not notice the pitfall, since it doesn't directly follow; thinking they will is, sadly, overestimating their intelligence. Then later they could easily try altering $_ and get bizarre results.

        In the end, it seems better to avoid this usage in code for maintainability, whereas the other examples seem perfectly valid. Maybe it's just me...

Re: Re: Would you use 'goto' here?
by demerphq (Chancellor) on Dec 06, 2001 at 15:38 UTC
    Just because this isn't what OTHER languages do with goto isn't a reason to avoid it.

    Bravo! My thoughts exactly!

    Yves / DeMerphq
    --
    This space for rent.

Re (tilly) 2: Would you use 'goto' here?
by tilly (Archbishop) on Dec 06, 2001 at 20:59 UTC
    IMNSHO throwing around the word silly as a way of saying, don't listen to them is stupid.

    There is a reason for the taboo. And anyone who cannot accurately state, in their own words, on demand, either succinctly or verbosely as requested, what the reasons are for the taboo has no business using the construct.

    I am not exaggerating.

    Please follow the link that Ovid had to his question, and my answer, about when goto is justified. As you will see there, my position about goto is not religious. There are cases where it is justified and justifiable. However without a complete understanding of why the construct is problematic you will simply not have the tools to recognize when its utility transcends the issues associated.

    This is one case where, while I like having people really understand what is going on, I would prefer that people avoid goto for cargo-cult reasons rather than trying to think up reasons to use it.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://129833]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others surveying the Monastery: (4)
As of 2024-04-19 04:43 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found