Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl-Sensitive Sunglasses
 
PerlMonks  

Re^4: Programming *is* much more than "just writing code".

by BrowserUk (Patriarch)
on May 11, 2007 at 18:39 UTC ( [id://614990]=note: print w/replies, xml ) Need Help??


in reply to Re^3: Programming *is* much more than "just writing code".
in thread Programming *is* much more than "just writing code".

But I gather that this is the reason you mentioned the "first six paragraphs", because you were explicitly ignoring everything else.

Yes. That is a fair assessment. As with most of the other contrary points made in the thread, including your own, every point MadraghRua made in his last two paragraphs was addressed in my original post. I saw little purpose in further reiterating my counter arguments to those points, as I saw nothing in those last two paragraphs that in anyway diminished those counter arguments.

His premise is, that when some relatively expert coder constructs a piece of code, he should make an attempt to review the code he writes in the light of the possibility that the next guy that will view that code may not be as expert in the language being used. He, (the expert original coder), should then add comment cards to explain anything that he feels that the next guy might not understand.

I addressed this premise in my OP. Nothing in those last two paragraphs forms a counter argument, so there is nothing there to change my mind, and nothing that I can address other than through repetition.

However, since you seem bent on continuing the discussion, I'll have a go at reformulating the arguments in a way that I hope will lead you, and anyone else still interested enough to go through the exercise, to either produce cogent argument against my point of view, or to accept it.

What assumption should I make about the level of expertise of the guy that might follow me?

  • Will he understand about context?
  • Will he know when to use $array[ ... ] and when to use @array[ ... ]?
  • Will he consider map too complex?
  • Does he understand the concept of recursion?
  • Will he understand
    if( !$cond1 && !$cond2 && !$cond3 ) { doit() )
    perfectly, but somehow be flummoxed completely by
    doit() unless $cond1 or $cond2 or $cond3;
    ?
  • Will he consider regex some kind of scarey magic?
  • While he consider this clear and maintainable?
    #! perl use strict; my %data; while( my $line = <DATA> ) { chomp $line; my $position = index( $line, ':', ); my $key = substr( $line, 0, $position ); my $value = substr( $line, $position + 1 ); $data{ $key } = $value; } my @unsorted_keys = keys %data; my @sorted_keys = sort @unsorted_keys; for( my $index = 0; $index <= ( scalar( @sorted_keys ) - 1 ); $index++ + ) { my $key = $sorted_keys[ $index ]; my $value = $data{ $key }; print "$key : $value\n"; } __DATA__ a:1 b:2 c:3 d:4 e:5
  • Will he consider this, unmaintainable, deliberately obfuscated, arrogant, 'show off' code:
    #! perl -slw use strict; my %data = map{ /^(.+):(.+)$/; $1 => $2 } <DATA>; print "$_ : $data{ $_ }" for sort keys %data; __DATA__ a:1 b:2 c:3 d:4 e:5

    An interesting exercise for anyone convinced that comments help is to try and add comments to the above two snippets. If you feel like doing that and then posting the commented code, please do, because I will have great fun :)

Even if it was possible, and desirable, to agree some 'base level' of understanding of Perl syntax below which it was not necessary to explain in comments; it would never be possible to reach a universal agreement at where that barrier should be set.

And even if that barrier existed, requiring each programmer to come up with accurate, meaningful and useful comments to explain any construct or idiom that breaches that barrier, is simply ludicrous.


The answer to the problem of encountering code you do not understand, is to educate yourself.

Look it up or ask someone!

Take 5 minutes now to experiment with the construct until you do understand it, and then you will understand it forever. Avoiding it forever, because it confused you the first time you encountered it is silly.


Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.

Replies are listed 'Best First'.
Re^5: Programming *is* much more than "just writing code".
by doom (Deacon) on May 12, 2007 at 18:45 UTC

    The answer to the problem of encountering code you do not understand, is to educate yourself.

    Look it up or ask someone!

    A code example, including some comments I have used:

    # add attributes to object my @fields = (keys %{ $attributes }); @{ $self }{ @fields } = @{ $attributes }{ @fields }; # hash slice

    The first comment gives someone skimming the code a hint about what's happening here (that they can figure it out by close study may be likely, but making them engage in that study just to find out if this is the part of code they care about is at best inconsiderate).

    The second comment, "hash slice", is the sort of thing a beginning programmer would need in order to have a hope of looking up the technique in use.

    The fact that the level of knowledge of the audience is uncertain does not obviate the need to address the audience at a certain level. Would you argue against explanatory subroutine and variable names because a really good programmer doesn't need those hints?

      I've been thinking about those comments overnight, and I don't have any particular objection to them. Certainly not the second one anyway. I think that one could easily fall under the auspices of my statement from the OP:

      ... used sparingly where they clarify things that the notation ... fails to convey.

      That said, context is everything, and your snippet in isolation of the code (and further commenting) around it, makes it hard to decide if these are really warrented or not. For example, here is a possible context for your snippet:

      package Junk1; sub new { my( $class, $attributes ) = @_; my $self = bless {}, $class; # add attributes to object my @fields = (keys %{ $attributes }); @{ $self }{ @fields } = @{ $attributes }{ @fields }; # hash sli +ce return $self; } package main; my $obj1 = Junk1->new( { a=>1 , b=>2, c=>3 } );

      And here are 4 more that, in the absence of further information, achieve the same thing. And all of which I think are preferable, and clearer to a lesser or greater extent

      This one avoids the hash slice, and the (potentially confusing) intermediate array (called @fields) to hold the names of the keys, that are referred to in the comment as attributes. (Not to be confused attributes of course, which are something quite different!)

      And by using %{ $ref } on both sides of the assigment, it makes it clear, even to a beginnner, that we are doing something with hashes:

      package Junk2; sub new { my( $class, $attributes ) = @_; my $self = bless {}, $class; %{ $self } = %{ $attributes }; return $self; } package main; my $obj2 = Junk2->new( { a=>1 , b=>2, c=>3 } );

      This takes it a step further and does away with the separate assignment completely. Of course, that may or may not be possible depending upon if and how you choose to validate the arguments to the constructor.

      package Junk3; sub new { my( $class, $attributes ) = @_; my $self = bless { %{ $attributes } }, $class; return $self; } package main; my $obj3 = Junk3->new( { a=>1 , b=>2, c=>3 } );

      This one goes a step further, and probably a step too far for safety. It avoids naming the object reference completely, and also avoids copying the data. This latter step is potentially dangerous if you pass anything other than an anonymous hash to the constructor, and I would avoid it for that reason.

      package Junk4; sub new { my( $class, $attributes ) = @_; return bless $attributes, $class; } my $obj4 = Junk4->new( { a=>1 , b=>2, c=>3 } );

      Finally, my preferred option. Pass the arguments as a simple list, accumulate them into a hash when unpacking them from @_, and bless a reference to that as the object:

      package Junk5; sub new { my( $class, %attributes ) = @_; return bless \%attributes, $class; } my $obj5 = Junk5->new( a=>1 , b=>2, c=>3 );

      To my mind this is the clearest, cleanest and most maintianable option and is, perhaps, less likely to confuse a "beginner". As such, I don't see scope for clarification via comments. But that is still making an assumption about the knowledge level of those that will follow, and that's my beef.

      The fact that the level of knowledge of the audience is uncertain does not obviate the need to address the audience at a certain level.

      But that's the problem. At what level?

      The idea that everytime any Perl programmer uses a hash slice, he should annotate that usage with # hash slice, still feels faintly ludicrous to me. Or to quote some of those I found on the net

      # Ooooh, hash-slice. :) # woo, hash slice # A slice of Hash # Aren't hash slices lovely? # Hash ref slice
      • But should we also annotate array slices with # array slice?
      • How about dereferencing code refs: $code->(); # Call the code?
      • Or creating them: thread->new( \&thread ); # pass a reference to the code?
      • How about the ternary operator: my $var = $x < 2 ? 2 : $x; # Lower bound for $var is 2?

      Where is that line to be drawn?

      Would you argue against explanatory subroutine and variable names because a really good programmer doesn't need those hints?

      Absolutely not, but the sting in the tail of the question is not the reason. It's because they do not create a maintenance problem. Nothing is duplicated; no couplings are created; they can't lie; they are tested.


      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      "Science is about questioning the status quo. Questioning authority".
      In the absence of evidence, opinion is indistinguishable from prejudice.
        I've been thinking about those comments overnight, and I don't have any particular objection to them. Certainly not the second one anyway. I think that one could easily fall under the auspices of my statement from the OP

        Cool. It could eaisly be that I've gotten an exaggerated impression of how sparse you think comments need to be -- and by the way, I agree that it's certainly possible to have a surplus of comments that just become inane (most would agree that every line is too many, for example). Unlike what some people here are saying, though, I find that problem to be tremendously rare. Far more common is the "it was hard to write, it should be hard to understand" attitude.

        That said, context is everything, and your snippet in isolation of the code (and further commenting) around it, makes it hard to decide if these are really warrented or not.

        I think we're wandering afield, but the context is, of course, href-based objects, in this case using a seperation of instantiation from initialization. I'm playing with a simple "new" routine (inherited from Class::Base) which calls an "init" sub. I've used a version of init (generated by template) that looks something like this:

        sub init { my $self = shift; my $args = shift; unlock_keys( %{ $self } ); # $self->SUPER::init( $args ); # uncomment if this is a child class # define new attributes my $attributes = { ### fill-in name/value pairs of attributes here # name => $args->{ name }, attribute => $args->{ attribute }, objectdata => $args->{ objectdata } || 23, parameter => $args->{ parameter } || 'bupkes', }; # add attributes to object my @fields = (keys %{ $attributes }); @{ $self }{ @fields } = @{ $attributes }{ @fields }; # hash slice lock_keys( %{ $self } ); return $self; }

        Note: some of the comments there are intended to be deleted as the code goes from template form toward production use.

        In general, the reason I think we're wandering afield is that I make no claims that these constructs are the best way of doing things. The question at hand is that if you are going to do something like this (e.g. use a mildly obscure feature such as a hash slice) is there something heinous about labeling it as such in a comment.

        The fact that the level of knowledge of the audience is uncertain does not obviate the need to address the audience at a certain level.
        But that's the problem. At what level?

        It's certainly a knotty problem all right, and like most such difficult problems there's one all encompassing solution: make a guess.

        You can't just wish the problem away because you'd like the world to be a simpler place.

        The idea that everytime any Perl programmer uses a hash slice, he should annotate that usage with # hash slice, still feels faintly ludicrous to me.

        And who says that you should? My guess would be that the first usage in a module is probably where it's needed.

        Or to quote some of those I found on the net ...
        None of which strike me as "ludricous": they're just jokes. Small human touches that give you some sense of the way the programmer was thinking about the code. Even if you don't think that a hash slice is particularly fancy, it can be useful to know that the original programmer did.

        (I suggest that the central difficulty here is that you're trying to find some way to make code into some sort of pure mathematical construct, and my own opinion is that it definitely isn't.)

        Would you argue against explanatory subroutine and variable names because a really good programmer doesn't need those hints?
        Absolutely not, but the sting in the tail of the question is not the reason. It's because they do not create a maintenance problem. Nothing is duplicated; no couplings are created; they can't lie; they are tested.

        Sorry, but this is just wrong. As code evolves, the function of a routine can easily drift away from what you would assume from the name of the routine. If you don't refactor the names of your routines when that happens, you can easily end up with a misleading name. (Note: you can help cover these problems with appropriate comments.)

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others browsing the Monastery: (4)
As of 2024-03-28 23:20 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found