Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Use tools that make it harder. Immutable datastructures, side effects constrained to a few places, good static typing etc.

Where I worked before we had 100k LoC Elm projects with virtually no bugs.

Now I'm working in a python/django codebase with probably thousands of small hidden bugs.



Use tools that make it harder. Immutable datastructures, side effects constrained to a few places, good static typing etc.

Those are good things, but they only eliminate the class of bugs where the code is wrong. Some bugs, and most important bugs, are problems where you've written entirely valid and working code that does the wrong thing. That is where going back and reading your code again, and having layers of review from your peers, will help most.


Yes, but eliminating those classes allow you to spend more time where it matters.


One thing that helps me a lot is: fail fast.

You program must break when something is not right because shitty lasts forever.

Immutable objects are great but you need to validate them when you construct them and throw an exception when something is not right. And functions should return what you would expect.

For example, this:

  function GetEntitryById(int id):Entity
  {
      var entity = [action to get an entity];
      if(entity == null) {
        throw new Exception("Entity not found");
      }
      return entity;
  }
is better than:

  function GetEntitryById(int id):Entity?
  {
      var entity = [action to get an entity];
      return entity;
  }


Or use Option/Maybe or Either to represent this and let callers explicitly handle this rather than catching an exception. Is an entity not being found truly an exceptional case?


In the case that you're providing an explicit id as an argument, yes. If it were a query, no. It's dangerous to use an empty value for all failed lookups, as you can't differentiate between "not found because it doesn't exist" versus "not found because the database went offline for a minute".


I think that code example depends on the type system. In elm, the compiler forces you to handle both cases if you return a Maybe. In Java everything can be null and blow up which is bad. In Kotlin you have to handle the possible null, but it's a bit brittle when calling into Java code.

But yeah, better to fail fast. That's why I want tools to catch stuff as I write the code, not when I run it, as I cannot run all cases so then it won't hit until prod.


If it's a bug, i.e a error made by the programmer then assert and dump core.


I think that's what the book and guidelines mentioned in the article are about. Best practices and design patterns for software development. For C, I can imagine the author promoting the use of Yoda conditions to prevent one category of bugs.

Overall, strictness and "anal" rules is how you can reduce the amount of common bugs - as long as they don't require too much active thought. Then you can focus on the domain, on the actual problem, and bugs on that level will be from your own limited understanding of said domain and logic, not the programming language, memory management, memory leaks, nil dereferences, etc. Those categories of bugs are solved problems, with either best practices, tooling / linters, analyzers, or newer and better programming languages.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: