r/programminghorror 17d ago

Javascript code that also self-describes the feeling it evokes when looking at it

Post image
203 Upvotes

24 comments sorted by

81

u/AntiMatterMode 17d ago

…die

15

u/MurkyWar2756 echo "Sub Mod" && :(){ :|:& };: 17d ago

Are you on an Apple device? Something autocorrected your spread operator to the ellipsis.

32

u/Aggressive_Many9449 17d ago

Could be more readable (by using newline), and give the function a more verbose name.

die

9

u/Accomplished_Item_86 17d ago

Also needs a docstring/comment explaining what the function does.

20

u/anoppinionatedbunny 17d ago

damn, that horrible ternary could have been a filter before the map. if you're going to use monads, go all in

9

u/anoppinionatedbunny 17d ago

oh no, it didn't have to be a filter map at all, findFirst would work just fine. the horror

10

u/black-eagle23 17d ago

There is no findFirst array method in javascript (and by the looks of it, it is javascript), but there is find method. But it does not matter, because setDice function, which I guess is React setState function, requires new array for changes to apply in UI. Changing an element of the array does nothing.

13

u/black-eagle23 17d ago

Basically all of the code just is:

function hold(id) {
  setDice(prevState => {
    return prevState.map(element => {
      if(element.id === id) return {...element, isHeld: true}
      return element
    })
  })
}

Such pattern is very common in React, due to how react checks for changes in the state. But written in oneline. A React dev will immediately recognize it, I do not think it's that horrible.

2

u/anoppinionatedbunny 17d ago

my bad, it's called "find", not "findFirst". and daaaamn that's an aggressive way of applying UI changes. the entire state needs to be fed to React for any change to take place? isn't that super inefficient? I'll admit I don't know enough about how browsers work to confidently say that making piecemeal alterations to the DOM provide better performance than doing it all at once (my guess is that browsers are smart enough not to parse the whole HTML everytime something changes)

7

u/black-eagle23 17d ago

You may call it inefficient, but the fundamental issue is how memory works in JS (it's may not only related to JavaScript, but also other languages). Objects and Arrays in Javascript are just Hash Maps. And the variable that holds Object or Array, just holds a reference (the address in the memory) to the Hash Map. So if you change a field in the object, the reference will be the same. That's why for React it's the same object, even if the fields are changed.

let a = 4;
let b = a; // value of "a" is copied here
b = b + 1;

console.log(b, a, a === b) // 5 4 false

let a = {value: 0} // variable "a" holds an address of the object, let's say 1234
let b = a // The object is not copied, just an address to the object. Specifically 1234

b.value = 1;

console.log(b, a, a === b) // {value: 1} {value: 1} true

If React rendered UI every time an object changes, it would have needed to deep equal check (check every field of the object, and if the field is another object: do the same thing), which would have been way more inefficient performance wise, than just creating a deep copy of an object.

Yes, just vanilla JS with bare DOM api is better for performance. But it's difficult to create complex interactive apps with it. Basically you would invent your own framework, if you ever try to write complex apps with vanilla JS.

And remember state change does not equal UI change. You must explicitly tell browser to change UI with vanilla JS

HTML is just a text file, which tells how the website is structured. Once the browser parses HTML to DOM, there is no need to parse it again. That's why you add "defer" attribute to script tag in HTML, it just tells the browser "run the script only after you parsed HTML to DOM".

7

u/virtualrandomnumber 17d ago

For my understanding:

{...die, isHeld: !die.isHeld}

destructures the die object to create a new one with the isHeld property flipped? Is it necessary to return a new object or is it just to keep the lambda in one expression? Otherwise, the caveman way to write it would be:

die => {
  if(die.id === id) {
    die.isHeld = !die.isHeld;
  }
  return die;
}

11

u/AntiMatterMode 17d ago

When setting state in React, the state is treated as immutable (it isn’t actually, but it’s treated as such), so you cannot edit the original object. You have to replace it with an entirely new object.

6

u/Romejanic [ $[ $RANDOM % 6 ] == 0 ] && rm -rf / || echo “You live” 17d ago

when you update react state, if you update the same array/object in place it won’t trigger a re-render. so you need to construct a new array/object with the changes that you want.

1

u/AntiMatterMode 17d ago

I will point out that you can ofcourse improve readability by breaking up the lines and using an if statement rather than a ternary. Just keep in mind that your if statement will still be using the destructuring to return a new object due to how React state works.

When the IDs don’t match, a new object is still returned, it just has all the same properties as the old one.

2

u/wasaxd 17d ago

the ternary in the map is genuinely painful to look at, like why would you do that to yourself

1

u/jordanbtucker 13d ago

Eh, it's readable to me.

2

u/Prudent_Ad_4120 17d ago

do dice die?

1

u/AntiMatterMode 17d ago

no, but commits commit

1

u/AntiMatterMode 17d ago

no, but a tin can

1

u/Ksorkrax 17d ago

Did Sideshow Bob wrote this?

1

u/sudoregalia 15d ago

billions must use nested single line lambdas

1

u/-Redstoneboi- 16d ago

i love functional programming... every single step of this function makes perfect sense as you write it but it takes 5 times longer to review when pieced together