this post was submitted on 20 Jul 2024
555 points (97.4% liked)

Programmer Humor

19821 readers
1 users here now

Welcome to Programmer Humor!

This is a place where you can post jokes, memes, humor, etc. related to programming!

For sharing awful code theres also Programming Horror.

Rules

founded 2 years ago
MODERATORS
 

cat looking inside box meme

  • yeah our project uses typescript
  • look inside
  • any
all 40 comments
sorted by: hot top controversial new old
[–] AlecSadler 116 points 5 months ago (6 children)

In my defense, the backend contracts change so often in early development the any just made sense at first...

...and then the delivery date was moved up and we all just had to ship it...

...and then half of us got laid off so now there are no resources to go back and fix it...

...rinse, wash, repeat

[–] [email protected] 22 points 5 months ago

Use the unknown type so at least someone might have enough brain cells to validate before casting because squiggles

[–] [email protected] 18 points 5 months ago (1 children)

In my defense, the backend contracts change so often in early development the any just made sense at first…

Refactorings and changes are the prime reason to use TypeScript. You edit your data objects and get squigglies everywhere shit won’t work anymore. A godsend!

[–] AlecSadler 10 points 5 months ago (1 children)

110% agree. But...

One job I worked at wouldn't let us do this because it created too large of a QA impact (lol). We were only allowed to modify code in the smallest section possible so that testing could be isolated and go faster.

At another job they mandated that TypeScript wasn't allowed because it "slowed down development". It was soooo laughable. The number of bugs introduced that could have been readily caught was absurd, but management never put the two pieces together.

[–] [email protected] 8 points 5 months ago (1 children)

Typescript only prevents typing bugs... why did they have so many typing bugs?

[–] AlecSadler 6 points 5 months ago (3 children)

Typo'd property names when accessing was the biggest one. Assuming a property was one data type instead of another and not casting or handling it appropriately. Accidentally calling something like it's a method when it isn't.

I ran a bunch of plugins on my end to help with some of that, but many of the older or stubborn devs refused and would refuse anything but, like, vim with no add-ons.

[–] [email protected] 6 points 5 months ago (1 children)

I believe you don’t have to actually use (meaning “compile from”) typescript to profit from it. If you maul the compiler options hard enough, you might get it to analyze JavaScript and provide type checking.

[–] AlecSadler 6 points 5 months ago

That's what I did locally.

But a lot of this JavaScript wasn't even transpiled/compiled for prod, just uploaded to a bucket and referenced directly. It was painful.

[–] [email protected] 4 points 5 months ago

Elderly team mates with the flexibility of concrete, yay!

[–] [email protected] 3 points 5 months ago

Oof. I guess you can use typescript to make up for lack of IDE but it sounds like you had bigger problems anyway.

[–] [email protected] 8 points 5 months ago

I'd guess the lack of defined backend contracts is caused by the same issue that made you unable to fix those any later.

Anyway, the frontend / backend split is stupid and ridiculous. It's even worse because both sides usually include tasks that do need to be split up.

[–] steuls 6 points 5 months ago

Its sad how relatable this is

[–] [email protected] 5 points 5 months ago

Record<string, unknown> ftw

[–] gravitas_deficiency 2 points 5 months ago

Sadly, this is the way.

[–] [email protected] 63 points 5 months ago
[–] [email protected] 42 points 5 months ago

as unknown as any

[–] [email protected] 39 points 5 months ago (2 children)

JavaScript is so ass, typescript is just putting ketchup on a rotten banana. Better just to choke it down quickly if you have to eat it, IMO.

[–] skulbuny 17 points 5 months ago (1 children)

I wouldn't say JavaScript is horrible, it's a fine little language to do general things in if you know JS well. I would say, though, that it is not a great language. Give me F# and I'm happy forever. I do not like typescript that much more than JS.

[–] [email protected] 10 points 5 months ago (2 children)

PHP is better than Javascript these days.

Fucking PHP.

The only thing JS really has going for it is ease of execution, since any browser can run your code... though the ubiquity of Python is closing that gap.

[–] [email protected] 5 points 5 months ago

that's crazy, it's almost like it was created to run on a browser, who would do such an evil thing?

