
Clear defensive programming with Go using Verifier library - kiyanwang
https://itnext.io/clear-defensive-programming-with-go-using-verifier-library-6f648810b453
======
ainar-g
This looks neat, but I would not call it clear. In cases where I need to check
many conditions and return, I would simply use a conditional switch (and also
use exact error values instead of generated ones):

    
    
      switch {
      case transfer == nil:
          return nil, ErrInvalidTransfer
      case person == nil:
          return nil, ErrInvalidPerson
      // ...
      }
    

This, to me, is both concise and clear.

~~~
storozhukBM
You can actually return specific errors using verifier library. Check out
documentation:
[https://godoc.org/github.com/storozhukBM/verifier#Verify.Wit...](https://godoc.org/github.com/storozhukBM/verifier#Verify.WithError)

~~~
nostalgeek
I believe the point of the OP is, you don't need the verifier library at first
place. This is one of these dependencies that offer very little for the cost
of adding a new dependency to a project.

~~~
icholy
I'm not going to use OP's package, but I'll definitely copy the idea into a
local helper.
[https://gist.github.com/icholy/fc41b8cfe74506cf93ec6b0fba1fc...](https://gist.github.com/icholy/fc41b8cfe74506cf93ec6b0fba1fc4ce)

------
nudpiedo
The more I read these things the more I believe that contract systems like
clojure.spec and strong type systems/contracts like ADA were too much advanced
for its time... golang is just above the stone age of programming languages...
better than assembly barely above C,...

Some days I even believe that by promoting developer's mental laziness to not
learn new paradigms/more advanced languages/technical systems we are just
delaying the progress of humanity.

EDIT: advanced for its age -> advanced for its time

~~~
IshKebab
I think Go was deliberately designed to be like C but less insane because
people still use C!

Go is a practical language designed to improve the situation. You aren't going
to convince someone who writes socat or curl or whatever in C to use Clojure
or Ada instead. They might plausibly use Go though.

~~~
nudpiedo
I get your point; GO is a low hanging fruit from the marketing point of view:
it is a smart business move; because as we all know markets as well as
societies have a strong inertia in regard of consumed products. But that
doesn't change the technical opinion of the topic and the fact that we are
still undeveloped using "C+" (aka go).

P.S. I am being a bit too hard on Go, but my whole point is that after seeing
really complete solutions for this problem, everything else pales next to them
and that we still encounter unnecessary problems.

~~~
laumars
I both agree and disagree with you. More sophisticated languages do have an
obvious benefit to a great many problems and you're also right that often the
problem is the developer's capabilities rather than the language. But you
could also flip that argument and say a good developer could write good code
in any language so why bother with anything more sophisticated.

However arguments about the developer aside, Go has other advantages that drew
me to it. Such as

* cross-compiling requiring no additional effort aside setting an env var (It's been a why since I've written C++ but I seem to recall no end of bother there. Again a seasoned developer will argue it's easy but I certainly didn't find it that way)

* It compiles down to a portable executable (there are surprisingly few languages that do that)

* It's not overly verbose. Ok, this is only true if you're not having to work around generics or the "if err != nil" syntax. But for most problems I've found Go to be refreshingly direct.

* It enforces strict code layout guidelines so I can pick up anyone's code and can run with it easily enough.

* Compiler error messages are very easy to understand.

Sure there are other languages that cover some, maybe most of those points.
But few cover all. Which is why I often describe Go as "a boring language
that's pleasant for just getting shit done". Which is why I tend to favour Go
these days despite having learned more than a dozen different languages over
the years.

Needless to say a great many of people - both on and off HN - will disagree
with me. But that's the beauty of personal opinion. Programming languages
really are just the realm of preference.

~~~
mixedCase
> But you could also flip that argument and say a good developer could write
> good code in any language so why bother with anything more sophisticated.

Because both inexperienced and experienced developers will be prevented from
doing the wrong thing more often when using a better language.

~~~
laumars
I do agree with your point but this is about more than just language safety.
The point the GP was making was more about expressiveness of languages (or at
least that was how I interpreted it). You can have safety even in arguably
unsophisticated languages (eg Visual Basic pre-dotnet). However it's true that
_some_ languages use their expression as a method of enabling developers to
write less buggy software.

------
chooseaname
So, I'm trading potentially error-prone if statements that are plainly visible
in the code for a potentially buggy library whose code I'm not familiar with
just for some syntactic sugar?

Sorry, no thanks.

~~~
ainar-g
Notice how OP had to add a check after verifying two pointers against nil. A
junior developer could've easily skipped it, and, if tests only go through
happy paths or are non-existent, deploy it somewhere where it would explode in
runtime.

~~~
chooseaname
> A junior developer could've easily skipped it...

But the senior developer should catch it in a review before ...

> ...deploy it somewhere where it would explode in runtime.

~~~
UncleMeat
Computers are much better at consistently catching errors than developers

------
alias_neo
The only benefit I can see in this, is that if each time I call GetError, it
will give a useful list of conditions that were not met, so that in conditions
where fast-fail is not necessary, but letting the caller know everything that
might have been incorrect, useful information is available.

If that's not the case (and it's not clear from any of the documentation), it
seems like this adds no real value, and in my opinion actually makes the error
handling ugly and harder to maintain.

Also, use package-defined, exported error types that you can refer to by name,
and errors become useful data again like Go intended.

~~~
storozhukBM
You can actually return specific errors using verifier library. Check out
documentation:
[https://godoc.org/github.com/storozhukBM/verifier#Verify.Wit...](https://godoc.org/github.com/storozhukBM/verifier#Verify.WithError)

------
nostalgeek
If only there were some features in some computer languages or type systems
that allowed to eliminate 99% of these kind of errors AT COMPILE TIME, making
these kind of libraries redundant... but Go is so simple "you don't need all
that" because sophisticated type systems "are just too hard", just do it all
at runtime instead...

~~~
ainar-g
If you're talking about nil, then yes, I would really like Go to never have
it.

But the other validations are more about contracts. Preconditions, to be
precise. Yes, I know that a sufficiently advanced type system (dependent
types?) could encode those in the function signature, but I am not entirely
sure if the technology is already there.

------
buchanae
> I think we all can agree that these lines are repetitive and even error-
> prone to some degree.

I don't agree. I'll take if-statements over a validation library 99% of the
time.

This is how we validation a message coming into our REST+JSON API:
[https://github.com/ohsu-comp-
bio/funnel/blob/master/tes/vali...](https://github.com/ohsu-comp-
bio/funnel/blob/master/tes/validate.go)

------
arendtio
Cool, I've been waiting for something like 'verifier'. A while ago I read
'Errors are values' [1] and always wanted to upgrade my error handling, but
never really did. Verifier looks like a small library which can help me with
that easily :-)

[1]: [https://blog.golang.org/errors-are-
values](https://blog.golang.org/errors-are-values)

