• FizzyOrange@programming.dev
    link
    fedilink
    arrow-up
    7
    ·
    22 hours ago

    I think this could have been about 1/4 the length. Fairly basic stuff by modern standards and you don’t need so many words. It is all correct at least, as far as I could see!

  • fulg@lemmy.world
    link
    fedilink
    arrow-up
    7
    ·
    1 day ago

    This was a great read, thanks for sharing!

    The thumbnail caught my eye because I bought the Dragon Book many years ago to get some insight on compilers. So much knowledge that is still relevant today…

  • Undertaker@feddit.org
    link
    fedilink
    arrow-up
    6
    arrow-down
    8
    ·
    24 hours ago

    Some knowledge about compiler was interesting. The advise to use combined return types (for errors and value) instead of exceptions is ridiculous. Some other points are weird as well. Changing language to avoid null…

    • bestboyfriendintheworld@sh.itjust.works
      link
      fedilink
      arrow-up
      2
      ·
      7 hours ago

      Depending on the language exceptions are used in many different ways. Some use it liberally for all kinds of error handling.

      A good feature of Exceptions is you can throw them all the way up the stack and handle them there, giving you loose coupling between the code that calls the dangerous code and the one that catches it.

      Exceptions have a big runtime overhead, so using them for normal control flow and error handling can be a bit meh.

      Using return types can be great, if the language has good support for. For example swift enums are nice for this.

      enum ResultError  {
        case noAnswer;
        case couldNotAsk;
        case timeOut
      }
      
      enum Result {
        case answer: String;
        case error: ResultError
      }
      
      func ask(){
        let myResult = askQuestion(“Are return types useful?”);
        switch myResult {
          case answer: 
            print(answer);
          case error:
             handleError(error);
        }
      }
      
      func handleError(error: ResultError) {
        switch ResultError {
          case noAnswer:
            print(“Received no answer”);
          case couldNot:
            …
        }
      
      }
      

      Using enums and switch means the compiler ensures you handle all errors in a place you expect.

    • douglasg14b@lemmy.world
      link
      fedilink
      arrow-up
      24
      ·
      23 hours ago

      Combined return types are wonderful and make for, generally, better engineered software.

      Exceptions still have their place, for exceptional circumstances, but the grand majority of errors should not be exceptions.

    • expr@programming.dev
      link
      fedilink
      arrow-up
      5
      arrow-down
      1
      ·
      18 hours ago

      https://en.wikipedia.org/wiki/Algebraic_data_type

      Some reading material for you. Sum types allow for proper, compiler-enforced error handling and optionality rather than the unprincipled free for all that is exceptions and nullability.

      Tony Hoare, the person that originally introduced nulls to the programming world, is oft-quoted as calling nulls the “billion dollar mistake”. Here’s the talk: https://www.infoq.com/presentations/Null-References-The-Billion-Dollar-Mistake-Tony-Hoare/.

    • Michal@programming.dev
      link
      fedilink
      arrow-up
      4
      arrow-down
      1
      ·
      21 hours ago

      Combined return types is a Rust feature.

      I recently started learning Rust, and would prefer exceptions. Even Java checked exceptions aren’t too bad to work with. Rust approach is Ok though and ir has a purpose.

      • setsubyou@lemmy.world
        link
        fedilink
        arrow-up
        3
        ·
        14 hours ago

        In Rust you’re kind of stuck with it, but at the end of the day combined return types are just syntactic sugar for something a lot of languages can do. Even in plain old C there’s a pattern where you pass pointers to your return and/or error variables. In many languages you can return structs or similar. In some I’d argue it looks nicer than having to write Result<>, e.g. in Python or in Swift you can just return a tuple by putting things in parentheses. (Of course you can also still use something more explicit too. But if every function returned (result, error) by default and every call was like result, error = fn(), I don’t think it’d be necessary.)

        However I don’t really know of any language where people prefer to use this over exceptions if exceptions are available. Even in C some people used to use setjmp/longjmp in macros to implement exceptions. Exceptions have their problems but people seem to overwhelmingly be in favor of them.

        Personally I like exceptions in languages that have some kind of built-in “finally” for functions. For example defer in Swift. You can have proper error handling for a lot less typing in many cases because passing through exceptions is fine if your defer blocks handle the cleanup. And if you do want to handle an exception, Swift also has optionals, and a try? that transparently converts a return value into an optional that’s nil when an exception was thrown, and a coalescing operator ??, which means you can catch exceptions and provide a default value on one line, instead of a 4-5 line try…catch/except block or an error checking conditional for every call.

        • Michal@programming.dev
          link
          fedilink
          arrow-up
          2
          ·
          13 hours ago

          Interesting that you brought up finally. I was learning Rust the last two days and didn’t realise it was missing. There may be some other way of handling it.