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

I don't know. The quality of this FAQ entry is in my opinion narrowed by their inclusion of FileNotFoundException, which it seems they did not understand. The use case for this exception is not to allow lazy programmers to use it instead of checking that a file exists, but to signal to a programmer that his world view of the state of his program may be wrong despite his best efforts, e.g.

  if(file.exists())
  {
    //do something
  }
There's a race condition between the if and do something which invalidates the programmers world view (someone can delete the file between these two statements). And this is an exceptional situation the program has to deal with. Error codes may tell the programmer this, but it is quite likely that the programmer will just ignore it, because "I've already checked that it exists - what could possibly go wrong?". Exceptions, especially checked exceptions (in my opinion the only good exceptions for "normal" program code)(1), force the programmer to deal with this problem. Or to say - deliberately - "Hey, program, I don't care for the stability of my software. Just explode if this happens!".

(1) Languages which have only unchecked exceptions do, in my opinion, cave in to the laziness of programmers: "but, but, it is so much WORK to deal with all of this. Can't it just go away? Please?" - the result is code which can explode everywhere. This is even worse than no exceptions. With return codes you know at least that you have to check the code yourself very, very carefully all the time.



> There's a race condition between the if and do something which invalidates the programmers world view (someone can delete the file between these two statements). And this is an exceptional situation the program has to deal with.

It's not an exceptional situation. It's a bug in your program. And it's not lazy to open() and check for existence. It's actually the _only_ sane way to check that the file exists, if you plan to open it.

> Error codes may tell the programmer this, but it is quite likely that the programmer will just ignore it, because "I've already checked that it exists - what could possibly go wrong?"

The following code is obviously wrong because of the race condition you mention. Nobody in their right mind would write code like this.

    if exists(file) {
        f = open(file)
        // do something with f
    } else {
        // handle "file not found" case
    }
This code is correct, to some degree:

    try {
        f = open(file)
        // do something with f
    } catch (file not found error) {
        // handle "file not found" case
    }
As is this Go code:

    f, err := os.Open(file)
    if os.IsNotExist(err) {
        // handle "file not found" case
    } else if err != nil {
        // handle any other error that might arise
    }
    // do something with f
The thing is, the above code is not me being extra careful about checking errors. It's just bog standard Go code. Checking error values is the only way to write even half-decent Go code, so everyone does it all the time.

No reasonable programmer would write Go code like this:

    _, err := os.Stat(file)
    if err != nil {
        // handle "file not found" case  
    } else {
        f, _ := os.Open(file)
        // do something with f
        // (or explode if file doesn't exist)
    }
To my Go programmer eyes, the underscore (where I'm ignoring the error) in the os.Open line sticks out like a sore thumb. You wouldn't write it, and when reading you would certainly notice it as bad code (or at the very least extraordinary code).




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

Search: