Hacker News new | ask | show | jobs
by sidlls 1304 days ago
This is one of the better things about Go and its community: eschewing frameworks like this.

Having an ecosystem of in-house libraries tailored to your products' use cases is not the same as developing an "ad-hoc framework". Where I work, we have several languages deployed in our fleet of microservices. A couple have frameworks, and these frameworks are "try to do it all" types, complete with dependency injection and layer upon layer of abstraction intended to help engineers avoid "needless" boilerplate or what have you. They're slow and difficult to debug/troubleshoot for any case that isn't anticipated by the frameworks, and even sometimes then. No, thank you.

Microservice architecture has its own problems, but these problems tend to be easier to reason about than the services themselves that use the frameworks.

4 comments

> A couple have frameworks, and these frameworks are "try to do it all" types, complete with dependency injection and layer upon layer of abstraction intended to help engineers avoid "needless" boilerplate or what have you.

Isn't this generally the advantage of using open source frameworks? The mature ones have run into most of these roadblocks, and have a solution for it already. And the ones with good taste have escape hatches to allow you to easily bypass for the one they haven't got a solution for. I've heard bad things about Spring, but I'd put forward Laravel as an example of a framework that can do an awful lot for you if you want it to, and gets out of you way when you don't want to use it for a particular task.

That is the value proposition of these frameworks. They work in some cases, and for services/applications where the complexity is generally low. They come with a big restriction, though: a very narrow, highly constrained ("opinionated") way to do everything. The escape hatches don't help--they still have to be within the context of the framework. And the gods help you if anything goes wrong and you have to troubleshoot something that touches any implementation detail of the framework.
I've spent the last year exploring different languages and ecosystems than the one I'm most comfortable in (Python) and what you said absolutely rings true. When you're picking up C#/.NET, there's this almost overwhelming amount of terminology you see getting tossed around that takes you a while to see how it all fits together.

Now that I'm exploring Go, I'm surprised at how many books/learning materials are basically surveys of the features of the language, and then it's basically - "Start building!" "Introducing Go" is just 100 pages for example.

The number of times that the asp.net "startup" has changed is completely ridiculous. It all started from a very bad place with a startup class that is stupidly called by reflection, forcing the developer to use trial and error to discover what methods should be used.

Thankfully, they have finally done away with this but it is sad that they ever allowed these horrible patterns in the first place. Another abysmal area is SignalR (clearly developed by children).

Everyone makes mistakes, even framework/compiler teams. I mean look at how long it took Go to get generics. Huge mistake IMO.

I still dislike what ASP.NET did with their startup, and I don't think it's improved much. The minimal startup is just a bunch of magic (where did the var 'args' come from? Just magic.)

Framework folks are people, they try new things, it doesn't always stick.

I don’t enjoy being critical, but sometimes it is justified. When you have something used by millions of people, it should be more carefully vetted.
That feels a lot of ‘old man telling skies’.

What is main(), where did it come from? Who calls it? What is argc and argv? Who puts that stuff there.

main() is a well established entry point in computer science. It’s the first thing one learns when learning to program. Nowhere else in C# are there “ambient” variables.

https://en.m.wikipedia.org/wiki/Entry_point

> layer upon layer of abstraction

I suppose it's a quibble, but this annoys me. It shouldn't matter how many layers of abstraction there are, because I should only have to interact with the topmost one. For example when I write vanilla Java there are, off the top of my head, the following layers of abstraction: the Java language, the JVM, Userland, Kernel, C, X64, and CPU microcode. No abstraction is perfect and maybe the day will come where I need to understand the hardware frontend on x64 chips to get my Java program working right, but in the overwhelming majority of cases I only need to worry about the abstraction presented by the Java language itself and maybe on the operations side those of the JVM.

All automated computing abstractions are, in the pathological case, leaky, but there comes a level of leakage where it essentially stops being an abstraction at all, useful or otherwise.

Spring Boot isn't an abstraction, it's a language extension implemented via Java annotations. Thus you must in addition to understanding the relevant parts of Java, also understand the relevant parts of Java/Spring. Personally I think it's poorly documented and doesn't really have a cognitively manageable semantic theory, but it's been a long time since I've worked with it so maybe that's been sorted out?

You’re talking about a different kind/level of abstraction. I’m referring to abstractions built within a language; there isn’t a direct; meaningful comparison to the abstraction of, say, a language over machine code.

Spring Boot isn’t an abstraction, but the language extensions and the things built on them within the frames are (badly engineered ones at that).

the clojure crowd went this way too, libs over framework, as opposed to django and the likes where you can indeed hit sad corner cases.