Hacker News new | past | comments | ask | show | jobs | submit login
Why I Hate Frameworks (2005) (fredrikholmqvist.com)
525 points by zkldi on Oct 19, 2021 | hide | past | favorite | 296 comments



I've always felt like there were two types of frameworks. Both types make the first x% of work relatively easy, but then the two types differentiate based off of how easily it is to drop down and go custom.

A framework with strong primitives makes it easy to create custom functionality that is still consistent with the framework's conventions. But a framework that relies too much on magic makes this much harder. It's like all of a sudden you're surrounded with old Mainers saying "you can't get there from here" while you desperately try to cobble some kind of solution using ancient lore documented once long ago in a forgotten scroll.


The best frameworks are the ones that cater to users working at a range of abstraction levels. Akka is a good example of a project that aspires to this and largely succeeds at it. If you are working at a particular abstraction level and need to drop down, it's a consistently polished experience. I have never had a shocking moment where I opened a door that users weren't supposed to open and saw something that users weren't supposed to see. Everything is created to be seen, understood, and used. And even in the rare cases where it's not supposed to be used, it's still designed to be seen and understood!


It's funny to hear someone say so many nice things about Akka.

I work with Akka streams, actors and http every day and and while I agree that Akka is really well documented, incredibly powerful and as you say polished, it is also the bane of my existence. It has made what could have been a simple application a rather painful experience for newcomers and even very senior engineers. The complexity of a framework like Akka is a huge barrier of entry for engineers and hinders development more often than it helps.

This is all obviously very subjective.


I wonder if this is the type of complexity that comes by default with state machines? I have the same feelings with complex react component structures, as well. There is something about state machines where the command flow (that updates the states) feels "hidden", and I thus far haven't found a way to design or document this kind of programming cleanly. Instead I have copious documentation explaining what each combination of states means and how it can be triggered.


Getting OT, but I am a fan of state machines.

They get big, but it is not right to confuse size with complexity. A huge state machine (size measured by the number of states) can be quite simple. Both in the whole, and each state transition can be isolated and considered independently


And at least a large state machine has the dignity to make the state + transitions explicit.

I’d much rather deal with a large state machine than something that does the same thing, but implicitly or inconsistently.


I'm also very positive on Akka having been deep into Cluster and Streams and Actors over the last few months. The barrier to entry is high because the problems Akka is appropriate for are complicated. Every time I want to complain I imagine managing state in a performant way using "simple" threadlocks or Futures and then magnify that over a distributed application.


Can you share a use cases where Akka provides a more performant solution over ""simple" threadlocks or Futures" ?


It's not going to be more performant than the constructs it's built off for a Hello World application. But unless you are a deep expert in concurrency and memory management (and have a team who can keep up) if you have a complex problem of concurrency and scale then the Application built in Akka will have high odds of getting to production readiness and stay maintainable while being performant and not getting bogged down in memory issues and shared state performance issues.

That difference in the odds of success increases by an order of magnitude again once you start talking about distributed data.


I'd like to form my own opinion on the trade-offs.

Can you share a use case please?


The most obvious case for Actors are usually anything where the time to process something isn't predictable and you need to manage state of that process. So the common example is Chatroom session management where some sessions might last 5 seconds and others might last for days. Likewise Games companies have built multiplayer gaming servers using Akka. Telcos and others are common users.

For me personally I'm using Akka to mangage the processing and reprocessing of a lot of entities through some algorithms where the processing time can't be known upfront and the data is unbounded.

In terms of wanting something to tinker with then I guess building a chat application backend is probably the easiest one to demonstrate the complexity of trying to manage that (and there are also some demos in the docs as well)


Thank you.

Would be interesting to compare Akka based solution to your problem with a hand rolled alternative.


The other decent alternative for some of these problems are often some flavour of messaging queues and event sourcing. E.g for the chat system you could probably shoot messages through a broker and then send a "chat finish" message. The disadvantage of this is if your broker is under heavy load then your chat app will perform linearly worse under increasing load while using the actors and state mean you can have a lot more stuff happening concurrently without the problems of waiting for events to go through a queue hence the latency advantages. Let alone if your servers are ephemeral and changing constantly then that's just another level of complexity to manually roll to keep your session state going that pretty much comes out the box to a production standard in akka persistence and sharding.


A chat system is one of the first network programming exercises. You must be trying to satisfy requirements that are beyond basics. Assuming persistent chat rooms are required, do you really need anything beyond some tables in a relational database that model chat rooms/chats?


This isn't talking about a hello world level application this is talking about an application managing complex state at scale. Maybe some bytes sent between points representing audio at the same time across several different sessions. I assure you that the problem set slack, people working on Fortnite servers etc is not the same problem set as a network programming illustration even if it's the same start point.


As a possible alternative, you could check out my library: https://github.com/centiservice/mats3


I've got to wrap my head round it a bit I'm definitely interested the approach as a lot of data/analytics people probably would be.


If you're talking about Akka Cluster sharding, basically any situation where you have distributed objects that have their own state and behavior. I've had two projects where objects needed to stay in memory so they could receive messages, update their state, and then behave by sending messages to other objects. And it was too many objects to live in one server. The naive solution of data repositories and caching isn't really sufficient for this, and a horizontally scaled Akka Cluster Sharding setup with Persistence was the right solution given the requirements.


I guess when I've encountered complexity in Akka, I've felt that it was in proportion to the difficulty of the problem I'm solving. In the future, if/when I get to work with frameworks that solve the same problems while exposing me to less complexity, then Akka will be obsolete in my mind.


And, well, you're also most likely dealing with scala which isn't helping.


Unlike, to use an example that is close to my heart, Atlassian @atlaskit, that while open-source, was clearly not meant to be used outside any Atlassian app.

So many undocumented hooks everywhere.


  > A framework with strong primitives makes it easy to create custom  
  > functionality that is still consistent with the framework's conventions.
  > But a framework thatrelies too much on magic makes this much harder.
This is what Laravel got right. It uses "Facades" (which differ from the Facade pattern) for the magic, but you don't have to use them. So socpers (Stack Overflow Copy-Pasters) can copy and paste their Facades without understanding them, but when I need to fix some edge case or write some functionality the framework designers did not anticipate, I can do it by reaching for the lower-level objects.

I've got tons of criticism of Laravel, but this is one thing that was done really really well.


I personally categorize frameworks into heavy and light frameworks.

I don't have very good explanation what I mean by heavy/light framework, this is the best I can do at the moment:

Heavy frameworks in my understanding are the ones that force constraints on your development process, application design, choice of other technologies and frameworks, on the types of products you can make with it, etc.

On the other hand light frameworks are like extensions of your fingers. They don't pretend to know better than you what you are trying to achieve. They just make a particular task easier for you.

The issue here is that heavy frameworks do not compose together very well.

You can safely have one heavy framework in your application.

When you start putting multiple heavy frameworks, they start colliding with each other and you start spending more and more time on resolving various problems that are not inherent to the domain problem that you are trying to solve but rather are completely accidental due to the technology choices you have made.


I think of it as whether or not your app is a cog in the framework machine or the framework is a cog in your app machine.


This is a useful perspective. I have often seen the first case called framework, and the second library.


> useful

I don't agree that it's useful (not sure if you were being ironic). All of the "frameworks" I've used were determined to make my cog their subject. I haven't come across a framework that was content to be a cog in my machine.

[Edit] Subject, as in royal or imperial subject.


Not being sarcastic. Let me rephrase, because I think we are saying the same thing. No framework was happy to be a cog. The ones that were I like to call libraries instead.

I say this point of view is useful because it seems like an elegant/simple way to distinguish them.


Composing light frameworks can make for a frustrating developer experience. Individually lighter, when combined, the end result may end up more "uneven" compared to the cohesion of a single heavy framework. VS Code is one example of the composition of lights approach.


Rails community sees this a lot. Rails is fairly heavy and there are some great lightweight solutions like Sinatra.

But what I’ve seen many times is that by the time you finish adding all the missing bits you end up with something as heavy as Rails, but non-standard. So now maintaining it is a huge burden.


Yep. Been there with Django vs (insert flask based solution here)


Another perspective is whether the framework is declarative or imperative.

If your code describes what is to be done without making the motions itself, you're using a very heavy framework or, honestly, DSL. These types of frameworks have lots of magic built into them and favor convention over configuration.

If your code performs actions imperatively, and moreover if it's explicit rather than implicit, then it can be easy to wrap or replace the framework. It's like a library.


But some frameworks allows you to have both convention and configuration. In ASP.NET you start with convention, which is good for the development speed. If you need to replace a functionality provided by the framework or do something in another way, you can do that with ease.


I've always liked Django's balance of declarative and imperative. The former gives you a clean and terse approach for the common use cases but there's always an escape hatch into the latter.


I think you want a framework that is heavy but swappable for stuff that is critical and easy to get wrong (e.g. authentication, http header parsing, input validation, routing, preventing sql injections etc) most of these things are "finalizing" concerns anyways, so you don't really need them to compose. And light for everything else (e.g. authorization, operations, templates, etc).


Being able to swap things out is one way to make a framework lighter.

Light ones: if I have a problem with the framework, I am guaranteed to have a local solution without getting rid of entire framework. For example, if Spring Framework does not let me create an object in a particular way, I can write my own function to create the object. If the way configuration is being located does not suit me, I can replace the mechanism without getting rid of Spring Framework or even configuration -- just by implementing couple of interfaces.

Heavy ones: if I want to do something that has not been planned for by framework creators I can potentially run into problems that I have no way out of without getting rid of it all.

An example would by systemd: it is built in an unnecessarily heavy way by insisting on you using it all. For example, if you don't like journald or can't use it for some reason -- tough luck. The only way to get rid of journald is to get rid of entire systemd.


artix and devuan devs like this post.


> A framework with strong primitives makes it easy to create custom functionality that is still consistent with the framework's conventions.

I agree but, Isn't that almost a library...?


I think he means an architecture where a thin layer of framework lays atop of a full-featured library.


This IMHO is why React destroyed AngularJs.


Angular is the Spring or ASP.NET of JavaScript while React is the Rails or Laravel of JavaScript?


No, Rails and Laravel are also the sprawling type of framework. They handle everything from routing to database access.

React does one thing. It’s arguably not a framework at all.


> React does one thing

Maybe this was so in 2013-2015, but React today does a lot of things (module loading, component rendering, basic state management, scheduling, memoisation, caching), and will soon do even more (server components in some custom json format, rendering server). Gone are the days when React was a simple "view library"


React doesn't load modules, you need a bundler for that. It just supports a component type that blocks rendering until a promise containing a component resolves.


I agree that it is arguable, but I would say that React is a framework for this reason: usually you do not decide when to call React code, instead React code decides when to call your code.


  > React does one thing. It’s arguably not a framework at all.
But that's React's failure, too. The lack of officially-supported libraries for common things such as routing leads to the horrible situation of having multiple competing, each-with-different-inconsistencies implementations of routing and moving from one React project to another transfers very little skills compared to other libraries such as Vue.


As someone currently using Rails, I would say React is nothing like Rails. Rails is just magic everywhere, where as React feels very explicit about what it does.


What parts of Rails are magical to you? This is an exaggerated stereotype imo. Spring framework felt way more "magical" than whatever Rails is doing to me. You can look at the Rails docs and it's all explained pretty clearly to me...


I went through a cycle of: study ruby -> start using rails -> seems magical -> realize you don't know ruby yet -> study more -> rails no longer feels magical. I suspect this is typical given that there is lot more to ruby than appears on the surface and rails heavily leverages the metaprogramming capabilities.


Yes not bothering learning Ruby when picking up Rails is very common...and sure, things look quite bizarre when you have no idea what's going on.


Maybe you mean the old ASP.NET. The new one is actually very flexible.


It's more analogous to an alternative history where the Ruby framework most people used was Rack [directly], not anything built on top of it (ie Rails).


The beloved and overhyped Next.js which I dislike with a passion is of the second type. It goes as deep as the simple examples from its documentation, and no deeper than that.


To be fair to Next.js, this is largely because its primary value is a Webpack config. Once you need to customize the build, you’re not customizing Next.js anymore, you’re working directly with Webpack.


It's certainly not marketed as a Webpack config, and my issues with it are with its React and Javascript API and design philosophy.


From my experience, the libraries and frameworks that have well designed primitives (and ideally primitive interop within the community) are the ones that generally “win.”

And also my experience, very few libraries and frameworks are built on reusable internal primitives. I just tide time until those frameworks die so I don’t have to learn them.


Seems determined by how good the underlying primitives are.

If the framework needed a completely different abstraction to make it easy to work with, dropping down to a lower level will be incompatible, difficult and confusing.


>But a framework that relies too much on magic makes this much harder.

Ruby on Rails...


Isn't that deliberate? Isn't it even in the name? "on rails" - you are supposed to be stuck on the track laid out for you, but the benefit is that you can move more goods with less effort as long as you do it on the given paths.


Yes calling Rails magical is a bit lazy imo. There is no magic and everything is documented to the point I would say it's actually quite a beginner friendly framework. You can say you disagree with some of the Rails APIs/conventions but that's very different than "magic". I think a lot of the complainers are people who just don't want to bother with Rails, they are not making the minimal effort of reading most of the docs. Maybe there was one Rails legacy project on their job that was a mess and interfered with their efforts to learn Node/React/Cool new stack. If that's your mindset then yes Rails is very "magical".


cough glibc cough


The hammer analogy breaks down from the get-go for me. The main distinguishing factor between a framework and a library is the classic "you call a library, but a framework calls you."

A better (but still imperfect) analogy might be buying a timber frame (with plan) versus home-rolling a stick frame from the ground up. With the planned timber frame house, the rough layout of the rooms and plumbing and such is somewhat predetermined, and as such it "calls you" in the sense that you're building out the amenities, but with the ground-up stick frame, you're explicitly making all the framing decisions too.

Like all things, there are bad frameworks, but scoped appropriately (simply) they can be incredibly useful. Just like houses, it turns out there are many ways in which web services are similar to each other and can benefit from a common framing.


Yes, a house frame is closer conceptually to a software framework than a hammer, but I don't think that's relevant and would only undermine the rhetorical effectiveness of the analogy.

The purpose of an analogy is fundamentally to describe some unknown thing (the subject) by comparing it with a different, known thing (the analog) that shares a common attribute with the unknown thing. The value in the analog is not in how many attributes it shares with the subject, but in how salient it makes the particular attribute you wish to highlight.

Consider when a boxer is described as having a "glass jaw". Here, the subject is the boxer's jaw, and the analog is the material glass. It would be pointless to complain the analogy is a bad analogy on account of the fact that glass is translucent whereas the human jaw is not. The point of analogy is to highlight that the boxer is vulnerable to impacts to his jaw. The value of using glass as the analog is the readiness with which we can conjure the mental image of glass breaking; the translucency is irrelevant.

Likewise, the point of this analogy about hammers and frameworks is that the author wanted something simple that would just work, and what he got was an over-engineered mess that requires considerable yak-shaving to get it to work. The fact that a hammer is more like a library than a framework is irrelevant, the point is that a hammer is something simple and familiar.


It is still a poor analogy, and the fact that a better analogy undermines the original point should suggest that the original point is flawed. Saying "I need a hammer" and reaching for a house frame is a poor choice. Saying "I want something simple that will just work" and reaching for a framework is the root of the author's woes. They don't even explain what the specific technical grievances are, it's just one drawn out analogy.

If they want a hammer to build a house, they'll need a screwdriver, and tape measure, and a table saw. They looked at a few toolkit options on the shelf, got tired of reading the instructions, and ranted.

To be fair, I'm sure frameworks in 2005 _were_ cumbersome. (I'm frustrated enough using Spring in 2021, but I still recognize that it's a fully featured house frame ready to go)


The analogy just makes so much intuitive sense to me that I may be having a "curse of knowledge" thing in trying to explain it to people who don't get it. In thinking about your response I think I may not have explained the author's analogy correctly. Let me try and correct that to see if things make sense.

The hammer here is not meant to be analogous to a framework. The hammer here is just supposed to be some sort of functionality provided by the framework. It is the store that is supposed to be the analog to a framework. Just like a hardware store provides tools, a framework is supposed to provide a collection of related pieces of functionality.

The point the author was making was that the frameworks available at the time would never just provide you the functionality in any sort of direct way (i.e. selling you a hammer). Instead, those frameworks were all about providing users with a generic set of abstractions for building or configuring the functionality you needed (i.e. a hammer factory).

Let's keep in mind that this is 2005, barely a year after the initial release of both Ruby on Rails and Maven, two pieces of software which which would later popularize the notion of "Convention over Configuration". At that point frameworks (especially Java frameworks) were generally these hideous, over-engineered, design-by-committee monstrosities. The fact that Ruby on Rails and Maven went on to be wildly successful is in fact a vindication of the point the author was making.


Thank you, I appreciate this. It drives me crazy when someone dismisses an analogy because some other attribute than what’s actually being compared doesn’t match. Yes, you’re right, they’re not the same! If what you compared were exactly the same in every way, they would be the same thing!

I think it’s part dishonesty, part emotional attachment to the things being compared (you should probably rarely bring Hitler into the mix, even if technically it works), and partly that some people just don’t understand analogies.


I think it's partly that it is easy, especially for technical people, to get hung up on details. And there is a good reason for this. It is often the case, especially with very technical topics, that the use of analogies can actually hinder understanding, because of the tendency to take the analogy too far[1]. Usually you just have to communicate a bit more on what the scope of the analogy is, and then it will make sense.

There's also a subjective element in terms of what analog will be salient. Using the phrase "glass jaw" isn't going to have the same effect for someone who first thinks of Pyrex or bullet-proof glass.

> Yes, you’re right, they’re not the same! If what you compared were exactly the same in every way, they would be the same thing!

LOL! I've had that conversation almost word-for-word.

[1]https://byorgey.wordpress.com/2009/01/12/abstraction-intuiti...


I remember the first time I heard the phrase “glass jaw”, by then I was early college age and it pretty much just made sense without requiring much thought. The only context I needed was that it’s a boxing term.

If I contrast that with the difficulty I had understanding the hammer factory analogy having just read the linked article , I’d say there is some value in creating better analogies. Not all analogies are made equal.

That said, I finished the article and didn’t feel completely connected with the analogy other than, true frameworks do make me jump through a bunch of hoops sometimes. Is that what he means with this analogy?

If an analogy is a tool to aid comprehension, or make a point, I can’t follow what this is supposed to mean.

Also FWIW, glassjaw is a great band if anyone likes 00s screamo


The analogy is that the hardware store represents framework, and the hammer represents a piece of functionality the framework is supposed to provide.

The point is that frameworks of the era rarely provided a simple, direct API for performing some task. Rather, there was often a whole bunch of "Abstract Factory Factory" patterns, which would require a bunch of ceremony before you actually had and object that did the work you needed to do.


I agree, it’s of course also possible for analogies to be strained or unclear. You need to keep the audience in mind as well.


If the analogy is misleading then it hardly seems a defense to tell me that a more accurate one would lack the same rhetorical force.


> "you call a library, but a framework calls you."

This is why I don't like when people say "React isn't a framework, it's just a library". Almost all of my React code is "called by React" with the one exception being `ReactDOM.Render()` (I don't count that since every other framework has some analogous "bootstrap" instruction).

Now if folks want to argue that React only handles the "view layer" without providing a built in state management solution, that's absolutely true (and considered a separation-of-concerns positive by a lot of people including me). But I feel like so many folks just boil this down to "React isn't a framework, it's just a library" and then use that as a segue to negatively comparing it with their chosen tool.


> Almost all of my React code is "called by React" with the one exception being `ReactDOM.Render()`

It only feels this way because your calls to React are hidden away behind JSX. I believe this is also why you can't write any JSX without importing the React module first.

If you've ever had the "pleasure" of writing React with plain React.createElement() calls (what your JSX ultimately gets transpiled to) then I think you would more likely agree with the notion that React is "just a library".

Create-react-app is much more akin to a framework in that it bootstraps an environment for you where you don't have to do any of the things that make React feel like simply a fancy library for rendering HTML.


> If you've ever had the "pleasure" of writing React with plain React.createElement() calls (what your JSX ultimately gets transpiled to) then I think you would more likely agree with the notion that React is "just a library".

I'm not sure why someone would unless you're strictly writing static JSX with no components whatsoever as some sort of weird replacement for just writing the equivalent static HTML. The minute you write a `render` or lifecycle method, React is now calling you. Not to mention stuff like Suspense asking you to throw a Promise to render from latest render cache.

I think something like Crank.js[0] is more a view library since it puts all the nuts and bolts into userland.

[0]https://crank.js.org/


You use React APIs to do everything you would normally do with React. You use the API directly if you don't have a build step for your web app and you cant or don't want to add one. Since React is indeed simply a library with an API, you can progressively integrate React into an existing web app in this way (a big selling point in the early days that people have sensibly forgotten by now). You couldn't progressively integrate a traditional framework like Django for example.

Lifecycle methods like render, componentWillMount, etc are just callbacks that get fired when you render you a component. I don't think any library is immediately graduated to the class of "framework" the moment a callback is added.


> You couldn't progressively integrate a traditional framework like Django for example.

I dunno here, is Rails a server application library because I can progressively integrate the different components of its total API, e.g. first use ActiveRecord, then adopt rails-api for the frontend, then adopt ActiveView and Turbolinks for the end-user frontend? Or is there different idea of framework at work here?

> Lifecycle methods like render, componentWillMount, etc are just callbacks that get fired when you render you a component. I don't think any library is immediately graduated to the class of "framework" the moment a callback is added.

But I don't write the code that says when they're called. Backbone is more of a library, for example, since it lets me do all that and it can be progressively integrated into an app too (I can just use models, I can just the views, etc). I mean thats part of why people ran to Ember and Angular when they appeared, they didn't feel like doing all that.

Also see Crank.js: you can emulate React's Component API in Crank, but the reverse is not true. If I'm not writing the code that "turns the gears" per se, then to me I'm using a framework. That framework might have a small API surface, it might have a large API surface. That's how I see it at least. A framework to me is defined by a certain threshold of abstraction.

This is an async task library because I can opt-in and out of, as well as control, or simply replace, the scheduler[0]

[0]https://github.com/mitranim/posterus


>I dunno here, is Rails a server application library because I can progressively integrate the different components of its total API

