Code Readability for "Higher" Level Languages

  • Thread starter Thread starter STEMucator
  • Start date Start date
  • Tags Tags
    Code
Click For Summary

Discussion Overview

The discussion revolves around the readability of code in higher-level programming languages, particularly focusing on the trade-offs between compactness and clarity. Participants explore the implications of writing code in a terse manner versus a more verbose style, using Java code examples to illustrate their points. The conversation touches on aspects of coding standards, maintenance, and the impact of readability on software development.

Discussion Character

  • Debate/contested
  • Technical explanation
  • Conceptual clarification

Main Points Raised

  • Some participants argue that compact code can obscure meaning and make it difficult for others to understand, especially over time as the original developer may not be the one maintaining the code.
  • Others suggest that writing compact code may not necessarily provide advantages and could lead to increased difficulty in maintenance and debugging.
  • A few participants express that coding classes seem to emphasize maintenance programming, implying that overly clever solutions can be detrimental.
  • There is a viewpoint that compact code may be beneficial in specific scenarios where similar lines of code can be grouped together for clarity, though this is contested.
  • Concerns are raised about whether compact code influences runtime performance, with some suggesting that optimizing compilers may produce similar object code regardless of the source code's compactness.

Areas of Agreement / Disagreement

Participants do not reach a consensus on the merits of compact versus clear code. While some advocate for clarity and maintainability, others see potential benefits in compactness under certain conditions. The discussion remains unresolved regarding the overall impact of code readability on software development.

Contextual Notes

Participants note that the effectiveness of code readability may depend on the context in which the code is used and the skill level of the developers involved. There are also references to coding standards that aim to prevent overly complex or nested conditions, highlighting the subjective nature of what constitutes "clever" code.

  • #31
The 1752 thing is a UNIX-centric thing. See the man page for the cal command
Code:
cal 1752
.

I've done work with museum accession and cataloging. At many different times Europe and other places were a changing crazy quilt of Julian/Gregorian/Other(French Republican for example) calendars.

1752 is just a drop in the bucket. To see why they did this try looking at the Netherlands in this link:
http://www.tondering.dk/claus/cal/gregorian.php
 
Last edited:
Technology news on Phys.org
  • #32
nsaspook said:
It's very useful but so is goto in the right context.

It could be useful, like when you decide which object to print:

Code:
  public String getLongDescription(Item playerItem){
      return "You are " + description + "\n" + getExitString() + ".\n" + toString(items)
      + "Player Item: " + (playerItem == null ? "N/A" : playerItem.getName()) + ".\n";
  }

Otherwise, it doesn't seem like its utility spans much further than simplifying things to look cool and eliminating code blocks.
 
  • #33
Zondrina said:
Otherwise, it doesn't seem like its utility spans much further than simplifying things to look cool and eliminating code blocks.

True but eliminating code blocks adds to code readability (my example IMHO) where there is a possible error condition (an early exit with cleanup via goto) OR a 'prior' calculated value to return.
 
  • #34
Literally came across a situation today where I changed a ternary to an if for a very good reason: debugging. Today I wanted to catch a particular case, the less likely case of an ternary and look at the memory. I originally placed the breakpoint at the ternary operator, but hit it way too many times in the case that I didn't want to. So I pulled the operation apart into an if statement and put the breakpoint only in the scope that I needed it. This is the biggest advantage to keeping code well structured.
 
  • #35
nsaspook said:
True but eliminating code blocks adds to code readability (my example IMHO) where there is a possible error condition (an early exit with cleanup via goto) OR a 'prior' calculated value to return.
Outside of C, you should never use goto, you should use scope to clean up:

Bad code
Code:
FILE * fp1 = fopen("/tmp/test.txt", 'w');
if (!fp1) goto error1;
FILE * fp2 = fopen("tmp/test2.txt", 'w');
if (!fp2) goto error2;

error2:
   fclose(fp1);
error1:
    return;

Good code
Code:
struct file_cleanup {
    file_cleanup(FILE * fp) : myfp(fp){}
    ~file_cleanup(){ if (myfp) fclose(myfp); }
    FILE * myfp;
};

file_cleanup fp1(fopen("/tmp/test.txt", 'w'));
if (!fp1.myfp) return;
file_cleanup fp2(fopen("/tmp/test.txt", 'w'));
if (!fp2.myfp) return;   //fp1 is automatically cleaned up
 
  • #36
newjerseyrunner said:
Outside of C, you should never use goto, you should use scope to clean up:

Bad code
Code:
FILE * fp1 = fopen("/tmp/test.txt", 'w');
if (!fp1) goto error1;
FILE * fp2 = fopen("tmp/test2.txt", 'w');
if (!fp2) goto error2;

