I am regularly up at night in a cold sweat worrying about how if I suddenly find a technically fulfilling job, realizing I forgot everything about computers after a decade on working on meaningless front end JavaScript framework.
What you do as your first job massively influences you career. I did .NET for years by the fluke that is what my first job did. If they did Java, I would be an expert in Java. If I worked somewhere they needed a compiler written in C++ I would have done it and may have a compiler career.
The paradox is as a graduate you generally, unless very exceptional or well connected, or live in the (not "a") tech city, just need to get that first job.
It is hard to get that breaking opportunity, and so that thing that will have echoes throughout your career, you don't have much control over! The reason it is hard to get the first job is because it needs interview experience, and you have very little proof yet. You are asking a company to take that leap of faith.
Later side stepping is possible but very hard as you are competing with people who can be paid the same as a web dev with deep experience.
Also as a young person back then, I had approximately zero confidence, both in myself and even that programming is a good thing to do. Getting into it was very weird, I was probably the only person at my high school of hundreds who geeked out on electronics and programming, for example.
Nowadays with HN and other sites, there is an online community such that even in a country town you can get a sense of community and what is possible. With that any graduate now could hatch a decent plan for their career. They might take any job to pay the bills, but aim to get into a FAANG for example, knowing what it pays and how to go about it. 2020's are amazing.
On the front end, the trends tend to be more extreme; people will not take you seriously unless you give up on whatever tools you use and go straight for React or VueJS... Then when TypeScript comes along, everyone has to switch to that... I couldn't believe it when people started combining JSX with TypeScript... It's essentially a double-transpiled language now... The trends keep adding more complexity and everyone is forced to switch to that regardless.
Introducing a transpiled typing system on top of a dynamically typed language is a recipe for all sorts of insane complexity, which is what I experience whenever I try to use TS. If you consider all the time and effort it took to introduce types for every NPM project out there, all the development of the language itself, the effort expended by individual devs and teams to learn the syntax...
...might it have been the same amount of effort just to introduce some strong types into Javascript itself? It's not like the language can't adapt, and there are already some strong types when you're working with the graphics APIs.
It doesn't make sense; kind of like transpiling lower level assembly code into higher level C code. You could always argue that there is value in forcing arbitrary constraints onto developers but in the end, you need to ask the question "is it worth the complexity?"
TS is really flexible and you can do some crazy gymnastics with it - I don't favour that. Just keep it very simple and don't go crazy with the generics.
I've never had a problem at all, I've never had to dig into what was transpiled.
I spent a ridiculous amount of time trying to design types. At some points I couldn't figure it out, or I ran into some limitation of the language to express what I need. So my code has a bunch of exclamation points everywhere to assert that a null ain't coming. It feels dirty.
Just too hard to use for me.
IMO it's not that Typescript is limited at all, it's just that the type system is different, more complex and also more flexible - there are typically more ways to define types compared to Java/C#, so a lot more decision points trying to write something elegant, or even just idiomatic/understandable, so IMO the learning curve is steep. And then you get to the fun stuff with more abstract type definitions, infer keyword...
It screwed with my head way more than I thought it would. Structural typing was really different, I had to spend a long time rewiring my brain. But when I went back to C#, I felt like the type system was crude. I lost all the nice and easy ways of writing dynamic code and had to revert to defining surplus kludgy interfaces, delegates, etc. And in Typescript I'd finally figured out how to write null-safe code and remove almost all ugly coercions, then back in C# null references were a real possibility.
But the frustration left a worse impression than did the benefits. Perhaps if I was being paid to do it and had mentors around to ask for help. But I couldn't find any good advice online.
It took me far longer than a few hours to feel comfortable, probably more like over a month of coding to get to the point where I mostly understood how to express what I wanted with the type system, and had stopped doing C# things in TS and adhering to style guidelines - functional modules, types instead of classes, injecting dependencies etc. And another month or two? to really figure out how everyone has been (ab)using the type system to do more complex stuff.
Are you using "?" optional fields in your classes/interfaces a lot? If so, do you need to? Unless it's truly optional, you're basically making the type system less useful if you put that all over the place. If you have a lot of sparse objects, it's probably an indicator of a data type doing too much. You might be much better off splitting it into smaller interfaces and using union types when you need combined objects.
Even if you can't do the above, checking for null at the start of a function/block will "prove" to the compiler that it's not-null for the rest of the block, so an upfront check can save you from a lot of "!" assertions.
Even if you can't do either of the above, you can probably use the elvis operator "?." to safely dereference things that might possibly be undefined.
In my experience with typescript, there's a few good rules of thumb and things to keep in mind:
- Prefer "interface" over "class" for describing most data types. Especially plain old data objects that don't have methods. I'd forget about the definition of "interface" you might know from Java. It can be used that way, but it can also be used like you would use "struct" in C
- Use the "Partial" modifier instead of using "?" in the base structure if you need to do something like sparse updates. For instance a pattern I use a lot is:
interface MyStruct { a: number, b: string }
function update(original: MyStruct, updatedFields: Partial<MyStruct>) {
return {...original, ...updatedFields}
}
- Always prefer readonly fields and non-optionality.- If you're not worried about GC pressure, it's almost always better to return a new object than mutate an old one. The spread operator is great for this.
- Within reason, it's better to prefer smaller data structures and use type unions when you need fields from both in one object.
I think I went into the deep end with some non trivial generic functions. It's been a few months, but I remember ditching interfaces for classes so I could do some run time type checking.
I wouldn't have fallen into these traps with something like Java.
It's not even that there's only happy heads-down programmers off HN who support these mainstream techs. Even in the active userbase here, I'd wager there are tons of people who have an adequate or better experience with typescript or react, and may disagree with the dislikers. But we're not as invested in our liking, don't feel like it's worth engaging in, and none of the banter changes what is or where things are going. These are the de-jure tools that the majority definitely uses widely, which at least the first anti- comment, on front-end frameworks, acknowledged. Whatever the targets-of-the-day happen to be, they will crop up repeatedly, which further dissuades from trying to come back with a positive or even neutral opinion that might represent that silent majority's take. And the silent majority must constantly face Brandolini's Law; what it's doing may be working & have good reason, but it's hard to keep supporting & reasoning through with a pact invested in disbelieving.
I liked the top post talking about disagreeing with the direction. That can be contributive, be value based. So often though the protests amount to gatekeeping "you've done too much." I evaluate where these comments would fall on Steve Yeggie's Software Political axis, from Notes from the Mystery Magic Bus[1], and almost universally the voices are conservative; they object rather than suggest, they refuse rather than support. I'd like to see more progressive protests, that can surface good, that acknowledge value & need but reflow or redirect the energy elsewhere, rather than being unhappy with what is.
I appreciate the high quality HN posts, but sometimes just like at a water cooler a bunch of us just wanna say, "agh I'm so sick of object oriented" and it doesn't mean "all object oriented programming is of no use".
TypeScript exists as a first step to adding types to JS. Some folks are currently trying to figure out a way to add type annotations that the JS engine will just ignore for now based on what we've learned from TS.
And how would it be different?
I've been using TS since 2016, both for front and back-end, and I can count an amount of times the transpilation abstraction leaked on one hand (and most of these were when I just learning TS and worked on weirdly configured projects). Aside from these, I could just forget about the fact that it's transpiled to JS under the hood.
It's had the pleasant side effect of also educating me on quite a lot--mixing in with people with different experiences and values has enriched my life, so I think it's a win-win. I just try and be careful to not get too wound up: that's the failure case haha (I'm not saying constantly check your blood pressure while using HN, but I'm not not saying it).
I was just talking about this, to someone, yesterday.
I'm often accused of being a "killjoy," or a "dreamkiller," by today's yutes. This is because I say 'orrible things, like "Have you considered what happens if..?" or "We tried that, a couple of years ago. It didn't work out, and here's why...".
In actual point of fact, I'm exactly the opposite. It's my job to Make Things Happen. I plan to ship everything that I do, and my work is generally focused around the endless practicalities and compromises, necessary to get products out the door.
This has often resulted in me being called every name in the book, as I try to avoid chasing shiny, and keep the eye on the ball. In my days of yute, this would keep me awake at night, worrying whether or not I had made the right decision, if I was an unintended, out-of-wedlock child, or if I really was a goose-stepping fascist.
But I have been getting stuff out the door, for pretty much my entire adult life.
These days, I sleep like a baby.
This hits too hard. I’m still in the “acceptance” phase of grief over the death of my ideal that there’s a “right” technical solution for every problem. And I’m in my 40’s.
It starts by accepting them, right off the bat, then using the time that I'd otherwise spend in fruitless pursuit of shiny, doing things like testing and documenting the codebase.
Experience gives me the ability to see them, at the start of things, other than waiting to run into them, later.
I’ve recently switched jobs and my team doesn’t write integration tests for our services but rather manually test them with postman. It’s definitely odd and very inefficient.
Today, the frameworks bite me in the ass about once a week, but I think it’s worth it to get safe React with strict TypeScript, and plenty besides.
Caveat: All infrastructure requires a lot of maintenance, though! YAGNI still applies, and hopefully you have (or are on) a team dedicated to supporting the tools that you do need.
XSS has long been a solved problem.
Security is definitely not an argument for using front end JS frameworks as they add attack vectors and complication to the stack.
Right now my position is something like tech lead, at least I do technical decisions in our company. And there's no way I'll allow to write anything complex without React.
And sites are bad not because of React. Sites are bad because of other things. If anything, React helps making sites less bad.
Second best thing is TypeScript. I don't like tooling, though, but I think it gets better.
This might be the oldest, grumpiest man on the front lawn yelling at childreniest take we on web dev, that I’ve ever heard
Web apps were never this complex before the creation of frontend web frameworks.
Frontend web frameworks have their use in rich apps, but using them for general web pages is just complicating things for no good reason.
It would definitely be better if there were a way to side-load those libraries as a standardized strata underneath the main browser content to save resources. So if someone uses React to do their form, yes it seems costly but the cost only needs to be paid once, and then the relevant framework is cached more statically than the transient web cache (and with an alternative to domain-based cache, such as checksums or signed binaries, to determine if two domains are using the same framework and save the download cost for all sites you visit using that framework).
... but only better if the tricky engineering questions around caching were sorted. There's plenty of risk that you'd end up with gigabytes of cached frameworks, because the current solution means I don't have to care if one site is using React 12 and another is using React 12.1.
But this isnt my field of expertise so I'll have to take your word for it that you're not joking.
Doing a form that will do things people expect these days (client-side validation, formatting, error-handling and highlighting / locating fields with errors in them, auto-fill of addresses... What, you don't expect the user to type in a whole address without verifying it's a real address, do you, there's validation services these days!) is the kind of thing you may want a framework for.
This relatively simple "Contact us" form (https://aflcio.org/contact) loads nine custom fonts, JQuery, an email-decoder script from Cloudflare, and a host of other things. Why nine custom fonts? Because the AFL-CIO has a brand and they're not obliged to deviate from it just because your browser doesn't have the font they use, anymore than they wouldn't show their logo because your computer doesn't have the logo yet. Why JQuery? Probably because there's a button on the page that hides and shows a field, and even in The Year Of Our Lord 2022 those are still an absolute witch to write without bugs in plain JavaScript. The email-decoder script is, I think, self-evident; lets them save the bandwidth of rejecting your input if you put "no" as the email address. And of course, the tracking scripts because they want to know how people are finding the "Contact Us" form (are they coming in from the main page? Is there some specific page that should be answering their question that they're falling over into "Contact Us" instead? Are they coming in from completely outside our org because someone shared a deep-link on a political site and said "Go bug the AFL-CIO", because if yes they can use that tracking to pre-filter the messages they get from that entry-path and bin them all low-priority). I'm seeing some inefficiencies in the Inspector (it's loading some Android-specific icons, probably because it's not good about refraining from loading assets for its mobile layout), but a lot of that stuff I'm not surprised at all to see.
There are several driving factors underpinning this phenomenon. One is that frameworks are more flexible (per unit of code written) than bare-AJAX development, so there's plenty of "everything looks like a nail" thinking going on; once you've paid the up-front cost to build out a dev environment using a framework, it's cheap to keep using it. Another huge factor is that relative to the web experience of, say 15 years ago, there are many incentives to push a lot of work (especially validation of inputs) client-side; few places have truly full-stack developers (or, more often, don't allow the authority for one developer to go hacksaw into the front and backend whenever they feel like it), so simply implementing one new validation rule may be a bunch of back-and-forth tickets if implemented server side or a couple hour's work if done client-side. And client-side work saves the server computation costs (and often bandwidth costs, even when one factors in the up-front cost of loading all that framework boilerplate if the site's used long enough per session).
All of this pushing of complexity to the client does come at a cost of client performance (and sometimes bandwidth, depending on how solid the caching logic is), so (especially at big companies like Facebook and Google) it's a constantly-shifting tradeoff. Google in particular has some incredibly clever partial-rendering logic in-house to allow them to push pieces of a big page on-the-fly to the client, saving bandwidth by rendering a mock button with no behavior attached until the user tries to click on it (and then the behavior script flies in as-needed). Of course, that's a huge amount of complexity that requires tight hand-in-glove coordination between client and server, so the framework that supports it is even more thick and robust, etc.
At the end of the day, "simple web sites" (unless they are truly read-only, in which case just use Hugo and call it a day) are still client-server distributed computing problems with complexity that scales nonlinearly.
Nested ternary operators... though, because of how TypeScript does constants, I saw why they used this way of doing things so often.
Such a shame, since this is ‘a great way’ to dissuade women[1].
[1]: https://hbr.org/2014/08/why-women-dont-apply-for-jobs-unless...
It's a mistake for companies to assume that just because someone has 3 years of professional experience with a particular tool, that they like that tool. I've witnessed many developers catch Stockholm syndrome after spending lot of time using (and becoming an expert in) a specific tool but I regard this is as a sign of inexperience.
Older me is now super embarrassed by my prior enthusiasm for object oriented programming and misc methodologies. I have very vivid memories of grey beards dismissing my naivety and me thinking "they just didn't get it." [0]
If there's any kind of karma, today's noobs will live long enough to be mocked by even younger noobs.
Small solace, I know.
[0] I always remember criticisms. I've got the voice of doubt in the back of my head always wondering what I'm missing, what if they're right, etc. It's a serious bummer.
There's probably a saying somewhere along the lines of "There are two kinds of programmers: those who admit they get Imposter's Syndrome, and those who are too afraid to admit it."
We all have those doubts. I've been in this since... what, 1994 professionally I suppose, and I still have doubts. It's totally normal. IS is not limited to software development either.
Even worse, people don't even bother to look at other options even if it's just to learn from them.
Compare the new hip thing with a different one and people get defensive.
The fact is, there is an essential complexity that simply can not ever be reduced. But we should also strive to not get blinded by the n+1 failed, bad attempt because true, novel approaches do turn up from time to time, e.g. nix actually solves the dependency hell problem.
Which is funny because most modern devops tools are written by organizations with no experience maintaining critical systems or large scale.
Very, very few come out of teams working on the real stuff. Both FAANGs and other companies are not going to release their crucial internal tools and not even discuss them in public.
> may include both the learnings as well as the mistakes
"release early" is not something anybody should do for production critical tools like devops stuff.
> frankly, most people aren’t building things that are critical or require scale
100% agree, but if I build ships they have to fit safety standards even if most people never meet rough seas.
It's a bit like in politics; when times are good for the majority, most normal people aren't interested in politics; they have better things to do; this apathy makes it easier for freaks to get power and start messing with things... Until it gets so bad that regular people start noticing and begrudgingly getting involved in politics.