I'm not familiar with Rails but it sounds like the individual components you list can be used independently of your traditional Rails web server so that would indeed make them libraries. I'm not sure that makes the entirety of Rails a library. Could you rewrite an endpoint with Rails within another Ruby web framework (I don't know of any) without needing to run two servers? If so, Rails is a library.

> But I don't write the code that says when they're called.

That's simply not true. Every lifecycle method is the direct result of a specific programmatic call. Whether it be a render (ReactDOM.render), prop change (also ReactDOM.render), or state change (setState). If you don't setup the logic to call these APIs appropriately no callback will ever be fired. It only feels like React is firing these events for you because these API calls are likely hidden behind JSX and hooks and they are also asynchronous by virtue of React having to manipulate the DOM.

> If I'm not writing the code that "turns the gears" per se, then to me I'm using a framework.

The only gear you don't get to control is specifically how the DOM is manipulated. Everything else is in your control when using React.


> I dunno here, is Rails a server application library because I can progressively integrate the different components of its total API, e.g. first use ActiveRecord, then adopt rails-api for the frontend, then adopt ActiveView and Turbolinks for the end-user frontend? Or is there different idea of framework at work here?

I think you misunderstood parent comment. Progressively integrate here means: you have a web page (facebook.com), you want to replace a part of it with react (chat function), you rewrite just that portion of the webpage in react.

You can't get a Sinatra application and replace just one route with rails. Well, you can use ActiveController, which is just an opinionated wrapper around Rack with a lot of sugar, but that wouldn't be rails and you won't get any rails benefits of doing that.


Great resource for anyone interested in this. It’s really enlightening: https://pomb.us/build-your-own-react/


yes, well if I didn't use most of the built in functionality of a framework I suppose it would be a lot more like using a library.


Support for JSX is not built into React. React is simply a JS library and JSX is not valid JS. So if you add React to a web page, and attempt to write logic with JSX, you will get syntax errors.


No, it's literally the case that JSX compiles into (indirect) calls to your own functions. It's not a magic 'framework' that calls your code when you use JSX, it's... your code.

When you write

   return <MyFunction foo={bar}/>
that gets turned into

   return React.createElement(MyFunction, { foo: bar }, [])
Which returns a refreshable wrapper round the result of calling your function.

It's really a reactive-functional type system, rather than a framework - with a syntactic sugar that makes it easy to generate a reactive wrapper round a function.

Then you take the result of passing all your functions into that syntactic wrapper and hand it to ReactDOM to have it synchronize it with the DOM.

React transcends the framework/library discussion because it really isn't either. It's a higher-ordered type factory.


React is a library that should have been a framework.

Literally everyone has to cobble some n-factor framework together and given the amount of inexperience out there, what results is a damn nightmare.

React solving the state problem natively would have made it an industry game changer. What we have is an industry mess.


Angular Vue and Svelte fit your description and none of them are more popular than React, I guess people have made their choice.


It's an open question whether React succeeded because of technical advantages or because of Facebook's initial support and the job market creating its own dynamic (people go where the jobs are).


> React is a library that should have been a framework.

React is a library that powers several different frameworks, as well as lets people use it without those frameworks. If one size fits all, answer-for-everything frameworks were the optimal solution for all problems, Angular would own the world and we wouldn't need React.


Google rug pulled angular, I know at least one very large company that pulled all Google tech from their stack over angular 1 -> 2.

React really isn't the thing people have decided is the optimal solution, jsx and keeping presentation tightly coupled to business logic is.

What is see with react is constant attempts to work against that ideal.


> React really isn't the thing people have decided is the optimal solution

My point is there is no one thing people have decided is the optimal solution. React is an element of snow me of (several different) things people have found is optimal for some problems, and not part of others.

> jsx and keeping presentation tightly coupled to business logic is.

JSX is more generally than React is, which is why many not-React solutions use React, too, though even that is far from universal. Tight coupling between business logic and presentation is, OTOH, far less generally what people have decided is optimal.


I've seen entire apps written as React components/hooks, the whole thing, no redux/mobx/etc managing state above the level of necessary local UI state. React markets itself as just a library but the truth is people tend to go all in precisely because there's too much pressure to research a whole stack for yourself.


Those are likely some really solid applications as a result.

In my experience redux just enables developers to sprinkle global state everywhere which makes tests a pain to write and code hard to debug.


I think React's original goal was to be a library, but the community made it a framework, because they could not conceive of any other way to operate.


Less that they couldn’t conceive of any other way, but more so we are slaves to the vdom diffs. That’s what we signed up for, and boy did we get trapped. Go ahead, put a little jquery into your React app, or that animation library that looks cool, you’ll blow up the whole point of React.

Sorry, you will have to do things React’s way until the end of time if you want your rendering to be optimal. That means whatever it means, hooks, suspense, fibers, context, so on.

A library means I get to plug in other stuff without totally crippling another library, as React claims it is.

Nothing wrong with React, just become the framework you are and provide the built in solutions.

Think of it this way, imagine the React team made curl. Now they say you can curl anything. So now you say, ‘ok, I want to curl this’ and they respond:

‘Oooo, I don’t know about that, that’s gonna mess up all the curl internal optimizations, hmmm, no no, you SHOULDNT be curling that’

And then we all walk away going ‘oh’, silently. Checkmate, hoodwinked.


Hmm, I don’t really agree on this one. Just a day ago I’ve added a totally not vdom, stateful component that was mutating DOM and adding nodes on it’s own to fix performance problems with critical part of the app that required instant feedback to user typing.

React was not bothered at all. From the start there were ways to escape React model in components and integrate components into other frameworks. Been there, done that, it was never a huge deal.


Yeah, that's been my experience, too, for instance in one of my toy projects dropping a rotjs game display into a React app.


Can you describe what you did? Breaking out of React for rendering means you are in deep shit. In fact, I’d love to see the hoops you jumped through, which I’m certain you will brush away as ‘not a big deal’.

But I am an American, so I won’t put up with any inconvenience and don’t consider it virtuous to do so (we fought a war over a tea tax after all).

But I’ll take a wild guess:

A bunch of useRefs? I’m excited to hear all of this.


React only re-renders a component if the state changes, the props change, or a parent component re-renders. In my app, I only have one component where I needed to break out of the vdom, and none of the parent tree ever re-rendered (except when navigating to a new page, which correctly tears down the component), so it was as simple as just one useRef to grab a reference and one useEffect to pass it to my other code after the component rendered.


A pretty straightforward pattern here (and one that I actually just implemented with no hiccups for a non-React animation library) looks like:

    import { useEffect, useRef } from 'react';
    import { Controller } from 'some-animation-library';

    const SomeWrapperComponent = ({ options }) => {
      const elementRef = useRef(null)
      const controllerRef = useRef(null)

      useEffect(() => {
        if (!elementRef.current) {
          return () => {}
        }

        if (!controllerRef.current) {
          controllerRef.current = new Controller(elementRef.current, options)
        } else {
          controllerRef.current.setOptions(options)
        }

        return () => {
          controllerRef.current.doSomeCleanup()
        }
      }, [options])

      return <div ref={elementRef}></div>
    }


Thanks, that’s exactly the simplicity I wanted you to share, you did good.


The most recent thing was the typing app where we had to change style if each character after user typed it. With long texts (10k of characters) performance of tree diffing was not acceptable (especially in Safari) so we replaced whole text component with manually managed DOM and were mutating nodes directly.

I’ve been using React for quite some time (started with version 0.11 or something) and had to integrate quite a few libraries on my own (stuff like OpenLayers for maps, etc) and it also worked pretty well. Also made few apps that had only few widgets (search UI, calendar, etc). It usually worked quite well.

Mixing React with non React is quite easy. You only need to encapsulate it - keep all non vdom stuff in one component and never escape single DOM node.


And with hooks that's become even more true, there's now a distinction between React functions and regular JavaScript functions, and you can only call a React function from another React function.


Not entirely true. Hookless function components can be called as regular old functions just fine


It stops being a library when you structure your entire codebase around it.


Or any part of your codebase for that matter


It used to try to be like that. Only calling setState re-renders things. And you control state and when to render.

Until the hooks introduced.

Now it also want to handles all the state and timing for update. And you are no longer able to call from outside or decides when to render (in a simple manner, as there are still workarounds).


> > "you call a library, but a framework calls you."

> This is why I don't like when people say "React isn't a framework, it's just a library"

Eh, this is just a breakdown in the "framework calls you" heuristic. It's still a reasonable heuristic, but it doesn't completely describe all distinctions people make between frameworks and libraries.

The distinction missing from the heuristic is the overall scope of the software project relative to other popular software projects in the same area. When people say "React isn't a framework, it's just a library" they're not saying much about the coding style one uses while using React. They're just comparing the overall scope of React to some of its close competitors (like Ember and Angular).


> "React isn't a framework, it's just a library"

There may not be a clear line between framework and library, but as written in the homepage of reactjs.org, it claims itself: React - "A JavaScript library for building user interfaces"


HN: Use the right tool for the job.

Also HN: Always and every time do use a carpenter analogy... or something involving woodwork.


I think a lot of programmers secretly want to be carpenters.


What happened to good old car analogies? This carpenter stuff is a little too waxed moustache hipster for me.


Modern cars are incredibly complex and car engineering/manufacturing has really complex lifecycles. It is quite difficult to make an analogy with a thing that requires a lot of analogies to in the first place to explain.

Carpentry/woodworking is somewhat simple. With a saw, planer, router, sander and a few primitive hand tools you can finish most woodworking projects. Most of the complexity of woodworking is in the accuracy/quality. Woodworking is simply easy to be conceptually* familiar with.


There's no irony in this statement unless you assume that "HN" is one person who you expect to be consistent.

I think we all visit HN because of the many people and varying opinions and ways of thinking. I hope we continue to see conflicting thought processes like this!


Also HN: lets take a few comments and pretend that's everybody on HN ;)


So what do carpenters use for analogies?


Software Engineering.

"Just imagine the facade is the frontend."


I liken this instead to GOTO vs COMEFROM. A library is a GOTO statement, while a framework is a COMEFROM statement. Deity help you with the latter if you have problems and not enough knowledge about the framework.


I always saw it as a tight-coupling with whatever framework you are working with but a loose-coupling with whatever library you are working with, but I like this more. It's much more emotional, almost psychological horror to a programmer.


It is...and then you can't help thinking about the "no-code" solutions.

Anyway, also:

1. any application with sufficiently complex use cases requires configuration

2. any configuration can be made programmable

3. frameworks are application configuration with an open-end configuration programmability

4. ...

5. profit



> The main distinguishing factor between a framework and a library is the classic "you call a library, but a framework calls you."

This definition does seem to match how I generally hear the terms used, but I think whether you call something or if something calls you depends more on the function of the library/framework than anything to do with the code itself.

I think we generally have "web frameworks" and not "web libraries" because if you are making an HTTP sever, then yea stuff is going to be calling you. ie.e the incoming HTTP requests are going to trigger your code. Now if I have a piece of code that extracts URLs from a string, that is obviously going to be called by me. That I can see, who is calling who has nothing to do with the design of the framework or library, and everything to do with the sort of task the framework or library performs.

Anyway, engineers obsesses over the distinction between library and framework, but it seems fairly mundane from my perspective.


> because if you are making an HTTP server, then yea stuff is going to be calling you.

Not necessarily. You could write the

  while True:
    request = getNextRequest()
    ...
yourself. A web server library would have functions for parsing headers, creating http responses, handling cookies, generating html, etc., and could have data structures that make it easier to dispatch requests to individual handlers, but your code would be in the driving seat as to what gets called.

Also a web framework could call a function to extract an URL from an incoming http request without any involvement of code you write.

A framework provides a main method; a library doesn’t.


The thing is that computer guys got too much in love with the word and started to think framework === full blown 15-tier industrial facility.

A good framework removes a chunk of work, guides you for the remaining part so you get there quickly but it should stay narrow if possible.

here's a small framework: https://imgur.com/a/rBBdRSO

here's j2ee 4 understanding of the term: https://imgur.com/a/EH3vpXD


It's trivially easy to reframe the hammer as a framework; just take the point of view that what you're bringing to the table is the nail and the two pieces of wood (or other kinds of parts on which some type of hammer might be used).

These pieces of yours are "called on" by the "hammering framework".

This would all be easier if we had a metaphor-factory-generating factory.


It invokes some of the particular absurdity of Spring or AspNet, though.


I personally have often drawn the analogy of frameworks-as-general-contractors. Subcontractors (devs/engineers) are hired throughout the lifetime of the project and are the ones actually building all or most of the individual components, using tools (libraries), but their work streams are specified and directed by the GC.

Some GC's are super opinionated (Rails/Django/Sails) and others kinda let you do what you want (Sinatra/Flask/Express). Neither disposition is inherently bad, but can have serious consequences as a direct result of both.

I think this maps pretty well to the "framework calls you" concept you point out, a nod to inversion of control I assume.


If we go down the woodworking analogy path, I guess the main difference between a library and a framework is that the former is a set of transformative actions and the latter is a set of building primitives.

A really great analogy wood be a wooden window. A router/planer/saw in a workshop are libraries: they can take a piece of timber and transform that piece in a certain, somewhat adjustable way. A set of standard hinges/locks/mounts and router/drill sizes is a framework.


When you instead call it a factory analogy, exactly as the story reads, it suddenly fits well.

Confusing a framework for arbitrary reuse is perhaps the best way to identify developers who aren't the mythical 10x developer. It is no different than confusing decoration for something useful when you are fending off destitution.


Past threads:

Why I hate frameworks (2005) - https://news.ycombinator.com/item?id=12635142 - Oct 2016 (65 comments)

Why I Hate Frameworks (2005) - https://news.ycombinator.com/item?id=9203959 - March 2015 (62 comments)

Why I Hate Frameworks (2005) - https://news.ycombinator.com/item?id=6542817 - Oct 2013 (36 comments)

Why I Hate Frameworks (2005) - https://news.ycombinator.com/item?id=6283601 - Aug 2013 (117 comments)

Why I Hate Frameworks - https://news.ycombinator.com/item?id=2787525 - July 2011 (99 comments)

Why I hate frameworks (2005) - https://news.ycombinator.com/item?id=1533274 - July 2010 (54 comments)

Why I Hate Frameworks - https://news.ycombinator.com/item?id=431786 - Jan 2009 (124 comments)

Why I Hate Frameworks - https://news.ycombinator.com/item?id=95722 - Jan 2008 (17 comments)


This article from 2005 definitely captures some sillyness around dev work at the time, but in retrospect a lot of that was caused more by Big Objects than by frameworks themselves, although Big Objects was definitely enabled by frameworks.

Big Objects was the idea that in the future, basic doing stuff level code would be fully replaced by bought or open source objects that would plug in in standard ways to industry wide interfaces. It was nuts, and was largely driven out by ruby and python gaining traction, libraries that were marketed as having more pleasant interfaces than their competition, and 'enterprisey' becoming a bad word. Still, you could take a couple swings through the conference circuit around 2004-2006 by saying that the future was kludging together fungible objects in Java or .NET.


> Big Objects was the idea that in the future, basic doing stuff level code would be fully replaced by bought or open source objects that would plug in in standard ways to industry wide interfaces.

We call them microservices now.


You just keep putting stuff in smaller and smaller Matryoshka dolls and then poof! No more stuff.


From "Mortal Engines" by Stanisław Lem:

> Pyron invented the wire telegraph, and then he pulled the wire out so fine, it wasn't' there, and in this fashion he obtained the wireless...

(https://english.lem.pl/works/novels/mortal-engines/136-intro...)

I always loved that passage and it would always crack me up from the sheer absurdity of it.


Aside from obviously great quote, thanks for reminding me of Stanislaw Lem and Pyron. I grew up reading translations of old Russian books and (I know he was Polish) your comment was a good walk on the memory lane


To be fair, they are a little better than the OG technology.


Everyone should try to build their own pluggable framework at least once, to realize how difficult it is, and to realize how small design decisions can cause massive headaches. I think a lot of frameworks are the result of someone shipping something, it gets popular, and then its stuck like that and they can't rethink it.

Having done this helps you to see things in new frameworks that will inevitably lead to pain.

As often as people deride it, the Node.js many-small-package philosophy (inspired by Unix) is what I keep coming back to. If one package doesn't provide the right abstraction to do something, if it's built on top of two smaller packages, I can assemble a new package with these smaller packages to achieve what I want. The smaller the package the better.

From the day the first line of code in a project is written, a desire to rewrite from scratch starts to grow - to return to the productivity of having an empty slate. If you compose your app from small single-purpose packages, rewriting becomes trivial.


Big Objects is explained in detail in the Java Beans Spec: https://www.oracle.com/java/technologies/javase/javabeans-sp...

The idea may have died, but there's still lots of vestiges of it in the Java world.

- getters and setters with standardized names

- Swing mechanics like EventListeners and PropertyChangeListener

- Java Serialization

They hoped that a Java bean could be plugged into any UI and be visualized, modified and generally integrated into any app, so you could "buy" beans made by other developers, for example.

It was definitely an interesting idea, but things went in a completely different direction, as we know.


https://netbeans.apache.org/kb/docs/java/quickstart-gui.html

It wasn't an "idea". It was/is working tech. How do you think a GUI builder for Java works? In fact, how would you build a UI design tool (in any language) without arriving at the equivalent of a Java Bean (aka Standard Component)?

[p.s.] Btw, "Big Object" is a funny way to call a Component. COP is not OOP. (Thus: POJO). So getter/setter naming patterns (so the 'tool' can infer semantics), distinctions made between run-time and design-time, etc. are all perfectly valid concerns for COP and Java Beans a perfectly sensible realization.

The problem with the Java community has always been two-fold:

1 - The conceptual disconnect between the target audience of Sun's architects and the said architects. SMI's failing here remains, imo, a pedagogical failure.

2 - A language that facilitates creating complex runnable monstrosities by programmers who would be crushed by the same complexity in other languages. This is an ironic aspect of the Java language. Even newbies can go nuts with complexity.


Even though the Swing thing was java bean based, the idea of an "event listener" is a still current and sound idea in software development beyond Java.

The funny thing about "standardized" getters & setters is that they completely broke OOP and went against this idea that Java was "object oriented". One of the most known articles of the time was the infamous "getters and setters considered evil".


I think sometimes the abstraction moat around an otherwise good idea definitely repels would-be adopters, which an idea needs to ascend to mainstream success, beyond just technical merit.


> the future was kludging together fungible objects in Java or .NET.

And, DCOM and CORBA :)


As a web developer in the open source, PHP (YUCK) environment, the single time DCOM has been useful for me was an insurance company who had a government-mandated PDF document they had to send to customers.

Could we just generate a document in plaintext? No. It had to be pixel perfect dummy. And PDF!

Could we just recreate a pixel-perfect HTML to PDF template? No. That would take weeks and the client only budgeted a few hours.

So I asked, how do they do it currently. And they sent over a mail-merge MS Word template. We said, hey, so, we use PHP, open source, Linux. TOO MANY WORDS WE'RE PAYING YOU TO MAKE IT WORK.

Could we use the template in an open source framework compatible with the PHP solution we'd built? Yeahhhhhhhh... but no. The open source framework mangled the fonts, layout, and the PDF rendering was bodgy to say the least.

And yes, we went back and asked really, trully, honestly, does the government really give a shit if this document is not formatted exactly the same as whatever law they apparently passed said it had to look like.

No dice.

So we could have used any language I guess, but we were familiar with PHP. PHP has a DCOM extension that only works on Windows. So I spooled up a Windows Server instance (firewalled within the DC of course) and installed XAMPP and did a bunch of config to ensure it stayed updated automatically and rebooted every night at 1am. A small PHP script on the Windows server provided an API the website could call at any time. The Windows PHP endpoint had an unzipped DOCX, the script would copy the folder, search-and-replace based on API inputs, zip it up as a new DOCX file, opened in Word with DCOM to save as a PDF which was then streamed back into the website's logic all in the same POST request that a client submitted.

It was a kludge, I could think of other ways to do it today, but at the arse-end of a project with an apparent doomsday requirement suddenly dropped in the mix, in the end it took about three days to implement when at the time we were facing a crisis.

So yeah, give DCOM some flak I guess because it failed to launch but it saved one small project for one small insurance company.

Edit to add: That solution ran for years without issue until the company merged with a larger healthcare provider.


FWIW, you seem to be talking about regular local COM and not DCOM. DCOM is COM-over-the-network, where you can create an object on another machine remotely and interact with it as if it were a local object. You are describing just using a local COM object on that Windows server. Unlike DCOM, COM is extremely popular and widely used.


> DCOM is COM-over-the-network

The hint is in the name: "Distributed COM" i.e. DCOM :)

> Unlike DCOM, COM is extremely popular and widely used.

My understanding was that DCOM is nothing but data marshaling and registring GUIDs with Windows registry so that the COM object can be created locally/remotely. If COM is widely in use, then DCOM should be as well. The whole gaming(DirectX) and finance(OLE) industry is built on the DCOM/COM infrastructure :)


> If COM is widely in use, then DCOM should be as well

I'm not sure what you mean. If you don't actually activate an object on another machine, you're not using DCOM. You're just using regular COM. The distinction is pretty clear; if you need the "Remote Activation" permission on a target machine, then you're using DCOM. Nobody is, for instance, instantiating DirectX objects over the network. It may help to know that COM predates DCOM by several years; they are not the same thing. DCOM adds additional infrastructure to allow it to happen over a network.

The distinction here is relevant because DCOM, not just local COM, is the competitor to CORBA. The "distributed" part is the part that didn't work out and that, it turns out, not very many people want.


Good point, it was a long while ago and I was definitely using COM objects. The network interface was handled by Apache with PHP scripting. I stand corrected, thanks :)


I’m curious what you would do differently. Maybe the docx part could be a little more robust, but it doesn’t sound too bad as a way to meet those really specific requirements.


Yeah, I'd do it exactly like he described. Clean? No. Who cares? No one.


Thank you for sharing this story. I consider war stories of this caliber to be unironically heroic exercises of thought.


Thanks, I took a lot of flak from my colleagues and it was always treated like this wart on the outskirts of our COE. The only other options required discarding two month's work and refunding the client, or investing another few weeks building a bespoke PDF generator for this one use-case. I never really saw it as a heroic exercise, just had to think of a way to save everyone's time, money, and reputation in the fastest, safest, most reliable way possible.

I never got a compliment for the solution (just a "okay if you think we can make it work go ahead", and afterwards a "nice work, let's hope it doesn't break") so this is a first. Thanks again.


>Big Objects was the idea that in the future, basic doing stuff level code would be fully replaced by bought or open source objects that would plug in in standard ways to industry wide interfaces.

Isn't this the same as API's as a service?


What is "Big Objects"?


A colloquialism that I explain in the second paragraph.


Oh I thought it's a real thing, started googling it and landed on Salesforce's Big Object! Thanks.


I suspect the OOP industrial complex like "Big Pharma".


As the original author of this post, I'm always amused to see it coming back again and again on Hacker News.

A lot has changed since 2005, but a lot of things have stayed the same. What a weird craft we practice...

Anyhow, thanks for all the laughs, everybody!


You should write a follow up and link that to the original post.


(2005)

Also reminds me of this framework parody (and the container one it was based on, linked within)

https://hackernoon.com/how-it-feels-to-learn-javascript-in-2...


What's funny is that now, 5 years later, all the crazy things the writer is parodying sound completely normal to me.


I last coded JS seriously in 2016 and I felt like I was losing my mind (though once things got working it was fun). Did things settle down since then?


Since 2016... yes, more or less.

Webpack became the de-facto standard for bundling for a few years there, but everybody hated configuring it, so it dramatically increased the "out-of-the-box" configuration. That said, the ES module standard has started to make its way into the world, so there are more than a few bundlers these days that aim to do Webpack's job better. They've also learned from years past, and most try very hard to remain "zero-config".

TypeScript has become extremely widespread, and has finally reached a reasonable level of maturity, in the sense that 1. most libraries now come with type definitions, and 2. its type system is sophisticated enough to express (and infer types for) common Javascript patterns. For non-Typescript code, Babel is still quite common, although like I mentioned, most bundlers are trying to avoid making you explicitly configure your compiler, so it's much less of a PITA to get working.

In runtime-land, I can only really speak to React. It's come quite a long way in the past couple years- the main difference is the introduction of "function components" rather than the previous "class MyComponent extends React.Component". These function components use a new effect/state management architecture (called 'hooks') that's sort of like a DSL. Personally I really like it, but it's kinda divisive. Next.JS has emerged as sort of the standard "React front-end framework", and it's quite nice- again, people took "Javascript fatigue" pretty seriously, so there's much less fussy configuration.

In semi-related tech, GraphQL has become quite popular for APIs, and there are a few libraries out there to help handle it.

Oh, and the Prettier formatter became popular, for whatever reason, which makes me want to bang my head against a wall because in spite of the name, it makes everything it touches uglier.

Anyways, I know that was kind of a wall of text, but the takeaway here is that although a bunch of new stuff happened, FE tooling is definitely trying to be more mature and avoid a Cambrian explosion of new stuff like there was back then. Hope that helps!


I actually really like Prettier. It ensures that everyone's code ends up formatted the same, and when you're working on a project that a bunch of different people touch, that makes reading the code so much easier. It may not always be beautiful, but at least it's consistent and readable.

It also means I have to spend zero time worrying about formatting. Now I often just type stuff out on one ugly line, then hit ctrl+s and everything magically formats itself, it's honestly great. Whenever I work on code without Prettier it makes me realize how much time I spend just formatting things.


I don't have a problem with the idea of a formatter (gofmt is freaking amazing), but Prettier itself makes extremely asinine and frustrating formatting decisions.

> It may not always be beautiful, but at least it's consistent and readable.

"Consistent" as in a consistent set of rules applied across the team, sure. But Prettier-formatted code ends up being extremely internally inconsistent. The best example (and the one that drives me bonkers the most) is function parameters (both traditional params and destructured-object params). Prettier forces you to go with whatever decision IT thinks is best about lining stuff up, meaning it'll force you to change:

    const myFunction = ({
      xAttr,
      yAttr,
    }) => {
      // ...
    };
into

    const myFunction = ({ xAttr, yAttr }) => {
      // ...
    };
That is, until you add another param:

    const myFunction = ({ xAttr, yAttr, anotherPropIAddedLater }) => {
      // ...
    };
And THEN it'll reformat it to a vertical list. Which is what I wanted all along! I could go on about other formatting BS it does (hooks in React are another good example) but I think I got my point across.

Again, like- I don't necessarily think formatters are a bad thing in principle. What I hate is the fact that the most commonly used formatter in JS-land is so mediocre in its output.


Your specific example makes perfect sense to me. It starts wrapping when you exceed the line length limit. It would be a bad formatter if it didn't do that.


No? Tons of formatters respect user-introduced whitespace, which is a good thing to do.


One of the main selling points of Prettier for a lot of people is that it is extremely opinionated and leaves very little formatting choices up to the user. If you respect user-introduced whitespace then the same code written by two different people can end up formatted differently, which is precisely the problem Prettier is trying to to solve.

I would argue the example posted above is still "consistent" because the rules Prettier follows for line breaks (and everything else) are consistent throughout the codebase. Things will be on one line until the line is too long or complex, and then it will break to multiple lines. The rules don't change depending on who was writing the code, what the code is, or any other factors. It may not be formatted exactly how you want, but that's kind of the whole point. It's formatted how Prettier wants, and that's the only option.


I love that this is being 100% serious and is probably close to 60% the wordcount of the parody article.

I know enough of javascript when I did it back in 2010 as to WHY people built all that. It's still basically the same feeling as watching the movie Brazil.

How will Webassembly possibly handle backwards compatibility to old browsers? Webassembly --> asm.js transpiling?

Edit: yes it will. And apparently Webassembly is actually Lisp.

Hm, I can see webassembly equalling/surpassing the JVM in technical capability. That might be a pretty good thing, because javascript on the server was never a good idea.


WebAssembly isn't a Lisp, it just happens to have an s-expr representation


After working with it for a while you get used to the ugliness from prettier, but still I really wish JetBrains would release their formatter as a prettier alternative / competitor.


Agree on all points...except Prettier, which is manna from the gods. Better to get used to it than to fight it.


It's ok except the wrapping rules. Everything turns out into vertical grotesque - and TypeScript has longer lines because of type names so it wraps often.


I use it with TypeScript, and I find the wrapped lines to be far more readable. You get used to it.

Many people do, though I understand it's a point of religion for some to Not Wrap Lines.

Had a short contract recently with a company that had a small team of two developers. My widest reaching contribution to the team, I think, was to vote with the team lead to adopt Prettier.

Their previous approach was to _never wrap import lines_. There were literally 1000-character import lines. One of the developers was totally religiously opposed to ever wrapping them. Deltas in PRs were impossible to actually parse with huge lines like that, and if two people modified the same import line, merging the two changes was a nightmare.

But with a facade of Democracy, the team lead was able to finally adopt Prettier and its wrapping to the project. This despite the fact that I'd already let it be known that I was only staying until the end of the contract (about three months) and moving on. Whatever works.


While fetch rules the browser, it’s still anybody’s game for succeeding request.js for node.

Recently I’ve been going with got.


I haven't really been following, but I just sort of would have assumed that node-fetch or equivalent would be mainlined into nodejs. I get that nodejs is not in the habit of replicating browser APIs, but it seems like that one, at least, would be on-point for nodejs.


Node-fetch?


Thanks, that does!


No.


Not sure which planet you're on, but it's been 16 Earth years.


The Hacker Noon article was released in 2016.


Ah, thought you were referring to TFA, my error.


Timely. I am kind of old-school when it comes to game development and recently got into teaching my daughter maths and programming and art through it. It's been a lot of fun.

Buuuuuut.... the early stages of starting game development these days are, "What engine do you use?"

And honestly it can be a daunting choice. They're all quite large and have their own jargon and way of doing things. I can get through a "Hello, world!" tutorial in an afternoon but it'll take months before I get something useful to work and load my brain with all of the jargon to navigate the documentation and forums...

versus writing everything from scratch. It's a slower start but I have already learned a good programming language and can go from there. I don't end up with a black box of performance problems. Nor do I end up trying to shoe-horn my round game into a square peg. It's quite common going down this route to write your own data formats and tools as well: level editors, compilers, debuggers. And the productivity starts going up fast as you build momentum.

So I typically go a "libraries not frameworks" kind of approach.

Which seems to be entirely alien in the enterprise world. The common wisdom here is to never write your own tools. Always use what's on the shelf and get going as fast as possible. Yet I often end up in those tar pits where cloud costs overrun operating budgets and failures happen constantly without any built-in observability... I wonder why more teams don't build tools for themselves?

Is it not as uncommon as I think?


> Which seems to be entirely alien in the enterprise world.

There are a few reasons for this.

1) Enterprise is mostly staffed with mediocre programmers. That's not meant to disparage anyone. Even great engineers will produce mediocre work if the incentives are aligned that way.

2) Enterprise problems have more to do with people management than writing the fastest and most cutting edge software. Frameworks can get hundreds or thousands of engineers speaking the same language for writing the boring code (which is the majority of code).

3) Enterprise companies often already have an established business model that works. They often have market dominance in some area and it's okay if their software is a little slower/buggier/etc. Game industry is no different.

4) Enterprise companies often have enormous scope that smaller handmade tools can't always cover. For example your average homegrown UI framework probably won't have accessibility in mind from day one.

5) There is no way to judge the quality of homegrown tools until it's too late. Our industry (like any other) has very loud yet very dumb people who convince others that their way is best. They build up layers of awful tooling/architecture that needs to be rewritten down the road. Frameworks have at least some form of validation.

I used to believe the above was fixable. Now I know better and just stay away from big companies. Work is more fun and fulfilling that way :)


>"Our industry (like any other) has very loud yet very dumb people who convince others that their way is best."

This is so f..g true. Also clearly seen here as well - preaching that this way is bad and that way is the true one.

>"I used to believe the above was fixable. Now I know better and just stay away from big companies. Work is more fun and fulfilling that way"

Exactly what I did. After reaching top still somewhat technical position at the company I got so fed up and burned out that I quit. Went on my own and been this way ever since for some 20+ years.


> Exactly what I did. After reaching top still somewhat technical position at the company I got so fed up and burned out that I quit. Went on my own and been this way ever since for some 20+ years.

I'd love to hear more about your journey. What did going out on your own look like? What type of work do you do? How long did it find you to figure out the kind of work that satisfied you and paid the bills?


Well, by the time I quit I already had my own product in progress. Since I was paid quite well when I was employed I've saved enough to just finish the product very fast and little by little it had started bringing licensing fee. After 10 years the money coming in from that product mostly dried up but I've started another one by then. This one is doing ok even now. Also while I was employed (we were consulting shop) I've acquired a reputation as the guy who can deliver best solutions for a given constraints. So all along the way many companies who knew me because of my previous work kept offering me contracts to design and build products for them. I am very versatile guy who can do firmware for microcontrollers, enterprise grade backends, desktop multimedia / hw accelerated graphics, middleware etc. etc. Also proficient in electronics and mechanical design. This all helps me to be afloat. In my other life I was a scientist back in the former USSR.

So to summarize: I am a product guy. I design and create various products either for my own company or for clients. I did it all my life and I love it and the only thing that had changed over the time is that at some point I've become ISV and am my own boss. I am 60 now but (keeping my fingers crossed) my brain still feels and performs like I am 30 and also in great physical shape as I do not forget physical activities. There must be something in our family as my wife is also work from home / consultant for the last 15 years and so is my daughter for even longer.


Some more:

- Compliance, in the financial, legal or data sense - increases code complexity greatly, and warps the architecture of the system under its weight

- Policy engines: who's allowed and not allowed to do what, limits

That's a whole lotta scope beyond the core competency of the program that you cannot outsource.


As someone who started out in the game industry in 1990, I can say that being able to choose between competently-built game engines is a HUGE bonus.

At last count I'd written six (!!) game engines. Nothing huge; mostly "casual" games as the target. One of those engines ended up having over a hundred published games written for it, though, so at least in that case I got some decent traction.

And honestly? If at any of the times I was starting a game engine, I could have just sat down and focused on _writing the game_? I would have taken that option and not looked back.

You have to make a decision, when it comes down to it: Do you want to write a game? Or do you want to build a game engine?

Because writing a complete game engine can take 2-3 years all on its own. And yes, that's counting gluing together existing libraries. I never wrote, e.g., a PNG or JPG loader from scratch. The engine with 100+ games? I started work at PlayFirst and immediately started working on the game engine. Nearly six years later when I quit to work on my own games, I was _still_ adding features to the engine.

Games were certainly released before that; the first game I released was probably only six months in. But the game engine (Playground) wasn't very mature yet, and it wasn't until at least 2-3 years in that using the engine really had a robust set of features (including cross-platform support).

And if you're looking at creating a 3d game, and don't want to start with an engine? Well, it can be done, but again, if your time budget is three years, at least half that time will be working on parts and fixing bugs that a solid engine would have handled for you. If your time horizon is shorter, then expect even more of your time to be spent reinventing the wheel.

Source: I spent 20 years in the game industry.


I believe, if you really want to understand how a game engine works, you need to try to build a game from scratch in your favorite programming language. It's a fun exercise and you really grow as a programmer. If you use an existing engine, you will never really need to know how to initialize a window for rendering, you never need to touch opengl/directx/vulkan/etc, you never create a rendering loop, a scene tree, implement a matrix library, create a basic physic engine or integrate a scripting language.

All those things are fun! I know it, because I spent about 8 years on and off tinkering on my own engine in my spare time when I was younger. And what can I show you after all those years? A fun tech demo maybe, but other than that, not a single finished game.

Game development is different nowadays. To stand out, you need to know about game design, concept art, color theory, texturing, tile-mapping, lighting, shaders, interface design, sound design, sprite animations or skeletal animations, networking... The list goes on and on. And then your game also needs to be fun!

If you go the route of implementing or integrating everything yourself, you will never reach the level of someone who knows an existing engine in-and-out. Today, if you want to create games, it's far more important to create as many games in a short time as possible. Just look at competitions like Ludum Dare to realize and appreciate how far even small game engines can help you to create a fully fledged game within 48 or 72 hours. It's crazy. This will improve your skills as a game designer far more than building your own engine.


> Buuuuuut.... the early stages of starting game development these days are, "What engine do you use?"

As someone who started from raw OpenGL and cobbling together various libraries (OpenAL, OpenIL, etc.), I think it's bad for pedagogy, but I love it for productivity. Just like React.js.

I think there's a huge advantage to not having to spend time writing code to glue together asset management to physics to animation to graphics to audio to AI and UI, etc., and also because scene graphs and entity/component systems are like game programming's equivalent to REST and MVC.

So once you know how to work with that stuff, jumping into an engine is a great way to get right to prototyping and skip all of the setup. But for building up the conceptual understanding... it's rough. It's just a totally alien way to think about programming if your background is classic frontend/backend.

> And honestly it can be a daunting choice. They're all quite large and have their own jargon and way of doing things. I can get through a "Hello, world!" tutorial in an afternoon but it'll take months before I get something useful to work and load my brain with all of the jargon to navigate the documentation and forums...

That's absolutely a problem, and I totally agree that it's exacerbated by starting from Unity as opposed to learning the component concepts individually. But that said, Unity genuinely saves me a ton of time, even if the result isn't as optimized. That goes double for VR, where the sheer conceptual load of designing/coding the interaction models makes doing it without an engine not really worth it.

> versus writing everything from scratch. It's a slower start but I have already learned a good programming language and can go from there. I don't end up with a black box of performance problems. Nor do I end up trying to shoe-horn my round game into a square peg. It's quite common going down this route to write your own data formats and tools as well: level editors, compilers, debuggers. And the productivity starts going up fast as you build momentum.

I think this is a difference of what you're trying to accomplish. An engine gets you off the ground much faster if you have trained on it because enough of the abstractions are common to most games that, for example, reusing a not 100% ideal graphics/physics/skeletal animation rigging/key framing/audio/collision detection system still saves you a lot of programming.


I'm intellectually interested in writing my own simplest-possible versions of game engines, but I have no idea where to get started. Do you have any tips or a book recommendation? How did you learn?


It's hard for me to recall how I learned because my first "game" I wrote was in '89 and I wasn't very old at the time.

Maybe check out https://www.youtube.com/watch?v=Ee3EtYb8d1o -- I've watched a fair bit of it and many folks agree it's thorough and interesting. If you don't know C already he has a decent introduction as well.

Maybe not the best place to learn C but it suits well enough for game development projects.

The nice thing I find with C is that bringing life back to older machines is definitely possible -- the homebrew scene for various old consoles is very much alive and well and there's probably a C compiler that targets it.


Thanks!


Game Programming Patterns from Robert Nystrom covered a lot of ground for me.


Thank you!


This is a really bad analogy though.

A spice rack has to do two things

1) hold spices

2) Not fall apart

3) optional : try not to look terrible

If I went through and tried to document every different concern my rails app handles, I 'd probably just give up after a few days of research and a list of thousands upon thousands of concerns.

Spice racks don't need to change and evolve over time, a third party can't remotely ruin your life if your spice rack has a design flaw, your spice rack can't make you millions of dollars.

So I get that this guy wants to go write tcp/ip stacks from scratch to build his neopets page or whatever but it's the wrong design decision for a vast, overwhelming porportion of projects.


I shall disagree on a few points of yours:

"Spice racks don't need to change and evolve over time" => why not hold some other stuff? maybe add something to hold fruits later?

"a third party can't remotely ruin your life if your spice rack has a design flaw" => have you protected your spice rack against children playing with it?

"your spice rack can't make you millions of dollars" => depends on you, not on the rack itself

"but it's the wrong design decision for a vast, overwhelming proportion of projects" => really depends on the person doing the code and who will do the future maintenance; updating a framework that evolves fast can sometimes be as hard or harder than maintaining your own code, it's mostly a choice of the developer/development team to make on how they see things going from now


> why not hold some other stuff? maybe add something to hold fruits later?

What?? No. I have a fruit bowl and a fridge drawer to hold fruit. Why would I want to glue them together? So I can use precious refrigerator space to hold my cayenne powder? Maybe I can add a cell phone to my vacuum cleaner next, attach a paintbrush to my broom, or combine a lawn mower with a trowel.

