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

>It exists as a hack because error handling in Go is convoluted.

What's the alternative, though? Sprinkle your code with try..finally's? RAII like in C++?



RAII is fine. If it's a language feature, APIs can provide that to you so you don't have to write RAII wrappers all the time.

Otherwise a generic _bracket_ operator could be introduced, similar to Python's `with` statement. In C it might be a bit hard to parameterize, but even if it just requires you to use a void, it's still an improvement vs. not having anything at all. (Talking about language features so `__attribute__((__cleanup__))` doesn't count.)

Imagine something like this:

    FILE* handle = bracket(fopen("data.bin", "rb"), fclose) {
        fread(..., handle);
        return;
        fwrite(..., handle);
    } // <-- implicitly calling fclose(handle), always
Edit: After writing this sample I could even an optional `else` block in case `fopen` returned `NULL`.

Edit2: Of course, syntax fine-tuning would be welcome. For instance, `handle` should be restricted to the bracket's scope.


Context managers, or an Auto-Closable interface with syntactic support.

Also why is RAII bad? It's an awesome feature in C++.


>Also why is RAII bad? It's an awesome feature in C++

I didn't mean it's bad (I used to be a C++ developer myself and enjoyed RAII a lot), just wondering what are the alternatives that the OP doesn't consider "hacks". RAII would require to introduce constructors/destructors in the language, with all the gotchas (and probably you'll want a full-fledged OOP after that), which is apparently against Go's design principles as a simple language.

>Auto-Closable interface with syntactic support.

I don't see much difference here in practice; the whole difference is that in C#, for example, you use "using" on a whole object, while in Go it's a "defer" on a specific method of the object (or a standalone function). You are not limited to a single method and can use it on any method you deem necessary.

Auto-closeable/RAII, however, is less flexible in ad hoc situations specific to a certain function (you have to define dummy classes just to make sure a function is called no matter what), Go allows to use "defer" on a lambda. Auto-closeable also ties control flow to an object, which makes sense in an OOP-focused language, but Go isn't one.


I agree with most of your points, but I wanted to also point out that you don't need C++'s ctor/dtor spaghetti to have useful RAII: Rust achieves it without even having first-class constructors (and opt-in custom destructors via Drop).


Result types


Defer is used to automatically release resources on function exit, I'm not sure how result types will help here. Can you give an example?


It's an alternative to try...finally or RAII.




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

Search: