I have been learning some Ruby recently and I had the following experience. I had written a small tool of about 200 lines of code and, as an inexperienced Ruby programmer, I had used several loops to build arrays from other arrays. E.g.

gs = ... # Some array of input data.
l  = gs.size
i  = 0
r  = Array.new
while (i < l) do
if (cond(gs[i]))
r.push(gs[i])
end
i = i + 1
end

# r contains the result now.


Then I discovered that I can do it in a functional style:

gs = ... # Some array
r  = gs.select { |g| cond(g) }

# r contains the result now.


So I immediately replaced most of my loops in the code with constructs like each, select, take_while, drop_while, and so on. I have decided to use a functional style in Ruby whenever possible and try to avoid an imperative style.

As another example, in C++ I tend to use classes and methods everywhere and use functions only for small utility tasks that are private to the implementation of some class. So I tend to think object-oriented when working in C++ and avoid a procedural style almost completely.

More in general, when working on a given project in a given language, I tend to pick one paradigm and stick to it throughout the project: I find this makes my code more uniform, easier to read and to debug, which, IMO, is very important, especially for production code.

Yet, I often think that maybe I should explore more and try out different possibilities offered by a language, e.g. use different paradigms and try out different solutions. For me this involves some overhead both while coding (should I make it procedural or object-oriented? imperative or functional?) and when reviewing or debugging code (what did I want to do here?) because of the increased complexity.

So my question is: do you also tend to select a preferred programming paradigm when coding and stick to it, or do you tend to explore more and mix different paradigms?

If you mix different paradigms, do you have the feeling that there is some overhead in terms of how fast you can write and debug code (added complexity, switching between different mindsets) or is it just a matter of learning how to do it and then you can even be more productive?

Or do you mix different paradigms in a more structured way, e.g. you apply each paradigm to a specific class of problems (e.g. functional for queries, object-oriented for architectural aspects, and so on)?

• My question is about how to use different paradigms or programming styles within a project in a organized, coherent way. This is an issue that I see often both in projects on which I work alone and in projects I work on in a team. Finding a simple and uniform design and coding style is also a frequent topic of discussion within my team. I see a close-vote: I can try to improve the question if I can have some hint. – Giorgio Apr 22 '12 at 15:42

do you also tend to select a preferred programming paradigm when coding and stick to it, or do you tend to explore more and mix different paradigms?

• Constantly exploring alternative solutions makes you a better programmer. You must be aware of available tools, it doesn't mean that you have to use them each time.

• Mixing paradigms is fine as long as it doesn't have a negative impact on quality of your code.

If you mix different paradigms, do you have the feeling that there is some overhead in terms of how fast you can write and debug code (added complexity, switching between different mindsets) or is it just a matter of learning how to do it and then you can even be more productive?

• If this is your project and nobody else will work on it, then it's absolutely fine. It might cost you later, but the good thing is that it won't affect anybody else.

• Generally, I think that teams will try not to use multi-paradigm as it is likely to have a negative impact on team's productivity. On other hand, experimenting, such as going from one paradigm to another is a great way to learn.

Or do you mix different paradigms in a more structured way, e.g. you apply each paradigm to a specific class of problems (e.g. functional for queries, object-oriented for architectural aspects, and so on)?

• No matter what you do, you need to plan for it and think what effect it might have in future. Therefore, yes, whatever you decide to do, it must be structured and planned for.

• My team has agreed on code guidelines and we have always been using these guidelines with very little if any paradigm-shifts. We also have tools that enforce these guidelines. In your specific example, ReSharper would suggest us to convert a foreach statement into a more readable LINQ statement.

To summarise, I think that exploring paradigm-shifts is a great way to learn, but it should be strictly controlled in a work environment.

