From 1df16842d2b825aebbebb1d89f3e66308dd1df43 Mon Sep 17 00:00:00 2001 From: Richard Metzler Date: Sun, 23 Dec 2018 21:39:18 +0100 Subject: Syntax highlighting Also I think Go has the better error handling. Because it is only one and it is supposed to be next to the fallible Operation. Last time I counted there were at least these methods to signal an error in JavaScript: - a return value indicating the error, sometimes as magic number (null or -1) - throw an Exception - an error callback function, which is totally dependent on the framework you use You didn't handle any errors in your JavaScript example, because you aren't forced to. In Java, there are Exceptions, but calling code isn't forced to handle unchecked RuntimeExceptions and Errors. And if you handle Exceptions wrong - and there are so many ways to do this, like swallowing or rethrowing without the root cause, you'll need much time to look into your production issues. Go code is explicit and requires the programmer of the calling code to recognize the possibility something might be slightly wrong in some computer sometime. You're still allowed to ignore this warning by using `_` in `a, _ := fallibleOperationA()`, but it is much better and also cheap if your editor has snippet support to just type `ife`and hit tab and atom is expanding it to: ```go if err != nil { return } ``` --- wiki/dev/go.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/wiki/dev/go.md b/wiki/dev/go.md index 6f04066..f20914b 100644 --- a/wiki/dev/go.md +++ b/wiki/dev/go.md @@ -55,7 +55,7 @@ The standard Go approach to operations which may fail involves returning multipl Because this is a convention, it is not representable in Go's type system. There is no generalized type representing the result of a fallible operation, over which one can write useful combining functions. Furthermore, it's not rigidly adhered to: nothing other than good sense stops a programmer from returning an `error` in some other position, such as in the middle of a sequence of return values, or at the start - so code generation approaches to handling errors are also fraught with problems. It is not possible, in Go, to compose fallible operations in any way less verbose than some variation on - +```go a, err := fallibleOperationA() if err != nil { return nil, err @@ -67,23 +67,29 @@ It is not possible, in Go, to compose fallible operations in any way less verbos } return b, nil +``` In other languages, this can variously be expressed as +```java a = fallibleOperationA() b = fallibleOperationB(a) return b +``` in languages with exceptions, or as +```javascript return fallibleOperationA() .then(a => fallibleOperationB(a)) .result() +``` in languages with abstractions that can operate over values with cases. This has real impact: code which performs long sequences of fallible operations expends a substantial amount of typing effort to write (even with editor support generating the branches), and a substantial amount of cognitive effort to read. Style guides help, but mixing styles makes it worse. Consider: +```go a, err := fallibleOperationA() if err != nil { return nil, err @@ -101,5 +107,6 @@ This has real impact: code which performs long sequences of fallible operations fallibleOperationD(a, c) return fallibleOperationE() +``` God help you if you nest them, or want to do something more interesting than passing an error back up the stack. -- cgit v1.2.3