“Do you really hate frameworks?” – this question won a contest for the most popular question after my talk at JDD this year. I don’t remember exactly how many discussions I had after my presentation, how many questions about my personal trauma caused by programming languages, paradigms and frameworks. I have to say that this makes me feel good about my presentation. I don’t know if you liked it, if you liked my style, slides and my English was good enough. One thing I know for sure is that my message was heard and was not lost in translation. I tend to have people confused after my presentations, they don’t know what I wanted to say.I usually have too many thoughts at once, too many views and never ever show last slide :).
Do I really hate frameworks?. Yes I do. Do I? No, I don’t hate them. It is really complex and dynamic relation. It is hard to say if I love or hate, something that is not alive. I can love or hate people, but I cannot say the same about frameworks. At the end of the day it is all about people, people who create and use frameworks, paradigms and programming langues. It is all about us,
lost in a universe of unknown , which expands with the speed of light. It is all about us, who master our skills to communicate better and better with machines, and lost our ability to express our thoughts in a “human readable” form.
It is all about expressiveness, about telling stories (thanks @pbadenski for your
inspiring talk “Catcher in the code”). Frameworks, paradigms and programming languages are not about solving problems. As I said during presentation “frameworks solve author’s problems. Not yours”. You don’t need zillions of dependencies in your POM xml to solve your problems. And let’s be honest. It is all not about solving problems, it is all about describing domain. If your description of domain is complete and expressed in a clear way, there will be no problems to solve, almost :).
Many, if not all problems in our daily life come from wrong, incomplete and ambiguous description of the domain. In short words your model is wrong.
Model is not a description of a problem, of a domain.It is one of the means of communication. Model exists to communicate your understanding of the domain, and by definition every model is wrong. So what is a “good model”? It is the model which communicates well your understanding of the world, your view of a reality.
This is what my personal problem with frameworks is all about. We tend to use them to solve problems, at the same time loosing “model” from our sight, the need to express domain in a clear way.
Let me prove it to you. Let’s imagine that we just got a new task in our TODO list.
Let’s imagine that we have a map of string keys associated with integer values. This map has to be transported over network as list of strings, where key and value are separated by ” = “. Simple model, simple enough so we don’t have to focus on understanding, but rather we are going to discuss implementation.
Let’s first start with Java.
Map<String, Integer> map = new HashMap<String, Integer>(); map.put("one", 1); map.put("two", 2); map.put("three", 3); List<String> list = new ArrayList<String>(); for (Map.Entry<String, Integer> entry : map.entrySet()) { list.add(entry.getKey() + " = " + entry.getValue().toString()); }
So what’s the story? First we create new hash map, then we put first key value pair, then second and third and create new array list. What happens next?
We get set of map entries and iterate over it. For every entry we get key and value, and join them with ” = ” sign in the middle. Once it is done we add newly created string into the list.
The truth is that in fact only line 10 expresses what we wanted to do, converts map into list of strings.
It is like play in a theater, when for first two acts actors introduce characters they play, repeating their last and first name, on and on.
And in the third act which lasts 5 minutes, they tell you that this play is about “meaning of life”. Interesting? Isn’t it?
Of course since we all are “framework seekers and followers” let’s use one. Lambdaj, please come and hear my prayers.
Map<String, Integer> map = new HashMap<String, Integer>(); map.put("one", 1); map.put("two", 2); map.put("three", 3); List<String> list = convert(map.entrySet()), new Converter<Map.Entry<String, Integer>, String>() { public String convert(Entry<String, Integer> entry) { return entry.getKey() + " = " + entry.getValue().toString(); } });
Is it better? It is even worse. It all looks better until monster called “anonymous class” steps out of its cave.
We even have some nice words, like “convert” which express our needs far much better, but concatenation of strings is devoured by Anonymous The Dragon. Do you really think you need framework?
Or maybe you chose the wrong one? Or maybe you just skimmed through docs and examples, it worked and you moved to next task?
Yeah, that’s the thing I hate too, really hate. All this copy paste from examples jumping out right on my screen from framework’s docs and example pages, and recently from StackOverflow.
The thing is that such “smelly code” will sneak through key strokes, and will infect your codebase faster than you expect.
Its readability is even worse then plain old Java code. But “It solved my problem” you may say. The same as first snippet, right?
So what’s the deal? Yeah, I know, your CV. The longer, the more cryptic the better.
During JDD with group of people I have come up with an idea to write Maven mojo, with goal “cv:generate”, which will create your CV based on project dependencies in 3 most popular formats. Wouldn’t it be nice?
You know what’s the another problem with frameworks, paradigms and programming languages?
You can hide time pressure or your ignorance behind it. Yeap, you really can.
“Architects forced us to use it”.
“This is a bug in a framework we will have to live with it until someone fixes it, in the meantime we have prepared a quick workaround (which will stay there forever)”
“There was time pressure to deliver this feature on time, we didn’t have time to get familiar with it, we will leave it in projects dependencies and will use it in next version (read it – never)”
“This framework is soo great, but it is complex, we will use it and learn it later”
Is Lambdaj so awful, no it is really nice but you have to take time and unlearn your old thinking and behaviors and learn new.
So let’s give it one more chance.
public void convertMap() { Map<String, Integer> map = new HashMap<String, Integer>(); map.put("one", 1); map.put("two", 2); map.put("three", 3); Closure closure = closure(); { of(this).toString(var(Map.Entry.class)); } List<?> list = closure.each(collect(map.entrySet())); System.out.println(list); } public String toString(Entry<?, ?> var) { return var.getKey() + " = " + var.getValue(); }
How do you like this approach? Personally I like it more then the previous one. But you know what? This is not obvious for novice lambdaj user, it takes time to get how closures work in this framework, and expressiveness comes with the price of performance penalty, you don’t get it for free.
Is this all we can get from Java? I think so. It is still a whole lot of code for such simple case, so let’s make another step forward, and write same example in Fantom.
map := ["one" : 1 , "two" : 2, "three" : 3] list := Str[,] map.each |v, k| { list.add(k + " = " + v.toStr) }
Isn’t it lovely? Does it mean Fantom is cure for all our headaches? Are you sure we will be able to express other models in Fantom in the same, really expressive way? I will leave this question unanswered, to feed your thoughts. It is better to answer such questions to yourself.
Warning!!!
This post is not about greatness of Lambdaj, functional programming or Fantom language product placement.
If you think it is, start to read this post once again.
And I know you will try to flood me with my example written in you favorite framework or language. But something that is more readable for you is not necessarily readable for others.
Frameworks are great, as long as they help you express your thoughts, as long as they help you tackle accidental complexity of the code. Yeah, complexity, an elephant in the room. You cannot hide from it, you have to face it and embrace it, a topic for long discussion.
I hope I have helped you understand my frustration, and I have explained that my presentation was about a need to better express our thoughts, and a need to focus more on a systems structures and models. Once we picture these often hidden structures and models, we will be able to better solve our problems without need to juggle with frameworks. Wise people before us understood that need, and developed a tool for us, for our brains to help us express our model, our understanding of reality.
It is called systems thinking.
“If your description of domain is complete and expressed in a clear way, there will be no problems to solve, almost .
Many, if not all problems in our daily life come from wrong, incomplete and ambiguous description of the domain. In short words your model is wrong.”
True, true
After few years of advising, training and coaching I could not find any cause that is more significant.
We can have code that shaped by brand new framework, covered by 100% TDD and super clean, but still completely wrong model:)
And once you find that your model is wrong you need to get ready to get big money to fix it, it is not so easy as change in technology 😦
yup, and only solution I see right now to reduce (not eliminate) risk of this kind of “mistake” and reduce cost of change is DDD (but I mean real, no “compromise” DDD). Of course it’s not a silver bullet, but best tool that is available – actually not always available:/
I am afraid it is not silver bullet. I have a hard time to think about DDD in a context of large scale SaaS solution. It doesn’t work so beautifully, or maybe I didn’t try hard enough…
Nice post, but I have a question.
If we are talking about DDD, then I have to ask – why?
Why these values are in a map?
It looks like some implicit concept is hiddedn down there…
Maybe (just maybe) some Value Object should be introduced, which would hold those pairs and expose a behavior – toString().
(I know that this post touches some different areas, but still… 😉 )
There is hidden assumption that we work with legacy systems which doesn’t know anything about Value Objects and communicates using uber object, called hash map. You should know it :), you worked with such system light years back 🙂
heheheheh you’ve made my day. 😀
There is another hidden assumption – “light years back” – and this one can be actually wrong. 😉
I have similar feeling. However, it is wise to find a framework which will cover generic domain of project, e.g. web framework. It could be even worse, because you have to make choice and discussion quickly heats up, especially when framework lovers join (current experience :))
… and it heats up quickly every time, imagine all this energy used for “flame wars” redirected to build common model, to understand system’s structure. I am a fucking dreamer, man! 🙂
Ha! If only “what do we want?” question is asked it would be great success. It even is, but is lost in flames 🙂