• +1. Thanks for the information. I will take a look at ReSharper: I did not know of tools for checking complex style rules, seems quite powerful! Of course I experiment a lot with different styles, but try to keep the experimentation out of production code and to keep the style uniform within one project, especially if working in a team. We also have coding guidelines, which we enforce with code reviews. We had long discussions about what should be included in the guidelines and what should be left to the free choice of each developer. – Giorgio Apr 22 '12 at 18:41
• These tools are great. ReSharper gives you basic suggestions. StyleCop is much more configurable regarding code guidelines. There is also NDepend which analyses how tightly coupled your code is. More information can be found in the books on continuous integration - these tools are normally used as part of a build pipeline. – CodeART Apr 22 '12 at 18:47
• Another team in my company does use Style Cop. I did not know that it can go as far as suggesting to replace a while loop with a LINQ statement, it seems a quite complex refactoring to me! – Giorgio Apr 22 '12 at 18:49
• Suggestion to refactor foreach loop into LINQ statement is done by ReSharper. StyleCop just checks whether you have violated any guidelines. Sorry, I should have made this clearer. – CodeART Apr 22 '12 at 18:52
• OK, thanks. I have just found out that a similar tool exists for Java (IntelliJ IDEA). I am going to look what I can find about C++ (our team works in C++). – Giorgio Apr 22 '12 at 18:56

I tend to think less in "paradigms" and more in terms of using the most appropriate (i.e. - simple, readable and maintainable) tool for the job. I don't believe in sticking rigidly to paradigms because I feel that often results in going out of your way to write code in a certain manner just for the sake of adhereing to the "rules". However it's certainly good to learn many different techniques for using your chosen language (and learning different languages can often open your eyes up to brand new ideas which perhaps you'd not have considered before)

for example, a "pure" OO approach is to wrap everything as an object; sometimes that's appropriate if you're writing a framework full of reusable components, but for a simple specific problem, the end result of doing that might just be unwieldy, bloated and over-complicated.

Likewise, a "pure" functional programming approach implies strict conditions of lazy evaluation - using completely stateless function-objects everywhere - this is simply impractical for 99% of problems, but the style of passing functions around can sometimes result in some very elegant and simple solutions.

in C++ (my main language), for example - I find that passing functionoids around can help build very clean code when dealing with situations which might otherwise be solved by passing references to objects everywhere (e.g. the standard library containers/algorithms, and for anything event-driven), but there's very often some kind of state associated with those functionoids so it doesn't truly qualify as being "functional".

At the same time, C++ templates can be used for interface-driven programming - templates are typically part of the generic programming paradigm, but I find myself using them as a way of handling compile-time Dependency Injection (a.k.a "Policy Based" classes), with the result being a fairly loosely coupled generic-OO hybrid allowing very easy unit testing.

This all varies between languages - I'm fully aware that C# programmers do not achieve Dependency Injection via generics (even though generics are the closest equivalent to templates), but that's because C# has a totally different set of rules - so again, it comes down to the most appropriate language tool instead of sticking to a paradigm. One of the reasons a lot of general-purpose languages are usually labelled "multi paradigm" is the fact that people who use those languages tend to avoid ideology and aim for solutions using a wide variety of different tools.

• +1 - Thanks for the answer. My question did not intend to ideologically defend purity in the sense of using only one paradigm throughout a project: e.g. I also use templates in C++ along with object-oriented features. My issue is the cognitive overhead of using different styles within the same project (understanding, debugging code written in different styles). This is a topic I often debate with colleagues (I work in a C++ project with about 50 developers and > 500000 lines of code). From your answer I seem to understand that this is not an issue, given enough experience with a language. – Giorgio Apr 22 '12 at 16:23

As in your example, I think each language pushes you towards a particular paradigm. If you're smart, you'll figure out how the language wants you to solve the problem and either do it that way or abandon the language. I suppose some languages are a bit more neutral. I found C could be bent in any direction, but it was a lot of work. If I'd stuck with it a couple more years, I'd have written my own garbage collector for it.

Currently, I split my time between C# and Java. To, say, a C++ programmer, these two langauges must look almost identical, but I find I write very differently in each. I have trouble saying why.

Most languages, however, have obvious differences--in the type of data they are intended to handle--in their tradeoffs between performance, ease of programming, hardware needs, etc. Hence their paradigm differences are obvious and understandable--and even predictable.