D component programming is a joke (Was: Re: Component programming)
John Colvin
john.loughran.colvin at gmail.com
Thu Aug 1 02:23:53 PDT 2013
On Thursday, 1 August 2013 at 00:47:43 UTC, H. S. Teoh wrote:
> On Wed, Jul 31, 2013 at 11:52:35PM +0000, Justin Whear wrote:
>> On Thu, 01 Aug 2013 00:23:52 +0200, bearophile wrote:
>> >
>> > The situation should be improved for D/dmd/Phobos, otherwise
>> > such D
>> > component programming remains partially a dream, or a toy.
>> >
>> > Bye,
>> > bearophile
>>
>> I disagree with your "toy" assessment. I've been using this
>> chaining,
>> component style for a while now and have really enjoyed the
>> clarity
>> it's brought to my code. I hadn't realized how bug-prone
>> non-trivial
>> loops tend to be until I started writing this way and avoided
>> them
>> entirely.
> [...]
>
> One of the more influential courses I took in college was on
> Jackson
> Structured Programming. It identified two sources of programming
> complexity (i.e., where bugs are most likely to occur): (1)
> mismatches
> between the structure of the program and the structure of the
> data
> (e.g., you're reading an input file that has a preamble, body,
> and
> epilogue, but your code has a single loop over lines in the
> file); (2)
> writing loop invariants (or equivalently, loop conditions).
>
> Most non-trivial loops in imperative code have both, which
> makes them
> doubly prone to bugs. In the example I gave above, the mismatch
> between
> the code structure (a single loop) and the file structure (three
> sequential sections) often prompts people to add boolean flags,
> state
> variables, and the like, in order to resolve the conflict
> between the
> two structures. Such ad hoc structure resolutions are a
> breeding ground
> for bugs, and often lead to complicated loop conditions, which
> invite
> even more bugs.
>
> In contrast, if you structure your code according to the
> structure of
> the input (i.e., one loop for processing the preamble, one loop
> for
> processing the body, one loop for processing the epilogue), it
> becomes
> considerably less complex, easier to read (and write!), and far
> less bug
> prone. Your loop conditions become simpler, and thus easier to
> reason
> about and leave less room for bugs to hide.
>
> But to be able to process the input in this way requires that
> you
> encapsulate your input so that it can be processed by 3
> different loops.
> Once you go down that road, you start to arrive at the concept
> of input
> ranges... then you abstract away the three loops into three
> components,
> and behold, component style programming!
>
> In fact, with component style programming, you can also address
> another
> aspect of (1): when you need to simultaneously process two data
> structures whose structures don't match. For example, if you
> want to lay
> out a yearly calendar using writeln, the month/day cells must
> be output
> in a radically different order than the logical
> foreach(m;1..12) {
> foreach(day;1..31) } structure). Writing this code in the
> traditional
> imperative style produces a mass of spaghettii code: either you
> have
> bizarre loops with convoluted loop conditions for generating
> the dates
> in the order you want to print them, or you have to fill out
> some kind
> of grid structure in a complicated order so that you can
> generate the
> dates in order.
>
> Using ranges, though, this becomes considerably more tractable:
> you can
> have an input range of dates in chronological order, two output
> ranges
> corresponding to chunking by week / month, which feed into a
> third
> output range that buffers the generated cells and prints them
> once
> enough has been generated to fill a row of output. By
> separating out
> these non-corresponding structures into separate components,
> you greatly
> simplify the code within each component and thus reduce the
> number of
> bugs (e.g. it's far easier to ensure you never put more than 7
> days in a
> week, since the weekly output range is all in one place, as
> opposed to
> sprinkled everywhere across multiple nested loops in the
> imperative
> style calendar code). The code that glues these components
> together is
> also separated out and becomes easier to understand and debug:
> you
> simply read from the input range of dates, write to the two
> output
> ranges, and check if they are full (this isn't part of the
> range API but
> added so for this particular example); if the weekly range is
> full,
> start a new week; if the monthly range is full, start a new
> month. Then
> the final output range takes care of when to actually produce
> output --
> you just write stuff to it and don't worry about it in the glue
> code.
>
> OK, this isn't really a good example of the linear pipeline
> style code
> we're talking about, but it does show how using ranges as
> components can
> untangle very complicated code into simple, tractable parts
> that are
> readable and easy to debug.
>
>
> T
Add in some code examples and that could make a nice article.
More information about the Digitalmars-d
mailing list