9 ms·
I'm not sure you can call structured programming a fad! An awful lot of languages (I'd say all commonly used ones) use if/then/else, do..while, for..next, and
by johnaspden 5y ago
I'm not sure you can call structured programming a fad!
An awful lot of languages (I'd say all commonly used ones) use if/then/else, do..while, for..next, and so on, but I can't remember the last time I saw a program with a complicated control flow done by gotos.
Such things were common in the 1970s, in fact the first professional program I ever read did it that way, and it took me ages to work out what was going on.
One particularly confusing technique was to goto a computed expression. Leads to all sorts of interesting bugs.
The whole point of structured programming was "Don't do that! You can do everything you want to do with a small set of restricted control structures, and the control flow is much easier to read".
I'd say that idea won so hard that we don't even notice it.
- walshemj 5y agoOriginally Fortran only had arithmetic if's And I agree by the 70's spaghetti code with goto's was on the way out - though some early GWBASIC code had some gnarly practices.
- ufo 5y agoThe arithmetic if might be one of the best examples of how structured programming has become the new standard. In 1960, it was the only way to do "if" in the most popular programming language that existed at the time. Today, I bet that most programmers haven't even heard of it.
- ljm 5y agoLooks like arithmetic if is now just a comparator operator, like `<=>`.
- kevin_thibedeau 5y ago> I can't remember the last time I saw a program with a complicated control flow done by gotos. I've run across this in C demo code for a chip designed within the last 10 years. It was all goto soup in a god function.
- bitexploder 5y agoSome embedded developers just never got the memo about control flow constructs. You can find some truly bizarre and concerning development practices in the embedded world.
- lugged 5y agoI think it's a symptom of the field. A lot of arduino code is ghastly but mostly comes down to hardware people coding things for the first time and having zero professional development experience or formal education.
- nitrogen 5y agoThe reverse is true -- app developers see something "weird" in embedded code and think it must be wrong, but often there is a reason. E.g. the unintended vehicle acceleration scandals, where codebases were criticized for having large numbers of global variables... but it's because there's no allocation permitted, and message passing is more expensive than just setting a bit of memory in a massive cooperative multitasking loop. You might see weird stuff in embedded code because it needs to interact with flakey hardware using a flakey compiler, and be cycle accurate in the process.
- bitexploder 5y agoI get it. I’ve done enough systems program and reversed many more embedded systems, bug hunting for customers. There are still a lot of bad practices in the embedded world. It often exists outside of normal best practices. Many choices embedded devs make are just plain bad. Using outdated libraries and binaries from a decade or more ago, etc. it doesn’t have to be so bad. I haven’t found many embedded systems that weren’t really bad from a security perspective. The way these systems get developed is a huge part of the problem. One team building hardware, another building the software no one communicating. Everyone hoping for the best. Frantic cleanup in software to make it all work on top of hardware thet can no longer change. I am sympathetic to the embedded developers position, but they still seem to exist in a different universe from modern software dev. As a security practitioner I don’t blame the devs. I like to ask questions about how things got to be this way. How we can make it better. But make no mistake. A decade will pass and some embedded developer will still be linking some ancient binary or throwing together a bunch of sketchy CGI files that let an attacker scribble everywhere in memory. Embedded is like, the final frontier of software security :) That’s my lens anyway :)
- swiley 5y agoWell puppet doesn't have loops. I hope that's not because the "fad" is ending.
- lostcolony 5y agoThere are plenty of further restrictions (such as immutable languages that don't have loops, because loops require mutation, and so instead rely on recursion), or which eschew being concerned about control flow at all (such as puppet, SQL, Prolog, etc; any declarative language). Certainly, those languages aren't "undoing" structured programming.
- masklinn 5y ago> such as immutable languages that don't have loops, because loops require mutation, and so instead rely on recursion These two are not as intertwined as you make them. OCaml has mutation but not iteration.
- int_19h 5y agoOCaml has while- and for-loops. A better example might be Clojure, which has mutable variables (opt-in, like OCaml), but no traditional imperative loops - only recursion. However, even then, the syntax for its tail-recursive construct uses "loop" as a keyword.
- lostcolony 5y agoI said immutable -> !loops (p implies not q). You're saying !immutable -/> loops (not p does not imply q) It's a fair thing to mention, but you're not gainsaying anything I said; I never said anything about mutable languages that don't have loops. In fact, to the topic at hand, you would assume that to be the case, given that structured programming was intended to force loops on languages at the time (mostly mutable) that weren't using them (but instead were using gotos and the like)
- 1vuio0pswjnm7 5y ago"... I can't remember the last time I saw a program with a complicated control flow done by gotos." Perhaps not "complicated" enough, but here's a fizzbuzz in spitbol (a fast SNOBOL interpreter). This is an unstructured, goto based language for non-numeric computation developed at Bell Labs. Would love to see a faster version in some popular, "structured" scripting language in the same number of characters. I find I can write scripts in more aesthetically pleasing ways than with "structured" languages. But of course aesthetics is subjective. (The term "subjective" here means what looks good to you might not look good to me, and vice versa.) ;var a = 0 ;start a = a + 1 ;break lt(a,101) :f(end) ;x01 y = remdr(a,3) ;x02 z = remdr(a,5) ;x03 x = y + z ;x01a eq(x,0) :s(x06) ;x02a eq(y,0) :s(x04) ;x03a eq(z,0) :s(x05)f(x07) ;x04 output = 'fizz' :(start) ;x05 output = 'buzz' :(start) ;x06 output = 'fizzbuzz' :(start) ;x07 output = a :(start) ;end Perhaps the unintended benefit of gotos is that it becomes foolish to try to construct overly complex control flow. Whereas stuctured programmming seems to encourage control flow complexity. The use of the phrase "complicated control flow" in the parent comment is a great example. It suggests for the author structured programming allows and arguably therefore encourages such complexity. But what benefit is served by creating "complicated control flow". Why not aim for simpler control flow.
- mycodesucks 5y agoThis is the opposite of aesthetically pleasing to my eye.
- thaumasiotes 5y agoAesthetically, it bothers me that you compute x by calling remdr two extra times, as opposed to computing it as the sum of y and z... or the bitwise OR of y and z... What's the difference between :(label) / :s(label) / :f(label) / :s(label1)f(label2) ?
- 1vuio0pswjnm7 5y agos and f are different conditions s=success f=failure default is unconditional Is bitwise OR a built-in or would it require writing a separate function.
- jay_kyburz 5y agoI've been learning lua, and loops don't have a continue or a break. You can use a goto to jump out. I tried it but didn't like it. Might just be prejudices. :)
- darek 5y agoIf I remember correctly there is a break keyword, but continue is missing. At least in Lua 5.1 which is still the most popular one.
- jay_kyburz 5y agoYou're right, apologies. I'm on LUA JIT.
- shakna 5y agoLuajit should have the break statement (Compatibility is Lua 5.1 with some backports from 5.2, and a couple extensions).
- dgb23 5y agoReturn works within loops right?
- andi999 5y agoIt is a prejudice. Knuth and Torvalds think goto is valuable. See https://pic.plover.com/knuth-GOTO.pdf https://pic.plover.com/knuth-GOTO.pdf https://news.ycombinator.com/item?id=8760518 https://news.ycombinator.com/item?id=8760518 (Somewhere on the internet is a discussion when somebody suggested to remove all gotos in the kernel with structured programming, the answers were entertaining and insightful; I cannot find it right now though)
- pwdisswordfish8 5y agoHave you read Knuth’s article? It is a bit more nuanced than a wholesale defence of GOTO in preference to structured programming. It surveys various control flow structures that are not easily expressed in terms of IF conditions and WHILE loops (what structured programming advocates of the time argued to replace GOTO with), but more easily expressed with GOTO, and it argues that, since we don’t know which of those constructs will ultimately end up the most useful, it might be prudent to keep GOTO around, at least for a while, and not confine ourselves to simple conditionals and loops just yet. But if we do find better structured control-flow primitives, perhaps we may get rid of GOTO after all. The comments under the Torvalds link kind of point it out already: GOTO is used in the Linux kernel as a crutch for the deficiencies of C, like the lack of scope-based destructors, exceptions and the ability to specify which loop a BREAK statement targets. My favourite part of the Knuth paper is this: begin until error or normal end: if m = max then error ('symbol table full') fi; normal end; end; then error (string E) => print ('unrecoverable error,'; E); normal end => print ('computation complete'); fi; This is pattern-matching on a Result<(), String>, in 1974. How adorable! It’s a shame that innovation in this area has stagnated so much: most languages only feature IF, WHILE, FOR, single-level CONTINUE/BREAK, SWITCH (with fallthrough), and GOTO as an escape hatch in case the others are insufficient, just because they are so familiar. Only now languages like Python or Java are getting any form of pattern matching. Though props to the latter for at least allowing to break multiple loops by way of labelling the outermost one.
- lmm 5y agoState machines and actors are occasionally cited as good ideas here, and they seem like much the same kind of unstructured programming IME.
- m_mueller 5y agoWhy? You can easily emulate a state machine with a while loop, a switch case and one more level of if-branches. Abstracting those in a framework doesn't make it unstructured IMO.
- lmm 5y ago> You can easily emulate a state machine with a while loop, a switch case and one more level of if-branches. You can easily emulate GOTO much the same way.
- m_mueller 5y agoobviously, as long as the language is turing complete, but you just converted an unstructured program to a structured one.
- maskros 5y agoAnd gained nothing except more verbose syntax. The goto spaghetti is still spaghetti whether you use "goto" or "switch".
- m_mueller 5y agoDisagree. You eliminate backward gotos except for the while loop, which is much more clearly communicating the way to extend the code (by adding more states or state transitions) to the next person taking over. I‘m not categorically against goto in certain contexts (like C based systems programming), but IMO backwards jumps with goto need to be eliminated.
- lmm 5y ago
- tsss 5y agoThere are things beyond for-loops and gotos, namely recursion schemes. It's been a long long time the last time I wrote a for-loop and I don't miss them.
- TeMPOraL 5y ago> One particularly confusing technique was to goto a computed expression. Leads to all sorts of interesting bugs. Huh. I suppose the modern-day equivalent is commonly done with higher-order functions - in particular, callbacks, CPS and returning functions. I've worked with people who find this confusing (particularly the last one - functions returning functions).
- oaw-bct-ar-bamf 5y agoI believe that this confusion comes from the avoidance of low level details. A function is just a location in memory where instructions are stored. Returning a function is nothing else as returning a pointer to a memory location. In languages like Java that want to hide everything memory related I also was struggling with grasping what a function really is. Is it even allowed to return a function? Languages that hide memory locations and direct memory access are one of the reasons that some programmers are struggling with functions returning functions.
- zozbot234 5y ago> Returning a function is nothing else as returning a pointer to a memory location. That depends. If the language supports proper first-class functions, it's basically an instruction pointer plus a record of the variable bindings the function code is "closed over" (i.e. parameterized on). Many languages do support this nowadays.
- urthor 5y agoAbsolutely this. You need that machine language model of how a computer works to really understand programming, otherwise you are just guessing why stuff works. I'm not capable at all with assembler, can't write my own compiler. But my model of how a computer works, in my head, is "functions are just sequences of bits arranged as CPU instructions." I know how it works, even though I can't write a compiler or parser. And it's absolutely essential to how I program, even in the highest level languages (SQL explain plans).