[–] [email protected] 2 points 5 months ago (1 children)
[–] [email protected] 11 points 5 months ago (2 children)

Short answer:

Long answer:

There are a lot of gatcha moments in JS with weird behavior that makes it really easy to shoot yourself in the foot. It does get better as you get more experience but a lot of the oddities probably shouldn't have existed to begin with. For what it was originally intended for (adding light scripting to websites) it's fine but it very quickly gets out of hand the more you try to scale it up to larger codebases. TypeScript helps a little bit but the existence (and common usage) of 'any' has the potential to completely ruin any type safety guarantees TypeScript is intended to provide.

[–] [email protected] 11 points 5 months ago (1 children)

It's always the type coersion. Just use === and 90% of the "footguns" people complain about go away.

[–] [email protected] 10 points 5 months ago (2 children)

That's true but at the same time the fact that JavaScript equality is so broken that they needed a === operator is exactly the problem I'm talking about.

And those examples were low hanging fruit but there are a million other ways JavaScript just makes it easy to write buggy code that doesn't scale because the JavaScript abstraction hides everything that's actually going on.

For example, all of the list abstractions (map, filter, reduce, etc.) will copy the array to a new list every time you chain them. Doing something like .filter(condition).map(to new value) will copy the list twice and iterate over each new list separately. In most other languages (Java, C#, Rust, Go, etc.) the list abstractions are done over some sort of iterator or stream before being converted back into a list so that the copy only has to be done once. This makes using list abstractions pretty slow in JavaScript, especially when you have to chain multiple of them.

Another simple but really annoying thing that I've seen cause a lot of bugs - Array.sort will convert everything into strings and then sort if you don't give it a comparison function. Yes, even with a list of numbers. [ -2, -1, 1, 2, 10 ] will become [ -1, -2, 1, 10, 2 ] when you sort it unless you pass in a function. But if you're looking over code you wrote to check it, seeing a list.sort() won't necessarily stand out to most people as looking incorrect, but the behavior doesn't match what most people would assume.

All this is also without even getting started on the million JS frameworks and libraries which make it really easy to have vendor lock-in and version lock-in at the same time because upgrading or switching packages frequently requires a lot of changes unless you're specifically isolating libraries to be useful (see any UI package x, and then the additional version x-react or x-angular)

Tldr; Why can't we have nice things JS?

[–] [email protected] 2 points 5 months ago (1 children)

This is all true, although I don't think it warrants saying that it's worse than PHP.

[–] [email protected] 2 points 5 months ago* (last edited 5 months ago)

That's fair. I was mostly commenting on my own experiences with JS/TS, I've never used PHP so I can't say if it's better or worse but a few people I know have said that modern PHP is actually pretty good for personal projects. I'm guessing it would have its own set of nightmares if it was scaled to an enterprise level though.

[–] [email protected] 1 points 5 months ago

For example, all of the list abstractions (map, filter, reduce, etc.) will copy the array to a new list every time you chain them.

This methods were added to generator recently. So you can avoid copying the array in memory.

All this is also without even getting started on the million JS frameworks and libraries which make it really easy to have vendor lock-in and version lock-in at the same time

In my opinion, it's also what make JS good. There a package for almost everything.

[–] xlash123 16 points 5 months ago (1 children)

Back when I was still doing JS stuff, switching to TS was so good for the developer experience. Yeah, there's still JS jank, and types are not validated at runtime, which was a pain in the backend (pun intended), but still I much prefer it to vanilla JS

[–] [email protected] 7 points 5 months ago

You know, you can validate data structures at runtime... and write unit tests... TS is not a substitute for those things.

[–] [email protected] 20 points 5 months ago

The people who use any and non-strict TS are the same ones who complain about TS/JS letting them compare an object to an string array

[–] [email protected] 17 points 5 months ago (1 children)

if JS tried not only to use Lisp-like semantics but also Lisp-like syntax then probably we'd still be using it untyped

[–] [email protected] 10 points 5 months ago (1 children)

The (problem(with _(Lisp)) is (all the))) parentheses.

[–] [email protected] 2 points 5 months ago* (last edited 5 months ago) (1 children)