error2:
   fclose(fp1);
error1:
    return;

Good code
Code:
struct file_cleanup {
    file_cleanup(FILE * fp) : myfp(fp){}
    ~file_cleanup(){ if (myfp) fclose(myfp); }
    FILE * myfp;
};

file_cleanup fp1(fopen("/tmp/test.txt", 'w'));
if (!fp1.myfp) return;
file_cleanup fp2(fopen("/tmp/test.txt", 'w'));
if (!fp2.myfp) return;   //fp1 is automatically cleaned up

Baloney. I agree your goto example is bad 'need to use goto' code, mine is not in the correct context (C device driver).
http://koblents.com/Ches/Links/Month-Mar-2013/20-Using-Goto-in-Linux-Kernel-Code/
http://eli.thegreenplace.net/2009/04/27/using-goto-for-error-handling-in-c

http://c.learncodethehardway.org/book/
 
Last edited:
  • #37
newjerseyrunner said:
Outside of C, you should never use goto, you should use scope to clean up:

Bad code
Code:
FILE * fp1 = fopen("/tmp/test.txt", 'w');
if (!fp1) goto error1;
FILE * fp2 = fopen("tmp/test2.txt", 'w');
if (!fp2) goto error2;

error2:
   fclose(fp1);
error1:
    return;
That's bad code because you left the file pointer fp2 open. That would be considered "good code" in some circles that code in C had you added a fclose(fp2) just before error2.

It would of course be considered very bad code in the C++ world. It would be non-compilable code in Java (even without the pointers).

Good code <elided>
I wouldn't quite call that "good" (raw pointers, leaky abstraction), but I do get the point, and it is a very important point. Well-written C++ code doesn't need gotos because the objects clean up after themselves on destruction. This goes by the terrible acronym "RAII" (Resource Allocation Is Initialization). This doesn't just apply to memory. It applies to resources of all types. I'm biased, but C++ is better in this regard than garbage collection languages. C++ doesn't have a "finally" keyword because it's not needed. Instances of classes that follow RAII magically clean themselves up when they go out of scope.
 
  • #38
Just used another ternary operator to add a delay enhancement to my local Linux branch for SPI transfers. If you don't change the field from the default of 0 the old 10us remains but if you set cs_change_usecs to a value >0 it's used instead of the fixed delay. Quick and easy to understand.
Code:
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index 57a1950..3f784df 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -836,7 +836,7 @@ static int spi_transfer_one_message(struct spi_master *master,
                                keep_cs = true;
                        } else {
                                spi_set_cs(msg->spi, false);
-                               udelay(10);
+                               udelay(xfer->cs_change_usecs ? xfer->cs_change_usecs : 10);
                                spi_set_cs(msg->spi, true);
                        }
                }
diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h
index 856d34d..131f145 100644
--- a/include/linux/spi/spi.h
+++ b/include/linux/spi/spi.h
@@ -622,6 +622,7 @@ struct spi_transfer {
#define        SPI_NBITS_DUAL          0x02 /* 2bits transfer */
#define        SPI_NBITS_QUAD          0x04 /* 4bits transfer */
        u8              bits_per_word;
+       u8              cs_change_usecs;
        u16             delay_usecs;
        u32             speed_hz;
 
  • #39
Zondrina said:
are there actual advantages to writing code so compactly?
There are only disavantages. A few of them have already been point out. This question is about High level language. You compact nothing by avoiding to write two return one "if" and two braces. The expression tree would be the same, if you had not introduced a bug. The correct equivalent is
Code:
return !booked ? booked = true : false;
So, concretely, you have shoot yourself in the foot already by asking explicitly to read 'booked' twice (**). It was too hard.

There is is more. Writing high level language means your code will have a long lifetime and be maintained by coworker.
This original code is surely a made up example. There is no way a real booking will use such a method.
Here is what's going to happens. The method will be called in a dozen places, expecting a bool.
One years later, another smart ass will turn (private) booked into an enum (confirmed state added), or worse, a object with bool conversion semantic (called trice ***)
So the method will need anyway to have its braces back.

Code readability, for any type of language, should express your intent with less possible obfuscation. In most case, the code will be its own documentation, and won't need even a glance at the comments. And in most cases, it will be more efficient.
 

Similar threads

  • · Replies 3 ·
Replies
3
Views
4K
Replies
2
Views
2K
  • · Replies 3 ·
Replies
3
Views
2K
Replies
5
Views
15K
Replies
6
Views
3K
  • · Replies 7 ·
Replies
7
Views
3K
Replies
1
Views
8K
  • · Replies 5 ·
Replies
5
Views
4K
  • · Replies 75 ·
3
Replies
75
Views
6K
  • · Replies 12 ·
Replies
12
Views
4K