Code Readability for "Higher" Level Languages

  • Thread starter Thread starter STEMucator
  • Start date Start date
  • Tags Tags
    Code
Click For Summary
Code readability in higher-level languages lacks specific guidelines, leading to varied opinions on compact versus clear coding styles. While some argue that compact code can obscure meaning and complicate maintenance, others believe that skilled developers can navigate both styles. The discussion emphasizes that overly clever code may introduce bugs and hinder future modifications, as maintenance programmers often struggle with dense logic. Additionally, there is little to no performance benefit from writing compact code, as compilers typically produce similar object code for both styles. Ultimately, clarity should be prioritized to facilitate understanding and reduce the likelihood of errors in long-term software projects.
  • #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
14K
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
3K