Hacker News new | ask | show | jobs
by mattgreenrocks 4571 days ago
The "libraries over frameworks" notion is something I keep noticing in communities that seem to be more engineering-minded than rock-star-ninja-dev-minded. Where do you think this comes from? I think it's a mix of maturity on the part of the community members along with how often the language is used to do things that are harder than CRUD.
3 comments

In my case, I'm speaking of a reaction to Spring and Struts. I personally use Grails on my recent projects, which is as close to batteries-included as it gets, but I occasionally have problems with square peg round hole problems, and fighting against a framework is more painful than a library.

The problem with the framework is that we run into a steep hill when we must diverge off the path. A good framework gives a great story. Unit tests, integration tests, consistent layers, convenient and powerful ways to access the database without writing a giant SQL generator (if x return "and b.id = c.id" else return "b.name = "%" + name + "%")...

But then, you hit the use case that the framework didn't consider. And suddenly, you either need to extend the framework (never pleasant) or go outside the framework for one portion, which means building all of the tools from the ground up.

Or, more often, ignore testing, hack in the best way you know how, and hope nothing breaks.

The library approach means that you have to build the integration pieces yourself. This is painful, but it means that when you reach a new use case, it isn't as large a jump to keep going.

Each has tradeoffs. There are times when each is superior. Someone like Bob Martin would suggest that you build your system independent of frameworks and treat the web as a client/compatibility layer, and that you build your system of small composable parts so that the framework/library question is a minor one. (This has its own tradeoff with an abhorrent amount of plumbing code that comes along.)

It all comes back to the problem at hand and how we judge the tradeoffs, like most engineering problems.

Do you know of any shops that use Uncle Bob's approach (besides 8th Light, of course)? I don't; I wish I did. I agree that isn't something you'd use every time, but I feel there isn't a whole lot of data out there when people have used it. All I see online are devs whining about the extra work.

I don't know what it is about the web, but it's as if we decided all of software architecture didn't mean anything and threw it out. My theory: it's harder to feel coupling in a dynamic language, thus it's just an academic concern!

I have plans to try it in a side project. I too am skeptical about the rewards of setting up a CRUD system like that.

It isn't that we've decided that software architecture meant nothing; rather, we settled on one architecture that is Good Enough. The View/Controller/Domain paradigm of Rails works for many projects.

It won't be great for CRUD. It's really meant for applications that have a bunch of business logic to them...you know, the interesting apps.

Aside: "good enough" seems to summarize the web as a whole. This is both discouraging and a fact of life.

You can still have an interesting business logic system that is CRUD at its core. A case management system, as an example, is CRUD at its basis but filled with business logic.
I'd say it's exactly about "maturity" not in the emotional sense, but the "breadth and depth of professional experience" sense.

A lot of the 'glamour' in the Bay Area is around web apps that 20-somethings use. As a consequence a lot of the headlines and centers of discussion are going to be around languages, platforms and paradigms that reflect that. And, these days, that would be dynamically typed languages, frameworks or framework-like 'libraries' and fad-following (which is where the "rock-star-ninja" meme comes from). I just try to filter the noise as best I can to glean the useful and interesting bits of articles and comments I read.

Except that of all the things you've named, dynamically typed languages are hardly "a fad". It's surprising (?), though, that the lousy ones are the most popular ones.
I take a very cynical view of these things, and from that perspective it doesn't surprise me at all, really. My cynical view is that the "lousy" ones are popular because they are easy even for non-technical people to learn well enough to be useful in the majority of business settings.

This sets up a kind of feedback loop: there is an abundant supply of "cheap" labor who can use these languages, which companies love, and so they create more jobs for this labor market to fill, which means more people want to fill it (since there are jobs there).

Edit: 1) I would disagree that python is a "lousy" language; 2) To give some perspective regarding where I come from, the vast majority of my experience is with statically typed languages like C, C++ and Java; I prefer them and in my experience they are at least as easy to develop with as any of the dynamic languages that are popular.

