Learn other languages. It will broaden your perspective and hopefully make you a better developer.
Alan Perlis, one of the developers of ALGOL, once said, “A language that doesn't affect the way you think about programming, is not worth knowing.”
Conversely, that implies learning other languages can and will affect the way you think about programming, provided you get some variety of exposure.
C++ is a multiparadigm language. But if you haven't had exposure to those paradigms in a more focused setting, you might not understand the value they bring, or their strengths, weaknesses, idioms, and insights.
So even if you do the bulk of your programming in C++, you may not be using it the most effective way possible.
I know I personally have gaps, because I haven't explored certain paradigms myself. I owe it to myself to at least dip my toe in some of them. I know this, because every time I learn a new language or environment, I sense a gap closing—a gap I may not have been aware of previously.
You don't even need to spend a lot of time to gain value, either. I may have only spent a week with Scala, for example, but I learned more than just the base language from it. I hadn't really encountered fold and match expressions as such basic and integral concepts, for example.
And despite its negative reputation, I found Perl to be an excellent language to learn about multiple programming techniques.
Mark Jason Dominus' Higher Order Perl opened my eyes a number of techniques that I believe originated more from the LISP world.
Example: Partial Function Application
In Perl, you can implement partial function application (sometimes conflated with the related concept currying) with you eyes closed and one hand behind your back. Suppose I want to bind the first argument of foo()
:
- my $f = sub { return foo(arg1, @_); };
Now I can invoke $f
as a function with that first argument bound, with a slight syntax tweak: &$f(…)
or $f->(…)
. I don't even need to think about the rest.
Trying to learn about that for the first time in C++ likely would have lost the forest for the trees.
C++98 was quite primitive. It offered std::bind1st
and std::bind2nd
for 2-argument function objects only. Boost offered boost::bind
,
std::forward
. And then there's object lifetimes to consider, so for your bound arguments you might need to trade off between copy, move, capturing a reference, smart pointers, etc. Oh, and finally, it won't yield a function pointer, but rather an function object, so it's not usable in places that need a pure function pointer. Although, if it manages to be captureless, it can provide a pure function pointer by applying unary +
to it… Can you see how you might lose the forest for the trees here?
If you didn't already have some idea of the usefulness of partial application, would you even try? If you hadn't encountered the concept before, would it have even come to mind when you saw lambdas?
Punchline
In practice, if you're already well versed in C++, it's not actually all that difficult to implement techniques like partial application in C++. You're already accustomed to the rigamarole described above, since C++ confronts you with those sorts of decisions regularly.
It does cloud things noticeably, however. Learning the concepts in a simpler environment separates you from the implementation noise.
Learn other languages and become a more rounded and hopefully better developer. Step away from C++'s innumerable trees of details to see different areas of the forest more clearly.
Footnotes