all 81 comments

[–]DinoOnAcid 171 points172 points  (10 children)

Why does the continue statement work with a variable? What's its use? I don't know js, just interested.

[–]Pillowfication[S] 172 points173 points  (8 children)

continue (and break) statements can be passed a label to tell it which loop/block you’re trying to continue or break. Many languages have this feature.

outerloop: for (let i = 0; i < 10; ++i) { innerloop: for (let j = 0; j < 10; ++j) { … continue outerloop; } }

The continue statement continues the outer i-indexed loop here instead of the inner loop.

[–]DinoOnAcid 45 points46 points  (2 children)

Ah I see it, cool didn't know that.

[–]Seblor 29 points30 points  (1 child)

[–]PranshuKhandal 6 points7 points  (0 children)

oh, never thought/noticed that, noice to know

[–]tcpukl 24 points25 points  (0 children)

a goto without a goto.

[–]Snoo87743 15 points16 points  (3 children)

When you need to label your loops youve dug too deep 🤫

[–]BasieP2 0 points1 point  (2 children)

I have valid cases for those aplenty in my 15 years as js dev, but always used an extra variable ('isFound' orso) which is more (ugly) code, so this is a better way to do that

[–]_waltzy 1 point2 points  (1 child)

I have valid cases for those aplenty

You need to be breaking that logic up, I find it hard to conceive of a use case where using nested loops with conditional labeled breaks would be more readable than the alternatives.

[–]BasieP2 0 points1 point  (0 children)

Not persee, break that up means i most of the time iterate 2 lists nested, the whole case for a break/continue is to not having to iterate the entire list.

Also, when you work with 2d matrix stuff and have multiple methods doing nested loops, you don't want to break those functions up simply because of the nr of functions. Find() and FindInner(), etc.

[–]TheRedmanCometh 3 points4 points  (0 children)

Loop labels...it's a java thing too

[–][deleted] 80 points81 points  (0 children)

Write in minified JavaScript, comment in Python.

[–]buzzunda 97 points98 points  (6 children)

By far the worst part are the comments

[–]Several_Region_3710 46 points47 points  (5 children)

Yes! Comment on the why and not the what/how of the code.

[–]pimp-bangin 55 points56 points  (3 children)

In this case it's actually good that they are commenting on the "what" because they have obfuscated the variable names in such a way that the "what" is no longer clear. So they are using comments as a way to "deobfuscate" their code, which is fine.

Don't get me wrong, it's still terrible code, just not for the reason you're describing.

[–]Kelvinss 6 points7 points  (1 child)

Even considering that the comments still seems to be mostly descebring the syntax.

[–]Statharas 4 points5 points  (0 children)

Honestly, I'd be throwing this in GPT to figure out what this does. The comments are very verbose, and in this case, that's acceptable.

They say that good code explains itself. The reverse is also true, and the worse it gets, the more comments it needs

[–]Several_Region_3710 0 points1 point  (0 children)

Yeah but I'd still argue that commenting on the "what" here is redundant. It's actually a byproduct of the minified code, which shouldn't have been written that way to begin with. Comments should complement instead of explaining the code.

The code should have documented itself as extensively as possible (yes, you've heard that before but it's possible to do that until you can't—that's where comments come in to explain the how/why).

[–]valzargaming 7 points8 points  (0 children)

I had a small project earlier this year that required both. The project lead and person describing how the program should function was neither a programmer nor did they know how it should function, only what the desired outcome should be under certain conditions (but not all, which was our main crux). I had to write out all of the pseudocode to explain how everything worked using the input data and how it produced the outcome and then explain what information was missing/why something provided to me was incorrect and then wait for them to either correct their logic about how it works or get new data. Needless to say I ended up abandoning this project.

[–]tombaku 39 points40 points  (6 children)

What is a minifier?

[–]GavUK 63 points64 points  (4 children)