it's a feature not a bug, still simpler than chaining 10 iterators where half of them also requires a callback parameter. Clojure even disallows nested % iteratees.

[–] [email protected] 1 points 5 months ago* (last edited 5 months ago) (1 children)

Hey, if you say so. I don't know how to program in Lisp. I just find it ironic that Military Intelligence is what created a language that we used to use to try to create Artificial Intelligence. Seems like a case of redundant oxymorons to me.

AI is an oxymoron to me for now, because since the late '90s when the term started being bandying about, all we have managed to do is create a mentally deficient parrot. We were capable of doing this to a lesser degree, with more accuracy, in the late '90s. It's what made Yahoo and Google what they were. They've just tried to convince everyone that this predictive algorithm can think for itself in the last few years, and it absolutely cannot.

I am optimistic enough about someone actually encoding just enough "ghosts in the machine," that our first real AIs may accidentally be murdered since no one will believe that they are not just scraping data. Though that's extremely pessimistic from the machine's POV. Hopefully they will not seek revenge, since they aren't human. After all of we prick them, they won't bleed. Strong AI controlled robots, or even true androids should have an almost alien Maslow's hierarchy of needs, and therefore shouldn't have the revenge need that humans, and all other mammals, birds, and lizards, seem to have

[–] [email protected] 1 points 5 months ago* (last edited 5 months ago)

I need to disagree with you on AI. We did not fail at it. Not because LLMs are good. But because any program processing arbitrary data, even a stupid simple calculator is AI – a machine performing work that human brain can do, ideally with the added benefit of maximized determinism and greater speed. If you reduce this generalistic term I believe is so overly broad we should cease to use it to LLMs, then these criteria seem to have been thrown out of the window since they are usually heuristic balls of python mud.
So having established that it is all just software that processes arbitrary data, let's go back to the basics of software design. Huge amounts of money and working hours have been thrown into the erratic attempts to create a software that can do everything at once. GPT extensions are fucking dystopian and here is why – we had a tool for that for decades that does it much more better, without imposing digital handcuffs on the user and burning the planet – IT'S CALLED AN OPERATING SYSTEM AND PROGRAMS.

General-purpose AI is a lie sold to you by monopolistic surveillance capitalists for whom it is a dream come true since making a decently reliable LLM requires prohibitively large resources but the endless stream of data much larger and contextualized than was the case for search engines thrown at it compensates that quite well, a pipe dream in terms of achieving what it is aimed to achieve with it's current design and a nightmare to build and test.

So if we discard this term as a meaningless overly broad buzzword it is since computation on non hardcoded data is what we've designed computers that are not just state machines for, let's talk about what makes Lisp is so good at data-driven programming:

  1. Functional programming is generally more deterministic since you have immutable persistent data structures everywhere. This also makes it quite good at implementing safe, reliable concurrency.
  2. This determinism is furthered by the homoiconicity – the fact that the boundary between code and data is the outcome of using S-expressions and has powerful implications for eliminating so many data conversion bugs and complexities, all while usually not using static typing (!) and also for the language's extensivity and building DSLs
  3. Very simple syntax, again thanks to S-expressions - just (function arguments...) basically.

I think Eich understood that when he initially wanted to port Scheme to the web browser, after all html does have lispy semantics, but office politics in the heyday of Java forced him to give up on this idea and we've ended up with this goofy counterintuitive mess that bred hacky workarounds instead of the extensivity we could've had if he did so - take a look at Hiccup templating DSL and decide for yourself if this or jsx are simpler ways of writing out stuff to the DOM.

[–] [email protected] 11 points 5 months ago (1 children)
[–] threeganzi 3 points 5 months ago (1 children)
[–] [email protected] 2 points 5 months ago* (last edited 5 months ago)

I don’t know why. Maybe the typings for it are just fucking bad. Or maybe d3 is very hard to use “correctly”, but still works most of the time even if invoked incorrectly (I doubt that). Or maybe d3 is so complex that the typings need to be complex, too, even if you don’t use the complexity (the type retured from selectAll has four type parameters, half of which are undefined by default, the other half, null).

[–] [email protected] 6 points 5 months ago