News for hackers. Stuff that matters.
Re:Skills Poor Programmers Lack by cgriswald on Sunday July 21, 2019 @12:42PM (#20492169)
> You may have seen code which misunderstands how expressions work:

> if isDelivered and isNotified: isDone = True else: isDone = false;

> Instead of:

> isDone = isDelivered and isNotified

Are people actually finding code like this in professional work or is this just an example? I'm self-taught and know I've got some gaps, but this example is so fundamental I find it shocking.

Re:Skills Poor Programmers Lack by onion2k on Sunday July 21, 2019 @12:58PM (#20492266)
In my 20something years of writing software for a living I've seen both. And I find it very hard to care which one someone on my team uses. It's not something fundamental. Both lines work perfectly well. They do the same thing. The second is more concise and 'better', but if the only improvement you can suggest in a code review is something like shortening a line then the code is basically fine.

A difference between good programmer and a bad programmer is that the good one writes working, readable, human understandable code that does the job it's supposed to do. That's it. Someone who writes code that's shorter without being more understandable, or faster, or significantly more efficient, isn't better.

Re:Skills Poor Programmers Lack by nicoburns on Sunday July 21, 2019 @03:11PM (#20493097)
I've worked on codebases where people consistently did things in 3-6 lines that could have been done in one (without it being an overly complex line).

It was massively detrimental to readability, because it meant what should have been a 5 or 6 line function suddenly became 20 or 30 lines. A 20 line function is suddenly 100 lines. And you had to wade through each part to work out what it was doing rather than just glancing at it and it being obvious...

Re:Skills Poor Programmers Lack by userbinator on Sunday July 21, 2019 @06:04PM (#20493949)
A 20 line function is suddenly 100 lines.

...and what's worse, that then gets broken up into smaller functions containing equally trivial-but-bloated code, and now you need to jump around even more to understand something that's actually very simple.

At the extreme end of the terseness scale are the APL-family languages, and the people who work with them have no problems reading or writing code like this:

https://code.jsoftware.com/wiki/Essays/Incunabulum

I think it really says something about the state of software development when you consider that a not-insignificant number of people who are perfectly fine with that level of density (and they are making $$$$), and yet there are others who will complain that even K&R's style is not verbose enough. IMHO it's a matter of education and attitude.

Re:Skills Poor Programmers Lack by agumonkey on Sunday July 21, 2019 @01:19PM (#20492401)
You have a point but the issue with redundant boolean code like above is that it shows a lack of metalevel thinking.

kinda like this python exagerated code:

    def sum(a,b):
        return operators.add(a,b)
It can lead to bloat.
Re:Skills Poor Programmers Lack by injb on Sunday July 21, 2019 @01:34PM (#20492499)
That's not really a fair comparison. The first example is a fairly natural way that a reasonable person could model the logic in their head. Knowing that your programming language provides a more concise way is an optimization. A basic one admittedly, but a mere optimization nonetheless.

In contrast, your example is kind of the opposite situation - it's an example of forgoing the most natural, human representation in favour of a highly Python-specific one. In other words, the first one happens when you know the abstract logic, but don't know your tools very well; your example happens when you know lots of useless details about the tool but you're struggling with the abstract logic.

Actually, the example from the article suggests to me that the author misunderstands what I regard as the most fundamental programming skill: knowing the precedence of correctness over all other concerns, including efficiency. It's better to attach the right parts together badly than to attach the wrong parts like a pro.

Re:Skills Poor Programmers Lack by munchbunny on Sunday July 21, 2019 @12:56PM (#20492250)
I've seen it in professional work. If it's actually a single variable conditional, that's irritating but by itself not worth more than a comment in the PR. However, in practice it's rarely this cut and dry. I usually see conditions expanded like this for clarity reasons. For example, I consider this kosher if it's in some business logic... instead of writing:

> return a && !(b || c) || d;

I've seen (pardon the formatting, I'm typing on my phone):

> if (d) {return true}

> else if (a) {return !(b || c);}

> else {return false}

It's usually a choice to be verbose for clarity.

Re:Skills Poor Programmers Lack by userbinator on Sunday July 21, 2019 @05:51PM (#20493894)
I think that would be clearer as "return a && !b && !c || d". Also, your second example doesn't directly correspond with the first, because condition 'a' is evaluated first.

The major problem with code that's "overly branchy", as in containing a lot of if/else, is that you're forced to go through each case when trying to understand how it works, and it often proliferates into even more branchy code as someone makes a bugfix (with another if/else) in one of the cases, but neglects to see that a similar if not identical change must be made to some of the others.

In other words, if/else cases like your second example optimise for micro-readability when what's often important in debugging and understanding is macro-readability.

Re:Skills Poor Programmers Lack by munchbunny on Monday July 22, 2019 @02:06AM (#20495670)
While I get your point, several thoughts:

1. I'm talking about acceptable code, as opposed to "the best choice". There are good reasons to go for verbosity. Depending on the problem domain I might agree with your expansion of the parentheses, but when we get to this type of discussion, usually my overwhelming reaction is "this is bikeshedding," because...

2. If it's "overly branchy" code and you're worried about causing macro-readability issues, the answer is to refactor, not to compress. Modifying inline conditions runs just as much of a risk of becoming inscrutable. You choose between following branches and enumerating binary tables. If it's showing up too many places, you're likely extracting either expression into its own function.

When overly branch code happens, my experience is that the root cause is underthinking/overthinking the method, not taking time to design the right high level abstractions, or as you mentioned a case of too much repeating yourself. Generally, the fixes for those issues don't have that much to do with your choice of boolean expression vs conditional.

Re:Skills Poor Programmers Lack by kingludite on Sunday July 21, 2019 @05:34PM (#20493812)

  // a b c d
  // * * * 1  true
  // * 1 * 0  false
  // * * 1 0  false
  // 1 0 0 *  true
  // 0 * * 0  false

  if (d)    {return true }
  if (b||c) {return false}
  if (a)    {return true }
  return false
Re:Skills Poor Programmers Lack by kingludite on Sunday July 21, 2019 @05:07PM (#20493674)
> return d || a && !(b || c);
Re:Skills Poor Programmers Lack by transreal on Sunday July 21, 2019 @12:47PM (#20492197)
I see this in professional work. The former reads more like English, and so there feels like there is an argument to be made that it is more readable, and also an argument that "the compiler will optimize it for you anyway".
Re:Skills Poor Programmers Lack by Biganon on Sunday July 21, 2019 @01:09PM (#20492342)
Are they wrong? To me, the long version is valid precisely because it is explicit (more to me than the short version), and will be optimized
Re:Skills Poor Programmers Lack by wisienkas on Sunday July 21, 2019 @01:09PM (#20492337)
and you question yourself if it was better to pack that readability into a function or not.

Also why would anyone store a boolean named isDone rather than just returning it as the contract of the function

Re:Skills Poor Programmers Lack by ravenstine on Sunday July 21, 2019 @01:26PM (#20492443)
Yes, absolutely. Even the biggest Fortune 500 companies hire interns and juniors to code in relatively complicated apps and systems. Sooner or later they hire more mid-to-senior level engineers to clean up the mess. That example isn't even bad, either. At least you can understand it by reading it. If you've never had to spend days deciphering an ouroboros of several nested loops and if-statements in 2000+ line functions in classes with multiple layers of inheritance written by someone(who has since left the company) with a lack of experience or talent, you are one lucky individual IMO.
Re:Skills Poor Programmers Lack by leetrout on Sunday July 21, 2019 @12:46PM (#20492196)
Yes.

And a coworker wrote his own string join method in Python (and was mad he wasn’t a senior engineer).

Re:Skills Poor Programmers Lack by itronitron on Sunday July 21, 2019 @01:18PM (#20492398)
during his job interview or after he was hired? (jk)
Re:Skills Poor Programmers Lack by drchewbacca on Sunday July 21, 2019 @01:15PM (#20492375)
Is anyone willing to explain the second line? I get the first means "if isDelivered and isNotified are both true then set isDone to True, if not set it to false". However I've never seen a variable being set "isDone = isDelivered" as part of a logical test.

Personally I think programmers who are "too clever" are cancer inside a codebase. Sure you saved a bunch of keystrokes but your code golf has locked the code forever unless someone is willing to rewrite it. This is not a bad example but in general I think people who strive to do things in less characters are highly problematic.

Re:Skills Poor Programmers Lack by whiddershins on Sunday July 21, 2019 @01:31PM (#20492475)
It feels clever if you aren’t used to it but it is super common.

isDelivered && isNotified

always resolves to a Boolean, either TRUE or FALSE

So you are just saying

isDone = TRUE

or

isDone = FALSE

that’s all

Re:Skills Poor Programmers Lack by edflsafoiewq on Sunday July 21, 2019 @02:26PM (#20492834)
It isn't (isDone = isDelivered) and isNotified, it's isDone = (isDelivered and isNotified). It's just an expression being assigned to a variable.
Re:Skills Poor Programmers Lack by drchewbacca on Sunday July 21, 2019 @03:19PM (#20493125)
Ah ok, great, thanks.
Re:Skills Poor Programmers Lack by LaserToy on Sunday July 21, 2019 @01:34PM (#20492497)
I tend to agree that, given compiler doesn’t care most of time, saving characters can’t justify decrease in readability.
Re:Skills Poor Programmers Lack by ilovepeppapig on Sunday July 21, 2019 @01:04PM (#20492301)
The worst production code I've seen (Java) included its own Object interface and a corresponding ObjectImpl (IIRC it was an abstract class).
Re:Skills Poor Programmers Lack by userbinator on Sunday July 21, 2019 @02:43PM (#20492933)
I've seen plenty of if(!(var != true) == false) and the like --- some people just seem to not really understand the concept of booleans.
Re:Skills Poor Programmers Lack by Izkata on Monday July 22, 2019 @06:24PM (#20502865)
It often goes much further than that.

I was a teacher's assistant in the intro-to-programming courses in college for 3 years, and eventually realized what students were seeing. Now, with some new hires, I'm seeing the same thing:

They think the expression is "if (.. == ..) { .. }"

Not "if (..) { .. }"

The simple explanation of what boolean expressions are, and that any boolean expression can go in those parens - and that it's the same thing as storing the result to a variable and then using that variable - is like a lightbulb suddenly blinks in their head.

Re:Skills Poor Programmers Lack by whiddershins on Sunday July 21, 2019 @01:26PM (#20492445)
I have that all throughout a codebase.

I felt momentarily bad about it, and myself, and then realized I have a reason:

The codebase I am maintaining is intended to be readable by people who have extremely varying levels of skill, and who have no intention of ever being professional programmers.

When possible I write stuff so you don’t have to “think like a programmer” to understand it. I’m pleased I use the conditional version more often than not, because I believe it is far more intuitive.

Re:Skills Poor Programmers Lack by CodeWriter23 on Sunday July 21, 2019 @02:07PM (#20492713)
Came here to comment on that too...and was surprised how many replies you had where the fundamental whooshed right over all these skilled programmer’s heads.

The shortcoming is failure to recognize your object has more than 2 states and the use of flags should be abandoned in favor of a state variable (or status bit vector, aka a state variable).

Re:Skills Poor Programmers Lack by thecleaner on Sunday July 21, 2019 @12:45PM (#20492188)
Can confirm. Made this mistake myself actually. However to make a contradictory point apart from being better style what are the other advantages of not using if statements and use boolean algebra instead ?
Re:Skills Poor Programmers Lack by munchbunny on Sunday July 21, 2019 @01:11PM (#20492353)
Verbosity tends to hurt readability, but trying to cram too much into one line tends to create something where nobody remembers how it works either. So it's really a judgement call on which approach reads more naturally.

My personal rule of thumb on this is that single statement conditions aka "a = {condition}" should be using only "and" operators or only "or" operators and should generally avoid nesting unless there's a clear explanatory comment. So "a and b and c and d" is ok but "a and b or c and d" is sketchy. The reason is that "all" and "any" are idiomatic, but "some" takes more mental work to parse.

Also it's always useful to keep in the back of your mind:

!(a || b) == !a && !b

Whenever I spot either side of the equation in a condition, I stop and consider whether the alternate formulation would be more readable.

Re:Skills Poor Programmers Lack by dymk on Sunday July 21, 2019 @12:45PM (#20492191)
Oh, yes, I saw stuff like this in Big Blue Company's source control.

At a different company, I found stuff like:

    ZERO_INDEX = 0
    ONE_INDEX = 1
    return arr[ZERO_INDEX]
Re:Skills Poor Programmers Lack by humanrebar on Sunday July 21, 2019 @12:50PM (#20492216)
That's usually a sign of overly aggressive linters and static analyzers. They probably got a "no magic numbers" diagnostic.

The solution to this problem is to add some sort of `NOLINT` comment to that line or, if possible, the comment that turns off that particular check. Then you link to the design document describing what "arr" is and how its interface involves accessing indices 0 and 1.

Or you could wrap "arr" up in a class or function of some sort so the code is theoretically more self documenting.

Re:Skills Poor Programmers Lack by torgard on Sunday July 21, 2019 @01:19PM (#20492400)
It took me a while to understand the whole "no magic numbers" thing.

I was basically just told that most (if not all) numbers should be stored in constants. So I just added int twentyFive and stuff, and it annoyed me, but my teacher was happy.

Much later, I realized the missing part: Name the constant not what it is, but rather what it does. So int rightBoundary instead of twentyFive, and the code suddenly becomes much more readable.

Re:Skills Poor Programmers Lack by BurningFrog on Sunday July 21, 2019 @01:09PM (#20492336)
Yeah, linters that make "you should usually do X" into "you MUST ALWAYS do X" cause a lot of terrible code.
Re:Skills Poor Programmers Lack by dymk on Sunday July 21, 2019 @12:54PM (#20492246)
We had no linters enforcing the "no magic constants" convention. If we did, I'd question the sanity of the engineer who added that linter.

The reason we got code like this was because of outsourced contractors cargo-culting something they saw elsewhere.

Re:Skills Poor Programmers Lack by humanrebar on Sunday July 21, 2019 @01:08PM (#20492334)
Well, maybe it's cargo culted from a place with such a linter. Or ornery peer reviewers who think their job is to be a human linter.

Correcting this sort of stuff is the job of a senior engineer, though. If it's extremely frustrating, I'd become independently wealthy or stay away from technical leadership positions.

Re:Skills Poor Programmers Lack by yawboakye on Sunday July 21, 2019 @01:07PM (#20492322)
I've seen variations of it. Usually along the lines of

   let isBoolean = false
   if (booleanComparisonOrComputation) {
     isBoolean = true
   }

   ...
Re:Skills Poor Programmers Lack by lasereyes136 on Sunday July 21, 2019 @04:20PM (#20493424)
All the time. There are a lot of reasons people write really bad code and being a bad programmer is only one of those reasons.
Re:Skills Poor Programmers Lack by itronitron on Sunday July 21, 2019 @01:37PM (#20492512)
yes, and that's a pretty tame example. Don't assume that any code you see is correct. A lot of misunderstandings about how a language works can be carried on for decades within a team.
Re:Skills Poor Programmers Lack by kyberias on Sunday July 21, 2019 @03:37PM (#20493212)
This is extremely common.
Re:Skills Poor Programmers Lack by 010101010101 on Sunday July 21, 2019 @12:47PM (#20492203)
Many, many times.