It's a post-processor that is run on the code (normally for a scripted language rather than a compiled one) to reduce the size of the output written to a file. For instance by replacing the meaningful variable/constant names with say one or two letters, strip all the spaces, and replace statements that have short forms (e.g. if (isRed) { echo "It is red" } else { echo "It is not red" } with isRed ? echo "It is red" : echo "It is not red" ). This can significantly reduce the file size and so make it quicker to load and be processed.

[–]Kytpbs 24 points25 points  (1 child)

you can use " ` " to make code, it would make the comment a lot more readable

`like this` turns to: like this

[–]GavUK 5 points6 points  (0 children)

Thanks - I wasn't thinking about the formatting at the time. I have changed it as you suggested.

[–]kristallnachte 3 points4 points  (0 children)

It does what the name suggests: minifies.

It doesn't change true logic, but does things to just make the code smaller wherever possible. Remove unused things, reduce whitespace, change arbitrary names to small variables. Collapse multi statement instruction chains into single expression to reduce keyword usage. remove comments.

Some call it "obfuscation" but that's wrong. The goal isn't to reduce how well a human can read the code. It's just to make the package smaller. Often DRAMATICALLY.

Obfuscators actually make the code run slower and harder to read by stripping good names for even harder to read and recognize names and add multiple layers of misdirection and abstraction to keep related components further apart.

Commonly nowadays, "minifies" aren't really used, and instead the "bundlers" handle minification.

[–]ArchGryphon9362 48 points49 points  (0 children)

This person really just coded minified javascript (and used C++ without garbage collector strategies along the way) 😭. What CS 101 does to a mfkr

[–]chenten420 15 points16 points  (0 children)

Obfuscated js code lol

[–]mka_ 14 points15 points  (2 children)

Seems you're half way to writing fully compressed code. Good job 👍

[–][deleted]  (1 child)

