[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [lmi] do_compute_column_widths_if_necessary()
From: |
Greg Chicares |
Subject: |
Re: [lmi] do_compute_column_widths_if_necessary() |
Date: |
Tue, 24 Apr 2018 21:53:51 +0000 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.6.0 |
On 2018-04-21 20:42, Vadim Zeitlin wrote:
> On Sat, 21 Apr 2018 19:54:27 +0000 Greg Chicares <address@hidden> wrote:
>
> GC> On 2018-04-21 13:08, Vadim Zeitlin wrote:
> GC> > On Sat, 21 Apr 2018 00:57:40 +0000 Greg Chicares <address@hidden> wrote:
[...]
> GC> > GC> I'm also not sure what the name
> do_compute_column_widths_if_necessary()
> GC> > GC> means--specifically the "if necessary" part. Is it unnecessary to
> call
> GC> > GC> this function at all in some contexts? Or OTOH is it always
> necessary
> GC> > GC> to call this function, but unnecessary to call it again after it has
> GC> > GC> been called once? (I'm guessing it's the latter, and that the flag
> GC> > GC> 'has_column_widths_' just means that the function has been called
> once.)
> GC> >
> GC> > Yes, this guess is completely correct.
[...]
> GC> AFAICT, it needs to be called after the last call to add_column()...so
> GC> wouldn't it make sense for add_column() to assert that this flag is
> GC> false, because any later call to add_column() would require calculating
> GC> the column widths again?
>
> Yes, this would be an improvement.
Assertion added.
> As usual, I tried to keep this code as simple as possible because this
> seems to be more in line with your preferences. Left to myself, I would
> probably do something to ensure that columns can't be added after computing
> their widths at compile-time, but this would make things more complicated
> and so I don't think you'd agree. But while a run-time check is not at all
> as good as a compile-time one, it's still better than nothing, I guess.
[...]
> GC> How can we be sure it's called exactly when necessary?
>
> I can write a prototype doing just this, but it would involve using
> separate classes and move semantics and I was rather discouraged by your
> reaction to my previous attempts to do it like this, so I'm not sure if
> it's really going to be useful... would it?
This comes up often enough in our conversations that I'd like to say a
few general words about it, even though I'm not sure whether they're
really applicable in this case.
Imperative logic + entropy --> spaghetti code
Inheritance metalogic + entropy --> lasagna code
I find spaghetti more digestible than lasagna. I don't know whether that's
just a personal preference attributable to the particular experiences I've
had over my programming career, or to mental habits, or to personality.
If there's a solid objective reason underlying this, it is that spaghetti
is linear: a single strand can be followed from one end to the other, and
no matter how often it twists, it never gets thicker. IOW, I can trace
and solve one isolated problem by following its execution in isolation.
Imperative logic is just a series of statements, one following another.
At least in procedural languages, there's always a control graph that
evolves along a single axis--time--and that's as simple as it can be.
But to follow a thread of execution through multiple inheritance layers,
one must first gain a good understanding of each layer. I can't just ask
where one bad value in a report came from: I must first understand that
it's a ReportWithXYZ, derived from ReportWithExtraStuff, derived from an
abstract base Report, because that one bad value may arise in any of those
layers. And if that's instantiated by an AbstractReportGeneratorFactory,
then there's a creational dimension crossed with an inheritance dimension.
To track down where that one bad value came from, I have to understand
the whole hierarchy--not just an imperative control graph, but also an
inheritance tree and another birth-life-death structure. I look upon such
things, and despair.
Re: [lmi] do_compute_column_widths_if_necessary(), Greg Chicares, 2018/04/21