[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [lmi] Are NAND assertions difficult to understand?
From: |
Greg Chicares |
Subject: |
Re: [lmi] Are NAND assertions difficult to understand? |
Date: |
Sun, 25 Apr 2021 22:22:54 +0000 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Thunderbird/78.9.0 |
On 4/25/21 2:07 PM, Vadim Zeitlin wrote:
> On Sun, 25 Apr 2021 11:11:18 +0000 Greg Chicares <gchicares@sbcglobal.net>
> wrote:
>
> GC> An insurance policy comes into being when it is "issued";
> GC> that occurs on its "issue date".
> GC>
> GC> Some events can occur only on the issue date, while others
> GC> can occur only after the issue date, so it's important to
> GC> know whether the policy was issued today.
>
> After being traumatized by dealing with dates and times for so many years,
> I've acquired a conditional reflex consisting in becoming very nervous
> whenever I hear the word "today". So, even though it's probably irrelevant
> here, I'd like to ask: what does "today" mean exactly, i.e. in which time
> zone is the date determined? And do we really want the "issued today" flag
> to become false as soon as the clock strikes midnight in it?
The present goal is to fulfill the rules in '7702.html' [5/8]:
| Events occurring on different days are never combined. All
| adjustment events and material changes that occur on the same
| date are combined together and processed as one single change.
Any sensible way of determining today's date is okay. I'm sure
there are detailed rules covering time zones etc., but they're
coded into an administration system that serves as an arbiter:
today's date is whatever that system deems.
> GC> A policy has a "duration", which is the number of full
> GC> years elapsed since the issue date.
> GC>
> GC> For example:
> GC>
> GC> issue date date today duration? issued today?
> GC> ---------- ---------- --------- -------------
> GC> 2021-03-05 2021-03-05 0 yes
> GC> 2021-03-05 2021-03-07 0 no
> GC> 2021-03-05 2028-03-05 7 no
> GC>
> GC> One subsystem passes
> GC> struct {int duration; bool issued_today;} args = {/*values*/};
> GC> to another, which must validate the passed-in object by asserting
> GC> the following invariants
>
> I also realize that you're not asking about this and probably can't change
> it, but it would be really great if we could sidestep the question by not
> having to assert these invariants in the first place and rather ensuring
> that they're always satisfied by construction.
From a change that I haven't committed yet:
+/// Both 'gpt_scalar_parms' and 'gpt_vector_parms' were designed as
+/// simple parameter objects, and each was originally intended to be
+/// passed to one function only, so it was okay to assert invariants
+/// only where they were passed in. For 'gpt_vector_parms', that's
+/// still true. But 'gpt_scalar_parms' has acquired more members and
+/// more uses, and more invariants, so arguably it is no longer a
+/// "behaviorless aggregate".
These simple parameter objects (structs) don't have ctors. That's
okay if they're passed to only one recipient, which can assert all
preconditions. Some data are received from external systems that
have been known to pass bad data, which we can only diagnose but
cannot prevent.
That said, I suspect that I can reduce the problem somewhat by
reworking these structs. One of them has grown so much (in as-yet
uncommitted work) that it probably needs to be split into two.
> If we don't need to deal with the not yet issued policies at all, this
> could be as simple as using "std::optional<int> duration", where invalid
> duration would indicate that the policy has been issued today.
Some people are allergic to shellfish, or tree nuts; I'm allergic
only to pointers and std::optional. But there are safer ways to
accomplish the same thing:
- something like std::pair<int duration, bool issued_today>, but
with mechanics to enforce invariants;
- simply let duration = -1 mean unborn, which is the same as
today's "duration = 0; issued_today = true"
Is there anything really wrong with this -1 sentinel?
> GC> --expressed as simply as I can imagine:
> GC> args.issued_today → 0 == args.duration
> GC> 0 != args.duration → !args.issued_today
> GC> or in natural language:
> GC> if the policy was issued today, its duration must be zero
> GC> if duration != 0, the policy cannot have been issued today
> GC> What's the clearest way to express that in code?
>
> The clearest way is to translate the statements above to the code word
by
> word, i.e.
>
> if(args.issued_today)
> {
> assert(args.duration == 0);
> }
> if(args.duration != 0)
> {
> assert(!args.issued_today);
> }
Glad to hear you say that. I do believe it's the clearest way;
I was just worried that conditional assertions would seem bizarre.
> This is, of course, verbose, but -- assuming we have to keep this data
> representation -- I would define functions for working with it anyhow and
> we could (and should) just have a member function in the struct containing
> these fields called assert_duration_consistency() or something like that
> and just call it from all the places where it's needed. And writing the
> above just once, in this function, seems to be clearly worth it from
> clarity vs brevity point of view.
As long as this thing is a struct, whose members can be assigned freely,
I'd prefer that it have no member functions. If it needs member functions,
then I should make it a class, with private data, and the usual accessors
and mutators (which can enforce invariants).