lmi
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [lmi] Are NAND assertions difficult to understand?


From: Vadim Zeitlin
Subject: Re: [lmi] Are NAND assertions difficult to understand?
Date: Mon, 26 Apr 2021 01:11:35 +0200

On Sun, 25 Apr 2021 22:22:54 +0000 Greg Chicares <gchicares@sbcglobal.net> 
wrote:

GC> On 4/25/21 2:07 PM, Vadim Zeitlin wrote:
[...]
GC> >  If we don't need to deal with the not yet issued policies at all, this
GC> > could be as simple as using "std::optional<int> duration", where invalid
GC> > duration would indicate that the policy has been issued today.
GC> 
GC> Some people are allergic to shellfish, or tree nuts; I'm allergic
GC> only to pointers and std::optional.

 FWIW I agree that there are some problems with std::optional, but it's
very different from a pointer _semantically_ and I don't think they are
comparable at all.

GC> But there are safer ways to accomplish the same thing:
GC>   - something like std::pair<int duration, bool issued_today>, but
GC>       with mechanics to enforce invariants;

 This is a union type, i.e. std::variant in C++. As we don't really need to
have any boolean, it naturally degenerates into just a std::optional in
this case, but if you find it more clear, std::variant would definitely
work too and might indeed be preferable.

GC>   - simply let duration = -1 mean unborn, which is the same as
GC>       today's "duration = 0; issued_today = true"
GC> Is there anything really wrong with this -1 sentinel?

 Yes. I suspect you already know what is wrong with it and the emphasis
here is on "really", i.e. the question is whether the fact that it's much
less clear, not checkable by compiler and has potential to easily evolve
(mutate?) into something even worse is "really" a problem. IMNSHO it
definitely is and I just don't see why would you possibly want to go with
some ad hoc hack like this rather than clearly encoding the semantics into
the data structure itself, as could be done with std::optional or
std::variant. Previously there was at least the excuse of not wanting to
use an extra library for them, but now that we can use C++17, I just don't
see it.

 The advantage of ensuring that the value is checked, at compile-time, in
every place where it's used on its own is already invaluable to me. Not
having to think about whether you need to check for a sentinel value or
not, and not having to think about what should be done if the check fails
is extremely liberating.

 Granted, using sum types in C++ is not as nice as in just about any other
language supporting them (because, in C++ case, like about everything else,
they were bolted on as an afterthought rather than designed into the
language), but it's still much nicer than not using them at all.

 IME the code I've written using std::variant might have been slightly
longer than equivalent code without it, but it actually took less time to
write because it was much more straightforward and, more importantly, it
was always much easier to reread later and didn't have any bugs, forgotten
corner cases or unexpected exceptions or crashes. If it seems like magic,
it's because it really is -- with the compiler checking my logic, even I
don't manage to make mistakes. You should really try using it if you
haven't yet.

 Regards,
VZ

Attachment: pgpRyzEQ0CcfK.pgp
Description: PGP signature


reply via email to

[Prev in Thread] Current Thread [Next in Thread]