• (nodebb)

    Of all the potential times this (and thinks like it) may be run against code as a black box, the percentage of people reading the implemenrtation will be small (so, still not a good thing, but low impact).

    There are shops where "especially if the idea of "optional parameters" exists " they are forbidden. If a function/method has optionals, they must all be explicitly stated (stupid policy, but a different WTF). In that environment that hard checks every parameter may even be the reason for this code existing.

  • (nodebb)

    I'm also left wondering two things:

    • Is it guaranteed that func1 and expr.arguments will be the same length?
    • What happens if func1 is shorter?
  • Prime Mover (unregistered)

    Am I the only one who feels uncomfortable with a structure that puts the "while" at the end of the do loop rather than at the beginning?

    You don't find out whether you're supposed to do whatever it is in the loop until you've already mentally processed it. Sorry, but I'd much rather find out whether I do it before I find out what it is I'm supposed to do.

    I remember my first formal programming course, which was Pascal. We were taught about 3 kinds of loop:

    1. The "For" loop, which you use when you know exactly how many iterations you want to do.

    2. The "Repeat ... Until" loop, which you use when you need to do the loop at least once, but you don't know how many times until you've evaluated the result of running it.

    3. The "Do While ..." loop, which is the most flexible, which you use when you don't even know whether you need to do it the first time.

    My brain still itches when I see these misused. A "for" loop with a "break" inside it is okay, because it's sometimes appropriate. But using a "do while (i < n)" and then the last line of the block is incrementing i, sorry but what's wrong with using a for loop? No I don't care what language you're using -- I've seen loop misuse in every language from Fortran to Java.

    So, "do while abuse" apologists, what would be the excuse for this, beyond not having been taught proper code grammar?

  • 516052 (unregistered) in reply to Prime Mover

    It's simple. For is as you say for. What you call "do while" is actually "while do". As in check before doing and loop until done. And the "do while" from this article is what you call "repeat until".

  • Mike5 (unregistered) in reply to Prime Mover

    Well, remembering the Pascal days, the 3 variant is a while () do S;. The do {} while(); is the C/C++/Java/JavaSvript/etc. variant of the repeat S until(); - it's just that in Pascal the latter runs until the test expression becomes true, and the JavaScript variant runs while the test expression is 'true'.

  • Bart (unregistered) in reply to Prime Mover

    Actually in Pascal it is: while .. do (not the other way around).

  • 🤷 (unregistered) in reply to Prime Mover

    I work as a developer for 7 years now, and the amount of times I encountered a "do ... while"-loop in the wild I can count on one hand. And only once was I in a situation where I thought "oh, a 'do ... while' will do nicely here!"

    Or, to use other words: I agree with you. I use for, foreach and while loops, and I find them much easier to process mentally than do-whiles.

  • 516052 (unregistered)

    Do-while is definitively a specialized case. I'll give you that. But I don't see how they would be hard to parse. Than again I've been programming for decades now so I probably find a lot of stuff intuitive that a sane man might not.

  • Prime Mover (unregistered) in reply to Bart

    Oh Bart, you're such a peadant.

  • Tim Ward (unregistered)

    Looks to me like the wrong language has been chosen. If you care about things like types of parameters, choose a typed language in which such things are first class constructs.

  • Brian (unregistered) in reply to Tim Ward
    Looks to me like the wrong language has been chosen.

    My thought exactly, any time I have to work with JavaScript. Simply the fact that there are so many frameworks that try to make it less of a trainwreck is a dead giveaway that there's something fundamentally wrong with it.

  • Steve (unregistered) in reply to Brian

    Javascript is the perfect solution for some tasks.

    The trouble is nobody has ever yet found out what one of those tasks is.

  • (nodebb)

    var found=false do {.....} while (found)

    Seems very clear to me....

  • (nodebb)

    I see do-while loops all the time on Stack Overflow, and almost all of them can be rewritten better as either for or while loops.

    What really bugs me is when they put the while keyword on a new line. Then it's not obvious that this is the end of a do-while loop; it looks like the beginning of a while loop where they mistakenly put ; before the body, creating an empty body.

  • Carl Witthoft (google)
    but someone went and made it hard.
    #thatswhatshesaid
  • Tim (unregistered)

    I don't think I've written a for,while, or do loop in the last 10 years. if you're iterating over a collection, use a collection iterator, it's what they're for. And if you're not iterating over a collection, think again - you probably are.

  • Sole Purpose Of Visit (unregistered) in reply to Tim Ward

    I'm a Typescript n00b (and try to avoid anything but elementary Javascript), but I suspect it depends upon which of the two environments applies.

    Typescript is (I believe) a runtime-typed generator language for Javascript. Javascript is what I would call Postel-typed (avoiding the static/dynamic wars).

    If this is pure Javascript, I don't see how type checking helps very much, because that's just not the way that Javascript works.

    If this is Typescript, then (again, as a n00b) I believe that this is just a bad design decision. Somewhere in the middle of that loop, I'd imagine that a type predicate is being called, relying on instanceof(). If you really want to do UnPostel-typed checking, I'd imagine that you're using the wrong Typescript mechanism. Something like Function Type Literals would make more sense:

    (arg1: Arg1type, arg2: Arg2type) => ReturnType
    

    Then again, I know absolutely nothing about anything to do with this. And I'd certainly agree that you choose Postel-typing or you choose the conservative alternative ... but you don't get to choose both.

  • ooOOooGa (unregistered) in reply to Prime Mover

    In C and its derivative languages, the 'do ... while' loop does run the loop block at least once. So it is appropriate to put the condition at the end of the block.

    It is the equivalent of what you listed for Pascal as the 'repeat ... until' construct. (I don't know Pascal at all, so I can't comment on the accuracy of the list of constructs and their meanings. I'll take your word for it.)

  • Bart (unregistered) in reply to Prime Mover

    peadant ??

  • (nodebb) in reply to Sole Purpose Of Visit

    Typescript is a compile-time typed version of Javascript. You annotate the types in the input file, and the "compiler" (transpiler, really) checks the types, and then generates Javascript if you haven't made any type-errors. There's no runtime checking. (So you may think your server's API returns a particular type, but it could return anything at all -- and you wouldn't know you're wrong until the Javascript code starts doing illegal things, unchecked by Typescript.)

    And for reference, I believe that Javascript is considered dynamically typed - once you declare a variable, you can stuff any type at all into it, changing types every single time. And once you get past the primitive types (string/number/boolean/undefined), everything is just type "object". (In my early JS code, I'd have a function that returns either array or false depending on whether it has something useful to return, and it worked just fine with the rest of my code.)

  • VI (unregistered)

    I'm not much of a type-ist, but I know you can't use (type1 == type2) as a condition for assignment - it has to be (value is-assignable-to variable-type), to allow for sub-classes and sub-types and implicit conversions. And TypeScript has a very complex type system, where a variable's type may be something like int or string or a object-with-these-keys, and the value would only have one of these types, maybe.

  • Duke of New York (unregistered)

    Tradition tells us that the ancient Mesoamericans invented zero. "Big deal," you might scoff, "who cares about inventing nothing?" But that just demonstrates your own ignorance, and one doesn't have to look far in code to find loops guarded with "if count == 0" because, 20 centuries later, someone continues to struggle with the idea that not doing is a way of doing.

  • Sole Purpose Of Visit (unregistered) in reply to PotatoEngineer

    Well, that was sort of my point (Typescript). I know the transpiler is compile-time checked. But, and we should really point this out to all Typescript programmers out there, that's not a whole lot of use when you're dealing with Javascript libraries.

    My n00b estimation of how often Typescript collides with Javascript libraries? A rough guess? 100%, give or take an epsilon here and there.

    So ... we're back to instanceof() and the like. Otherwise known as "runtime typing."

    I can see how this is appealing to the likes of the OP irritant. But it just feels wrong. Write Postelly things in Postelly type systems. Write UnPostelly things in a "properly" or "officiallly sanctioned" type-checking system.

  • Sole Purpose Of Visit (unregistered) in reply to Duke of New York

    "Do or do not. There is no try."

    Allowing for exception handling, of course.

  • PotatoEngineer (unregistered) in reply to Sole Purpose Of Visit

    You can use JS and TS together... kinda okay. You just desperately hope that the JS library has written some typings declarations, or else you write them yourself. Or, more likely, you write a catchall "moment is type any" declaration, and fall back on the usual JS development style, of "looking up the docs every 5 minutes because you've forgotten the exact type and order of parameters."

    And, for what it's worth, I have never once seen instanceof() used in TS or JS development, but I suppose it's just used in some other areas I'm not involved in. It's far more common to duck-type JS in my experience: "if it has a .length property, I might be able to treat it like an array" sort of things. (and getting bitten when you try to splice() a string, of course.)

  • ooOOooGa (unregistered)

    Reading through these comments makes me wonder who decided that creating an entire operating system in JavaScript was a good idea, and how on earth the project was ever even completed.

  • Sole Purpose Of Visit (unregistered) in reply to PotatoEngineer

    I'll betcha a dollar against a cup of coffee that this loop here eventually degenerates into an instanceof(), however. I can't see how it would work otherwise.

    But, yes. I take your points.

  • Sole Purpose Of Visit (unregistered) in reply to Sole Purpose Of Visit

    I should be more precise.

    I can see how native types and collections (for some Javascript definition of native types and collections) would work.

    But I don't see how that loop would make any sense if you're dealing with things that are "prototyped," which is a Javascript fundamental that is dealt with via Typescript in who not I knows how.

    At that point, as a n00b, I surmise that an instanceof() is going to be the sole reason to use this loop at all.

    (And, apologies to all the oldsters like me above: I really don't care about how the loop is structured. Back in the day, we used JR NZ, e

    My personal theory is that life would be a lot easier if every single programming language out there (saving the functional and declarative ones, for obvious reasons) had unconditional respeck for Z80 and Z8085 constructs.

    But that boat has sailed, unfortunately.

  • 516052 (unregistered) in reply to Tim

    There are plenty of reasons why you would want to itterate over a collection and still have an index. Also itterators don't give you the same freedom to modify the data structure and its members that a non itterator approach does. And than there are the cases where you really do just want to do something N times.

  • David (unregistered) in reply to Prime Mover

    Conversely, why not use the "do while" instead of a break in a for loop?

    There is no fundamental difference between

    for (;;;) {
        doSomething;
        if (condition)
            break;
    

    }

    and

    do {
        doSomething;
    } while (!condition);
    

    (Or even while do, depending on if the condition can happen even before the first loop can be executed)

    Some people prefer the do while instead of having a break in the for loop. Probably because that implies that you don't actually KNOW how many times you are going to run the loop, just that you might have a lower and upper bound (number of records, etc) and you want to exit the loop if you find what you are looking for. At least the do while is honest about it.

    You just use whatever you think it express better your intention for the task at hand. do while, while do and for loop are in the end just variations of a theme, they are just going to end up as code with GOTO/JMP instructions anyway :P

    And yes, death to those that put the while in a different line.

    Ah, REPEAT UNTIL... I just went back some 25 years ago when I started learning programming with Turbo Pascal. Such good times.

  • Best Of 2021 (unregistered) in reply to David

    Conversely, why not use the "do while" instead of a break in a for loop?

    That's worse in pretty much every way. Now I have to read inside the loop, not just at one end or the other, to find the exit condition. for(;;) or while(true) , when it's not actually an indefinitely executing loop (like a thread function or message pump or something) is a mini-WTF of its own.

    do ... while (or repeat ... until, a better formulation imo, having written Delphi for a bit) does have a valid place. Something like repeat { try to get thing } until(got the thing). This WTF of course is not it and a normal for loop (or iteration over collection - this is ES6 land, right? you can use Array.forEach?) should be used.

  • 516052 (unregistered) in reply to David

    I prefer to have while on a separate line. I also despise having brackets on the same line as anything else on principal. while() { }

    do { } while()

    or death.

  • 516052 (unregistered)

    And god dam it. It shrunk the brackets down. That was supposed to be: do \r\n{\r\n} \r\nwhile() and while()\r\n{\r\n}

  • Duke of New York (unregistered) in reply to Best Of 2021

    I don't need your holy war, Your do-while breaks or your infinite for. You're so nitpicky about braces While new features get ignored. I don't need your holy war!

  • David (unregistered) in reply to Best Of 2021

    I'm confused.

    I'm not advocating for the break inside the for loop, but rather for using do while, which by definition has the condition at the end, so why would you need to look for an exit condition inside the loop?

  • Some Ed (unregistered) in reply to Best Of 2021

    You always had to read inside the loop to understand it. Simply having a convention of not having 'goto', 'continue', 'break', 'return', 'exit', or 'longjmp' in the body of a loop doesn't guarantee that they won't be there. Simply having the convention of having all changes go through review before they go to production doesn't guarantee that nobody will make a change directly in production anyway. Just having a convention that one team generates all the code updates and a different team applies them, with that dev team not having prod access, does not guarantee that somebody who does have access to prod won't make a change there.

    I used to feel uncomfortable with my organization's decision to have all of the senior developers have access to prod and be the production support team. Then I heard from a former coworker who worked at a company with a firm separation between the roles, who had a six month debugging nightmare because they were having problems in production because one of the production team members decided to implement a breakfix change to a problematic update, and not only violated their process but did the wrong "fix". He put it behind the correct if statement, but simply returned nothing from the function, rather than taking the correct corrective action and continuing the loop.

    Worse, when my former coworker fixed the official version with the correct fix, the same maintenance team member decided to just not apply it, because it was supposed to fix something he'd already fixed. With no access to the prod environment, it took my former coworker months to find out this, and only did then because the problem prod team member called in sick, so his coworker had to do the next update. They sanity-checked first and determined what was in prod wasn't what the developer said was the old version.

Leave a comment on “Don't Do This”

Log In or post as a guest

Replying to comment #:

« Return to Article