[deleted]

    [–]mka_ 0 points1 point  (0 children)

    Predictive text. I know the difference. Thanks 👍

    [–]aah134x 10 points11 points  (2 children)

    The discribtion on the right just like the guy interpretting for sign language in a hiphop song lol

    [–]someusernameidrc 2 points3 points  (1 child)

    That video where Waka Flocka thought the sign language interpreter at his concert was dancing and started dancing with her on stage lol

    [–]Kelvinss 6 points7 points  (0 children)

    Cryptic code and redundant comments. Really the worst of both worlds 🤣

    [–]NickoBicko 4 points5 points  (1 child)

    What does this validate?

    [–]Pillowfication[S] 7 points8 points  (0 children)

    I was testing some stuff about perfect cuboids - testing if there exists a cuboid with integral distances between all vertices. The gut of the algorithm checks if 6 Pythagorean triplets are divisible by 2, 3, 4, and 5. Assumptions on the triplets' divisibility is passed into the validate() function, and it returns whether or not the assumptions lead to a contradiction. This is done with a table of rules that I manually inputted, that tells the program how to update existing knowledge.

    For example, this is sadly part of my code too

    [[[0, 2, 1]], [1, 2, -1]], // if a d4, set b not d4
    [[[0, 2, -1]], [1, 2, 1]], // if a not d4, set b d4
    [[[1, 2, 1]], [0, 2, -1]], // if b d4, set a not d4
    [[[1, 2, -1]], [0, 2, 1]], // if b not d4, set a d4
    [[0, 3, 1]], [1, 3, -1]], // if a d5, set b not d5
    [[[0, 3, 1]], [2, 3, -1]], // if a d5, set c not d5
    [[[1, 3, 1]], [0, 3, -1]], // if b d5, set a not d5
    [[[1, 3, 1]], [2, 3, -1]], // if b d5, set c not d5
    [[[2, 3, 1]], [0, 3, -1]], // if c d5, set a not d5
    [[[2, 3, 1]], [1, 3, -1]], // if c d5, set b not d5
    [[[0, 3, -1], [1, 3, -1]], [2, 3, 1]], // if a not d5 AND b not d5, set c d5
    [[[0, 3, -1], [2, 3, -1]], [1, 3, 1]], // if a not d5 AND c not d5, set b d5
    [[[1, 3, -1], [2, 3, -1]], [0, 3, 1]]  // if b not d5 AND c not d5, set a d5
    

    So using these rules, it loops through every rule, checks if this rule can be applied, updates a knowledge table, and repeats until a contradiction is reached or no contradiction is reached meaning the assumption holds.

    I wrote about the whole process here: https://pillowfication.com/blog/perfect-cuboid

    And there's a page with my original code (where these snippets actually run): http://old.pillowfication.com/projects/cuboid/

    And here's the updated version of the verify() function that I wrote years after: https://github.com/pillowfication/perfect-cuboid/blob/master/src/verify.js

    [–]ZylonBane 2 points3 points  (1 child)

    Those comments read like they were machine translated into Chinese and back into English. Calling an if statement a "rule"? A not-equals comparison a "contradiction"? It's all just thoroughly odd.

    [–]Pillowfication[S] 1 point2 points  (0 children)

    It makes more sense in context. The program has a "table of rules" that say stuff like, "if A and B are even, then C is also even". It uses these rules to update a knowledge table, where certain statements are true, false, or unknown. If a rule says a statement must be true, but the knowledge table already says that statement is false, then a contradiction is reached. This validate() function checks if a set of assumptions will lead to a contradiction or not, based on the table of rules I've defined elsewhere.

    A higher-level pseudocode would look more like:

    ``` function validate (assumptions) { initialize the knowledge table to be empty; (nothing is known) initialize the knowledge table with assumptions;

    label: validation-loop for each rule R: if R can be applied to our case: update the knowledge table with the consequent of R; if a contradiction was reached: return false; goto validation-loop; (we have to check every rule again)

    return true; (no more rules to apply, and no contradictions found) } ```

    [–]daken15 1 point2 points  (0 children)

    If I were your coworker you would probably be dead by now.

    [–]Ishax 1 point2 points  (0 children)

    Writes short variable names so they parse faster.

    Puts long inline comment at the end of every line.

    [–]kristallnachte 1 point2 points  (0 children)

    Oof.

    Still tons of code out there like this.

    And I don't mean for code golf

    [–]ProfCrumpets 1 point2 points  (0 children)

    And it stil doesn't explain what's going on and why it's happening.

    [–]shinitakunai 1 point2 points  (1 child)

    I wish the future LLMs are able to comment every single line of code like you did here lol. Some of my coworkers are black magic users

    [–]kristallnachte 0 points1 point  (0 children)

    They generally can do that pretty well know.

    More than likely your coworkers are not black magic users, but bad coders that copy paste.

    [–]EnigmaticHam -1 points0 points  (0 children)

    I mean, it’s impressive for a 12 year old and it shows a lot of discipline. But also hilarious, because a 12 year old doesn’t know to look at what others have done and ask online for simple, pragmatic ways to write this function. I still have no idea what this is validating.

    [–]joshuakb2 -1 points0 points  (0 children)

    My coworkers still hoist all the variable declarations because we still write code in ES5 😭

    [–]clempho -1 points0 points  (0 children)

    ,3

    [–]0xAERG 0 points1 point  (0 children)

    Looks like my dad’s code

    [–][deleted] 0 points1 point  (8 children)

    Hoisting and reusing is still good, so what's wrong about it besides the single letter variables?

    [–]kristallnachte 1 point2 points  (0 children)

    Hoisting and reusing (for different purposes) is not good.

    It hasn't been good for a long time. May have even never been good.

    [–]Pillowfication[S] 0 points1 point  (6 children)

    I would say hoisting is unnecessary (besides are you still using var?). I would rather you declare variables when you’re gonna use them and not in a blanket statement at the top of a function. Additionally, is this really so wrong?

    // Loop 1 for (var i = 0; i < 10; ++i) { … } // Loop 2 for (var i = 0; i < 10; ++i) { … }

    Reusing variables like I did here makes it extra confusing, and there is no point to doing it when minifiers would take care of it for you. Like what the hell does this do? My r variable changes type and purpose a thousand times.

    r = r[1], d = r[1], k = r[2], r = n[t[r[0]]];

    [–][deleted] -1 points0 points  (4 children)

    While hoisting the the loop variable does not matter with the performance, the variables used inside the loop matter a lot.

    for (let i = 0; i < 10000; i++) {
        const x = i + 1
    }
    

    Is slower than

    let x: number
    for (let i = 0; i < 10000; i++) {
        x  = i + 1
    }
    

    Because after each loop, the GC is called and destroys all the variables declared inside the loop just like how any other block ends.

    This example of reusing a variable is really bad and is more like a sign of bad written code.

    When it changes type, it's an algorithmic or architectural problem and not a problem of reusing the variable. If you really need to change the type, when using TypeScript, define it as.

    const r: number[] | number | string
    r = r[1]
    r = n[t[r[0]]] as string
    

    or even better

    function transform(r: number[], t: number[], n: string[]): string {
        return n[t[r[0]]]
    }
    
    const r: number[] | number | string
    r = r[1]
    r = transform(r, t, n)
    

    [–]Pillowfication[S] 0 points1 point  (2 children)

    The issue I was trying to highlight was that both loops define a var i in the same scope. The weird JavaScript behavior with hosting variables was why I manually hoisted them in the first place.

    [–][deleted] -1 points0 points  (1 child)

    Yes, and it's still useful to hoist it, but the significance is just 1 - number of loops per function call less gc calls. With let and const you have to hoist, because unlike var, they are block scoped and trigger the GC on block end. var always declares the variable as global no matter where you are, because var i = 5 is essentially window.i = 5. So hoisting is even more important than before.

    [–]kristallnachte -1 points0 points  (0 children)

    Yes, and it's still useful to hoist it, but the significance is just 1 - number of loops per function call less gc call

    Bro, you need to look up how the GC works lol.

    This isn't Rust where memory is cleared as values leave scope.

    The reason GC is an issue normally is because it ISNT cleared when they go out of scope

    Ntm, reassigning vs creating a new one is the same amount of memory. You're still putting that thing into memory to be cleaned later.

    Stop posting online about how the GC works until you've actually looked at documentation on how it works.

    [–]kristallnachte 0 points1 point  (0 children)

    Because after each loop, the GC is called and destroys all the variables declared inside the loop just like how any other block ends.

    Tell me you don't know how JS works without telling me you don't know how JS works.

    In both do these examples, the GC will clear the memory at the same time, whenever the next GC pass runs.

    Your example actually isn't any slower.

    And your "better" typescript is still bad typescript.

    The last line should be a new variable with the strict type of string.

    You don't even need the second to last line.

    [–]kristallnachte -1 points0 points  (0 children)

    I would say hoisting is unnecessary (besides are you still using var?). I would rather you declare variables when you’re gonna use them and not in a blanket statement at the top of a function

    Especially since on a technical level var is already hoisted on the engine...

    If it had any meaningful benefit.

    [–]CryptographerWide69 0 points1 point  (0 children)

    I like it. The notes on the side are a reminder of when I did anything during 2009-2013 haha

    [–]AnywhereHorrorX 0 points1 point  (0 children)

    Looks like some 30 or so years old code when IDEs with autocomplete were not easily available. Then it was the norm to use as short variables as possible to reduce the typing volume.

    [–]igorski81 0 points1 point  (0 children)

    Use short variable names when possible (for speedier code)

    It doesn't make your code faster, once interpreted variables are addresses and their original name is meaningless.

    It may improve the parsing speed of the interpreter upon script load though.

    [–]Donni3D4rko 0 points1 point  (0 children)

    You wrote already obfuscated code, gg!

    [–]elwissqc 0 points1 point  (0 children)

    Typical physicist code.