Right now the title reads essentially: "Here's a library".
It takes about a minute to find any information at all about this library besides the fact that it's used at Facebook (by the way, did you miss that? it's used at Facebook! Facebook!!). And even that information is empty bromides about how it's "designed with practicality and efficiency in mind". Hmm, I prefer my software to be impractical and inefficient...
All I take away from this is that Facebook has an irrationally optimistic expectation of how the world views its engineering prowess.
Right in the intro section, second paragraph, it says "It complements (as opposed to competing against) offerings such as Boost and of course std". Come on, what more do people want?
the opposite from practical is general. for example is std not practical but general. Its api is not optimized for 95% of the use cases but rather so that everything is possible and equaly verbose.
the opposite of efficient can for example be trade of for readability, portability and cost (as in development time).
For me as a possible user of the lib i found this information critical. I write always similar info in the readme for my libraries.
That said, this is an issue for other languages as well. Another example: the "Google core libraries for Java": https://github.com/google/guava
This has library contents: it’s a mix of various utilities - type conversion, data structures, memory management, random numbers, concurrency, etc.
https://github.com/facebook/folly/blob/main/folly/docs/Overv...
Writing thread-safe code isn't easy, and it isn't made easier by libraries that offer footguns like Synchronized. It's easier to get it right with compiler thread annotations than with Synchronized.
Synchronized cannot guarantee thread-safety, but in my experience wrappers that do not allow unsynchronized access to the object are better than the alternative. Annotations are just another way to guard access.
However, the API encourages practices that make it very hard to recursively acquire the lock (Synchronized is about access to objects, not critical sections).
I am also partial to explicit error handling over exceptions, and there is a lot to like about absl::Status (and absl::StatusOr).
Disclaimer: I work for Google but the views expressed are my own and don't necessarily reflect those of my employer.
Conan
Vcpkg
Cpm.cmake
A lot of projects these days use conan.
Developing in c++ vs (for example) python does seem like more work. I think it is a consequence of offering more control, which is expected in the c/c++ community.
What the two options offer.. Is different. With a higher level language, you can get more work done for less cost [1]. With a lower level language, you get more control —- which is great, but you shoulder that responsibility yourself. And you recognize this already..
If you want to move with the crowd (which the higher level abstractions are likely tailored for), then you will be able to move fast and far. When you need to exert more control, however, things get tricky.
For example managing the OpenSSL library used in your project independently of the system library?
More precisely, one that defines a datatype (no SDS-like trick) and has all goodies like SSO, CoW, views, thread-safety, etc..
I'm making such a lib but can't seem to find other examples to compare.
It's not c but almost c, it could be useful for you
[1] https://github.com/MoustaphaSaad/mn/blob/master/mn/include/m...
There are a few pure-C made STL alike containers for C that uses no c++ code at all, a random github search finds this: https://github.com/assyrianic/Harbol , there are quite a few of them just not recalling them now.
Which unfortunately means Folly is an extremely heavyweight dependency to pull in compared to Abseil, if you're not already using Boost
I understand the FB rationale to have it, but what whould be a reason for other projects to adopt this lib?
I won't imagine maintaining such a lib as a dependency by ourselves. Maybe for one short-term purpose, but then it's still safer to go with standard or boost, or, God forbid, carve out some pieces and wrap them up.
folly is a community effort within Meta; it doesn't have a specific theme about what's included in it, but it is a set of core libraries that are likely to be depended on by most C++ software within the company, and are enough high-quality and self-contained that they can be useful externally, or showcase implementations undergoing standardization efforts (for example experimental/coro for coroutines).
Main focus is server applications, but it is also used in mobile, in particular Thrift (the serialization/RPC infrastructure) depends on it.
A very personal list of favorites:
- experimental/coro is the coroutines infrastructure, which is now widely adopted.
- SharedMutex is a heavily optimized mutex which supports shared/upgrade/exclusive semantics, and allows near-linear scalability in shared mode. It is used pretty much everywhere as it is the default mutex for Synchronized, a wrapper to safely synchronize access to objects. Its footprint is just 4 bytes.
- DistributedMutex, OTOH, is an exclusive-only mutex that supports flat combining, and performs extremely well under high contention.
- MPMCQueue and UnboundedQueue are lock-free MPMC queues, respectively bounded and unbounded, which are used in almost all our thread pools (see the executor/ directory)
- Userland implementations of RCU and hazard pointers, for deferred reclamation.
- LifoSem and Baton are other fundamental synchronization primitives that are not available in most core C++ libraries. They do a magic trick internally, where if they're waiting long enough, they unmap the unused suffix of the stack, so idle threads don't hold unused stack memory.
- Function is like std::function, but move-only, so it can hold non-copyable function objects (think lambda that captures unique_ptr). It is the vocabulary type for callbacks used in futures and executors.
- F14 is a SIMD-optimized hash table. Similar to Abseil's SwissTable, it was published around the same time.
- TDigest is a highly scalable quantile estimator, widely used for service counters (see fb303, also open source).
- (shameless plug, as I wrote this one) enumerate() is a replica of the Python function, so you can do
for (auto&& [i, element] : folly::enumerate(collection)) { ... }
However, I did have decent success taking the classes I was interested in (CPUThreadPoolExecutor, and surrounding), stripping the library down to just those bits, and using them. Obviously a PITA to stay current with upstream, though.
If nothing else, it's worth reading for some of the highly-optimized stuff going on in there.
folly [https://www.wordnik.com/words/folly]
fŏl′ē
noun
Lack of good sense, understanding, or foresight.
An act or instance of foolishness.
A costly undertaking having an absurd or ruinous outcome.
At the risk of starting a meta conversation (pun intended) I wonder why the team chose this name for a set of core library components. The GitHub page indicates it is a loose play on an acronym. “acronymed loosely after Facebook Open Source Library”
Yet why accept a name with a negative connotation.. The name leads the product, so why not at least make it _neutral_?