These things do not belong together. I appreciate the vendor would like more of our kitchen storage spending, but that’s his problem, not his customers’.


These are all devils advocate answers. None of these are things I would spend a lot of time pondering if I was building a spice rack with the exception of #2 if I had kids which is solved with a single extra screw or a single piece of 3m style adhesive strip

How many people spend their free time modifying their spice racks. I'm sure you can find some webpage of someone who has this as a hobby but let's go with less than .01%


If you apply that analogy backwards, I think it makes an interesting point.


> Spice racks don't need to change and evolve over time

Your cooking may change to require more spices than it did before, exceeding the functional capacity of the rack. Change in circumstance may mean you now need a mechanism (e.g. door) to block direct sunlight from hitting the jars. Spice theft may become an issue, requiring heightened security. Or your preferred spice brand might make a seemingly minor change to the shape of their jars which cause them to no longer fit in your rack.


Again all devils advocate kind of stuff. No one who is not an industrial engineer spends time actually doing any of this stuff and the analogy is about making your own.

You could think about these things. But no one does. Necause I can buy a spice rack for $20 at target and then throw it out and buy a bigger one for $30 if that one is insufficient.

So sorry, consider me 100% unpersuaded.


Excellent case of analogy abuse


I don't see this as an argument against framework, I see it as an argument against continued abstraction. Developers seem to be obsessed with solving the N+1 order of abstraction than requested of them. "Why solve the specific case, when I can solve the general?" If you continually ask yourself this question, that is how you end up with an Abstract Abstract Tool Factory Factory. Solving multiple specific cases is hard, so sometimes it's easier to solve the general, and push the specific problems to the consumer. Except of you do this continuously then you have pushed the entire problem to the consumer. Plus you push the additional configuration problem since these solutions rightful attempt to expose declarative configuration.


I have a funny anecdote from my experience.

We sit in a meeting and discuss some feature, there are two new devs in the room, I am dev as well but I worked with those business people for quite some time.

Business people start talking about "generic solution" and I already hear devs asking questions/talking like they are preparing to build "reusable and flexible framework for all your needs".

Where "generic solution" for business was maybe 2 or 3 types of texts with possibility to add maybe 1 at some point. But that was nowhere near what devs were imagining especially when "generic types" has specific meaning for programming languages.


Translating from business terminology to developer terminology is always fun, especially when they use the exact same words.

One of the first times I encountered it at the early web, when a customer wants you to 'connect' two systems, before you start analysing the data models, first check if maybe all he wanted was a hyperlink.


Yeah, developers tend to take the most of a meaning.


I couldn't agree more. Highly configurable frameworks are essentially just home grown programming languages, in which your code just happens to live in a configuration file.


Frameworks are a whole discussion about the topic of complexity, switching cost, sunk cost, incentives, personal preference, market position and job security.

I built enterprise B2B applications for several years, saw a lot of frameworks come and go. Worked on technical evangelism for many developer products, hardware + software.

Job Security: - The internal framework architect / maintainer is unfireable - Building a framework is high prestige, worth potentially millions (contracts, books, consulting) if it catches on (see: Ruby on Rails) - Successful frameworks spawn massive industries (React training, anyone?)

There are tremendous market incentives to try to build and market a framework. Even if you fail, you learn a lot by trying. For the most part; the act of Building a framework is nearly always a good idea for career purposes. This is part of why there are so many of them. And it’s fun.

Programmer Preference: - I have rarely seen two programmers agree, or be happy about the most basic decisions in same code base: capitalization etc. - Programmers are highly particular, the odds two programmers will love each others code is close to zero

Thus: A framework represents one programmers attempt to fully encapsulate their entire vision of “how it ought to be done.” This vision is often non-transferable.

Complexity: A program of any size involves thousands of decisions that form an interlinking network. Largest application I have written was 100,000 lines of C. Relied on many external libraries, user experience and design decisions.

Altering a framework by swapping out a single component can have cascading effects throughout entire system and to the user of the framework. Who is going to train everyone to go from Objective-C to Swift, for example?

This makes frameworks highly brittle. Which leads to topic of sunk cost / switching cost.

Switching cost: Once a framework changes or a new framework arrives, programmers must make an economic decision. Switch to new framework (lose time and money) or keep going switching is painful.

Meanwhile, new crop of learners focusing on new framework get ahead learning that. Too bad for you: Your experience in Spring doesn’t translate to new framework XXX.

Anyways:

I can talk about the sources of the problems, but it is unlikely to ever get solved by humans writing code. Programming is just a complex field.


> This makes frameworks highly brittle

Inevitably, popular frameworks address this by making themselves so configurable that you can use them however you want... defeating the purpose of using a framework in the first place.


I was just thinking on this same analogy this morning.

What many people don't realize is that there are, off the top of my head, at least a dozen different distinct types of hammers, and then if you're talking working with metals at least a dozen or two more. There are way more types of nails, and then of course you have nail guns, of which there are multiple types, and of course screws. In philips heads alone, you have at least eight different sizes, and then of course flat head, torx (many types), allen (many sizes), square, hex, etc. For drivers you have a basic driver, a driver with swappable bits, a drill (cordless, corded (12v, 14v, etc)), a ratcheting driver (and hex bolts), an air driver, a butter knife, etc.

In many cases, there is clearly a "best" choice. If you're putting a treated deck on with nails, you're going to have a bad time. If you're framing with finishing nails, everyone is going to have a bad time.

But if you're building a shed, what do you go with? First and foremost, you make sure the fastener you're going to be working with is going to work, and then you choose the one you've worked with in the past, the one you have experience with, and the one you have on hand.

Software developers tend to be young. They tend not to have respect for what has come before them. They tend to be really, really fucking bored, nearly all the time.

They don't create new fasteners every two months, and switch hammers twice as often because it's prudent, more efficient, or necessary. More often than anything else, it's because they're way smarter than their job demands and they have nothing better to do.

There are ways to solve this. There are other professions that solve this. Prescribing statins all day and telling people to lose weight doesn't take a 135 IQ, and yet somehow doctors manage.

Programmers need to interact in a more masterful way with their tools.


The problem with the long analogy is that it's serial, not random access. You have to read the entire thing to understand the writer's message.

But I think it can be summarized as follows:

> “And this is the way everyone is doing it now? Everyone is using a general-purpose tool-building factory factory factory now, whenever they need a hammer?”

There's something very strange about writing web applications. You can start off just writing without much regard to architecture. But by the time you've implemented a dozen or so endpoints, you realize that tight coupling and code duplication are going to ruin you.

What can you do about it?. Frameworks promise a solution. But you can still end up with lots of duplication and coupling. "Controllers" can be code duplication repositories, especially in "restful" applications. Then there's the fact that you're chained to the framework from the moment you start using it until you quit or the application dies. That hard dependency can make adding certain kinds of features very challenging. And maintenance becomes yet another problem, especially if the framework falls out of favor, which it probably will.


It’s true that frameworks e.g. Django, Ember, and Phoenix may limit flexibility and scalability in the long-term, but forgoing a framework up-front is, like microservices, a premature optimization; you might become successful enough to need to break things apart, but if you do that too early, it might limit your ability to become successful in the first place.

Put 10 React developers in a room, and you will hear ~10 opinions on how to handle routing, state management, tooling, testing, file structure, etc. Startups don’t always have time for that nonsense.

True, you may need to work harder to find decent Ember devs vs. decent React devs (and pay the Ember devs higher salaries when you do find them). But they are more likely to skip the bike-shedding, hit the ground running, be productive much earlier, and sustain higher output than their React counterparts.


https://docs.spring.io/spring-framework/docs/2.5.x/javadoc-a... - Convenient proxy factory bean superclass for proxy factory beans that create only singletons.

Somehow, only Java seems to suffer from this.


Learn Clojure. Then you can spend the rest of your life building with hand tools, lol: https://www.youtube.com/watch?v=ShEez0JkOFw

(Seriously, though, Clojure is awesome—but occasionally I miss the guardrails of a framework.)


This article is bullshit. And 16 years old.

No one is taking away your hammers. You are free to code native JS.

If you want to reinvent the wheel every time you start a project, go nuts. I want to buy pre-made wheels. They don't have to be a certain color with a special font, just round, rubber and reliable.

The problem is today there are wheels and wheel factoriess and types of machines that use wheels, and their support levels vary wildly. Some wheels only go on square axles, some factories made great wheels and then closed up without warning, others only go on boats.

E.g., VueJS is awesome and heavily supported today. But lots of the tooling around VueJS doesn't keep up with the changes (cough webpack/fusebox cough), so huge ecosystems built without forward support (or a deeper evaluation of their tool) decay rapidly. When I see a package.json boilerplate on GitHub from a year ago with 15 different tools, I know 50-70% of them are going to have problems.

You should do a lot of research before bringing in a framework, and understanding the tooling required to make it usable.

No one is taking away your hammers, but don't expect the latest stupid multi-gadget you bought on QVC at 3am and built an entire ecosystem on to exist forever.


This article was written at the peak of Enterprise Java, and it did have a negative effect on the industry. Tons of boilerplate and fragile XML.

"Framework" meant something else then. It more was like a kitchen sink of design patterns and maybe some persistence.


Ahhhh, good point. Every time I hear framework I immediately think "node/web". My prejudice / conditioning.


"You are free to code native JS". this really does seem like a simple/obvious statement, but I've been in the position where I've taught JS to beginners and holy crap...the amount of people that think they need to know React to do something as simple as a counter is absolutely insane. I think that the space of intro to web dev has been polluted by people pushing frameworks/libraries onto people when really just simple dom manipulation would do the trick.

I think the issue the article was getting at is that the idea of the hammer is considered "obsolete"/useless by the experts in the field, leading those experts to push tool making factories onto beginners who really don't need it for their purpose (but don't know the wiser since they're new to woodworking after all).

...or maybe i'm reading too much into it.


On the other hand, but not aimed at you, I've noticed a common theme with people who rail against frameworks and ORMs.. They act like everyone who likes them don't understand the low level or SQL :D Thay may be true for some, but all of the best people I know also embrace those niceties and know where the escape hatches are...

"We don't use frameworks" <- Big red fracking flag.


I misunderstood the context. OP was referring to the state of Java in 2005 and I thought the reference was to JavaScript. Whole different world, but I can't delete/edit my post now.


certain company has spent considerable resources continuously promoting that framework. At times I seriously think it has a real chance of evolving into a full blown religion.

I am only semi joking


Original: https://web.archive.org/web/20180927070411/http://discuss.jo... (also has the second part which is missing on the link above).


> “Well, the problem with hammers is that there are so many different kinds. Sledge hammers, claw hammers, ball-peen hammers. What if you bought one kind of hammer and then realized that you needed a different kind of hammer later? You’d have to buy a separate hammer for your next task. As it turns out, most people really want a single hammer that can handle all of the different kinds of hammering tasks you might encounter in your life.”

This reminded of a recent episode where I had to replace my rear bike tire. I already have a toolset for basic maintenance: a full set of hex keys, flat and philips screwdrivers, track pump, 14/15" wrench, as well as lubricants and cleaning sprays. Served me well so far so I thought all I had to do was buy inner tubes and the tire.

Wrong. To begin with, the wrench I had was too short to remove the wheel nut; I had to buy a longer one for better leverage. Then, when removing the old tire, I needed tire levers to get them off. Maybe a better mechanic than me could've McGyvered the operation without tire levers but it blows my mind that I needed such a specialized tool. You will notice all the tools I've had so far were multipurpose, exactly why I bought them. Even the pump can inflate footballs. The name "tire levers" captures their singular purpose perfectly.

Anyway, after I accomplished the task, I was quite pleased with myself. I even finally bought a proper toolbox. In my mind I was considering DIYing further upgrades to my bike. What about a new chain? Or why not a new gearset?

Nope, turns out I still don't have enough tools to even accomplish this. If you want to unlink your chain, there is a special tool for that too. To remove your cassette you need to keep the gears from spinning with a "sprocket lock tool"[1]. In fairness other tools like the torque wrench and the lockring, aren't so single-purpose but I'm unlikely to use them for something else other than my bike.

Lesson of the story: In real life, there are a lot of specialized tools. You can buy a Swiss Army knife but there's a reason why it's not yet the DIY-er's best friend. I agree with the sentiment of the article but I'm even more glad that I'm a software engineer, not a mechanical engineer.

[1] I don't know the exact name for the tool but you can see it 23s in https://www.youtube.com/watch?v=9KAaP7pbFV0


