Live data from Hacker News

Write Libraries, Not Frameworks

brandons.me

151–160 of 338 posts

Re: Write Libraries, Not Frameworks

#151

A framework, usually, must predict ahead of time every kind of thing a user of it might need to do within its walls. The one thing not mentioned in the article is that the above line of thinking is almost guaranteed to lead to an insane level of abstraction, which was parodied in this classic article from nearly 15 years ago: http://web.archive.org/web/20141018110445/http://discuss.joe... (Sadly, that site is gone, b…

I remember the Rails people making fun of the Spring stacktraces vs the Rails one (being much shorter). Guess what, a couple of years later Rails has the same layers of abstraction

Re: Write Libraries, Not Frameworks

#152

I’m pretty sympathetic to this, as my experience with Spring has been “it’s convenient when it works, but awful to deal with when it’s not working”. However, I think to push this line of thought, it would help if we had examples of how to build significant applications without a framework. Ideally someone could provide a walkthrough of an app like that. Unfortunately I can’t volunteer myself: the last time I built wi…

I think Dropwizard is a great alternative to Spring. If you want to draw a spectrum between framework and "curated libraries + best practices", it's much closer to the latter. But then I guess that also depends on how much you consider the libraries it uses like guice and jndi to be "mini-frameworks". Ultimately, all that matters is how easy it makes your job, in both the best case and worst case scenarios, so I'll leave that to your own judgement as an engineer.

Re: Write Libraries, Not Frameworks

#153
post #128

Earlier quoted context omitted.

I think you are being completely unfair here. AOP in Java (and .NET) is a metaprogramming facility that has few equivalents in other languages. The closest thing that comes to it is macros, but those are often compile time modifications. More importantly, nothing about standard Java development requires The use of AOP.

> AOP in Java (and .NET) is a metaprogramming facility that has few equivalents in other languages. The closest thing that comes to it is macros, but those are often compile time modifications. You don't need macros to achieve what grandparent was talking about - handling cross-cutting concerns like logging or transaction boundaries without being too intrusive. In a language that lets you do a half-decent monad imple…

If I give you a jar (or equivalent) of my compiled app, can you still apply cross cutting concerns (over compiled code you may not own)? Because that's what AOP and bytecode transformation can do.

Re: Write Libraries, Not Frameworks

#154
post #120

Earlier quoted context omitted.

For those of us hazy on the AOP concept... Is it an artifact stemming from restrictions of static languages, or would it be a valid concept with dynamic languages too?

In the dynamic languages world this is done with monkey patching. If you invent a declarative way to monkey patch your code, you've got AOP as done in Spring.

Don't forget AOP can work on top of compiled classes, not sure I'd there is an equivalent in python or ruby.

Re: Write Libraries, Not Frameworks

#155

Earlier quoted context omitted.

One option is using XML with complicated enough XML Schema. Good editors like Intellij Idea support editing such an XML and provide good autocompletion, on-the-fly validation. XML libraries would parse that XML into tree and validate it against schema without any additional effort. While XML certainly deserves some blame, the amount of tooling around it is unmatched.

XML's main limitation derives from its base primitives: Strings and hierarchies of ordered strings labelled with strings. Starting from that premise adds a great degree of schematic overhead to convey semantics, which tends to overflow into syntactical boilerplate. Traditional parsers start from one string and evaluate that a character at a time. JSON starts from a few JavaScript primitives. SQL has primitives that v…

It's somewhat unfortunate that XML arrived at this perception of being complex, when SGML (= superset of XML, HTML, and everything angle-bracket markup) very much is a technique to give structure to ordinary plain text. For example, SGML could parse .INI file syntax such as the following (and present it as a fully-tagged, canonical markup ie. XML):

    [config-item-X]
       config-param-Y=bla
       config-param-Z=123
If you look at how popular markdown and other wiki syntax is, and at the same seeing folks hit markdown's limitations fairly quickly (for example, markdown has no way to pull-in content from other files or doing any document composition whatsoever), then I hope you can see that SGML is a technique designed for a broad application in this area, being able to handle standard markdown and custom markdown extensions (not to mention that SGML is the only ISO markup meta-language able to handle HTML with all it's tag omission rules).

In XML-land, this has been re-discovered as "invisible markup" a couple years ago, going full-circle in the "dumbing down" of SGML into XML (which was seen as progress and win for simplicity at the time when XML was subset from SGML).

I would also disagree that the defining characteristic of SGML/XML is nesting of tags so much as it is regular content models. A content model such as

    configitem: configparam+
    configparam: configparam-name, configparam-value
is what drives SGML's tag inference in the above example.

