[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)