You can use a butter knife as a tire lever in a pinch, or the handle side of other flatware. Chain tools are a necessity, since manufacturers would have to either offer chains for every different number of links someone would feasibly have to install on a bike, or weaken the chain or make it wider to be accessible with "standard" hand tools. A thinner chain is a necessity to have more gears without obnoxious wheel spacing and derailer travel.

The tool you pointed at at is a chain whip. You used to not need a chain whip to replace sprocket clusters, but the old way of removing a freewheel still needed the proper shim to lock the freewheel mechanism, which was built into the sprocket. Now the freewheeling mechanism is built into the hub, which means the sprocket cluster has to remain put so you can unlock the lockring (instead of spinning the wheel). You /could/ do it by just holding the cassette with your hand, but I don't recommend it :)

Although bike tech is in many ways suffering from the same march of "more tech, sleeker package" that makes parts smaller, weaker, and with shorter service lifetimes in other industries, most the specialized tools needed to work on bikes haven't changed in some decades.


> To begin with, the wrench I had was too short to remove the wheel nut; I had to buy a longer one for better leverage.

When I was young, we used to slip a piece of pipe over the handle.


Those specialized tools can be seen as the bad side effect of mass manufacturing and market streamlining. They're extremely wasteful when you have 2000 people buying one to service a piece of their bike. They don't look so wasteful when you have one shop buying one to service 2000 bikes a month with it, or one factory getting a bunch to assemble 2000 bikes a day. It's the latter two use cases that shape how products look and work.


Chain whip!


The hammer analogy seems overdone. The framework , lets say , caters to 60% of your needs (being cautious here). OTOH, If your needs are pretty specific, and you go minimalistic, then you build 60% of your functionality by hand. Yes, code bloat can cause issues, with unused features. I'd rather not spend time building mundane features, and especially in Java.

Now if the language you code in, suffers from a lack of good frameworks, but that's a different issue.

I wouldn't comment too much on Java, due to an intrinsic dislike for the J2EE environment (and all its baggages - maybe baggage that I have mentally). But in Python I've not found a distasteful framework. There's no single framework that can be like a Swiss army knife, though framework fanatics, by definition will sell that vision.


The factory-factory-factory thing is quite an old joke. There was one version about creating a double in Java: AbstractFactoryFactory->createAbstractFactory()->createFactory(Double)->createDouble(1.0)->getValue().

Or something like that.


Frameworks that work — or at least seem to (imo):

• Tokio, Glommio (Rust)

• Seastar (C++)

• React, Node, Angular, etc. (all JS)

• Django, AIOHTTP (Python)

Each of which seems to be its own "hammer" for various problems. Yet each is also a kind of "factory" to make specialized "hammers," if you will.

