Things I Don’t Know as of 2018
overreacted.io
overreacted.io
> Containers. I have no idea about how to use Docker or Kubernetes. (Are those related?) I have a vague idea that they let me spin up a separate VM in a predictable way. Sounds cool but I haven’t tried it.
> Deployment and devops. I can manage to send some files over FTP or kill some processes but that’s the limit of my devops skills.
I'm working hard on trying to tease out a method to educate developers about DevOps / Kubernetes... It's hard to explain to people who have not been on-call or walked into a company on their first day as a devops, but I am strongly in the camp of "Kubernetes is live-saving, game-changing, etc". I tend to fail to explain to most product-focused developers successfully - Either too low level, too high level and hand-wavey, or they walk away with a sense of "man one day, that might be cool", rather than "We could get going on this _today_!". The most success I've had is in demonstrations (I have a raspberry Pi Kube cluster with 4 pies, with which I can physically unplug power, network, disk, etc and show off Kube's self-healing and auto-discovery powers), but at companies with day to day stresses, not so much. Plus the demo only scratches the service of cool features of even the Deployment API object.
Shameless self promo, but I'm working on a project with a friend that hopefully helps. I want product-focused developers to have a "Heroku" moment about kube and understand the immense benefits they get from designing their applications with a "cloud-native" mindset. That the small cost is _vastly_ worth the benefit. The project is here: https://kubesail.com/.
My "thing I dont know as of 2018", just for good measure: How to build complex front-end applications without making a complete mess of things!
Same with enterprise software development. It's kind of neat that the world of software engineering is so big that one can go 20 years into their career and be totally experience-deficient in large spaces of the industry.
If you find anyone that truly knows the answer, please let us know :)
I'm sure plenty of people claim to, and many more will just claim that the mere concept is flawed so there's no point, and there are even more non-answers. But the actual problem is very difficult. I remember when AngularJS (the old Angular) first came out and it felt like we finally started having an idea of how to handle frontend after years of dissatisfaction with jQuery, Knockout, etc.. Then React, Polymer, Web Components, ES6, Webpack, Modules, TypeScript, Redux (and its Flux-based ancestors) and so, so much more hit and... it's mesmerizing.
I think React is the best option so far, it's still not 100% where it should be but it offers my favorite API and the essence of it is simple enough to fit in a tiny, minimal library if you want. It can be tricky here and there, but the way it encapsulates state is, for the most part, super predictable. I love the way you fold asynchronous streams into state and props using tools like create-subscription so that components don't have to fiddle around with confusing, long async chains.
For me, Polymer and Web Components were both huge misses - the promise of Web Components is still neat to this day, but I really don't think I would want to compose my application out of many Web Components, it just doesn't seem like the right tool for that job, it seems like a better tool for embedding or shared widgets. There's really a lot that can be said here w.r.t. Polymer and Web Components in general but I don't think any of it hasn't been said better so I'll leave it alone.
Angular 2+ do not do it for me. It is amazingly nice having so much out of the box unlike React, but at the same time I find myself constantly annoyed. The NgModule system feels like a relic of AngularJS. When it was standard to simply concatenate JavaScript files together and call it a bundle, this system made perfect sense. In the world of ES modules and Webpack, it's just a layer of needless complexity. The AOT compiler causes all sorts of shenanigans where valid, obvious JavaScript won't work. I don't really care for dependency injection, at least not the way its implemented in Angular. It does give you some neat tricks, but I am happier with my obvious, ugly code, thanks. Even disregarding modules and DI, I still don't like Angular. My favorite concept from React is that the tree of components is out of line of the DOM. In Angular the component is actually in the DOM. This usually only matters in a few cases, but when it does it's really annoying. Example would be CSS, or say, if you want a component to be a table row. The way event listeners work is not orthogonal between child elements and the so-called 'host' element due to this, as well, whereas in React you can just use HTML-style on event attributes since you are rendering all of the elements that end up in the DOM always. Angular's documentation frequently doesn't have example code showing you how to use things, which may actually be because the developers aren't sure - I've often tried to figure out how to use basic features only to find GitHub issues pointing out the severe limitations in them. Like, Angular Router - What if you want to compartmentalize some routes in a child module? You could of course just define a Routes[] variable somewhere and import it, but there is actually a RouterModule.forChild, so surely you can use that? No. You can only use that if you are using loadChildren, which uses lazy loading. Lazy loading is actually a PITA especially depending on how you have modules setup, and the AOT compiler once again does some truly confusing stuff. Like, you can fake loading something synchronously with loadChildren, but check out what you gotta do to make it work with the AOT compiler: https://github.com/angular/angular/issues/10958#issuecomment... - Nearly every interaction with Angular beyond trivialities end in multiple open GitHub issues that lead nowhere, and it's frustrated me like crazy. Angular also seems to like RxJS, a library I really want to love but can't seem to quite get there. It's very powerful, but I hate that to get the exact behavior I want I often end up with quite a long list of operators where the order can be important in subtle ways. It's easy to leak subscriptions in RxJS especially if you're new to it. Some things are hard to implement, like say if you wanted to implement some kind of feedback loop where the result goes back through. And worst of all, you tend to get RxJS subscriptions and subjects at the component level at Angular, meaning you've got to deal with these async values in rendering code, in logic code, etc. Which can cause RxJS to spread like a virus when all you wanted to do was pull some state in and combine it with some other state. And if you want change detection to work, there's even more rules you need to be careful about following...
I've yet to try Ember. I've looked at Vue.js but ultimately haven't been as drawn in.
...But even despite my preference for React, large apps are still super hard to structure, and many problems feel unsolved. Like saving and synchronizing state to a server. There's individual solutions to that problem, but none feel like they're 'perfect' across all of the domains you want them to be. GraphQL seems like it could be nice but so far I have been mystified by it in practice, and longing for better type-safety on both sides. React obviously is far from perfect, too, and because of its imperfections, you are going to want a lot of linting to prevent people from shooting themselves in the foot, especially if you are working on a team. I've never fully figured out unit and integration testing in React, last I checked the standard was to use Jest and JSdom and JSdom required native Node.JS modules and bla bla... needless to say, I was unsatisfied. Because unit test suites on JS apps tend to compile to one giant bundle, you have a harder time parallelizing work and doing coverage-based tests.
Organizing components? Smart components vs dumb components? Container components? High order components? Where to put the Redux reducers and actions and state? How to split your bundle? Whether or not to split your bundle? Webpack vs Rollup vs Parcel? I'm barely scratching the surface. Production frontend apps are insanely difficult and it's fragmented to all hell. I don't buy in super hard to the JS fatigue thing, but I do think we're very scatterbrained right now on how to build good frontend apps, and it seems like it's gonna take a while to fully collect our thoughts and figure out how things 'ought' to be done. Right now, it's really super all over the place.
So yeah... I think it's OK if you don't know how to write complex front-end apps without making a mess. I doubt you are alone even among the pioneers.
- create-react—app or Parcel bundler, both of which require zero config. CRA is easiest but I’m not a fan of their defaults for Typescript (which is to prevent the app loading in dev if you have any tslint or compiler errors, even if they are just warnings) so once I’ve messed around fixing that, it’s almost just as easy to use Parcel.
- For website projects, I use react-static as a static site generator as it can handle all your data loading, bundle splitting, server side rendering, etc. for you automatically. It’s best to start your project with react-static rather than retrofitting it, they have a command line tool to set up a new project so this is usually instead of CRA/Parcel. Gatsby is probably an equally valid choice, react-static seemed a little simpler to me and I’ve been happy so far but Gatsby community seems larger.
- I’ve not used Redux for a couple of years now, instead using MobX for application state. Personally I find it so much quicker and easier to use, although it is undeniably more “magic”. Honestly think this is one of the biggest productivity enabling changes I’ve made since switching to React.
- Personally I’m a fan of Typescript, while it can be a bit of a pain initially, I think you reap the rewards as a project progresses in terms of ability to refactor easily and avoid wasting time on syntax errors.
We're talking about hours of study leading to a long-term hundreds of hours of time saved.
Nothing prevents you from still writing entire Babel and Webpack configs by hand if you want to, but it shouldn't be a prerequisite for actually using React (or any other framework).
The problem is there is a huge gap between a development react application and a production react application that is served to users with best security/operational processes. The own creators of CRA do not recommend it be used in production and isn't that the goal for most react developers, to put apps into production?
> No Configuration Required: You don't need to configure anything. A reasonably good configuration of both development and production builds is handled for you so you can focus on writing code.
Nowhere in the docs do I see phrases like "don't use this in production".
As for the math analogy: I'd say the difference is that many calc concepts do require understanding of algebra to grasp and use, whereas the only thing about React that _sorta_ implies knowledge of Babel is the JSX transform, which isn't a hard requirement to use React but is certainly the common preferred approach.
Again, I'm not at all saying that people _shouldn't_ learn how to set up build tool configs. I agree that's valuable knowledge to have. I'm just saying it shouldn't be a hard blocker for using React, and that React tutorials shouldn't have to spend half their time teaching unrelated build tools instead of React itself.
* spend less time debugging dependencies across version changes
* reduce bundle sizes
* create a better CI/CD pipeline
* reduce unnecessary dependencies
* fork/fix/create your own plug-ins and other tools
* self-hosting npm to avoid production/dev outages
* easily learn new tools because you understand the underlying systems/alternatives
For example, I had a little game where initially I wrote a React+ecosystem solution that worked. Then, considering that I don't need x updates per seconds, I switched to server-side rendering + morphdom.
As a result I could reduce all my code to 1) websockets messages to the server and strings of markup from the server, and 2) a few 'optimistic updates' on the client-side by directly changing the DOM. Having no more client-side state to maintain really simplifies things.
Considering that this was a viable solution to a game that has to update the DOM on pretty much every click (but no more than that), it's probably a fine solution to the vast majority of apps I build.
I can't wait for Phoenix LiveView to make this kind of solution less ad-hoc, but at least so far even the ad-hoc solution is so much simpler...
I can understand you’re opinions about the module system, but I disagree. For a small to medium size app it can seem like annoying boilerplate that gets in the way. If you’re working on a large app across multiple teams then it’s very helpful. You have a single entry point for all relevant code. You can define the api for that module so other teams don’t misuse what you have built. It can get frustrating when you have a single component that you want to share and you need to wrap it in a module, that feels very unnecessary, but I know the angular team is working on that.
I actually really like that my components are in the dom, I can see clearly where it is, not which div with which class or Id it is. It makes inspecting the tree very easy.
RxJS can be difficult and hard to learn, which doesn’t help that the docs are meh and you can never find exactly where to go. Juniors really need someone to help them not leak subscriptions. Though if you follow Angulars promoted idea of using the async pipe, then that will automatically clean up your subscriptions. Again, for small components/apps it feels way overkill, but it feels oh so nice when your trying some complex async stuff and can handle it and pass it along so easily.
Genuinely, I have not been able to figure out what it actually does from the documentation. Either it isn't there or I have been holding it wrong.
Because, loadChildren actually would import the routes from a child module as children of an existing route. But what you're saying, it sounds like the child routes would get placed at the root of the tree. I don't want that though, that doesn't allow me to do the decoupling I wanted to do. I don't fully understand why I can't just specify a module for children when loadChildren will happily take one asynchronously.
>I can understand you’re opinions about the module system, but I disagree. For a small to medium size app it can seem like annoying boilerplate that gets in the way. If you’re working on a large app across multiple teams then it’s very helpful. You have a single entry point for all relevant code. You can define the api for that module so other teams don’t misuse what you have built. It can get frustrating when you have a single component that you want to share and you need to wrap it in a module, that feels very unnecessary, but I know the angular team is working on that.
I work on only relatively large teams and I still don't get it. If I didn't want someone to be able to use part of my API, I would just not export it. Further, systems like Bazel already provide package visibility, which is a lot more powerful in terms of limiting the spread of an API imo. I know in Angular sometimes things have to be exported because of the AOT compiler, but that's not a great justification.
>I actually really like that my components are in the dom, I can see clearly where it is, not which div with which class or Id it is. It makes inspecting the tree very easy.
I would've thought it would make this easier, but due to the amount of power you have in the selector for components and the way directives work, I've still definitely found myself confused at times. At the end of the day, I didn't really have a complaint with the way React handled it, aside from the inconvenience of needing a separate debug tool to see the component tree.
>RxJS can be difficult and hard to learn, which doesn’t help that the docs are meh and you can never find exactly where to go.
To be honest with you, I found the RxJS docs to be OK. It is a bit hard to search them, but most of the information I actually needed was available if I did. I personally had more trouble finding answers with Angular than RxJS.
>Juniors really need someone to help them not leak subscriptions.
I don't like the way you've worded this because it heavily implies that it's mostly only an issue for junior developers. However, I've seen some very tricky takeUntil setups that are surprisingly nuanced. If your async chains are simple it's easy to define the lifetime, it's not so easy when your chains lifetime may be a subset of your components or services lifetime.
Interestingly, if we had things like higher order components, we could turn the problem into a component lifecycle problem, which is what React likes to do. I miss being able to encapsulate problems like that.
>Though if you follow Angulars promoted idea of using the async pipe, then that will automatically clean up your subscriptions.
I use the async pipe where possible because it does offer a reprieve from manually managing things like lifespan. Sadly, there are a lot of times where using the async pipe is not super nice. Let's say a value that was synchronous has become an observable, now if I was using other pipes or using the dot accessor suddenly it becomes more complicated. Generally I just give up at that point.
>Again, for small components/apps it feels way overkill, but it feels oh so nice when your trying some complex async stuff and can handle it and pass it along so easily.
With the caveat that it actually does not map all complex async problems elegantly.
It is super nice for some common cases like implementing type-ahead, and I generally use RxJS even outside of Angular nowadays because of the fact that it's just easier to express complex asynchronous behavior with it, but there have definitely been moments when I realized my somewhat complicated RxJS code could be replaced with relatively simple use of async/await and a for loop :|
I have a very large number of Angular gripes other than what I listed, so please don't take it to be exhaustive. I just wanted to illustrate in great detail the ways I did not like Angular because if I don't do that many people will assume it's because I didn't give it a fair shake.
It's the io loop. Components must change state and react to state. This where the complexity arises. If you remove the loop by having components only react to state, you will find your programs to be simple, modular and more beautiful.
The feedback loop of IO destroys the functional and modular nature of UI. Functional programming simplifies programming through restriction, however ui development is inheritly an object oriented problem due to the IO loop, so the results of trying to make it functional will have limited benefites.
The way to make UI work is to find a way to have components react to state and change state in a simple way and without hard coding a refrence to external state in the component itself. Aka stateless.
Many people believe that passing a closure is the solution. The reality is passing a closure is awkward and a form of encapsulating state with methods that leads to the same issues of complexity that you get with oop. Keep data and functions seperate always, a closure is technically a functional concept, but it is also oop in disguise as it is instatiating state coupled with a functions just like an object in oop.
Global event emitters might be the best way. I'm not sure if redux does this. I'm not a UI guy so everything is just imho.
What you've discussed above seems to overlap pretty well with both redux and monadic state management like Elm.
There's nothing OO about the IO loop. The main thing that calls for some OO in UIs is the widget hierarchy.
Widget hierarchy does not necessitate OO. Hierarchies can be built with plain data structures. OO comes into play when you place methods within the data structure. Methods coupled with data is essentially an object as described by OOP.
Why would you need integrate a method inside data structures?
Because IO.
Do you consider the "OOP"-ness to be evident in the fact that subscription functions (whether 'onclick' functions or 'fetch' callbacks) contain both code to react to events and an implicit binding to the IO loop? Or is your issue that some (not all!) DOM APIs happen to let you attach on-event functions to the same things you can read data out of?
Basically, I don't see why UI programming is any more inherently OO or functional (assuming those are even opposites, which has historically been debated more or less to death) than any other domain. There are UI toolkits that subscribe to each and both of those paradigms, with varying amounts of rigor.
>Do you consider the "OOP"-ness to be evident in the fact that subscription functions (whether 'onclick' functions or 'fetch' callbacks) contain both code to react to events and an implicit binding to the IO loop? Or is your issue that some (not all!) DOM APIs happen to let you attach on-event functions to the same things you can read data out of?
Look at where events come from and where they are sent. How do you associate the action of button A with the data representing button A? The most obvious way is to merge the action and the data into a single primitive. An object as described by OOP. You will have to do this regardless of what an API such as the DOM offers as primitives.
>(assuming those are even opposites, which has historically been debated more or less to death)
They are opposites. This is only up for debate for people who don't truly understand the differences. In OOP as described by JAVA or C++ you have a graph of mute-able objects instantiating other mutable objects and modifying each other. In functional you have a linked list of composed immutable functions with an input on the head and an output on the tail. Nothing is mutated. To get functional working with UI you need to employ obscure tricks as a UI widget is more of an object than it is a function.
They are opposites according to the most common definition of OOP. They are only orthogonal if you get rid of mutation which is NOT the way most OOP is used nowadays.
>Basically, I don't see why UI programming is any more inherently OO or functional
A UI widget cannot just be a function. A widget in-itself is data, the structure, the display, the color ... etc. And It must react to state and IO like a function. It is both data and methods and thus OO.
Without IO the the widget can just be a plain data structure. HTML is basically pure data. You can still keep it functional if you have a function dynamically generate HTML based on a set of parameters (IO without a loop). However when you need to introduce the "loop" and have UI both send and receive data that's when methods need to be attached to the UI widgets.
When you talk about an event emitter, what kind of code structures are you referring to? An EventEmitter a la Node.js is a pretty decent separation of IO and data, though not perfect: something external (perhaps an event loop) triggers subscribed code based on IO, but your code is given only data (payload) to process. Is your beef that 'someThing.onEvent(eventType, e => whatever)' is more 'OOP' than 'bindEvent(someThing.eventType, e => whatever)' is 'functional'? If so, how or why?
In general, it sounds like you might be referring to typical JS asynchronous IO (callbacks/promises/async-await and whatnot) when you talk about IO loops. But I can't for the life of me figure out what those things have to do with OOP vs functional programming, nor why using those structures requires you to store state on a "widget".
> Look at where events come from and where they are sent. How do you associate the action of button A with the data representing button A?
I can say 'button.onClick(() => { button.clicked = true })' just as easily as I can chain every computation which would happen as a result of 'button.clicked' being true onto the event instead. The former is more OOP, colloquially, than the latter, but is definitely not inherent to UI programming: tons of popular patterns and frameworks exist whose primary goal is to remove the coupling between state and UI appearance.
> In functional you have a linked list of composed immutable functions with an input on the head and an output on the tail. Nothing is mutated.
This has nothing to do with functional programming, or a functional style. Immutable data exists as a very common pattern in both colloquially-FP and colloquially-OOP languages, and so does mutable data.
At the point where you start talking about linked lists, I begin to think that you're misunderstanding or misusing some fundamental term we're discussing (Mutability? IO? Functional? Object? I'm not sure): a LL is a data structure (which is mutated by adding/removing elements, traditionally), and has absolutely nothing to do with programming style or paradigm.
> A UI widget cannot just be a function. A widget in-itself is data, the structure, the display, the color ... etc.
No, a data object can contain those things, but in higher-level UI programming, the data object is very very rarely the "widget" itself; it's just data that is supplied to the renderer (the API of which, in web UIs, is the DOM), and the renderer generates the UI based on that.
You can do that in a tightly coupled way and store all your state in the DOM, or you can use any one of many powerful systems that allow you to separate those and perform operations only on data, which can be applied to the external UI state outside of your code. React is a good example of this.
> HTML is basically pure data.
I think you're confused about the difference between HTML (text, can be generated and passed around by code) and the DOM (the API to what is being rendered by the browser). HTML is data, sure.
> You can still keep it functional if you have a function dynamically generate HTML based on a set of parameters (IO without a loop).
That's what event listeners and callbacks are. Whether or not you're dynamically generating HTML, or whether code is mutating it after it's loaded into the DOM, has nothing to do with functional-or-not. Code doesn't stop being 'functional' as soon as its goal is to alter the state of or handle input from some external thing, whether that's a DOM node or a traffic light.
I don't even know where you're getting all this from. I defined the "IO loop" the access of external state as both a read and a write. Once I defined it, it should be clear what I'm talking about. You should be aware of my definition through my explanation regardless of implementation. You go on to talk about asynchronous IO which is a whole different thing all together. I am not talking about concurrency. I am talking about IO from a very high level perspective.
Let's simplify it. Imagine an API that reads and writes strings from IO:
func read(source: str) -> str
func write(source: str, data: str) -> None
If you have both of these things in your program you have an IO loop. If you don't like the wording, give it another name. Either way, this "IO loop" is what I am addressing in the conversation. If I have a button widget that does IO, say... write data on click, then the most obvious way to create that widget is to unify the data describing that widget with a method that calls "write." When you unify data and methods you get an object. You understand now?>This has nothing to do with functional programming, or a functional style. Immutable data exists as a very common pattern in both colloquially-FP and colloquially-OOP languages, and so does mutable data.
This is completely wrong. Mutable data is not part of the functional programming paradigm. Here's the definition straight from wikipedia:
"In computer science, functional programming is a programming paradigm—a style of building the structure and elements of computer programs—that treats computation as the evaluation of mathematical functions and avoids changing-state and mutable data."
>No, a data object can contain those things, but in higher-level UI programming, the data object is very very rarely the "widget" itself; it's just data that is supplied to the renderer (the API of which, in web UIs, is the DOM), and the renderer generates the UI based on that.
Obviously, we're not giving pixel level instructions (aka the actual widget) to the ui renderer. The renderer still needs to associate what's rendered with a function. A widget is not just a visual representation of something; it is an interactive visual representation. Data needs to be unified with methods to fully define a UI widget. Hence Object. As I will mention in other responses, this is the most obvious and common way of handling the UI problem. There are other methods that don't use OO. But a UI widget and what it does has a one to one match with the definition of an object in object oriented programming.
>I think you're confused about the difference between HTML (text, can be generated and passed around by code) and the DOM (the API to what is being rendered by the browser). HTML is data, sure.
I am perfectly clear about what I am talking about. There is absolutely no confusion. I am perfectly aware of what you just said. HTML is data, the DOM is an api that can manipulate said HTML.
>That's what event listeners and callbacks are. Whether or not you're dynamically generating HTML, or whether code is mutating it after it's loaded into the DOM, has nothing to do with functional-or-not. Code doesn't stop being 'functional' as soon as its goal is to alter the state of or handle input from some external thing, whether that's a DOM node or a traffic light.
When did I say the DOM was functional? I'm not talking about the DOM. I'm talking about UI development in general from a very generic perspective. I'm not looking at UI development soley from the perspective of javascript, HTML and the DOM. What I was talking about in the statement was this:
input_parameters = get_io_stuff()
renderUI(input_parameters)
Also this statement:>Code doesn't stop being 'functional' as soon as its goal is to alter the state
is completely and utterly wrong. Functional programming by its nature avoids all state changes. If it doesn't avoid state changes then it hides state changes through blackbox abstractions.
>I can say 'button.onClick(() => { button.clicked = true })' just as easily as I can chain every computation which would happen as a result of 'button.clicked' being true onto the event instead. The former is more OOP, colloquially, than the latter, but is definitely not inherent to UI programming: tons of popular patterns and frameworks exist whose primary goal is to remove the coupling between state and UI appearance.
This is exactly what I'm talking about. I never asked for the specific implementation in javascript, It's baffling why you bring it up. Here's what I'm saying: I'm saying the former OOP method is the most obvious method, the later method is using a global event emitter. The latter method is better because it makes the UI widget reusable across systems that utilize the same event emitter while the OOP method ties the handler and a reference to IO to the widget itself. Thats it. I think we can both agree that the majority of systems utilize the OOP method due to the prevalence of that style of programming.
>When you talk about an event emitter, what kind of code structures are you referring to? An EventEmitter a la Node.js is a pretty decent separation of IO and data, though not perfect: something external (perhaps an event loop) triggers subscribed code based on IO, but your code is given only data (payload) to process. Is your beef that 'someThing.onEvent(eventType, e => whatever)' is more 'OOP' than 'bindEvent(someThing.eventType, e => whatever)' is 'functional'? If so, how or why?
Yes. This is exactly what I'm talking about. I am also saying the latter method is better. It is better because it allows me to take that widget and reuse it in another project with a very different IO patterns. Imagine two implementations for button. We have code like this:
One implementation requires this: button.onClick(() => { button.clicked = true }) Another requires this: button.onClick(() => { button.color = "red" })
Try to think of onClick as just something that registers a handler to when the button is clicked. Ignore all the lower level details of what actually happens underneath and think of each as a method definition.
The code is not re-useable in general. Usually if I implemented the first requirement and hit the second requirement I have to write a lot of code to make an abstract version of button in which I can inherit two buttons with two different handlers.
Now look at this: button.onClick(() => { sys.triggerGlobalEventName("button.clicked") })
This makes the button reuse-able in any system that has sys.triggerGlobalEventName. The typical way to handle this issue is usually through inheritance and polymorphism. That style of abstraction leads to over complexity.
I think Redux actions are essentially emitted global events.
Redux's `store.subscribe()` function is obviously a general event emitter, where the only event is "an action was dispatched", so it doesn't even need a name.
On the actions side, Redux really only has a single "root reducer" function. Since having a gigantic monolithic function for all state updates would be unmaintainable, we split that function up into smaller functions, like any other piece of code.
Since Redux was based on the existing "Flux" concepts, the idea of having multiple "stores" for each different type of data was translated into having multiple "slice reducers", each one responsible for independently updating the data at a given key in your state object. Redux provides a `combineReducers` utility for this use case, which iterates through all the keys in the state object and calls the slice reducer at each key.
If you squint at this reducer setup the right way, you can see it as being a limited pubsub event system as well.
So, it's reasonable to view a Redux store as being a 2-way pubsub system. Different parts of the app dispatch an action to "publish" an event to the mostly-independent slice reducer functions, and the store publishes a single event to let any part of the UI know that the state _may_ have been updated.
Of course, that doesn't mean you now know any of these things, but even some small experience breaks through a psychological barrier, from something intimidating and unknown to something a bit more tangible.
Also, I find that when I start to learn about something, as long as I'm just going thru the motions on a hello world, and actually look up what the things do, I learn the most. Coming in with that beginner mindset you learn faster, then it's kind of a slow crawl to become an expert. The first week of playing with a new language / domain / piece of software I think I learn the most. It's the 80/20 rule at work.
Plus I find just having a small amount of knowledge and understanding where a piece of technology fits in the greater scheme of things to be really useful.
I always assumed that all the folks behind React were driven by a desire to make web programming more functional generally - that this was an ideal toward which they thought we should be working. And furthermore assumed that this was informed by a deep understanding of functional programming generally and the reasons why it is desirable as a programming methodology.
That inspired me to learn more about functional programming... which definitely wasn't a bad thing to do.
But I guess I have just been projecting - I have a friend who I've always considered smarter than me who raves about functional programming... and I guess I just thought this is what smart people generally have come to realise is the god's truth about programming.
It's good to know in a way that Dan is not in fact this religious about it. I wonder how other React devs feel.
But there’s a reason “deep” functional programming hasn’t gone mainstream — many people (including me) find it hard to contort their product code to express their thoughts in 100% functional way.
React has always been about taking the pragmatic parts of FP and making them easy to benefit from without buying into learning category theory or something like that.
I think there’s an interesting point in there as to the attributes needed to build something new vs scale something existing to a new level. They’re both clearly great at the things they seem to prefer doing.
Most technology companies are also terrible at explaining what they do so you need to be able to do a bit of reading to understand their value proposition. For example Docker, their website's homepage states.
Future proof your Windows apps and drive continuous innovation Protect your legacy, invest in your future.
Which is techobabble nonsense, and doesn't tell me a fucking thing about what Docker does. Docker isn't just for windows apps, so I don't know why they are alienating linux users. It makes no sense, and I would assume most people would move on unless they already knew what it was. This is sad, because I like and use Docker and want them to succeed.
How I would describe Docker to the uninitiated. Docker is a file. In that file you can run a series of commands to install and compile all the software necessary to run your application. Once you execute the file, it outputs another file which you can send to someone else who will automatically know how to run it. That's all it is, there is no reason for confusion.
I was formally educated to do low level development, did operating systems, hardware design, and communications for a living for 15 years. During that time I also learned and regularly used FP, data processing, windows GUI, full stack web development. Every year I pick a new tooling language so that I'm not completely tied to one language or paradigm. Every time I have an opportunity to use the right language or tool for the job I learn it and use it.
The whole point of my education process was not to learn C and Assembly, it was to motivate me to he constantly learning. When I wanted a new job I created a "real world problem" to solve, did actual design docs, took courses online, read books, etc. Was able to get a new job in a completely different field, doubling my pay and reducing my work load. That's all due to the fact that if I had a list of stuff I didnt know I'd be out there learning that stuff every waking minute.
I would immediately try to get you fired for lying about your knowledge and qualifications.
One of the best possible things you can do is admit when you don't know something. That should always be safe to do at any GOOD employer.
Other devs: desktop app devs, mobile devs, backend devs, devops devs, network devs, data scientists, game devs get exposed to those a little bit more.
If you are interested in learning a lot of those at the same time, write a server in C.
Here's an older verison of the same guide by the same author, more than 2 decades ago: https://web.archive.org/web/19970812031954/http://www.ecst.c...
Amazing how little has changed. I strongly suspect anyone will remember the UI framework du jour 10 years from now but Berkeley sockets have staying power. Despite occasional efforts to replace (OpenTransport anyone?).
Don't know: start with Dan's list, it has many similarities. I know more Bash, but not enough to write a shell script more complex than my aliases file. I vaguely know z80 and 6502 assembly. I know Java extremely well, but am faking C++ and C#. I understand flexbox but not CSS floats. I don't even know what sockets and streams even are in this context, they don't sound like the sockets and streams I know. I don't know node. I do know graphics and algorithms.
More don't know: the only front-end frameworks I know are Backbone, raw javascript, and various immediate-mode graphics APIs. I barely understand the AWS services I use. I don't understand matrix decomposition and that's actually relevant to things I do. I have to look up basic SQL commands when I'm writing it.
Do know: graph search algorithms in excessive depth, sequential Bayesian filtering in excessive depth, most of 2D graphics, 3D graphics up until you need to sample the local region in world space, most of procedural terrain generation, 2D computational geometry, 2D physics, sensor error characteristics for various sensors, GPS from the high level down to pseudoranges (but not down to signal analysis), rather a lot about data formats and compression, video game networking models
The "do know" list isn't exhaustive. The "don't know" one even more so.
Most of my games have been done in Java or Javascript.
Yes, that's literally the definition of Imposter Syndrome.
> I was considered by all my masters and my father a very ordinary boy, rather below the common standard of intellect.
-Charles Darwin
> That any civilized human being in this nineteenth century should not be aware that the earth travelled round the sun appeared to be to me such an extraordinary fact that I could hardly realize it.
> “You appear to be astonished,” he said, smiling at my expression of surprise. “Now that I do know it I shall do my best to forget it.”
> “To forget it!”
> “You see,” he explained, “I consider that a man’s brain originally is like a little empty attic, and you have to stock it with such furniture as you choose…”
> “But the Solar System!” I protested.
> “What the deuce is it to me?” he interrupted impatiently; “you say that we go round the sun. If we went round the moon it would not make a pennyworth of difference to me or to my work.”
-Sir Arthur Conan Doyle, A Study in Scarlet
What do you consider "actual coding"?
If, for example, you need to hash/salt passwords correctly and you haven't done that lately, even if you remember for certain how to do it, you should look it up to see if the best method has changed in the last year. Knowing algorithms off the top of your head might almost be a negative, if it makes you less likely to check with a bit of research first when it's time to use one.
[1] https://twitter.com/dan_abramov/status/1078658656344903683?s...
For even moderately sized companies, someone with wider knowledge will fare better, because such companies aren't going to spend $500k/yr on someone who doesn't know algorithms (or on someone who ONLY knows algorithms). The marginal cost to Facebook is near zero, the marginal cost to a smaller company certainly is not.
It is well established that “knowing more” is not really a thing; we just learn to further understand relations and distinctions, feeding our ability to know of more things we have yet to learn.
The rest of his blog so far is basically about things he does know.
If someone non-junior knew no shell scripting and had no FP knowledge — or thought that JavaScript counts as FP [spoiler alert: it doesn’t] — I wouldn’t hire them.
https://github.com/jfmengels/eslint-plugin-fp
https://github.com/fantasyland/fantasy-land
That subculture is what I was referring to.
If you’re splitting hairs over such definitions without acknowledging the cultural aspect and use that as a hiring criteria I wouldn’t want to work with you either.
Your position is that I should not argue against Dan Abramov because you perceive him to be relatively accomplished. This is an embarrassing point of view.
Burn your idols.
Where are you getting anti-intellectualism, rejection of category theory, or a defense of pragmatism at the expense of either of those things? Who is this directed at?
Reading back up this thread, you're the only person referring to those, unless I'm missing an edit somewhere.
But, no. Here it is: https://news.ycombinator.com/item?id=18783434
Maybe you can read some other articles on the blog (it’s new so there’s not many) to get a sense of my interests.
I also have a StackOverflow profile: https://stackoverflow.com/users/458193/dan-abramov
Not memorizing the algorithm book is one thing, but being considered a “rockstar” when you don’t know basic sorting algorithms...
Dan made a bit of a name for himself in a couple of ways I can think of: creating a very popular library (Redux) and communicating extremely well in English about React and Redux.
"Able to communicate about with a broad audience about complex technical topics" is a skill I wish more developers had.
So he's able to create things his audience wants and then communicate to his audience about those things. Sounds exactly like a rock star to me.
That's meant as a compliment, not an insult. The ability to communicate well and the ability to be honest about you don't know are two things the developer community needs more of.
In every other field of engineering, there are standards of knowledge and competency. Software is notable, in that not only are there no standards, but we actually see the glorification of ignorance of even basic knowledge.
There are lots of bad, popular github projects (particularly in the JS universe, where the bar for competency is already quite low) and having a popular project is not prima facie evidence of engineering skill (how many projects was the string-reversing NPM module breaking, again?) Which is to take nothing from the author; I don’t particularly care about his level of skill, nor am I saying his projects are bad. The argument is not about the author.
What I care about is when someone says “hey, I’m ignorant of the basics of the field in which I work, but it’s OK, because I work on a big, famous project.”, and people interpret that to mean that their ignorance is dandy, too. There are dozens of comments to this effect on this page (cf every comment that mentions “impostor syndrome”)
It’s OK to not know things. It’s OK to be a beginner. It’s not OK to excuse yourself from knowing things you really should know as a professional, because someone else got famous without that knowledge.
So consider that maybe, just maybe, for a developer working full-time on a SPA framework, not knowing Docker or Bash scripting might not be a real impediment to working effectively or delivering quality product. If it were, perhaps React & Redux wouldn't be as great as they are. And since they are great, maybe we should consider that fact not as a celebrity get-out-of-jail-free card, but as counterevidence to your implication that these topics all constitute a universal educational imperative, and that someone lacking in any of these areas is by definition not a professional in the software field.
I don’t routinely write sorting algorithms either, but I know what they are, how they differ, and how to implement them. And it’s useful knowledge - it comes up often in lots of domains.
I see lots of comments about how this is a bold stance against “imposter syndrome”, but at some point, it isn’t a syndrome. There really is basic knowledge that defines professional competence in this field, and it can’t be replaced by github stars.
Companies pressure Engineers to be "Generalists" because it lowers salary rates and makes people more replaceable. But it's the Specialists (like Dan) that drive actual innovation.
EDIT: In another comment Dan himself mentions that Facebook tries to hire generalists.
To put it in a different way: If someone asked me what I know I couldn't show it in any other way than "watch this".
I then mark off topics I am focusing on learning now and topics I want to learn ‘Next’. This helps me greatly. I also try to learn things in context of projects I am working on and the direct knowledge I need to solve the problems I have.
My point is that knowing 20 different programming languages did not make me more successful or better. This guy kind of sort of knew one language and was crushing me in sales.
On an unrelated note, I knew a guy that knew every new tool and language under the sun. Was always learning the latest thing. Terrible engineer —- everything too complicated and abstracted. Hard to follow, hard to work with.
I don’t believe knowing more necissarily makes for a better enginner at all.
(I can't be the only one)
Redux is a simple library that you can read through in a few minutes. It's working great for hundreds of thousands of users. Why would Dan's background scare you off from using it?
As for React, there's more than just Dan on the React team. (In particular, Seb Markbage is an incredibly deep thinker, and the rest of the team is great too).
"and I already forgot most of C#"
Does not inspire confidence here.It scares me off for the same reason that hundreds of thousands of people use dynamic languages, and I still believe that this is far from being a good idea.
The same way that hundreds of millions of people believe in god, and I still think this is absurd.
React itself represents a shift in webdev thought where, instead of desperately trying to establish itself as a "respectable" programming field (see: any Google web technology), it instead focuses on being as accessible as possible and embraces the populist nature of the web. This article is just an extension of that ideology.
And, as you've indicated, anyone who would be horrified by that ideology probably is already horrified by the web to begin with.
I’ve been doing full time JS with some Ruby for the past 5 years. I doubt I could write anything more than “Hello world” in C# without a lot of Googling.
"I understand the concept of types and can read annotations but I’ve never written it. The few times I tried, I ran into difficulties."
I know it's part of the "typescript" section. But it honestly sounds like it is quite general.I looked his github, and his only C# experience seems to be a tictactoe made in 2014.
I’ve worked on C# codebases professionally for about four years. They’re not open source because half of that time I worked on enterprise software (ASP .NET MVC, Entity Framework, NHibernate) and another half was a closed source product (Xamarin aka MonoTouch, Rx). Prior to that I worked a little on an open source static analysis tool (Gendarme) using Mono Cecil.
Prior to that I was moderating the .NET section on one of the largest Russian programming forums and translated documents like LINQ Overview when they came out. I also have a silver C# badge on StackOverflow. (https://stackoverflow.com/help/badges/39/c-sharp?userid=4581...)
I know how types work. My remark was that I haven’t worked with C# for about four years. I’m not aware of changes between versions 5 and 9, and might have forgotten some of the C# syntax for things like lambdas, having worked a lot with JS since then.
I’ve mentored a few junior devs in my day, and this kind of thing would have been really helpful to encourage them to keep pushing.
> The same way that hundreds of millions of people believe in god, and I still think this is absurd.
Well, that takes the idea of a 'programming language holy war' to a very literal place.
Maybe my React needs are minimal, but I tried following a tutorial using React and Redux and I was immensely confused. Once I struck out on my own and ditched Redux for just straight React, everything became so much clearer and simpler.
We're currently planning a revamp of the Redux docs. I'd really appreciate any feedback on what things caused problems, so we can know how to make the docs better.
Feel free to comment here, or ping me on Twitter or in the Reactiflux chat channels. I've also got a survey open asking for suggestions on docs structuring: https://docs.google.com/forms/d/e/1FAIpQLSfzIkY3fXZ8PrQKScYM...
Also, fwiw, you may be interested in my suggested resources for learning Redux:
https://blog.isquaredsoftware.com/2017/12/blogged-answers-le...
I haven't looked at the docs in a while but I'm not sure that's where the big problem lies. The hard thing about Redux is that you need to "get" the core concepts (not that complex), and how they interplay with how (and when) React renders component subtrees (very complex - this requires a new understanding of react you didn't need before).
After you learn React and finally "get" it you definitely won't get Redux. Not because of Redux perse, but because the way you structure your application is so different. After that you'll encounter more subjective questions like do we put this (semi localized) state in Redux? And there are no right answers anymore, just opinions.
Also the boilerplate doesn't help.
As part of that, I definitely want to have new category sections on "Using Redux with a UI" (which would include both how that works in general, and specific pages for use with React, Angular, Vue, Ember, etc), and "Real World Usage" (which could cover things like app structure, code splitting, choosing a side effects approach, and so on).
As for the "boilerplate" line... everyone throws around this word, and everyone means something different. Could you clarify what specific things you're thinking of when you say that?
FWIW, we have a new package called `redux-starter-kit`, which is specifically intended to help simplify several common Redux use cases. It includes utilities that help with store setup, reducer definitions, immutable update logic, and even creating entire "slices" of state automatically without having to write any action types or action creators yourself. I'd encourage everyone to try it out, and let us know how much it helps improve your apps and what else ought to be included:
As stated before I haven't done a big JS project for about a year now. In the last project I did we used redux in a create-react-app. At the time the best practice was creating presentational and container components[1].
The biggest boilerplate was:
- Whenever we added a react component (presentational) we would need to create a container component to wrap it in, this would always result in ~20 or basically the same lines (in our project we did things pretty verbose, so we didn't have a HoC or whatever people use).
- "immutable update logic", reducing deeply nested objects is a pain an error prone (using es6 spread or Object.assign), I've heard about some libraries that can help with this, but we didn't use anything at the time).
> FWIW, we have a new package called `redux-starter-kit`
I am most definitely going to use this for an upcoming project!
[1] https://medium.com/@dan_abramov/smart-and-dumb-components-7c...
Similarly, I'm actually thinking that in the upcoming Redux docs revamp, I'd like to have the tutorials and examples switch from a "folder-by-type" approach to either a "feature folder" or even a "ducks" approach, and maybe even cut down on having separate action constant variables. There's valid reasons to do things in multiple files, but it's also not _necessary_, and I want to simplify things.
Yes, I totally agree immutable update logic is a pain to write and write correctly, which is why Immer is awesome, and why the starter kit uses Immer internally. My only concerns are that the code _is_ mutating unless you wrap it in RSK's "magic" `createReducer` utility that uses Immer, and it's going to be hard to figure out how to teach this properly. But, in terms of LOC and simplicity, it's a huge win.
Please let me know how well it works for you, and if you've got any other suggestions for what it should include!
> My only concerns are that the code _is_ mutating unless you wrap it in RSK's "magic" `createReducer` utility that uses Immer, and it's going to be hard to figure out how to teach this properly. But, in terms of LOC and simplicity, it's a huge win.
It's only a win since we decided that "mutation is bad" and we had to do spread notation gymnastics in all our es-2025 code that we are compiling to es5 anyway. From an abstraction point of view this is how I feel consensus about state management changed over time in the frontend world (or the part/frameworks I was involved in):
- 2010: jQuery will help you update the DOM anywhere (looking at IE6) - but you have to solve state yourself. A deeply nested object attached at `window` was considered best practice.
- 2012: We need to manage state properly, here is a nice Backbone "model" class: pass it a schema and use getters/setters to update so you can glue state change events to your view logic.
- 2014: Angular (first version) is great! Don't worry about managing your state yourself, just attach whatever you want to $scope and we will simply use dirty checking to check everything whenever something changes.
- 2015: React uses a vdom which behaves similar: change whatever you want and keep rendering it and React will figure out what actually changed. And for your state we made this flux thing which you implement as a bunch of different data stores (in my mind similar to backbone models except they only go "one way").
- 2016 (redux): here is a single store that also flows one way. Oh yea you need to do everything functional and you can't mutate any objects anymore or things will break. These 20 lines of code show you how to change the property of object with another property called id with value "x" in a nested list. This is better because it makes diffing faster in the vdom. You have to make sure you never mutate so here is a way to "freeze" your objects which will make sure you don't do this.
- 2017 Immer (I haven't used this yet): We realize it's a pain to change big objects if you can't mutate, so here is a dummy object you can mutate, we will clone it to make sure it's a different object. This is a proxy to the objects that will end up in your store (and exposed to your view layer).
I understand how we got to needing Immer, but it's a solution to a problem we only have because of how frameworks like React figure out what changed (strict equality). But it's too verbose and error prone for us to do manually. React only got designed as it did because too many people got tired of OO style state management. Right now I'm noticing a lot of people are getting tired of the verbosity, boilerplate and complex abstractions that come with doing things the "proper React way" (updating state represented in an object is the main example here, but that whole chain is verbose: you need to create actions you can dispatch, you need to write a reducer to catch those actions and mutate your objects, you need to glue the correct state to each component).
React is great tech, but in a lot of ways it's a counter movement. Countering complexities you get when managing state the OO way. But now it has gotten very complex itself, we now need a solution (immer) introduced by a solution (redux) that was needed to manage state inline with React. In other words, also very complex.
It feels almost as if I took the Backbone code, renamed it and marketed as "a simpler way to manage your UI" I could get a lot of people to switch away from React + redux + immer + immutable + redux-thunk + etc...
The number of new developers has been outstripping the number of old developers in most environments and this has been happening for at least the last 15 years.
Thus, we come back to Richard P. Gabriel's Worse is Better, or at least the essay's focus on the importance of social components of a project[1]. N.B.: not implying Redux is worse than any of the other discussed projects.
Newer generations cannot possibly have the time to go through the history and tradeoffs of various frameworks that used to be extremely popular and the reasons people moved on. Too many previous frameworks and too few posts like what you just wrote. Besides, where to start? It's not like TAOCP is going to have a chronology of Browser UI frameworks.
Instead, the tendency is to leverage the rapidly developing ecosystem and work with the projects that have the largest numbers of stars on github, etc.
If you are a very large well heeled eng. organization with a capability to enforce the use of particular frameworks, it is in your interest to popularize them. You will pay and encourage your engineering org to, among other things they do, market it to the dev. community. If there are enough engineers in your org (say: tens of thousands), you will begin exerting a tremendous concentrated influence on the Open Source community.
At the same time, for everyone else who does notwork inside a 10K+ engineer org, the lack of future maintenance and upgrades presents such a huge downside risk to not using the most popular open source frameworks. The open source community moves so quickly that you run into the risk of being stuck with maintaining the reusable components you plucked from other open source efforts.
The backwards compatibility guarantees are so much lower than what they used to be. The browser world is still figuring out how to link dependencies[2], let alone generate a stack that is stable enough where you don't have to continually update your UI codebase if you want to keep continuing to reuse other people's widget code.
So you tend to stay with the pack. React is the new most popular thing? OK, let's do React. Redux is the new way? OK, Redux. Pick anything else and you risk being stuck with a stack that rapidly loses the ability to interoperate with a huge majority of new Browser UI open source code.
[1] https://en.wikipedia.org/wiki/Worse_is_better
[2] https://medium.com/webpack/the-state-of-javascript-modules-4...
Those new sections sound awesome! Kudos for thinking about adding them to the docs.
https://github.com/reduxjs/redux/issues/2590
https://github.com/reduxjs/redux/issues/3313
I'm particularly hoping to do some brainstorming about the revamped docs structure and content over the next couple days.
I will admit I did not choose to use Redux, it was part of a tutorial I was following on Udemy. I never got the hang of it, and once I figured out React Native well enough, I quickly scaled back my reliance on Redux. It's made my life a lot easier.
My day job is a technical consultant for a major tech company, and we have meetings to discuss the meeting we're going to have before the meeting. The administrative overhead of Redux reminds me of that in a very bad way. Instead of my Facebook login button calling auth_actions.js which then returns the auth token to auth_reducer.js which then returns the auth token to auth_screen.js (but don't forget to add it to the combineReducers in index.js), I just put the authentication code in 'await doAuth()' inside of the auth_screen.js file. I've never heard a convincing reason as to why I shouldn't do that, even though the tutorial I followed said it's a bad idea.
Were you following Dan’s tutorial on Redux? Because that is a beautifully made tutorial as well. (https://egghead.io/redux)
If you have tried to build a substantially big app with React alone, you will find yourself lost in passing down the props and callbacks and hoisting variables and what not. You definitely need a state management library where you can CRUD from all your React components. Thats where Redux/Mobx comes into picture, unless you want to write a new one.
I agree that Redux needs a lot of boilerplate though.
I can't count the number of hours I've lost to stuff like this.
It's interesting that people who don't know that will view that post negatively but people who know what he has accomplished would be inspired by it.
To end off, pay your respects at: https://dan.church/
Didn't know him, but I like him now.
If you know what you don't know anything, you know more than if you don't know anything and you don't know.
There’s a React team. I’m on that team. We develop React. Facebook uses it all over the place.
There’s also a Reason team. (Its creator also wrote React originally.) They work on Reason and its React bindings. Facebook uses it in some places.
We talk to the Reason team of course. But there has never been a plan to force all React users to use Reason. I don’t know where you heard that. If you like it, that’s cool. If not, that’s cool too. We’re just sharing what we use.
I’m not sure what your practical concerns are (are Reason bindings or TS typings not good enough?) but I’d like to hear them!
Of course I know “about” ML and TS. If I didn’t know about them I wouldn’t mention them. :-) I haven’t developed anything meaningful in either of them but it’s not like I’m clueless about what types are. I’ve been using C# for years.
Additionally, the opinions of popular leads, managers etc on what should be used will count more. Winning their mindshare will win you a lot of FB org.
Winning a lot of FB org will exert a tremendous influence on the Open Source community as you now have large numbers of engineers working on open source projects on premium pay.
I believe this is how it works in most modern large engineering orgs. After reaching a certain critical mass of adoption, a team will be hard-pressed to use anything else, especially if reusing other team's components requires you to master, say, Redux anyway.
He, obviously, does NOT list things that he does not know at all. (How can you describe something that you do not know?)
Yes, comfort with bash and a knowledge of how networking actually works is something I expect someone working on computer software for 10+ years to have gotten familiar with at some point.
I also expect people who build libraries inspired by prior work (FRP) to actually learn a bit about the prior work. I’m surprised he has not dabbled with functional programming.
What IS difficult to master, is people.
Software engineers command huge salaries because it’s not easy. Just because anyone can learn anything doesn’t make everything is easy.
I don’t understand why tech celebrates amateurism and ignorance... We don’t all know everything but we shouldn’t wear our ignorance like a badge of honor either.
I'm very surprised by how accurate this is...
Have you ever used shared hosting or know how this works? Then you can cross this off.
Any half-decent shared host ought to be able to scale you at least as far as a single database server on commodity hardware will suffice.
I would say someone with 5 years experience could be senior to someone with 10 years under their belt, granted the former worked on the right projects that gave them valuable experience, with some combination of design, understanding trade offs, implementation, and social/management skills managing delivery of their features or taking complexity and simplifying it (both technically and from a requirements perspective). You could work 10 years and not hit those points.
I expect someone with 10 years is hands down more experienced than someone with just one year under their belt, but otherwise, looking at how long you’ve been in the industry is kind of meaningless without understanding what it is that you did.
WinForms -> ASP .NET MVC
and then
Backbone -> AngularJS -> React
(including participating in React development) gave you the kind of exposure and experience you needed for Redux.
I think a lot of people reading on here missed this parts and I certainly didn't catch onto this reading your Things I don't Know as of 2018 post or the "Things I do Know" post you linked to.
It is also not a good problem to have, either. There will always be a few people who think you know everything, and a few people who think you know nothing. The only plausible reason why everybody would think you know everything is that you act like you know everything around everybody. Put differently, if most people think you know more than you do, it would imply that you are not very humble in your interactions with most people.
> Folks from minority groups often suffer the opposite bias despite their hard-earned credentials, and that sucks.
Does it suck, though? It is much better to be underestimated than to be overestimated. I've read a lot of Dan's articles. He offers a lot of interesting insight and advice in pretty much every article he's written. The guy comes off as a know-it-all! Not saying it's bad, but it something to introspect on if you constantly find people overestimating your abilities.
I personally kind of figured he knew a lot about everything Webdev related since he knows so much about React, but that’s obviously not the case now that he’s listed all that out. In fact, now I don’t feel like the extent my knowledge is as limited as I did because I have a basis for comparison! Which I.. figure might be the point of the article?
Being constantly underestimated probably doesn't feel so great when it's hard to find employment or when people don't respect your technical opinions.
That's the mainstream narrative as regards to minority groups in tech :-)
I too am not convinced that being underestimated sucks. Being overestimated may be stressful when you keep trying to fit the image that others may have formed of you and to meet their expectations. When underestimated, the most likely way is upwards, towards greater appreciation; when overestimated, one quite possible way is downwards, amid general disappointment of those who had higher expectations of you.
I am not sure which is better.
1, things you know about
2, things you don't know about (this article as an example)
3, things you don't know you don't know about (hackernoon and medium are full of this kind of c*ap, people creaming their pants over switching their computer on for the first time)
There's absolutely zero value in the last two, they add so much noise and worse they make the author look like a complete idiot, even if they're not. I genuinely don't understand why people are so insistent on broadcasting their ignorance/stupidity though?
The only article of worth is the first kind, writing about your subject area, that adds value and is how people learn.
There are far more accomplished people in the world who know far less about far more topics. This case doesn't seem particularly extraordinary.
1. In this article, the author says that he does not know streams. Now, when he learns it well, he can write about "How he learned about streams", and a beginner would empathize more with this article rather than some expert ranting about it in their blog. 2. It is inspiring for the readers. It sends a message: "If you master one skill and master it well, you can still add a lot of value to the world. Knowing everything in the field is not really important". 3. Many people write not just for others, but also for themselves. Making your insecurities public is a good way to acknowledge and face them.