Skip to main content
added 1067 characters in body
Source Link
gman
  • 532
  • 3
  • 15

The problem is that x, y, width, and height all swap meaning because when rotating 90 degrees the destination becomes width tall and height wide which makes referring to thingsthose variables confusing. I always wished a programmer would add some more variables to help make it clearer for themselves, like this

console.log("cx: " + circleX = ", cy: " + circleY);

Yet another example,

class Person 
{
public:
   ...
   const String& name() const { return m_name; }
   int age() const { return m_age; }

private:
   string m_name;
   int m_age;
};

vs

class Person 
{
public:
   ...
   const String& name() const 
   { 
     return m_name; 
   }

   int age() const 
   { 
     return m_age; 
   }

private:
   string m_name;
   int m_age;
};

I know some of you will scream at this example because your personal style wants getters and setters to be 1 line but hear me out ... when debugging, depending on the debugger, in the first style if you put a breakpoint on age or name the debugger will not be able to inspect this nor m_age nor m_name so you'll have no way to checking before the function returns what it's going to return or what object it's referencing. In the second style you can put breakpoints on the return lines and you'll be able to inspect everything.

The point of this postanswer is that more lines is often not only good for readability. It's also often good for writability and for debugging.

The problem is that x, y, width, and height all swap meaning because when rotating 90 degrees the destination becomes width tall and height wide which makes referring to things confusing. I always wished a programmer would add some more variables to help make it clearer for themselves, like this

console.log("cx: " + circleX = ", cy: " + circleY);

The point of this post is that more lines is often not only good for readability. It's also often good for writability and for debugging.

The problem is that x, y, width, and height all swap meaning because when rotating 90 degrees the destination becomes width tall and height wide which makes referring to those variables confusing. I always wished a programmer would add some more variables to help make it clearer for themselves, like this

console.log("cx: " + circleX = ", cy: " + circleY);

Yet another example,

class Person 
{
public:
   ...
   const String& name() const { return m_name; }
   int age() const { return m_age; }

private:
   string m_name;
   int m_age;
};

vs

class Person 
{
public:
   ...
   const String& name() const 
   { 
     return m_name; 
   }

   int age() const 
   { 
     return m_age; 
   }

private:
   string m_name;
   int m_age;
};

I know some of you will scream at this example because your personal style wants getters and setters to be 1 line but hear me out ... when debugging, depending on the debugger, in the first style if you put a breakpoint on age or name the debugger will not be able to inspect this nor m_age nor m_name so you'll have no way to checking before the function returns what it's going to return or what object it's referencing. In the second style you can put breakpoints on the return lines and you'll be able to inspect everything.

The point of this answer is that more lines is often not only good for readability. It's also often good for writability and for debugging.

Source Link
gman
  • 532
  • 3
  • 15

Spelling things out can help not only with readability but also writability.

This might seem like a silly interview question but I was asked once in an interview to write a function to rotate an image 90 degrees. The source and destination are provided (you don't need to do any memory allocation) and the width and height of the source. Yes, it's an easy problem. I suggest you do it before continuing and see if you have any trouble.

.

Did you? Did you test it? Since I was asked the question in an interview I used the question in interviews as well and what I found was many programmers would get confused. They'd write code like this

 void Rotate90(const Pixel* src, Pixel* dst, int width, int height) 
 {
    for (int y = 0; y < height; ++y) 
    {
      for (int x = 0; x < width; ++x) 
      {
         dst[???] = src[???];

And that's where they would get stuck. They would spend sometimes as much as 20 minutes on the whiteboard trying to figure out what goes in those ??? area. Lots of times they'd think they have the answer and write things like

         dst[x * width + (height - 1 - y)] = src[y * width + x];

getting the fact that using width with dst is wrong. Or often they'd get the x and y mixed up in one side or the other.

The problem is that x, y, width, and height all swap meaning because when rotating 90 degrees the destination becomes width tall and height wide which makes referring to things confusing. I always wished a programmer would add some more variables to help make it clearer for themselves, like this

 void Rotate90(const Pixel* src, Pixel* dst, int src_width, int src_height)
 {
   int dst_width = src_height;
   int dst_height = src_width;

   for (int src_y = 0; src_y < src_height; ++src_y) 
   {
     for (int src_x = 0; src_y < src_width; ++src_x) 
     {
       int dst_x = src_height - src_y - 1;
       int dst_y = src_x;
       dst[dst_y * dst_width + dst_x] = src[src_y * src_width + src_x];
     }
   }
 }

It seemed to me breaking things out into their explicit meanings would make it far easier to write the code and far easier to avoid mistakes. I felt like if I saw a programmer do this I'd think of them as wise and rate them higher.

Yes there are a few optimizations you can make. That's not the point. Yes, the math inside the last statement could also be broken out into separate lines. That would be fine as well. The point is, adding more lines made it easier to understand for the person writing the code, not just a person reading it later. In this case because the meaning of x, y, width and height are different in relation to dst vs src making separate variables for each makes the code far clearer to read AND write.

Continuing...similarly it's often useful to be able to inspect values before a function is called, especially if it's a function in a library or the system that you can't step into. If you write code like this

ctx.lineTo(x + Math.cos(angle) * radius, y + Math.sin(angle) * radius);

vs this

var circleX = x + Math.cos(angle) * radius;
var circleY = y + Math.sin(angle) * radius;
ctx.lineTo(circleX, circleY);

In the second style you can now stop the debugger at the ctx.lineTo line and inspect circleX and circleY. You might find they are NaN which would probably get you to check that x, angle, and radius are actually the correct names, something you wouldn't be able to do in the debugger. ("strict" mode probably catches that). It also allows you to easy log the values

console.log("cx: " + circleX = ", cy: " + circleY);

The point of this post is that more lines is often not only good for readability. It's also often good for writability and for debugging.

Post Made Community Wiki by gman