ex: Seastar is a shared-nothing, highly distributed, highly async framework upon which folks have built a database (Scylla — disclosure, my employer), but also a streaming data platform (Redpanda), and a storage platform (Ceph's replacement, Crimson).

So maybe the one option the author left out is "a factory-building hammer."


As someone who built a forge and a good deal of blacksmithing equipment in order to make tools for woodworking... This analogy is supposed to make the situation sound ridiculous, but it really isn't. If customizable physical tools were able to be created and destroyed as cheaply as objects on the heap, every carpenterwould want a tool factory factory factory. There's so many jobs where a custom tool is really useful.


Around 2015 I worked on a Liferay Portal project and worked with a designer to make portlets that consumed and displayed data from various API's. It was actually not bad and I didn't have to spend a ton of time onboarding. I was able to become productive quickly.

It's decidedly unsexy to have to put "JSR-168" on your resume but it felt fun at the time because of the velocity I was able to achieve.


Frameworks are the "No-Code"-solutions of programmers. Like these they work well for the intended purpose and become a horrible pain, if you try to venture of the beaten path.

To expand them, to cover the whole solution space, destroys the framework, due to bloat and the huge code necessary to solve "all problems and have all the answers."


You can tell it was written in 2005 because there's no mention of General Purpose Tool Building Factory As A Service.


I feel like coding in general has broken down. I used to do a lot of coding until about 5 years ago. Back then Google still worked, stack overflow still worked - at least in my memory.

Now I'm coming back to coding and I'm having trouble reading a MP4 video and showing one frame as an image using python. I've never done it, but it's a simple task. Except Google keeps sending me to the wrong libraries (the ones that don't work or are badly documented), and I end up hitting bugs and error messages that seem impossible to google either.

Without a working search engine, and with the proliferation of a huge number of weakly documented or poorly working libraries, coding new things by yourself is really not fun anymore.

(Or maybe I'm getting old and just don't have the patience to spend any amount of time on seemingly trivial tasks and boilerplate?)


Video is just complicated. The libraries have to be native, because of performance (even if you don't need the performance, the kind of person who writes a video decoder from scratch will), so they have to be built as a c extension. Which means you need a c build environment, and all the complexities of setting that up. And then the api will be "bent" around high performance patterns, which might not be obvious if you're new to that field. I remember when I first did some graphics programming I couldn't understand why people were using char* all over the place instead of a 2d array class which contained instances of a Color class with all sorts of fancy getters and setters. After a few years working with graphics code that question just doesn't seem reasonable anymore, my frame of reference has changed. If I were to write docs about a new library I made, it would be hard for me to write for a new person, even if I was a good writer, and genuinely tried. Many makers of open source libraries are not, and do not try (and noone's paying them to, so why should they, if they don't want to).

So yeah, basically, I think it is just a hard problem in easy problem's clothing.



Article author is not a wood worker -- generally you would not use hammers and nails for small projects like that. Glue would be a much better choice. You would use nails for homes (framing) though.


> Article author is not a wood worker -- generally you would not use hammers and nails for small projects like that. Glue would be a much better choice.

In my day, we usually used both. In retrospect, the nails were probably mostly for holding it together tightly while the glue dried, but we left them in.


I spent the last year "writing" web backends in Java using Spring Boot.

Wasted days trying to figure out the latest magic spell to do the most trivial things.

This is the kind of code that will be automatically generated any day now.


Any examples of trivial things you've struggled with?

My Spring Boot experience is the opposite and it is usually my go-to framework when I need to get a backend up and running fast. It takes 30-50 lines of Kotlin to serve some JSON endpoints backed by a SQL database. And those lines are mostly defining the shape of the JSON response, database model, and hooking up the request route to the controller and repository. All the rest is generated, inferred or in libraries.


Everything?

It's all very opaque and specific to Spring; and it keeps changing every few months, which means that a lot of information online is not applicable.

I strongly prefer writing my own scaffolding and pulling in specialized libraries for specific tasks.


Same. I've tried other frameworks like Django and even Express, but I still go back to Kotlin + Spring when I need a quick backend for a personal project.


Every time I look at modern source code, with hundreds of lines of classes, constructors, setters and getters that could be done with a record type or two, and far, far less code, I have this same feeling.


Context is everything.

Writing an app that going to do like 3 things? Keep it barebones.

Writing an app that will eventually be 100k lines of code that runs a business. Spend a lot of time organizing and abstracting! Mistakes in your architecture will be expensive to correct but balance avoiding those with premature optimization.

And beyond just the purpose of the app, remember who is going to build and maintain it. A project with 100 engineers and a project with 1 engineer should use very different architectures and project management regardless of the problem they are solving.


Nah, all this is just rationalisation. I've already heard this a hundred times and seen it go awry every time afterwards.

Complex architectures and unnecessary abstraction are the main reason lots of apps "eventually" get to have the 100k lines of code you mention and require those 100 engineers to maintain in the first place.

It's a self-fulfilling prophecy: When you follow the complex architectures where you need "hundreds of lines of classes, constructors, setters and getters that could be done with a record type or two" that GP mentioned, it's no wonder that the software reaches 100k LOC. Could have been 10k or 20k if the grandparent did it. When there are too many levels of abstraction to navigate, it's no wonder you need 100 engineers to maintain. Could have been 5 or 10.

There is nothing preventing those complex apps from using something that's more expressive and simpler like the records pointed by GP. And there is absolutely nothing in the popular complex architectures we see everyday that is proven to be inherently scalable.

As long as the original goals are maintained, you'll still reap the benefits: testability, composability, predictability, maintainability. And you don't need complexity to reach those goals. In fact, complexity is what people should be running away from to get to them.

If you want to burn both money and time for no future benefit other than having a behemoth of a project, however, that's your prerogative.

The only major issue with "simpler code" as advocated by GP is that it's not sexy. You can't put "wrote simple code" in your resumé.


I was waiting for the inevitable "we now sell monthly subscriptions to spice racks, hammers, factories, factory factories..." but I guess 2005 was a bit before the time for that complaint.


This almost sounds like an argument against AWS, not just frameworks.


AWS is closer to a day-laborer you hire to help you build a doghouse for your son. However, when your doghouse business explodes, your day-laborer is no longer able to keep up with your business needs and you run into absurd, yet very real problems.

Edit: with your son lol - good catch


I sincerely hope you're not putting your son in a doghouse lol


Unless your son is a dog. Some of us, due to life constraints, can only have fur babies.


Some of us, due to personal preferences, wouldn't actually consider that a son.


Usually the moment you have an actual son and realize is several orders of magnitude more love, commitment, work, sacrifice, and money.


(Sadly, we were forced into building a dog house as a pre-requisite for the spice rack project detailed in the original article. We needed something to guard the factory factory factory.)


I used the spice rack hammer for the dog house because I don't really know how to make other hammer factories and the one from the tutorial (that I cant seem to find how) only makes spice rack hammers.


Tangental, but one of the most useful tools I have my garage is a rubber mallet of all things. I would have never thought a rubber mallet would have so many random, odd-job, uses (e.g. when you need to apply pressure but without breaking force). Makes me wonder what are some software equivalents of "rubber mallet", tools you wouldn't think of but end up using quite frequently and, when you do, its perfect for the job in an incredibly specific way.


The closest analogy I can think of are just basic data structures. Dictionaries, lists, tuples, sets etc.


I wonder if it's also a rant against "old frameworks". When a framework is young, everything is easy and optimized for newcommers. When it starts getting old, everything becomes optimized for framework users that already know that framework. At first everyone used $framework because they needed a hammer. Then their requirements changed, so the framework changed, in response to the initial users. And then it changed again, and again, and again.


Most people do not hate frameworks. They either use an existing framework, or they eventually end up creating a custom framework which only they understand and which gets thrown out and replaced with a common framework when they leave the company.

Unless one's need is trivial or very specific to a narrow scenario, frameworks are helpful. At the least, they give new devs a common understanding to begin from when they join or take over an existing project.


I don't know if I would say that I hate frameworks, but in general, I find most of them to be pointless. I use them because my teammates insist on them, but I spend far more time working around them than I spend taking advantage of their strengths - if there even are any.

I've been working with Java for 20 years now, and Spring is the ultimate "framework" - it's so framework-y that it doesn't actually do anything or offer anything, it's just a thing that gets in your way. When people defend Spring, they invariably say "but why would you want to do all of that by yourself" and I say "do all of what by myself?" The Spring framework saves you the trouble of... calling the "new" operator (by making everything a global variable)? At least with an ORM framework I can see what it actually does, even if I don't really want it to do that, but Spring just doesn't do anything except add libraries you don't need and make your stack traces useless.

Ok, I take it back, I don't hate frameworks, I hate Spring.


Yea, whenever a new abstraction makes the ”you won’t have to do all these things yourself” promise, I guarantee that the abstraction just replaces those things with another, potentially bigger set of things you’re going to now have to do.


Can someone explain why Spring, or J2EE in general, is a necessity for its target audience, and for that matter, what its target audience is? I've only worked on Spring applications when I had to, so forgive my ignorance, but every time I've worked on a Spring application, I never found a good reason why Spring was necessary.

I always thought that Spring was meant for maintaining large codebases with many interconnected parts that you might want to swap out at a given notice. We can talk about whether or not Spring is a good fit for that scenario, but I at least understand why you would use it. But the applications I've worked on that used Spring were offline, single-purpose, non-changing, and (relatively) small. I would then ask why we're using Spring for this, and I basically get the same responses as the parent post with a facial expression that's pondering if I'm high.

Am I missing something?


So if you go back to the early days of J2EE, you'll notice that it was very EJB-centric - for the most part, J2EE containers were EJB containers with some extra stuff to support EJB. EJB, for the most part, was pre-ORM ORM back when object-relational mapping was a relatively new concept. There was more to it than that, of course, but using Entity EJBs for object-relational mapping was the core of what J2EE was all about.

The problem was, it was a massive unusable beast of a mess. Rod Johnson came along, found some ways to simplify the concept into a "lightweight" container and called it "Spring" as an alternative to the heavyweight EJB containers of the late 90's.

The thing that everybody seems to be missing is that the only reason you needed the container in the first place was to support the Entity EJB's that were more trouble than they were worth. Standalone ORM tools like Hibernate solve the actual entity-relational mapping problem far less intrusively than J2EE or Spring ever did (Hibernate is still more trouble than it's worth but at least you can understand why it's there).

Spring doesn't actually do anything except make other things available in Spring, and it actually damages your codebase by forcing you to make most of your variables effectively global (which Spring calls singleton beans).


You don't need Spring to maintain large codebases with many interconnected parts that you might want to swap out at a given notice. You can just create ('wire up') your objects in your `main` method.


I hated React when I had to jimmy it into a Drupal website, I loved it when I was doing React + Redux on a data-driven project.

Pre-shopify, I loved Magento when we were just building basic eCommerce websites. I hated it when we had to provide bespoke functionality to suite various niche business purposes because rarely did any of the community plugins work well together, and life became a routine of building custom intermediary plugins that resolved the conflicts - but at least Magento had a way to resolve conflicts between plugins.

I loved Doctrine when I could define my object model with simple block comments. I hated it when the client's business model enforced an object model incompatible with Doctrine's, and we had to extend Doctrine to allow for it.

I tried making a game from scratch many times over the years. From writing my own assembly pixel routines (draw a line without gaps... that's a fun challenge), to decoupling logic from rendering, custom double-buffering, etc. At the end of the day, fuck it, Unity does everything I need much more efficiently than I have the time to figure out.

Unless you're doing really low-level embedded (and even these day's there's off the shelf hardware with frameworks rather than bit-bashing IO ports), having no framework at all is usually worse than having "a" framework. Want to build an entire game engine from scratch or why not just use Unity? If you have a good reason and can justify the cost of doing the stuff Unity does yourself, just to achieve the stuff Unity can't do, then go for it!

Like I guess, I don't hate frameworks, but I don't LOVE them either. Pick the tool for the job. I hate jingoism, where someone will tell you Redux is the only way we're going from now on because functional reactive programming is Jesus, or we've decided from now on the project will use webpack, even though it's been working fine for a decade using a different build strategy. Oh and we need to convert the APIs to GraphQL instead of OpenAPI on no budget, it's your fault for not understanding best practices duh...


I had that "I hate Spring" moment a few years ago as well.

Another part of the problem is that at some point you are programming in Spring more than Java. I've even interviewed candidates who struggled to tell the two apart.

The question becomes "would I rather program in Java or Spring?" and, generally, for all its other shortcomings, I'd prefer to program in Java over Spring.


We have a custom framework at work, with a really large codebase, and I find it was easier to understand than any open-source framework I've worked before, because everything is well-encapsulated and changes have very local consequences. That wasn't my experience with most open-source web frameworks, that often seem optimized for conciseness and people that already know them.

I also reject the idea of "They either use an existing framework, or they eventually end up creating a custom framework which only they understand and which gets thrown out and replaced with a common framework when they leave the company". The popular open-source frameworks were created by people like you and me. Those people were good, for sure, but not perfect, just like us. They also often try to make something very generic that may not fit your specific use case. Trying to bend a framework to do something it's not meant to isn't better than writing your own code.

I think that these days we have too much worship of open source code. Sure, not having to write code is sometimes very nice, but sometimes a few lines of code can help you avoid a dependency.


Isn’t your custom framework exactly what I said? Use an existing one , or write one that only you (and your team) know.

Of course, the bigger your codebase and the more unique your needs, the more reasonable it becomes to create your own.


> Isn’t your custom framework exactly what I said?

No, it's not.

> Use an existing one , or write one that only you (and your team) know.

Not only my team, pretty much any people working with it in the company. The difference with something like Django is that people don't know it before coming in the company, which doesn't make a big difference.

To go back to the message I replied to, you said

> "They either use an existing framework, or they eventually end up creating a custom framework which only they understand and which gets thrown out and replaced with a common framework when they leave the company."

I disagree. There's no reason to replace our custom framework, as it's working well and since the codebase is getting a bit old, this would be just too much. We also have good training material around it, better than what you can usually find about open source framework online, without even mentionning mentoring. Then there's

> "At the least, they give new devs a common understanding to begin from when they join or take over an existing project."

The flip side of that is that you need to recruit developers that know a framework, which will by definition limit your talent pool.


If I am working in a team, I prefer frameworks because it provides a set of idioms and documentation out of the box. That's great for making sure we are doing things consistently across the team and making sure it's harder for new devs to get stuck spinning their wheels. It can make hiring easier too, but I would still hire a good dev without specific framework experience.

Solo projects it really depends on the size I expect it to get.


I like the frameworks you can have around for a lifetime and never change.

I really appreciate JQuery (ok it’s a library) and ASP.NET MVC which is about 13 years old I think (vintage these days!).

To me the problem is a framework is like 200 hours to even get efficient in and if you already know X a there are not much returns in Y in general.


I like to use training wheels as an analogy. They are great if you want to get started right away and be productive. The alternative is to fall a few times and learn the hard way. The only problem is that when you learn how to ride you can't just take off the training wheels, they will slow you down.


i saw the title and thought "java", then loaded the story and in the first paragraph found a java apology. my suspicions immediately confirmed.

lots of really sharp people work in java, what is it about java that encourages this? is it the aggressive object orientedness of the language? or is it maybe the really strong ides/tooling that people use that encourage creation of lots of classes so that nice little tree view on the left gets populated with things that look like they should go there? or is it the design of the core libraries and j2ee that nudge people in that direction?

why does the java universe have more frameworks than programs and why do they all seem to want to pack your brain with so many useless abstractions that your skull wants to split open?


In a time before Rails and Django and way before Nodejs there were not that many programming languages available to do big backend or web projects. Java and C++ were the obvious choices as those languages were available, being thought in schools and used in the industry.

Both languages lean heavily on Object Oriented principles. It was around then that books like Refactoring, Clean Code and Gang of Four design patterns were popular. Maybe the Domain Driven Design book as well. Dependency Injection.

JSON wasn't big yet, XML everywhere, SOAP and Corba for RPC. Applications weren't run standalone like they are now, instead they were served by application servers like Glassfish and Tomcat.

Java jumped on that enterprise bandwagon. J2EE standardized a lot of things like those application servers and introduced concepts like Enterprise Java Beans. Frameworks like Spring and Apache Struts became popular as they handled all the common stuff.

It was also around the same time that Extreme Programming, Pair Programming, Test Driven Development, Agile and Scrum were massively adopted in software projects.

The whole Java enterprise framework thing was a child of its time.

Then later frameworks like Ruby on Rails and Django entered the scene. Leaving a lot of the "legacy" stuff behind and improving on the annoyances of J2EE. The Java frameworks adapted and started modernizing. Configuration and DI moved from XML to annotations, SOAP was replaced by REST and JSON, instead of hosting applications on application servers, the application servers moved in-process as libraries.

Of course Java being Java with its focus on backwards compatibility, all those new features and improvements were added alongside the old stuff. Adding to the bloat of the frameworks with abstractions on top of both old and new methods under a common interface.

Meanwhile new frameworks and languages popped up. From scratch frameworks that learned from the old ways and left all the legacy behind, only supporting modern features.

Java and Spring might not be the most popular choice in 2021 but I am convinced most of it was all necessary evolution to get where we are now.

All that being said. I have since moved on from Java to Kotlin but modern Spring (Boot) is still my go-to solution when I need to write a backend application, and I suspect it will stay that way for a long time.


> In a time before Rails and Django and way before Nodejs there were not that many programming languages available to do big backend or web projects. Java and C++ were the obvious choices as those languages were available, being thought in schools and used in the industry.

you forgot perl, where perl plus a handful of database and session management cpan modules were kind of the ruby on rails of the era. (with mod_perl on apache as the application server, of course) perl was huge in infrastructure, but also powered quite a few massive web properties. the tradeoff arguments were interesting... while static analysis was weak, developer productivity seemed to massively overshoot what you'd see in java teams. although long term scaling and maintainability probably did suffer.

> It was also around the same time that Extreme Programming, Pair Programming, Test Driven Development, Agile and Scrum were massively adopted in software projects.

i remember being doing a training and the instructor preached all these gospels. i asked them why they weren't used in open source so much and they replied that open source software was okay, but that all the best software was constructed with these fancy philosophies and was hidden inside of companies. that was when i stopped paying attention to this person.


Obviously the more people using a language, the more 3rd party libraries/frameworks proliferate, of course, and Java is very popular.

But: Technologies are separate from their cultures. You might think the tech enforces its own culture, but that's a half-truth at best.

Most language designers are pragmatists at heart, and inasmuch as they remain leaders, that sense of pragmatism is cultivated within the community around their language. For example, Python's creator - Guido VR - remains a very emphatic leadership figure within the culture, so that it's a culture big on pragmatism, not just because of Python the technology, but because of Guido's leadership. Also ref. Rob Pike, or in a different technical sphere, Linus.

With Java, James Gosling started receding into the background when "Enterprise Java Beans" came out, because he knew that was garbage tech and he was being shushed by the corporate honchos, so a leadership vacuum appeared in his absence. Any and all asshats proclaimed themselves the experts on what programmers really need and started pushing a lot of junk frameworks that the community happily adopted, being readily impressed by the self-confident asshats, and really, just about anything compared well to EJB.

So nowadays many folks would find it hard to believe that the creator of Java was a pragmatist at heart, but yeah, he was; he just didn't stick around as a leader.


Article is from 2005. Java has lost mindshare since then.


Use the Spring Framework. Within the context of your analogy, I'd not call it a "Universal Hammer," but rather a tool box that contains multiple hammers. For any construction job I've encountered, there's a tool in that toolbox that will handle it.


Can someone explain this for someone who is not a web developer (which I'm guessing this is aimed at)? So there are frameworks out there that... generate frameworks that generate frameworks that generate websites? That seems excessive, even by web standards.


>When we really looked at the situation, we determined that that’s just too complex for someone who really just wants to build a spice rack.”

hmm, I think the secret of this text is actually the hardware salesman has ESP and is messing with Fredrik Holmqvist.


Well at least one can talk together about stuff and then see if the other suffered and dislikes certain parts or maybe finds it great and exactly why. Then you know quite fast how many experience he/she has in the field.


This guy's argument (in a nutshell, heh): I want to build a spice rack, do you have any oak tree seeds?

I do have to say, though, a lot of things I wrote ~17years ago probably haven't aged well either so...


The best frameworks work well for the tasks they solve and don't make the other tasks harder.

The bad frameworks work well for the tasks they solve and can potentially make other tasks harder.


Frameworks make the hard things easy and the easy things hard


Or easy things hard, hard things impossible, and optional things mandatory.

They solve one problem by giving you two new ones. Then they scold you for not following arbitrarily decided conventions. They corner you into using inferior janky solutions that do less with more and prohibit consolidation, abstraction or aggregation because ahem, that's their job to do, not yours.

Instead You are supposed to be stupid and do things naively regardless of the fact that's how piles of garbage get made

It's like relying on the worst engineers you've ever worked with and you aren't allowed to change their code. Awesome

I use them all the time professionally because I feel like it's what I'm supposed to do but good lord almighty are they ever totally broken bullshit


To put another analogy down, it's a coupling issue. Nobody wants to hammer in a nail and then buy a new hammer for a slightly different nail.


While there is a good underlying point I don't enjoy the analogy and I am glad other people have pointed out its flaws.


I'm sure Joel Spolsky wrote about absurdities of having factories for everything, I can't find it though.


This is a post from 2005 by Benji Smith in the old (and now closed) Joel on Software Discussion Group. It's titled "Why I Hate Frameworks". But I know it as "the hammer factory" post.


aha thanks, maybe I remember it from there.


I'm not sure if it matters much in this case—the analogy sadly holds up well, if not better—but

> (2005)


Are there any big projects done without being developed into a framework?


Couple thoughts:

- This wouldn't be a problem if we could have matter replicators like in Star Trek, so I'd have just a single box in my shed that could spit out the exact hammer I want, the exact tape measure I want, and whatever else I need, from nails to three-course dinner. The problem with factories and factory factories is the ridiculous amount of yak shaving that stands between your wish or design and its realization.

- The above is also true of frameworks: the issue is that they come front-loaded with accidental complexity.

- Where the reality deviates from the hammer story is that, past hammer factory factories, we didn't build universal tool factory factory factories - we've just made Hammer Factories as a Service.


When you talk frameworks, in reality you talk DSLs.


I read it as more of a critique of design patterns.


this post never gets old!


Bit of Deja Vu. 2005.


So... Why did it have to be Java?


tldr: OOP sucks.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: