Posts Tagged ‘Programming’

On Patterns…

Thursday, November 20th, 2008

I’ve recently stumbled across this post (which, by the way, I highly recommend its reading), which has someway enticed me to add some comments. Now, this doesn’t mean I don’t agree with the author concerning a few arguments; I just want to raise the awareness over some points I find particularly important. 

Linda Rising, in the last PLoP conference, said something along these lines: “A pattern shouldn’t be an Ahah! or Eureka! but something more like an Hmmmm!”. 

The thing is, a pattern is something recurrently seen in the wild, that try to give an answer to a problem by balancing the forces in some particular way. Not an intelligently crafted solution in the author’s basement. A good pattern is one where a domain expert is able to easily recognize the pattern as: “I’ve seen this!”.

Now, if the GOF’s Design Patterns should have been more or less abstract than they are is ultimately irrelevant; the authors observed those patterns in a particular context, and while they may hold outside that context, that can’t be neither guaranteed nor intended by the authors. That’s why patterns typically have a target audience. In the context they wrote the book, putting additional effort into implementation details have probably lead far more people to grasp it, than it would have been otherwise.

Furthermore, as an example, Ralph Johnson, during the last PLoP workshop, suggested that the patterns I wrote could be generalized far beyond Adaptive Object-Models and into a broader OO perspective. However, that would need a completely different context-problem-forces triplet. Now, someone reading my paper could say: you focus too much on AOMs; you should have generalized. Well, it’s true. But the proposed pattern is intertwined in a specific pattern language, which has it’s own context and forces. For that purpose, I may actually have given too little detail, since several comments I received asked for more in that direction!

Alexander’s work is a great example of what I’m trying to say. The Notes on the Synthesis of Form could, and are easily abstracted into several realms far beyond Architecture. Should we state that Alexander coupled himself into unnecessary detail?

I believe the problem may not be in the patterns per-se (nor even in the GoF book, which should be regarded as a germinal work), but in the people using them. Personally, I think too few people know the GoF book, or for that matter, patterns in general. Those who know and apply them blindly, have completely missed the fact that a pattern is NOT a building block! Maybe that’s why GoF entitled their book as Elements of Reusable Object-Oriented Software, and not Design Rules of Good Object Oriented Software.

Richard Feynman once said: “Know how to solve every problem that has been solved.” I believe the study of patterns endure this ideal. They are not engraved laws of the tissue of software. They are a systematization of intrinsic, almost empirical, observed knowledge.

Quote of the Day

Saturday, November 15th, 2008

(…) there are two ways of constructing a software design. One way is to make it so simple there are obviously no deficiencies, and the other way is to make it so complicated that there are no obvious deficiencies.

 – Tony Hoare [Turing Award Lecture, 1980]

Innovation stiffs old practices…

Sunday, October 12th, 2008

While reading a post about the new language Microsoft is supposed to release in their next development platform, I’ve found an alarming message in the author’s blog:

“But if all newbie programmers learn these new languages, who will manage the billions of lines of C and C++ we currently use in the future, unless it is implied to be completely be rewritten?”

I’ve heard this line of rationale before… Who will manage the billions of lines of assembly now that people use C and C++? Who will program hardware, now that Universities’ degrees only focus on high-level software?

Careful: this kind of thought is presumptuous at best. Don’t get me wrong, this is not a direct critic to the author, but to the concept. Practices and tools *need* to evolve, so we can achieve higher degrees of abstraction. Attempting otherwise only hold back evolution (and may turn us into old-school dinosaurs, who keep mumbling “back in those days, we used two big drums to program; one was called 1, the other 0″).

After all, there will always be people wanting to beat those drums… :)

PLoP paper accepted

Tuesday, September 16th, 2008

A paper I submitted this year to PLoP, “Patterns for Data and Metadata Evolution in Adaptive Object Models”, co-authored with Filipe Correia and Leon Welicki, has been accepted for publication. I’ll be attending both PLoP and OOPSLA this year in Nashville, Tennessee, USA. Meet you guys there :-)

All Your Pointers Are Belong to Us

Wednesday, September 10th, 2008

At the sound of I’m a Believer - Smash Mouth:

I thought memory leaks were only true in unmanaged code.
Meant for someone else but not for me.
Leaks were out to get me,
That’s the way it seems,
There are pointers haunting all my DIMs.

And then I saw Dispose(),
I’m a believer.
Not a trace,
Of leaks in my memory.
I saw Dispose(),
I’m a believer, 
I couldn’t leave it, 
If I tryed{} catch{}.

I thought GC was more or less a given thing,
The more I new’ed the less I got, Oh Yeah,
What’s the use of collecting,
All you get is lag,
Being OutOfMemory() is too bad.

And then I saw Dispose(),
I’m a believer.
Not a trace,
Of leaks in my memory.
I saw Dispose(),
I’m a believer, 
I couldn’t leave it, 
If I tryed{} catch{}.

Lyrics by me and Hugo Silva ;-) Ready yourself for an MP3…

.NET Memory Leak and no solution from Microsoft…

Sunday, September 7th, 2008

You think that living in a managed world eliminates your worries with memory leaks? You think that as long as you don’t touch unmanaged resources you’re safe? Well, think again…

I’ve recently been struggling with .net because of Panels not being destroyed. Since I dynamically create these panels, which hook upon several events in the system, the application started to crawl down after a while due to some thousands/millions of events being fired to panels that should no longer exist. When we started testing the code line-by-line, what we’ve found amazed us: a particular Panel couldn’t be destroyed due to having AllowDrop set to True. WTF?

But there it was: set it to false, and the garbage collector happily destroys the object. Set it to true, and Dispose() is never called, the Panel lives, and the application stalls.

We thought: a bug in .NET? Does this happens in 3.x as well? Yes, it does. But, how is it possible? No one ever found it? After all, Drag’N'Drop is a common feature. Well, apparently, one guy did. But, either I’m misunderstanding the solution, or there is no solution at all.

Help?

Cocoa Programming

Monday, August 25th, 2008

I’m currently reading Cocoa Programming for Mac OS X. I’m becoming astonished by the underlying technology in Cocoa. There are some drawbacks, it’s true: for instance, Objective-C is much less intuitive than Java or C#, the whole .h files seem pretty much deprecated nowadays, and there’s definitely a learning curve there. But having a book like this can help a lot in the process.

I’ve just finished chapter 11 from 35 in total. I must say that by now, CoreData amazed me by allowing to create an application to display, manage and persist (with an Undo/Redo mechanism and all) a simple Information System to catalog Books (along-side with an Image, rating, etc…) without a single line of code. What amazes me most, is that there’s barely code-generation going under the hood: it’s the whole pervasive MVC architecture in Cocoa that allows you to bind hotspots everywhere.

I strongly advise every programmer who can to read this book and do the exercises up to the eleventh chapter. If after this point you aren’t convinced, you can flame me at will :)

My whole dilemma now is: I’m a developer for Windows (it sucks, but that’s what the company I work for do). I can see the potential in this framework, business-wise, but I can’t seem to find a way to bring this into the Windows world. Any ideas out there?

Logic gates with Dominos!

Monday, July 21st, 2008

Pre-Thesis and Current Research

Tuesday, July 15th, 2008

I’ve presented my PhD pre-thesis on the past 2 of July, and I’m glad it has been accepted by the Jury: “Adaptive Object-Modeling: Patterns, Tools and Applications”. I was also honored to have Joseph Yoder, from Refactory Inc., as my external supervisor. His contribution and ideas will be, undoubtedly, extremely useful during my doctoral research. I’m now officially a PhD. ABD (All But Dissertation).

For those who are wondering, the Adaptive Object-Model (AOM) is a software architectural style which allows for runtime adaptivity of the domain model. It succinctly consists on using an object-based metamodel as a first-class artifact from where all concerns are inferred, or derived from; classes, attributes, relations and behavior are represented and stored as data. At runtime this information is interpreted, instructing the system which behavior to take. Changing the model data immediately results on the system following a different business domain model.

The fact is, while an AOM defines a software architecture and design, any particular implementation of an AOM results in a Domain Specific Language (DSL). There are no standard DSLs for AOMs, and probably there will never be; the strength of AOMs rely in the fact that they are built bottom-up, instead of the top-down approaches other MDSE (Model Driven Software Engineering) methodologies and tools are based upon.

Actually, my thesis will be exactly about that: the study and documentation of a set of patterns, recipes and tools, together forming the basis which any developer can pick and use in its system. The validation of the thesis will, in part, be evaluated by the construction of a prototype framework that lies upon the theoretical models inferred (which, incidentally, is progressing fast enough to already have some production-level commercial applications built on top of it!)

For those who are not following along, let me put things this way: imagine you pick up any semi-formal notation, like UML + OCL, and you feed it to a program. This program will adapt itself, from structure to interface, resulting in a new application ready to use, without any further programming from the developer. You feed it the model that represents an Archeological Heritage Information System, and done! But there’s more: while the system is running, you change the model: you create new objects, new business rules… All applications will react according to the new model, and will evolve automatically, while maintaining their integrity, without any kind of code-generation or shut-down.

Do this seem like a dream? Well, it isn’t. It’s reality, right here, right now. But, somehow these theories never became mainstream. I intend to change that… or at least, give a small contribution :-) And this is my thesis on a nutshell (details are always boring).

While writing this post, I also received an email from a friend suggesting that I should read Martin Fowler’s latest blog posts. It’s interesting that DSLs and MDSE is gaining so much attention these days. Martin, we are all anxious to lay our hands in that new book of yours ;-)

Writing Papers…

Wednesday, May 14th, 2008

As I finish my paper for submission tomorrow (PLoP’08), the following strips start to give me that sense of deja-vu:

I guess one day I will laugh out loud about this… but not today :-)

Singleton using Generics

Friday, March 28th, 2008

Here goes a tip from my colleague José Vilaça for “elegantly” creating Singletons using Generics in C#2.0+ :

public sealed class Singleton<T> where T: class, new() {
 private static T _instance;
 private Singleton() { }
 public static T Instance {
  get {
   if (null == _instance)
    System.Threading.Interlocked.CompareExchange(ref _instance, new T(), null);
   return _instance;
  }
 }
}

Here’s an example:

Console.Writeline(Singleton<object>.Instance == Singleton<object>.Instance);

Of course, T must be a class with a public constructor without any arguments.

Code Q&A

Tuesday, March 25th, 2008

Turing 2008 Award

Tuesday, February 5th, 2008

Goes to Edmund M. Clarke, Allen Emerson, and Joseph Sifakis:

“Model Checking is a type of “formal verification” that analyzes the logic underlying a design, much as a mathematician uses a proof to determine that a theorem is correct. Far from hit or miss, Model Checking considers every possible state of a hardware or software design and determines if it is consistent with the designer’s specifications. Clarke and Emerson originated the idea of Model Checking at Harvard in 1981. They developed a theoretical technique for determining whether an abstract model of a hardware or software design satisfies a formal specification, given as a formula in Temporal Logic, a notation for describing possible sequences of events. Moreover, when the system fails the specification, it could identify a counterexample to show the source of the problem. Numerous model checking systems have been implemented, such as Spin at Bell Labs.”

For those interested in Model Checking and Formal Specification, you can take a peek at lectures from my PhD, specifically the courses Program Semantics, Verification and Construction and Model-Driven Software Engineering.

C# Odds, Part IV: Give me usefull Boolean Operators

Tuesday, January 8th, 2008

How many times have you written an ‘if’ statement like this:

if ((a && b) || !a) ...

You can think of condition ‘a’ behaving like a switch. Its like saying, if the switch is on, please take into account condition ‘b’ in order to do something; if it is off, then simply do it*. Now rewrite ‘a’ and ‘b’ as larger, real-word, classes’ fields/properties, mix more logic evaluation, and voila: an unreadable long expression.

Funny thing is, there *exists* a boolean operator that evaluates the very same way: it is called “implication”. Unfortunately, C# doesn’t have a keyword for it (same with Java, Python…). If it had, the code could be written as simple as:

if (a -> b) ...

Far more readable to me. Maybe they didn’t wanted to use the -> symbol because of the C++ syntax heritage? Who knows…

* Real-world example? Easy. You want to override the display of a dialog-box: if the switch is on, the application always asks for user confirmation; if it is off, it simply executes whatever it needs to.

Update: Hugo Ferreira (same name as mine), as pointed out that you can simplify ((a && b)  || !a) to (!a || b); thank you.

C# Odds, Part III: Beware of anonymous delegates

Sunday, December 30th, 2007

Consider the following code:

public class TestEvent {
  public event EventHandler FireUp;
  public void InvokeFireUp() {
    if (FireUp != null) FireUp(this, EventArgs.Empty);
  }
}

class Program {
  static void Main(string[] args) {
    List<TestEvent> fires = new List<TestEvent>();
    for (int i = 0; i < 10; i++) {
      TestEvent t = new TestEvent();
      t.FireUp += delegate { Console.WriteLine(i); };
      fires.Add(t);
    }

    foreach (TestEvent t in fires) t.InvokeFireUp();
    Console.ReadLine();
  }
}

If you are expecting it to print the numbers from 1 to 10 then you’re wrong :-) The thing is, external variables used in anonymous delegates are passed by reference (even value types like int). In the loop, the variable i is not recreated but increased by one. In the end, i will contain the last value and every event fired will simply write down the value 10. To work as intended, you should write the loop as follows:

for (int i = 0; i < 10; i++) {
  int j = i;
  TestEvent t = new TestEvent();
  t.FireUp += delegate { Console.WriteLine(j); };
  fires.Add(t);
}

Because j is defined “inside” the loop, it will always be a new variable (and hence a new reference in memory).

C# Odds, Part II: More about Access Modifiers

Saturday, December 29th, 2007

In my previous post I argued about the behavior of the protected keyword in C# being counter-intuitive. Some people commented on my post (to whom I thank for the participation), with several kind of reactions: there were suggestions to just change the field to public, to make a getter/setter method (property in C#), to go back to university and stay awake in OOP classes (*sigh*), and to use a real language instead of a Microsoft one (eheh). I’ll try to answer to all of those comments here, because I believe that understanding the languages we work with is important to develop correct and sophisticated programs using the Object Oriented paradigm (and not just write C with Classes).

To clarify further the issue, let’s just call stuff by their name: the concept we are discussion is called Access Modifiers. Access Modifiers are also used in C++, Java, Smalltalk and several other OO (arguably more or less) languages. Access Modifiers exist to aid the process of Information Hiding which is part of the Encapsulation strategy used in OO (or separation of concerns). Some argue that Encapsulation and Data Hiding are the same. Personally (and several other people including some from the Python and Java community) I tend to disagree. But the important concepts to stick around can be summed up by the following quote from wikipedia:

“In computer science, the principle of information hiding is the hiding of design decisions in a computer program that are most likely to change, thus protecting other parts of the program from change if the design decision is changed. The protection involves providing a stable interface which shields the remainder of the program from the implementation (the details that are most likely to change). In modern programming languages, the principle of information hiding manifests itself in a number of ways, including encapsulation (given the separation of concerns) and polymorphism.”

You may follow the links for further information, but the main reasoning I’m trying to follow here is that using public everywhere around is bad (I’ve seen this countless times). It can appear to be harmless in simple/academic applications, but when designing a full blown framework that will be used by other people, don’t ever underestimate the capacity of users to screw up things (including yourself after you decide to reuse a component you’ve done 1 month ago and don’t remember that, while that field is public, YOU SHOULDN’T TOUCH IT!!).

That said, lets look at the definition given by Microsoft to their Access Modifiers:

  • public: The type or member can be accessed by any other code in the same assembly or another assembly that references it.
  • private: The type or member can only be accessed by code in the same class or struct.
  • protected: The type or member can only be accessed by code in the same class or struct, or in a derived class.
  • internal: The type or member can be accessed by any code in the same assembly, but not from another assembly.

Still with me? Great. Everyone knows public well enough. Internal is simple to understand too. But if you think private and protected follow the same rational, guess what: you’re wrong. Compare the following code with the one in the last post:

class A {
  private int protectedField;
  public void doStuff(A a) {
    a.protectedField = 3;
  }
}

class Program {
  static void Main(string[] args) {
    A a = new A();
    A aa = new A();
    aa.doStuff(a);
  }
}

It compiles, as it should! Though members doStuff and protectedField are of different instances, they are defined in the same class. Look at the definition of private: “The type or member can only be accessed by code in the same class or struct”. Are you following me? Private basically says: “I don’t care who tries to access this member, as long as it is within the context of the same *class*.”

Now let’s remember the code using protected:

class A {
  protected int protectedField;
}

class B: A {
  public void doStuff(A a) {
    a.protectedField = 3;
  }
}

It fails to compile, though the definition of protected says: “The type or member can only be accessed by code in the same class or struct, or in a derived class.” Can you spot the differences? The text is the same except that it adds “or in a derived class”. Well, B derives from A. So what is the problem? The problem, it seems, has nothing to do with instances being different. The exact error code the compile gives is: “Cannot access protected member ‘A.protectedField’ via a qualifier of type ‘A’; the qualifier must be of type ‘B’ (or derived from it)”. So in order for the member doStuff to have access to the protected field, a should be typed as B, despite the fact that protectedField is defined in A.

I would personally like to know the person who thinks this is intuitive (and sorry, but I will not even discuss why not just simply cast A to B).

To finalize, I just want to point out that these posts are called C# for a reason: this behavior does not emerge in Java :-) For example, the following code compiles and runs perfectly in JRE6:

public class A {
  protected int protectedField;
}

public class B extends A {
  public void doStuff(A a) {
    a.protectedField = 3;
  }
}

C# Odds, Part I: “Protected” Keyword

Friday, December 28th, 2007

What is wrong with this code?

public class A {
  protected int campoProtegido;
}

public class C: A {
  public void doStuff(A a) {
    a.campoProtegido = 3;
  }
}

Actually, it won’t compile. It seems that the protected keyword only works at the instance context. So, although class C is a subtype of A, because it is a different instance than the instance of A we are trying to access, it fails at compile time in line 7. So much for encapsulation…

Any ideas besides turning the field campoProtegido public?

Nostalgia

Thursday, October 11th, 2007

If I could pick a perfect time to be born as an hacker, it would definitely be the 80’s. In 1982 Commodore and Sinclair Research Ltd. changed the world by releasing the Commodore 64 and the ZX Spectrum respectively. In 1983, Japan announced the MSX standard and further released the MSX-1 computer. In the very same year, Apple introduced the first commercial personal computer to employ a graphical user interface: Lisa. 1984 gave us the Macintosh and 1985 was the year of the Commodore Amiga and Atari ST. In just 4 years, the future of personal computers scene was set in stone.

I had contact with all these computers, either directly or indirectly. At the age of 6, my father bought me an used Philips VG8000 MSX-1, though the ZX Spectrum was much more popular among my friends. I learned BASIC at that very same age (didn’t we all?). Those were the times were hexadecimal dumps for games and applications were published in printed magazines, and people exchanged POKEs to hack through the rules of challenging games.

I can’t help but feeling nostalgic when thinking in titles like Chuckie Egg, Jet Set Willy, Dizzy, Bubble Bobble, Target Renegade, Paradise Cafe and dozens, dozens more. I can almost replay in my head the sound of tapes LOADing”", the idiosyncratic humming they made when a splash image was being shown at the beginning of a game, and that tape loading screen. So many hours I’ve spent tuning my tape loader with a screwdriver (and sometimes, almost driving me mad). Then came the AMIGA-500, Workbench, Mice, Lemmings, XCopy, AMOS, Floppy Drives, Joysticks. Years later came the Modems, BBSs, fidonet, demoscene.

Something was deeply different then; something I feel is lost forever… Something only people who lived those times can possibly understand. I’ve never since met a 10 year old who knew binary just for fun.

Now I sit in front of my laptop while writing this article. Internet is pervasive, Petabytes of information make 16Kb seem, well, insignificant. Millions of colors and pixels strike my eyes and I have more computing power in my cell phone than that clumsy machine where I learned the art of programming. And yet, to me those were truly magic times.

Beware of Singletons!

Thursday, August 9th, 2007

Finally, someone agrees with me about the subtle dangers of Singleton. Actually, I suggest everyone to read this blog “Where leading programmers explain how they find unusual and carefully designed solutions”. Their book, Beautiful Code, is now definitely on my ‘Books-To-Read’ queue.

Why learning Haskell/Python makes you a worse programmer?

Thursday, August 2nd, 2007

Recently, I’ve been having a lot of conversations with a friend of mine about meta-programming, partly due to some development we are working on, and partly due to our coming PhD. Some of the time we incur in largely (perhaps irrelevant) philosophical ruminations about programming languages.

But today, he found a rather peculiar blog-post, where the author teases the readers arguing “Why learning Haskell/Python makes you a worse programmer”.

Why learning Haskell/Python makes you a worse programmer?

The author presents two claims to defend his thesis: a) Demotivation and b) Code Obfuscation. Considering demotivation, he states that he “(…) constantly find (himself) wanting to use idioms from these languages, or noticing how much less code (he would) be able to write if (he) was using one of these languages (…)”. Further, it notes that it finds “(…) C# code very ugly compared to both Python and Haskell (…)”. The conclusion, he remarks, “is to make me very depressed and demoralised. I feel like a human compiler, translating the Haskell or Python in my head into a language which is a whole level lower.”

In what comes to code obfuscation, the author believes that because “C# has begun to get some features that are more friendly to functional style programming”, the programmer “when faced with a very common situation” tends to try a “functional solution”. Adapting this “functional solution” to a language like C#, results in “writing such complex code — using such advanced features as anonymous delegates — when a simple loop would have sufficed”. The overall conclusion is “don’t bother improving yourself, unless you have the freedom to improve your environment accordingly.”

While I tend to sympathize with the author frustrations, I believe this to be a classic example of misunderstanding about programming paradigms and languages. In fact I’ll try to summarize my arguments on “Why learning Haskell/Python makes you a *better* programmer”.

The difference between Paradigm and Syntax

First and foremost one must understand the difference between paradigm and syntax. Each different paradigm usually results in a different algorithm. Though, the same algorithm can be expressed in different syntaxes, which depends on the language one’s using to implement. The fact that a certain syntax is less ugly to a programmer implementing a certain algorithm designed in a certain paradigm qualifies the expressiveness of a language. This expressiveness is dependent on the domain’s problem and the paradigm of the solution, so different algorithms (that solve the same problem) can make the same language seem very beautiful or very ugly.

Expressiveness in Programming Languages

A common metric used to quantify the expressiveness of a language is the number of code lines needed to implement a certain algorithm. It is very common to find advocates of every language, using as arguments single-liners to convince that her/his language is the best: “just compare this one-line quick-sort implementation in X to this 30 line implementation in Y”. This makes the reader believe that X is more expressive than Y, while not noticing that the algorithm paradigm used for X is the same as the native paradigm of X, while the opposite isn’t always true (e.g. see [1] [2] and [3]).

The “other side”

It’s also amusing to see many people learning functional languages, believing they are the other side, and putting C and C# (or Java) in the same bag. Why this happens? Because people tend to learn syntaxes and not paradigms. If a language has a syntax very close to another (like C, C++ and C#), they tend to believe that the paradigm is the same. Even worse, because they find that a certain syntax in a certain language produces expressive code, they incur in the pitfall of trying to apply the same paradigm in a different language (and, surprise! that language wasn’t designed to be expressive in that paradigm). I’ve seen this problem occur over and over, especially in people that already have some programming experience; how many times I’ve seen code written in Java which is plain old C in another syntax?… These authors don’t have a clue what Object-Oriented is all about, and I doubt they also have a clue what Functional Programming or Logic Programming is about too (somehow, Prolog and the Logic Paradigm tends to be forgotten).

Which is the best?

What is the solution? In portuguese we say “Cada macaco no seu galho”, which losely translates to “To each its own”. One must understand that there are several forces to be taken account when choosing a certain language to implement a desired solution. Most of the time this are related to infrastructure features (like available frameworks and tools). But an important force (most of the time marginalized) is related to the problem’s domain; I would argue that functional languages are very expressive in what comes to mathematical defined algorithms and that I would definitely choose C to implement a device-driver (don’t confuse the choice of expressiveness with performance) and SQL to define relational queries.

The author’s mistake, in my point of view, is trying to force-fit a solution in a paradigm that is not natural to the language in question (for the author’s sake, I know that he knows this, but not everyone understand this). Just because a language has the infrastructure to deal with certain paradigms (like C# 2.0 new functional-oriented features), this doesn’t mean the necessary syntax is there to make it expressive in that same paradigm; “while in Rome be Roman”.

What can we do?

One solution for the problem of expressiveness are Domain Specific Languages (DSL). DSLs try to solve this by extending/redefining the original syntax and semantic of a language to better express solutions designed for paradigms more closely related to the problem’s domain (consider LINQ and mathematical sets) while maintaining the concepts horizontal between syntaxes (which differ from scripting or embedded interpreters). DSLs aren’t just syntactic sugar (I will argue about this on a different post).

Why learning Haskell/Python makes you a better programmer?

So why does learning other languages (especially languages that implement other paradigms) makes you a better programmer? a) Because it teaches you different points of view and b) because it gives you the best syntax and semantic for a certain domain. Learning different languages don’t necessarily make you better in other languages. It makes you better in understanding and designing new algorithms, though. But most important, it should make you feel more decoupled from implementation details and more detached from syntax.

There is an analogy that I like to apply when people ask “Is it worth it?”. Scott Ambler, in his book The Object Primer, talks about the difference between the Specialist and the Generalist. He argues that while a specialist is a “Jack-of-all-trades and a master of none”, good developers should try to be generalists, as in a “Jack-of-all-trades and a master of few”.