[HN Gopher] Flowcharts of programming language constructs
       ___________________________________________________________________
        
       Flowcharts of programming language constructs
        
       Author : martinfjohansen
       Score  : 156 points
       Date   : 2020-02-14 14:13 UTC (8 hours ago)
        
 (HTM) web link (www.progsbase.com)
 (TXT) w3m dump (www.progsbase.com)
        
       | azhenley wrote:
       | Best article I have read in a while. I'm going to try to
       | incorporate this into my PL course.
        
       | PacifyFish wrote:
       | What did the author use to make the charts?
        
         | martinfjohansen wrote:
         | I used "yEd live".
        
       | emmanueloga_ wrote:
       | I think flow charts are a lot more useful when the granularity is
       | more coarse: the boxes should represent functions, not the logic
       | inside.                   compute thing -> predicate true ------>
       | compute some other thing             |         -> predicate false
       | ->|             \---------------loop-----------/
       | 
       | ... etc ...
        
       | raslah wrote:
       | I actually really like flowcharts, though they are somewhat
       | inefficient to draw out more complex structures, they are great
       | for working out small sections of thorny logic. The only issue I
       | sort of take those in the article is the physical flow is a
       | little distracting when decisions don't branch laterally. having
       | them continue top to bottom sort of throws me off. perhaps its
       | just because i draw them with branches to the side.
        
       | MadWombat wrote:
       | I don't know about everyone else, but to me these are confusing
       | as fuck. In continue/break/early return diagrams, there is no
       | second condition, so it is not clear when/why the dotted line
       | logic path happens. The "no fall-through" has so many arrows it
       | takes some zen meditation to figure out what it means. And the
       | exception diagram is just amazing, does the catch block get
       | executed no matter whether there was an exception or not? Because
       | there is an arrow leading to it from the regular, no exception,
       | path. I could go on, but it becomes progressively more and more
       | bizarre.
        
         | martinfjohansen wrote:
         | Hi, I am the author of the article, thanks for noting an error
         | in the exception and finally diagrams! I have fixed the error
         | where controlflow always went to the catch block.
        
         | grawprog wrote:
         | >I don't know about everyone else, but to me these are
         | confusing as fuck.
         | 
         | I was alright right up until it got to exceptions. Simple
         | statements are fairly nicely represented in flowchart form and
         | almost condense the information a bit. Then it hits exceptions
         | and everything after that just got so convoluted it became
         | pretty ridiculous. Imagine trying to write out even 100 lines
         | of modern code like that. You'd need a page the size of the
         | side of a barn just for that.
        
         | keithb- wrote:
         | I agree. The semantics even within this set of flowcharts is
         | confusing: blocks start out representing statements but by the
         | time you get to Dependency Injection, they represent anything
         | (library, service, etc.). Also the dotted-line vs solid line
         | doesn't help. With Goto or Exception, the dotted line _is_ the
         | process, not the alternative which is solid. Those need to be
         | inverted because  "normal" flow of control from statement to
         | statement is altered and the "exceptional" flow is now active
         | and other statements are ignored. Just waiting for someone to
         | say "we tried this with UML already. please just stop."
        
       | _0ffh wrote:
       | Pretty decent, but covers the pre-test loop as "loop"
       | (unqualified), omitting the post-test loop.
        
       | zabzonk wrote:
       | A brilliant explanation of why no-one uses flowcharts.
        
         | chrisseaton wrote:
         | These graphs are how the compiler I work on represents your
         | programs while it's compiling them!
        
           | throwaway17_17 wrote:
           | This is essentially the point I made in a comment above,
           | these representations are valid considerations for a
           | programmer to weigh when selecting abstractions and
           | constructs to implement some functionality. But it seems like
           | very few people agree.
        
         | notacoward wrote:
         | ...because if they did, they might realize that some of their
         | favorite structures are a hot mess. Seeing things in a new way
         | often leads to learning, which a good developer would welcome.
         | Personally I can't remember the last time I used an actual
         | flowchart, but I do use state machines. Sometimes I'll go
         | through an exercise of re-casting complex logic as a state
         | machine. Often, that leads to a realization that making the
         | state machine explicit would yield far more testable and
         | maintainable code than leaving it in its more common
         | if/loop/nested-function form.
        
           | AnimalMuppet wrote:
           | > ...because if they did, they might realize that some of
           | their favorite structures are a hot mess.
           | 
           | They may only be a hot mess _when expressed as a flowchart_.
           | But so what? I 'm not programming in flowcharts. If
           | exceptions can do what I want cleanly, why do I care if it's
           | a mess considered as a flowchart? That's not my problem.
           | 
           | This argument is like saying that the library function I call
           | is a mess of a flowchart. Why should I care? Can I express
           | what I need to express cleanly by calling that function, or
           | not?
           | 
           | Of all the arguments against exceptions, "it's got a mess of
           | a flowchart" is the absolutely least relevant one.
        
             | throwaway17_17 wrote:
             | The flow charts in the link represent control flow.
             | Compiler optimizations are, in part, constrained by their
             | ability to map and statically determine control flow. So I
             | think it is a grave mistake to say that something having a
             | 'mess of a flowchart' is the least relevant concern about
             | some PL construct. The implication that a flowchart
             | representation offers nothing to a programmer, implies that
             | the performance characteristics of your code does matter to
             | the programmer. So sure, in some application domains
             | (although I don't think there are any) performance may take
             | a backseat to performance and efficiency, this information
             | is useful and can very well illustrate the pitfalls and
             | trade offs of using certain constructs in code.
        
               | AnimalMuppet wrote:
               | I'm pretty much never worried about the performance of
               | the "exception taken" case. The compiler can be really
               | quite inefficient there before I have any reason to care.
               | 
               | There are places to worry about compiler efficiency. I
               | don't think that this is one of them.
        
           | whatshisface wrote:
           | > _they might realize that some of their favorite structures
           | are a hot mess_
           | 
           | Normal brain: Find the representation that best expresses the
           | structure to discover the hidden simplicity in everything.
           | 
           | Galaxy brain: Use flowcharts to draw out how exceptions work,
           | forget your previous understanding, and then realize that
           | they are too complicated for anyone to use.
        
           | gugagore wrote:
           | I strongly agree that multiple ways to look at things is
           | good.
           | 
           | Programming languages have different "things" built in. Like,
           | if you have re-entrant function calls, then your language has
           | a built-in data structure called "the stack". If you have
           | some algorithm that needs a stack, you have the choice of
           | using the built-in stack, or using an explicit stack.
           | 
           | If you have a programming language with some sort of type
           | system, then you have tagged data built-in. You can model
           | your domain in the type system, or you can model your domain
           | using a tuple like (tag, datablob).
           | 
           | If you have object-oriented programming with dynamic (single)
           | dispatch on the first argument, then your language somewhere
           | has a built-in data structure called a
           | table/dictionary/associative-array. If you want to implement
           | some sort of switching behavior you can do a switch on the
           | `tag`, or encode the tag in the type system, and use dynamic
           | dispatch.
           | 
           | Some programming languages have support for asynchronous
           | calls. That programming language has a built-in scheduler of
           | sorts. You can use it, or build your own, (or use the OS!).
           | 
           | A state machine, I think, is a great example of the same
           | idea. Your CPU has a bunch of state (e.g. the program
           | counter), and your programming languages has a bunch more
           | state (like the current stack frame, the line number). You
           | can encode your state machine in that, or you can model it
           | explicitly. How well you can do it "implicitly" depends on
           | other language features, like whether you have coroutines.
           | 
           | I think it's challenging, without expertise that might come
           | only from having solved an identical problem already, to know
           | ahead of time when to use these built-in things or roll your
           | own. When you mention testing, I think that's a great example
           | of expertise you've acquired. If you would like to test
           | certain invariants in your state machine, e.g. "a transition
           | from A to B never happens", then you're going to have a hard
           | time doing so if your state machine's state is encoded in the
           | line number of your language interpreter or the program
           | counter, or whatever.
        
           | gnulinux wrote:
           | Exceptions are rather easy to reason in the code but their
           | flow chart looks like a hot mess. So your argument is
           | invalid?
        
             | carapace wrote:
             | > Exceptions are rather easy to reason in the code
             | 
             | In _some_ code, for _some_ people.
             | 
             | > their flow chart looks like a hot mess
             | 
             | In code where the "exceptions are rather easy to reason"
             | about the flowchart would _also_ be easy to read.
             | 
             | In code where the exceptions hide a flowchart that's a hot
             | mess the exception syntactic sugar _hides_ the mess.
        
               | airstrike wrote:
               | One could argue hiding the mess is the whole point of the
               | exception. It allows you think about the problem with a
               | much smaller cognitive load.
               | 
               | I'm not suggesting every code with exceptions is good.
               | Just saying that not every exception is bad, and many are
               | indeed great.
               | 
               | I can't imagine writing Python without try blocks...
        
         | tartoran wrote:
         | They can be useful though, like once in a blue moon on a white
         | boarding session with non-technical users, explaining a bug or
         | something like that
        
           | DonHopkins wrote:
           | They're great for compressing lyrics!
           | 
           | Rick Flow:
           | 
           | https://pbs.twimg.com/media/DHnyCwiXsAAFyzq.jpg
           | 
           | Circumstances In Which Whipping It May Be Appropriate:
           | 
           | https://gypsywitchcampfire.files.wordpress.com/2015/08/whip-.
           | ..
           | 
           | Total Eclipse of the Heart:
           | 
           | https://i.pinimg.com/originals/86/17/e8/8617e878f9c33ab3a3ba.
           | ..
           | 
           | We Will Rock You:
           | 
           | https://www.edrawsoft.com/template/lyric-flowchart.png
           | 
           | Let It Be:
           | 
           | https://i.pinimg.com/originals/a7/74/b5/a774b576f45a6eb71a42.
           | ..
           | 
           | All You Need Is Love:
           | 
           | https://www.researchgate.net/profile/Alex_Ruthmann/publicati.
           | ..
           | 
           | Modern Love:
           | 
           | https://i.pinimg.com/originals/8f/fc/9a/8ffc9a199caa1da49ec1.
           | ..
        
             | tartoran wrote:
             | Yes, this is a great use. I wonder if there's any tool to
             | automate this.
             | 
             | I just gave Modern Love a listen, thanks, this was great.
        
               | DonHopkins wrote:
               | Paul Lamere from The Echo Nest made an awesome music
               | analysis demo called "The Infinite Jukebox" (for when
               | your favorite song just isn't long enough), for
               | automatically finding loopable points in music. And it
               | can use that analysis to stretch a song out to any
               | duration you want, by seamlessly skipping and looping
               | parts of it to shorten or stretch it. It's interactive,
               | so you can point and click on the arcs to control how it
               | loops at any point.
               | 
               | https://en.wikipedia.org/wiki/The_Echo_Nest
               | 
               | http://infinitejukebox.playlistmachinery.com/
               | 
               | Infinite Jukebox
               | 
               | For when your favorite song just isn't long enough
               | 
               | This web app lets you upload a favorite MP3 and will then
               | generate a never-ending and ever changing version of the
               | song. Infinite Jukebox uses the Echo Nest analyzer to
               | break the song into beats. It plays the song beat by
               | beat, but at every beat there's a chance that it will
               | jump to a different part of song that happens to sound
               | very similar to the current beat. For beat similarity the
               | uses pitch, timbre, loudness, duration and the position
               | of the beat within a bar. There's a nifty visualization
               | that shows all the possible transitions that can occur at
               | any beat. Built at Music Hack Day Boston 2012.
               | 
               | Billie Jean Forever:
               | 
               | http://infinitejukebox.playlistmachinery.com/?trid=TRSFLT
               | X13...
               | 
               | Scatman (Ski-Ba-Bop-Ba-Dop-Bop) by Scatman John:
               | 
               | http://infinitejukebox.playlistmachinery.com/?trid=TRXKEZ
               | N13...
               | 
               | Lots more cool Echo Nest demos:
               | 
               | http://static.echonest.com/labs/
               | 
               | http://static.echonest.com/labs/demo.html
        
               | tartoran wrote:
               | Wow, I didn't know about this. Thank you, this is great
               | !!
               | 
               | [0] This is a slightly related vaporware loop which, I
               | don't know, I find it mesmerizing.
               | 
               | [0]: https://invidio.us/watch?v=-RFunvF0mDw
        
       | Supermancho wrote:
       | This is a wonderful idea, but by the given numbering scheme, I
       | can identify a slew of problems.
       | 
       | [1a. If] _Note This is the first time we see synchronous calls,
       | decisioning, and the representation makes no specific callout to
       | the structure. The structure IS the case.
       | 
       | [4. Break] _Inconsistency _Confusion This is the first time we
       | see a specific part of the flow called out as the structure (it
       | isn 't a structure). This is flow control, not a construct. This
       | confusion plagues the rest of the document.
       | 
       | [7. Switch (No Fall-Through)] _Inconsistency _Confusion This is
       | the same as If /elseif.../else/, but the post goes with the oddly
       | specific "switch". Would be more appropriate as [1c.
       | if/elseif.../else] and a [1d. Switch] - The different terminology
       | if/switch does not change the fact they are the same structure.
       | Grouping Switch-type by name is a bad choice.
       | 
       | [9. Local Goto] _Omission The Goto example has no exit node.
       | 
       | [11. Exceptions] _Mistake The exception travels the stack,
       | meaning (from the perspective of the original parent function),
       | from grandchild to the child, to the parent catch.
       | 
       | [12. Finally] _Omission _Confusion Finally should be it 's own
       | block, since it is treated as such and has an implicit catch
       | mechanism, even if it's not always required in the syntax.
       | 
       | [13. Blocking, Synchronous Calls] _Confusion This is rather
       | pointless. All the flows, prior, were blocking. Now introducing
       | another metaphor that changes past examples is inconsistent.
       | Blocks which are synchronous (blocking) are represented by 2
       | different forms. It's unnecessary.
       | 
       | [14a. Non-Blocking, Asynchronous Call, Callback] _Inconsistency_
       | Confusion There is a whole function called, which should be
       | represented by a starting and ending node.
       | 
       | [14b. Device Input] _Inconsistency_ Confusion This isn't even a
       | different construct. Event handling is what this is and is poorly
       | represented, in the same way as 14a.
       | 
       | [15. Framework] _Mistake_ Confusion This isn't a construct, nor
       | is it an accurate representation. Frameworks are a collection of
       | idioms, which usually has little to do with constructs (as
       | defined in the beginning). It feels like the author has gone off
       | the rails here.
       | 
       | [18 Come-from & 19 Aspects & 21 Destructor] _Confusion? The size
       | of the block is supposed to indicate a specific syntax, which is
       | inappropriate for describing logical constructs. They should be
       | full sized and optionally labeled blocks, as they are evaluated.
       | 
       | [20 Dependency Injection] _Confusion This is another "timing adds
       | a new way to represent things" issue. There's no difference
       | between an Aspect and DI, logically.
       | 
       | [22. Defer] *Confusion Adding data (even a function) to a
       | separate stack, which is called later, does not make the diagram
       | presented.
       | 
       | All in all, this needs work. Even the grouping description at the
       | bottom does nothing to help make this more useful.
        
       | tabtab wrote:
       | The C-style switch/case construct is obsolete and awkward, and
       | cleaner alternatives exist, such as VB.net's technique. There is
       | no need for "Break".
       | 
       | The following could be added to C-style languages without
       | overlapping with the existing syntax:
       | select(a) {             when 1,2,3 {...}             when 4 {...}
       | when 5,6 {...}             ...             otherwise {...}
       | }
       | 
       | C# recently added a pattern-matching alternative, but it's still
       | a bit verbose for most needs.
        
         | nneonneo wrote:
         | GCC has had case ranges as an extension for a long time now:
         | https://gcc.gnu.org/onlinedocs/gcc/Case-Ranges.html
         | 
         | It's a far cry from general pattern matching (a la Rust,
         | Scheme) but it's helpful in some circumstances. Otherwise, you
         | can also stick multiple case labels together, i.e.
         | switch(x) {             case 1 ... 4:             case 7:
         | case 9 ... 16:                 ...             default:
         | ...         }
         | 
         | I don't see why you need to call the C-style construct obsolete
         | and awkward, though. It works plenty well for enumerations,
         | which is basically what it was designed for. If you need to do
         | something more fancy, if/else if chains always work.
        
           | tabtab wrote:
           | Ranges are nice, but not a replacement for sets. (Allow
           | both!) The main "fix" I propose is to get rid of the Break
           | statement and the very need for it. If you have set-based
           | lists, you don't need "fall through" behavior because you can
           | have more than one item per matching expression.
           | 
           | The Break statement is _error prone_ because it 's easy to
           | forgot. Some languages "solved" that by making Break
           | required; but if it's required, then it's superfluous: code-
           | bloating eye clutter. If you never used a language that
           | didn't need "Break" you may not understand how annoying it is
           | to go back.
           | 
           | My suggestion above allows C-ish languages to add a
           | modernized version and yet keep the existing construct for
           | backward compatibility. In other words, the old one would be
           | "deprecated".
        
       | proc0 wrote:
       | I love this! Visually seeing computation flow is great for
       | understanding what the code is doing.
        
       | edflsafoiewq wrote:
       | The goto diagram contains an erroneous arrow and an extra block.
       | It should look like                      o            |
       | v         +--#         |         |  #<-+         |  |  |
       | |  v  |         +->#--+
        
       | notacoward wrote:
       | Pretty neat. Three things that occurred to me while reading it.
       | 
       | (1) Makes it pretty clear why exceptions are even more of a
       | control-flow nightmare than goto. What a messy graph.
       | 
       | (2) The 'defer' diagram is a big WTF. Couldn't even figure out
       | which box is supposed to represent which statement in the
       | example.
       | 
       | (3) I'd love to see a graph of the control flow when you throw in
       | a few spurious lambdas like "advanced" C++ programmers tend to do
       | (and similar in a few other languages). Might even make
       | exceptions look good.
        
         | jfkebwjsbx wrote:
         | > when you throw in a few spurious lambdas
         | 
         | What do you mean?
        
         | LessDmesg wrote:
         | (1) There's nothing messy about that graph. It's just two
         | nested function calls. An exception by itself is just a goto to
         | the catch block.
        
           | poiuyt098 wrote:
           | yep, the goto example is doing something completely different
           | and less than the exception code, of course it will look more
           | messy.
        
         | avodonosov wrote:
         | exceptions are simple and convenient
        
           | DonHopkins wrote:
           | Except when they're not.
        
             | avodonosov wrote:
             | Don't blindly repeat what Go fans say, it's useful to use
             | own head sometimes.
        
         | dabei wrote:
         | Exception is a nightmare only if you use it as a general
         | purpose control flow mechanism.
        
           | DonHopkins wrote:
           | That's the exception that proves the rule.
        
           | notacoward wrote:
           | Unfortunately, many do. When that includes popular libraries
           | and frameworks, "abuse" becomes idiomatic or even strictly
           | necessary. When it's in the language itself, such as Python's
           | use of KeyError or StopIteration, that's even more true.
           | Since better alternatives exist for most exception use cases,
           | I'm of the opinion that direct language support was a bad
           | idea. A more general and explicit cousin of signal handlers
           | would suffice for those few "stop the world" cases, and can
           | be done via library functions. Optional types, multiple
           | return values, or plain old error codes (I like Zig's "non-
           | ignorable error code" approach) suffice for the rest.
        
         | bibyte wrote:
         | My takeaway was the exact opposite of yours. For example the
         | goto graph seems very intuitive and simple. But it is much more
         | complex to reason about compared to exceptions. My takeaway was
         | that simple graphs like these can't really explain the pros and
         | cons of high level programming constructs.
        
         | zozbot234 wrote:
         | There's actually a fairly natural way of representing Result-
         | like types (including exceptions) in a flow chart. Draw
         | multiple "exit" terminals for the function, one for "success"
         | and one for each error case. Then a function invocation can
         | have multiple flowlines leading from it, one for each case. And
         | one can "rethrow" the exception quite naturally, by having a
         | flowline for a "rethrown" exception lead to an exit terminal of
         | its own. This also applies by analogy to the case of multiple
         | _entry_ terminals, which come up most naturally when desugaring
         | async functions.
         | 
         | (It's actually even simpler than that when accounting for the
         | functor and monad properties of Result<T, Err>, but the
         | graphical representation for a "functor" or "monad" is a bit
         | more complex; these would be drawn as labeled regions, and
         | functor and monad properties would describe how such regions
         | can be "merged" or "combined".)
        
         | rovolo wrote:
         | RE (2): Defer. The diagram has an extra box in the control flow
         | which is unnecessary. You can label the big boxes from top to
         | bottom like so: A E B <unnecessary> D C.
         | 
         | A good use case for understanding the control flow of 'defer'
         | is when cleaning up resources.                   mutex.lock();
         | defer { mutex.unlock(); }              val f =
         | File.open(filename);         defer { f.close(); }
         | // write to file
         | 
         | It's a nice construct because it keeps construction and
         | destruction close together instead of far apart
         | mutex.lock();         val f = File.open(filename);
         | // write to file              f.close();
         | mutex.unlock();
        
         | lwb wrote:
         | My impression was that the article made the exceptions graph
         | much more complicated than it needed to be. Each function
         | doesn't need three boxes, and they don't need to each throw
         | exceptions twice. IMO exceptions are much cleaner in practice
         | and are great for things like "kill this script" or "throw a
         | 500 error".
        
           | edflsafoiewq wrote:
           | Actually the exceptions graph is simplified. The code to
           | perform unwinding is not depicted.
        
         | ken wrote:
         | If you think exceptions look messy as a flow chart, try
         | conditions! It's be like exceptions x come-from.
         | 
         | And yet in practice, it's really not that confusing.
         | Expressivity counts for more than the number of branch opcodes
         | generated by the compiler.
        
           | DonHopkins wrote:
           | It all boils down to "flaggy code" -vs- "spaghetti code" (or
           | vexillology -vs- pastafarianism).
           | 
           | https://wiki.c2.com/?GoTo
        
       | DonHopkins wrote:
       | The Nassi-Shneiderman diagram is one way of representing
       | structured program flow by dividing up a two-dimensional area. It
       | can't represent unstructured gotos and exceptions, though.
       | 
       | https://en.wikipedia.org/wiki/Nassi%E2%80%93Shneiderman_diag...
       | 
       | >A Nassi-Shneiderman diagram (NSD) in computer programming is a
       | graphical design representation for structured programming. This
       | type of diagram was developed in 1972 by Isaac Nassi and Ben
       | Shneiderman who were both graduate students at Stony Brook
       | University. These diagrams are also called structograms, as they
       | show a program's structures.
       | 
       | >Overview: Following a top-down design, the problem at hand is
       | reduced into smaller and smaller subproblems, until only simple
       | statements and control flow constructs remain. Nassi-Shneiderman
       | diagrams reflect this top-down decomposition in a straightforward
       | way, using nested boxes to represent subproblems. Consistent with
       | the philosophy of structured programming, Nassi-Shneiderman
       | diagrams have no representation for a GOTO statement.
       | 
       | >Nassi-Shneiderman diagrams are only rarely used for formal
       | programming. Their abstraction level is close to structured
       | program code and modifications require the whole diagram to be
       | redrawn, but graphic editors removed that limitation. They
       | clarify algorithms and high-level designs, which make them useful
       | in teaching. They were included in Microsoft Visio and dozens of
       | other software tools, such as the German EasyCode.
       | 
       | >In Germany, Nassi-Shneiderman diagrams were standardised in 1985
       | as DIN 66261. They are still used in German introductions to
       | programming, for example Bottcher and Kneissl's introduction to
       | C, Baeumle-Courth and Schmidt's introduction to C and Kirch's
       | introduction to C#.
       | 
       | >Nassi-Shneiderman diagrams can also be used in technical
       | writing.
       | 
       | When Ben Shneiderman and Ike Nassi (who were grad students at the
       | time) submitted their paper about them to Communications of the
       | ACM, it was quickly rejected on October 4, 1972, with the most
       | brutal rejection letter Ben Shneiderman has ever received.
       | 
       | But then they submitted it to the unrefereed ACM SIGPLAN, where
       | it was published in August 1973, and since then it has been cited
       | many times, widely implemented by many tools, and used for
       | educational and documentation purposes. It's a great example of
       | the importance of persistence for people whose new ideas are
       | brutally rejected by respected authorities:
       | 
       | Flowchart techniques for structured programming:
       | 
       | https://dl.acm.org/doi/10.1145/953349.953350
       | 
       | Scan of the brutal referee's report:
       | 
       | https://www.cs.umd.edu/hcil/members/bshneiderman/nsd/rejecti...
       | 
       | >My first thought was to write a referees report which would by
       | its sarcastic nature be funny. For example, I thought of writing
       | that it was a sound, useful theory, but it wasn't practical
       | because it would be difficult to design flowcharting templates to
       | be manufactured and sold.
       | 
       | >I guess, however, that it is best to come right out and say that
       | I feel the best thing the authors could do is collect all copies
       | of this technical report and burn them, before anybody reads
       | them. My opinion is that it shows the inexperience and ignorance
       | of the authors with respect to programming in general, and their
       | misunderstanding of so-called structured programming.
       | 
       | >To say that [BEGIN body END] should be written as [NS diagram]
       | is ridiculous. Even more ridiculous is having to write [DO i=1 TO
       | N; DO J=1 TO N; S = 0; DO K=1 TO N; S=S+A(I,K)*B(K,J) END
       | C(I,J)=S END END] as [NS diagram].
       | 
       | >The authors mention that "the ease with which a structured flow-
       | chart can be translated into a structured program is pleasantly
       | surprising". My retort is "yes, just erase those silly boxes!"
       | 
       | >Flowcharts are a crutch we have invented to try to understand
       | programs written in a confusing style. This was due to our
       | ignorance of the programming process and what was needed -- after
       | all, programming is only 20-30 years old. So-called "structured
       | programming" helps to limit us to, as Dijkstra calls them,
       | "intellectually manageable" programs, in which case flowcharts
       | are completely useless and in fact a hindrance to programming.
       | They shouldn't be used.
       | 
       | >I shudder at the thought of further explorations revolving
       | around the context-free nature of this [flowchart] language.
       | 
       | Ben's rejection letter story:
       | 
       | https://www.cs.umd.edu/hcil/members/bshneiderman/nsd/rejecti...
       | 
       | >Rejection letter from the Communications of the ACM
       | 
       | >Ben Shneiderman, June 12, 2003
       | 
       | >Our submission of the structured flowcharts to the
       | Communications of the ACM was quickly rejected, on October 4,
       | 1972, by the Programming Languages Editor David Gries of Cornell
       | University. He included a single anonymous reference letter which
       | is on paper that has a Cornell University watermark. I assume
       | Gries gave our paper to one of his colleagues (you can play the
       | guessing game too), who wrote the most brutal rejection letter I
       | have ever gotten.
       | 
       | >The reviewer wrote: "I feel that the best thing the authors
       | could do is collect all copies of this technical report and burn
       | them, before anybody reads them." As graduate students, this
       | stinging rejection shocked us, but we kept getting enthusiastic
       | responses from people around us. We sent the paper to the
       | unrefereed ACM SIGPLAN Notices, where it was published in August
       | 1973. It didn't take long for others to produce extensions,
       | software tools, and applications of structured flowcharts.
       | 
       | >The next problem was theft of the idea. I had sent a draft to
       | respected colleagues, and soon others published slight
       | variations. One of these respected colleagues was Ned Chapin, who
       | greatly troubled us by publishing what he called 'Chapin Charts.'
       | A friend of mine sent me his published paper with a note
       | encouraging me to sue. For several years I feared that Chapin's
       | reputation and his frequent professional seminars would wind up
       | leaving the idea tied to his name, but as the decades passed, the
       | ending has proved to be a happy one. We called the idea
       | 'structured flowcharts, but they are widely known as Nassi-
       | Shneiderman Diagrams.
       | 
       | >Another problem was the appearances of patents for variations on
       | our idea, but these have not limited the widespread recognition
       | we have gotten over the years.
       | 
       | >I wish every graduate student or young inventor would have the
       | pleasure of seeing his/her ideas spread so far and influence the
       | work of so many people. I also hope that the story of the bold
       | rejection of our novel idea and its eventual international
       | success, is an inspiration for anyone whose new ideas are
       | rejected by some respected authorities.
       | 
       | More on Ben Shneiderman and NS diagrams:
       | 
       | https://news.ycombinator.com/item?id=11368430
       | 
       | https://news.ycombinator.com/item?id=11370099
       | 
       | https://news.ycombinator.com/item?id=22093072
        
       | lwb wrote:
       | The point this article makes most clear is exactly to what extent
       | C++ has the attitude of "screw it, let's put it in". There are
       | only a handful of constructs listed that C++ doesn't implement.
       | 
       | Also, TIL about "long jump". Seems like a feature I'd never use
       | in a million years, but maybe it has its applications.
        
         | TFortunato wrote:
         | LongJmp can be used as a way to implement exceptions at a low
         | level, especially in languages like C, where you dont have them
         | as a language construct.
         | 
         | You call SetJmp, where you would want to put your try/catch
         | blocks, then no matter how deep down some call stack you go, if
         | an errir occurs, you can immediately jump back to where you
         | called setjmp and handle it / report the error or whatever,
         | rather than having to handle and bubble up the error by at
         | every intermediate level, "returning" your way up the call
         | stack.
        
       | inetknght wrote:
       | As someone who's self-taught everything, this is... awesome. It's
       | exactly what I needed to be able to up my game in describing code
       | to management using the flowcharts they've asked for.
        
         | throwaway17_17 wrote:
         | If you find these flowcharts instructive, and I think that you
         | are well founded in doing so, good on you. A majority of other
         | comments seem to be of the opinion that pointing out the
         | complexity of control flow generated by the constructs in a
         | language is a negative. It certainly seems like the prevailing
         | attitude is 'if I can't see it, it doesn't exist.' But you said
         | you were working on game code, so I will encourage you to keep
         | thinking about the complexity of the choices you make in which
         | constructs to use and don't buy into the thought that says
         | performance implications are not a really concern.
        
           | inetknght wrote:
           | > _you said you were working on game code_
           | 
           | Actually, I didn't. I said I wanted to "up my game" which is
           | a phrase commonly meaning "to get better". Said another way:
           | I needed to get better at describing code to management.
           | 
           | > _I will encourage you to keep thinking about the complexity
           | of the choices you make in which constructs to use_
           | 
           | Indeed, management generally wants simpler code even at the
           | cost of performance. Simpler code generally translates to
           | cheaper developers and cheaper maintenance.
           | 
           | > _don't buy into the thought that says performance
           | implications are not a really concern_
           | 
           | I actually write DNA analysis software. Performance
           | implications definitely _are_ a concern. :)
           | 
           | But performance is useless if I'm the only developer who
           | understands how it all comes together (eg, high bus factor).
           | So I've been writing a _lot_ of documentation to that end,
           | from file-level down to the systems-level and bit-level
           | descriptions. I really would like better support for diagrams
           | in markdown.
        
         | zabzonk wrote:
         | In case you haven't gleaned it from the majority of comments
         | here, flowcharts are a terrible way to describe code,
         | particularly modern, multi-threaded code that uses exceptions.
         | Don't go there.
        
           | crimsonalucard wrote:
           | This is because flow charts are two dimensional. What you
           | need is a 3rd dimension to represent parallelism. These
           | programs are better represented as 3d structures rather then
           | 2d flow charts or even text.
        
             | AnimalMuppet wrote:
             | 3D. I like it. I think I agree.
             | 
             | The closest I've seen to anything that actually _does_ that
             | is UML. But it does so only by having multiple different
             | diagrams. That 's like having a drawing with a front view
             | and a side view - it's not a 3D diagram, it's two 2D
             | diagrams that you can use to kind of see what's going on in
             | 3D.
             | 
             | I don't know of any good system of notation that does what
             | you're asking, nor any software for drawing or viewing such
             | diagrams. But I agree that 2D flowcharts don't represent
             | parallelism well, and that 3D looks like a better answer.
        
           | inetknght wrote:
           | I quite agree. Unfortunately management wants single-threaded
           | code and wants it documented with flowcharts. So right now
           | there's lots (!) of clouds detailing "this calls into another
           | API documented in another flowchart..."
        
             | AnimalMuppet wrote:
             | To me, that screams "put your resume out on the street".
             | 
             | I mean, I'm not opposed to documentation. It's important.
             | But if your management thinks that flowcharts are the way
             | to do it, I wonder what millennium they think it is.
        
               | inetknght wrote:
               | Indeed? Flowcharts aren't the only documentation. Swagger
               | describes the API parameters, flowcharts describe the API
               | code flow, and text provides a story, and comments in the
               | code describe particulars.
               | 
               | Flowcharts are just where I've felt that I've
               | significantly underperformed; where management has asked
               | for more of them.
               | 
               | Putting my resume on the street is something I do often.
               | Want to look at it?
               | 
               | If you think flowcharts aren't the way to describe code
               | flow, then I'm curious what method you think is better.
        
               | AnimalMuppet wrote:
               | Ah. Flowcharts were all you mentioned, so I assumed (bad
               | move) that they were all you did.
               | 
               | Depending on what exactly you are doing, parts of UML
               | _might_ be better. It lets you describe different aspects
               | with different diagrams, so that, if one kind of diagram
               | is sub-optimal for showing some aspect of what 's going
               | on, another kind might be better.
        
       | edflsafoiewq wrote:
       | Speaking of reasoning, I believe a Hoare proof of correctness for
       | a flowchart is
       | 
       | * a choice of a precondition and postcondition, Pre(B) and
       | Post(B), for every basic block B
       | 
       | * for every basic block B, a proof that {Pre(B)} B {Post(B)}
       | 
       | * for every arrow a : B1 -> B2, a proof that Post(B1) /\ Cond =>
       | Pre(B2) where Cond is the condition for the arrow to be taken
        
       | theaeolist wrote:
       | Have a look at these diagrams for PL concepts, but done formally
       | and with execution rules:
       | 
       | https://tnttodda.github.io/Spartan-Visualiser/
        
       ___________________________________________________________________
       (page generated 2020-02-14 23:00 UTC)