Is there a C ++ library similar / equivalent to functional Java?

Are there open source C ++ libraries that are similar or equivalent to the excellent functional Java library ?

Features include:

  • display, reset / decrease, filter, etc. at iterations, etc.
  • type of option
  • immutable data structure implementations

(asked out of curiosity, once away from C ++)

Yes, some of these features are traditionally considered necessary for garbage collection. But with modern C ++ functions and libraries, did anyone start passing managed pointers through functional conversions or something else?

UPDATE To be clear, I am interested in something similar to functional Java, so the following might be the typical syntax:

// assumptions: // * my_list is a standard library iterable of ints // * f is a function of int that returns a std::string // * p is a predicate of std::string returning bool // * head_opt returns an option type stream(my_list).map(f).filter(p).head_opt.get_or_else("None") 

This is the idiom that functional Java offers, and I find it very easy to get used to it ...

+4
source share
3 answers

As @jalf said the map and fold are already in the standard, hidden behind different names:

  • map -> std::transform found in the <algorithm> header
  • fold -> std::accumulate , found in the <numeric> header

In Boost.Range, you can find more functional things that are a pretty amazing library. Especially range adapters give a real functional feel, as they create views across other ranges. With C ++ 11, possible predicates are also easy to create on the fly through lambdas.

Boost.Optional may be your "option", depending on what exactly you mean.

Inevitability in C ++ can be achieved by simply declaring your const object. You can avoid copying by passing arguments by reference. In truth, this, of course, is not equivalent to true functional immutability, since immutable containers in functional languages ​​can be copied, but you want, and usually just share the internal representation. After all, copying to recording is awesome if you never write.

On your managed pointers, I had no idea what you mean by them. In C ++, you usually don't need pointers or objects with dynamic allocation. Just create them on the stack: Foo obj; .

If you mean co-ownership, there is std::shared_ptr . There is even a good range adapter there if you store such a pointer in a container:

 #include <boost/range/adaptor/indirected.hpp> #include <boost/range/algorithm/generate.hpp> #include <boost/range/algorithm/copy.hpp> #include <vector> #include <memory> #include <algorithm> #include <iterator> #include <iostream> int main(){ std::vector<std::shared_ptr<int>> v(5); int i = 0; boost::generate(v, [&i]{ return std::make_shared<int>(i++); }); boost::copy(v | boost::adaptors::indirected, std::ostream_iterator<int>(std::cout)); } 

Your concrete example

my_list.map(f).filter(p).head_opt.get_or_else("not found")

can be implemented as follows (note that std::vector is the default container in C ++):

 // Warning, C++11 only! // Boost.Range doesn't like lambdas without this: #define BOOST_RESULT_OF_USE_DECLTYPE #include <vector> #include <string> #include <iterator> #include <iostream> #include <boost/optional.hpp> #include <boost/range/adaptor/filtered.hpp> #include <boost/range/adaptor/transformed.hpp> #include <boost/range/algorithm/generate.hpp> // only needed for filling the vector #include <boost/range/algorithm/copy.hpp> // only needed for printing // we need a little helper for the optional stuff struct head_opt_gen{} head_opt; // just a tag type template<class Range> auto operator|(Range const& r, head_opt_gen) -> boost::optional<decltype(r.front())> { if(r.empty()) return boost::none; return r.front(); } int main(){ using namespace boost::adaptors; std::vector<int> v(5); int i = 0; boost::generate(v, [&]()->int{ ++i; return i*i; }); // first, without the optional stuff boost::copy(v | transformed([](int x){ return std::to_string(x); }) | filtered([](std::string const& s){ return s.size() > 1; }), std::ostream_iterator<std::string>(std::cout, "\n")); std::cout << "=====================\n"; // now with std::cout << boost::get_optional_value_or( v | transformed([](int x){ return std::to_string(x); }) | filtered([](std::string const& s){ return s.size() > 2; }) // note: > 2 | head_opt, "none"); } 

Compiled using the Clang 3.1 trunk, this leads to the following output:

 16 25 ===================== none 
+8
source

I don't think there are libraries that explicitly contain immutable data structures. Although no one is stopping you from simply changing data structures outside of certain contexts.

But you can build part of what you want from Boost.Range . It has powerful range-based designs, filtering, etc. However, you will have to deal with memory management.


It seems your question is: "Is there a C ++ library that accurately implements the behavior of strict functional programming constructs?" The answer is no. As far as I know, there is no C ++ library, which has as its main objective the explicit and direct implementation of strict functional programming constructs. C ++ is ultimately not a functional language.

There are many approximations of various functional designs. But there is no library that implements them exactly in accordance with the rules of strict functional programming.

+2
source

FC ++ seems to be an older library (the 2001s, the last changed in 2007 to SourceForge ), offering some functional programming functions in C ++.

Hmmm, FC ++ was introduced as a potential Boost library in 2003 ?

Elsewhere in StackOverflow, the main developer of FC ++ indicated that modern C ++ and Boost supplanted some of the uses of FC ++, but others are not yet available in the modern C ++ library?

It also seems that someone has come up with writing README for the github project , which describes, in essence, what I requested, but apparently did not get any further participation in the project.

Hope this helps someone ...

+1
source

Source: https://habr.com/ru/post/1398314/


All Articles