But yeah, SGML/XML is made for markup, not necessarily config files and service payloads. And I agree SQL could be improved by treating it like an ordinary programming language, with the same focus on SQL artifacts wrt syntax highlighting, static checking, and testing (though probably not in the way you suggested, by reading-in SQL script files as a primary means to serialize DBs :).

Re: Write Libraries, Not Frameworks

#156

Writing libraries is a never ending grind of: 1. trying hard to do one thing and do it well (and failing usually), but ... 2. there are many dependencies that you should allow your user to pass explicitly ... 3. and that’s the problem - you have 0% control on how the library is integrated but receive full responsibility for how well does it work. Even libc could be very different and will not behave the way you’d exp…

This is why I love writing libraries in Rust: the language provides so many ways of protecting users of your library to shoot themselves into the foot.

Combine this with the built in and easy to use testing and I find myself often to break out core functionality of my applications into libraries just because it is a sane way to keep things decoupled.

This is far harder in languages without a strict type system: you can do everything right and your users still abuse it.

Re: Write Libraries, Not Frameworks

#157
post #150
post #141

The more I program, the more I am convinced that owning flow of control is one of my primary jobs as a programmer. If I surrender this to a framework, there are a lot of decisions I can't make with regard to performance, and I have a lot less certainty about when and in what order exactly things are executed. There are of course some exceptions, but in general I want libraries to provide me simple, synchronous functi…

On the level of practical risk: on the security level libraries are much more risky imo. A good framework for most project i've seen will lead to a more structured and secure codebase. Probably precisely because there is less room for creativity. For instance Laravel is very structured: orm, auth routes, controllers system etc., where express.js let's you do whatever. And almost all Expressjs or other Nodejs projects…

oh, Laravel is actually an excellent example. It has a lot of hidden "magic" knowledge inside and it takes many months to get a good understanding of how it works. Until then it is trivial to make bad decisions based on this wrong knowledge. Lack of proper IDE support (because of laravel's dynamic nature) doesn't help. And yes, I know about laravel-ide-helper. It has it's issues too

Re: Write Libraries, Not Frameworks

#158
post #92

A framework, usually, must predict ahead of time every kind of thing a user of it might need to do within its walls. The one thing not mentioned in the article is that the above line of thinking is almost guaranteed to lead to an insane level of abstraction, which was parodied in this classic article from nearly 15 years ago: http://web.archive.org/web/20141018110445/http://discuss.joe... (Sadly, that site is gone, b…

I kinda want to make a Spring class name generator now.

Somebody already did that for us others to enjoy: https://github.com/achin/boss-work-manager-configuration, running at http://java.metagno.me/

Re: Write Libraries, Not Frameworks

#159
post #104

Earlier quoted context omitted.

Just use a language where it's possible to implement those things in plain old code. When you have higher-kinded types you don't need any bytecode manipulation, you can just have a type that wraps anything that needs to happen in a transaction, and compose together transactional operations in a visible but type-safe way - and you don't even need the runtime cost. How anyone can look at Java as it's actually used and…

How would you then, say, do a profiled run of the application, to help find the choke points in your application? You'd have to make sure that you apply the exact same "trace the runtime of this function" wrapper around every single function call, then make sure you haven't missed anything anywhere, then have to maintain such usage, and then mentally ignore it everywhere when you're trying to read through the code.

Profiling isn't really a good example; I don't actually mind doing it via language-level magic, since it doesn't affect the actual behaviour of the application - every function still executes the same and still returns the same thing, we just observe it in more detail from the outside.

But to answer the question, I'd use a monad, something akin to treelog ( https://github.com/lancewalton/treelog ). Apply the wrappers at the points where you want them (and they'll be visible in the type), and then the tracing is naturally threaded through in a way that's visible but not intrusive (basically just the difference between <- and =, so when you're reading the code you can see it but it doesn't get in the way of reading the business logic). Maintaining it is easy because it's just part of the type of everything, so automated refactoring in you IDE will do the right thing; testing is easy because everything's still just a function and a profiled computation is still just a value, but you have access to the profiling trace in a normal way as a first-class value in the language.

Re: Write Libraries, Not Frameworks

#160
post #63

This has generally been the approach in the Clojure community. Of course, lacking standard frameworks, every library gets abandoned every few years so you have to learn a new even cleverer one. And wherever you might benefit from a group of very cohesive abstractions (e.g. in data science) you’re instead left with a bunch of random incompatible things (that again, will be abandoned in due course).

What are you talking about? Every Clojure library does not get abandoned. It's just a process of survival of the fittest, like with any language. The popular libraries in Clojure are (mostly) actively maintained like with any other language.
Post reply on HN