The commoditization of web devs will occur, it's just a matter of when. Consider it the collateral damage from ever-more-powerful frameworks, a de-emphasis on SOLID-type software architecture, and businesses wanting to pay less for developers.
Couldn't agree more. I'd argue it's already well on its way. It seems there has been a resurgence in companies trying to shoehorn every application into a specific development pipeline within the last several years (specifically, the HTML5/JavaScript in-the-browser solution, rather than a more appropriate native solution). It happens every so often in this industry, but lately it seems to have accelerated.
I think its more of the realization that types are actually freaking useful for determining "provability" of a system. C++ perhaps takes it too far with Const, but it allows the compiler to prove that certain functions will not attempt to modify certain variables.

Compared to Python or Ruby, you're pretty much relying entirely on culture and good habits to ensure the proper rules of encapsulation. Any code may modify the private members of your objects. (Granted, C++ has "mutable", Java has the whole "Reflection" loophole as well. But you can search for those edge cases rather easily).

I think its more of the realization that types are actually freaking useful for determining "provability" of a system. C++ perhaps takes it too far with Const, but it allows the compiler to prove that certain functions will not attempt to modify certain variables.

There is very little in terms of "provability" that either C++ or its types give you. Proving anything really interesting (for example, the absence of race conditions in concurrent code) still seems like pretty much an arduous process in languages not explicitly designed for such things.

Compared to Python or Ruby, you're pretty much relying entirely on culture and good habits to ensure the proper rules of encapsulation. Any code may modify the private members of your objects. (Granted, C++ has "mutable", Java has the whole "Reflection" loophole as well. But you can search for those edge cases rather easily).

That didn't seem very comprehensible to me, but if you're claiming that in Ruby, you can modify member variables of someone's objects, well, you can't, unless you use reflection as well (not only that, but the access to member variables is object-based, rather than class-based, so you can't access the member variables of an object from any other object, even if they are of the same class, unlike in C++ - so much for the "objects communicate by passing messages" in C++!). More to the point, in C++, you can always cast a pointer into something that makes the raw data accessible. There's enough stuff in C++ for you to blow your whole leg off instead of just shooting yourself into the foot.

Take for example, proper use of a unique_ptr<lock_guard<std::mutex> > in C++. You can pass around the unique_ptr, and guarantee that you are in "unique ownership" of a particular lock at compile-time.

In C++, you may not be able to prove "the lack of race conditions", but you can prove things like "I'm the only one who is holding onto this mutex right now" thanks to stuff like unique_ptr... which tracks that stuff. These primitive proofs are performed at compiletime, and have little-to-no effect on runtime as well.

Stronger languages with stronger type-systems (ie: Haskell) can prove / disprove which code has side-effects... because you've explicitly passed the Monad around. (Note: Code without side-effects is guaranteed to not have race conditions).

So yes, there are important things you can prove using the type-system. More importantly, it is the compiler's job to automatically conduct these proofs every compile cycle.

In Ruby, you can break into any other object with a judicious combination of send() and instance_variable_{set,get}()
Alternate theory: "lousy" is a subjective measure, and those languages are popular because in many other peoples' subjective reality, they are not lousy. Just a theory though, by all means, keep thinking that languages are objectively ranked identically to your subjective ranking and anybody using ones at the bottom are just dumb dumbs who are incapable of using the ones at the top.
I didn't rank any languages. I made an observation that it is easier for non-technical people to pick up dynamically typed languages and be productive enough for use in many business cases than to pick up statically typed ones. That doesn't mean the dynamically typed ones are "easier" or "worse" than statically typed ones. It doesn't mean people who prefer them or learn programming with them are "dumb dumbs," either. There's a reason I put "lousy" in quotes and didn't flat out agree that they were, in fact, "lousy".

Seems to me that's a chip on your shoulder; not mine.

Hmmm, I re-read your comment and its parent a couple times, and maybe I didn't give proper credence to your sarcasm quotes. I do think that your comment strongly implies agreement with the non-sarcasm-quote-using parent comment, but hey, maybe that's really just my reading of it. Your edit also confusingly says that you don't think the "lousy" languages are really any easier than the static languages you prefer, despite your second paragraph seeming to say the opposite. So maybe I'll just bow out of trying to interpret what you think :)

I'll freely admit that it peeves me to no end when people make value judgments based on what programming languages people do and don't like and use, on both sides of the static/dynamic divide, so maybe I do have that chip on my shoulder.

I first saw this in clojure, and thought it came for the builtin immutability of most types. Meaning you can't have order problems with libraries functions, unlike in the mutable world where a framework will shield you a bit.