Golang be like
Golang be like
–env “stage”
Changing it will bring down the entire system.
We’ve spent ten million dollars and do not know why.
Isnt the syntax highlighting it as mever used?
So why would they wonder?
If it is a pure value, I’d assume yes, but if it is tied to a side effect (E.g. write its value to a file), then it would be not used but still could break your app if removed.
I’m not familiar with rust language specifically, but generally that’s what could happen
Let’s not pretend people acknowledge warnings, though. It’s a popular meme that projects will have hundreds of warnings and that devs will ignore them all.
There’s a perfectly valid use case for opinionated languages that don’t let you get away with that. It’s also similar to how go has gofmt to enforce a consistent formatting.
You can, if you want, opt into warnings causing your build to fail. This is commonly done in larger projects. If your merge requests builds with warnings, it does not get merged.
In other words, it’s not a bad idea to want to flag unused variables and prevent them from ending up in source control. It’s a bad idea for the compiler to also pretend it’s a linter, and for this behaviour to be forced on, which ironically breaks the Unix philosophy principle of doing one thing and doing it well.
Mind you, this is an extremely minor pain point, but frankly as with most Go design choices there is a better way to solve the problem.
Some people simply ignore warnings, that’s the main issue. Trust me, I saw this way too often.
If you cannot compile it than you have to fix it, otherwise just mark unused variables as ‘not an error’ via _ = someunusedvar.
It is better than in most languages with exceptions, except from languages like Java, that require you to declare that certain method throws certain error.
It’s more tedious in Go, but at the end of the day it’s the same thing.
When I use someone else’s code I want to be sure if that thing can throw an error so I can decide what to do with it.
Are you sure?
There’s a load of confusion in this thread.
What the post is about is compiler based clean code enforcement. JS doesn’t do this, but your editor in combination with ESLint prevents you from running the program. However this isn’t a general JS thing, just the way your setup works.
Just saw your edit, and yeah, that makes sense as to the confusion.
Either way, your comment enquired as to whether it was “the same” and it still isn’t because for Go it’s a language feature and ESLint is not a language, it just allows you to create similar behaviour for JavaSvript which, by default, does not exhibit that behaviour.
I wonder what portion of all go code written is
if err != nil { return err }
It’s gotta be at least 20%
The language was designed to be as simple as possible, as to not confuse the developers at Google. I know this sounds like something I made up in bad faith, but it’s really not.
The key point here is our programmers are Googlers, they’re not researchers. They’re typically, fairly young, fresh out of school, probably learned Java, maybe learned C or C++, probably learned Python. They’re not capable of understanding a brilliant language but we want to use them to build good software. So, the language that we give them has to be easy for them to understand and easy to adopt. – Rob Pike
"It must be familiar, roughly C-like. Programmers working at Google are early in their careers and are most familiar with procedural languages, particularly from the C family. The need to get programmers productive quickly in a new language means that the language cannot be too radical. – Rob Pike
The infamous if err != nil blocks are a consequence of building the language around tuples (as opposed to, say, sum types) and treating errors as values like in C. Rob Pike attempts to explain why it’s not a big deal here.
Result monad that could represent either the data from a successful operation or an error. This can be generalised to the Either monad too.
Either[A, B] monad
Wait, that’s all monads are? some generic class Either?
Nope. Monads enable you to redefine how statements work.
Let’s say you have a program and use an Error data type which can either be Ok {Value: T} or Error:
int a = new Ok {Value = 1}; int b = foo(); return new Ok {Value = (a + b)};Each statement has the following form:
var a = expr; restYou first evaluate the “expr” part and bind/store the result in variable a, and evaluate the “rest” of the program.
You could represent the same thing using an anonymous function you evaluate right away:
(a => rest)(expr);In a normal statement you just pass the result of “expr” to the function directly. The monad allows you to redefine that part.
You instead write:
bind((a => rest), expr)Here “bind” redefines how the result of expr is passed to the anonymous function.
If you implement bind as:
B bind(Func f, A result_expr) { return f(result_expr); }
Then you get normal statements.
If you implement bind as:
Error<b> bind(Func > f, Error result_expr) { switch (result_expr) { case Ok { Value: var a}: return f(a); case Error: return Error; } }You get statements with error handling.
So in an above example if the result of foo() is Error, the result of the statement is Error and the rest of the program is not evaluated. Otherwise, if the result of foo() is Ok {Value = 3}, you pass 3 to the rest of the program and you get a final result Ok {Value = 4}.
So the whole idea is that you hide the if Error part by redefining how the statements are interpreted.</b>
“Some generic class” with specific methods and laws, Monads are an algebraic structure and you want those laws included same as if you enable some type to use + you want to have a 0 somewhere and x + 0 == x to hold. Like “foo” + “” == “foo” in the case of strings, just as an example.
In Rust, Result and Option actually are monads. Let’s take Option as example:
pure x is Some(x)a >>= b is a.and_then(b)Then we have:
Some(x).and_then(f) ≡ f(x)x.and_then(Some) ≡ xm.and_then(g).and_then(h) ≡ m.and_then(|x| g(x).and_then(h))Why those laws? Because following them avoids surprises like x + 0 /= x.
Rust’s type system isn’t powerful enough to have a Monad trait (lack of HKTs) hence why you can’t write code that works with any type that implements that kind of interface. Result names >>= and_then, just like Option does so the code reads the same but you’ll have to choose between Option or Result in the type signature, the code can’t be properly generic over it.