Live data from Hacker News

Skills Poor Programmers Lack

justinmeiners.github.io

171–180 of 211 posts

Re: Skills Poor Programmers Lack

#171

> 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.

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 format…

  // 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

#172
post #99

> Using sleep(), cron jobs, or setTimeout is almost always wrong because it typically means you are waiting for a task to finish and don’t know how long it will take. What if it takes longer than you expect? What if the scheduler gives resources to another program? Will that break your program? It may take a little bit of effort to rig a proper event, but it is always worth it. While I understand the sentiment of thi…

I initially had the same reaction, but I don't think that's the author's intentions. He's saying don't use sleep() and cron to constantly poll if some asynchronous thing has completed, have a proper event fire at the end and handle that. Don't think that's in conflict with what you like about your systems :-)

Yes, but in the article author also argues that proper definitions are important. In more general case I'd say that expressing ideas in a non-ambiguous manner is important.

Re: Skills Poor Programmers Lack

#173

Earlier quoted context omitted.

That's what !! is for!! :)

Which is not really needed here. isDone will be boolean, and the other ones are still Truthy / Falsey values...

if the first term is undefined, isDone will be undefined, not false. At least in Javascript.

&& returns the falsy value on the left side of the expression if it evaluates to a falsy value

(undefined && true) evaluates to undefined

correspondingly || returns the truthy value (which might be an object) on the left hand side if evaluates truthy. That's useful for expressions like this:

const a = b || 'default value';

!! turns truthy/falsy values into booleans.

Re: Skills Poor Programmers Lack

#174

> 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.

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 format…

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

#175
post #21

Earlier quoted context omitted.

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…

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 gla…

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

#176
post #77

In all fields there is a minority who are not very good at what they do. I think, though, that in programming that minority might actually be a majority. The thing is, if you are a poor plumber who causes floods in peoples houses you are not going to be in business for a very long time. In programming there seems no such discipline because it actually takes somebody good at programming to perceive the difference betw…

One of the best clients I had told me something once (she knew IT pretty well and was a very good manager). (paraphrasing) In her experience, only 10-15% of people in IT actually knew what they were doing and were good at it. The next 20%-25% had something of an idea and could get stuff done, but you had to pay attention to them. The bottom 65-60% were basically useless.... I think it does take a certain to really grasp this field at a deep level, but as most jobs are CRUD type ones, that level of skill is not essential - and as always, the money / business side of things always trumps the engineering.

Re: Skills Poor Programmers Lack

#177

Earlier quoted context omitted.

The real idea for OOP is quite similar to the actor model ala Erlang. OOP as implemented and C++ and Java is an abomination. I still don't get how Bjarne Stroustrup did not steal co-routines from Simula. It's very easy to implement actual actor model style OOP with procedural code. You can get most of the benefits by using a message bus.

>C++ and Java is an abomination. It's also the OOP version I'm talking about. Most people are talking about this when they talk about OOP, not smalltalk. Why does everyone turn it in this direction... yes smalltalk was the first, but nowadays the traditional term used is not OOP as defined by smalltalk, it's OOP defined by JAVA.

[deleted]

Re: Skills Poor Programmers Lack

#178

>I believe OOP and relational database get a lot of flack because programmers tend to be bad at design, not because they are broken paradigms. OOP has Fundamental and Intrinsic problems that can be described in a very concrete way. If you believe OOP gets a lot of flack just because programmers are bad at design, then you are the one that is also bad at design. I will say this, OOP is bad for many and most design pro…

> Objects are actually arbitrary mixtures of lower level primitives: functions and data. A well-chosen object is a grouping of a set of data items that are closely related to each other, and the functions that act on them. It's almost the exact opposite of arbitrary. Your programs are going to be a mixture of data and functions. Why should the lower-level building blocks not be the same?

Ideally the choices you make would fit the domain. However for very large projects that have existed for a long time, three things happen.

1. Requirements change and this causes a change in primitives.

2. Small errors in design and scope creep in because objects allow you to mistakenly scope functions with the wrong piece of data, over a long time these small errors accumulate into something called technical debt. I call it inevitable.

3. Correct design principles appear after the project is complete, often because the design solution to the problem domain is unknown. You may have segregated you data and functions in the wrong scope because you simply didn't know what your program would end up doing when your finished.

By forcing your data and functions into groupings like this you lose flexibility of composition, you take away the future proof of your design. Too often programmers realize that the lines of segregation of their designs are wrong or have changed. They see a function that should have been universal but is trapped on an object mutating data so they're forced to make a similar method on a another object and they just call it a trade off between technical debt and time.

This happens all the time on large projects because the concept of the object as a primitive is wrong. The primitives are data and functions, not the two combined into an object.

Without that arbitrary artificial line called an object drawn around data and objects your code can react instantly to design changes. You can change a function without damaging the entire context the function relies on because it has no context in the first place, functions are independent and modular from context; methods are inexlorably tangled with state. And therefore when the time comes to inevitably change your program, you create technical debt to get around the immoveability of your methods.

I understand the need to place everything under a single primitive type and while this is ideal it only works if primitives can compose; of which objects can't. You will see across mathematics the quest for an elegant assembly language and simplified language to describe the field first began with set theory than transitioned to category theory. In both theories the dichotomy between function and data remains solid, if they couldn't unify for theoretical math then it likely says something about the primitives of the universe and your designs as well.

Re: Skills Poor Programmers Lack

#179

Earlier quoted context omitted.

That would be part of it, but since was talking about inability to think in types I suspect they were taking aim more at things like excessively stringly-typed[0] code. [0] https://devcards.io/stringly-typed

I do a lot of TypeScript these days. It's possible to define a type which equates to one or more literal string values. The TypeScript compiler will complain if you try and supply an invalid string parameter. So --at least for TypeScript-- I think this is less of a concern than in the past (and TypeScript is growing in popularity within the JS community). In a more general sense, I agree with the author that the 2nd…

That sounds like a type that holds a string, which is just what the article suggested to use.

Re: Skills Poor Programmers Lack

#180

Earlier quoted context omitted.

I do a lot of TypeScript these days. It's possible to define a type which equates to one or more literal string values. The TypeScript compiler will complain if you try and supply an invalid string parameter. So --at least for TypeScript-- I think this is less of a concern than in the past (and TypeScript is growing in popularity within the JS community). In a more general sense, I agree with the author that the 2nd…

That sounds like a type that holds a string, which is just what the article suggested to use.

Which, prior to TypeScript, wouldn't have been an option. The ever-evolving front end ecosystem!
Post reply on HN