Personally I think it’s a great response and very well written. I didn’t jump on the congrats-Databricks wagon when the result first came out because of the weird front page comparison against snowflake. Both companies are doing great work. Focusing on building a better product for your customer is much more meaningful than making your competitor look bad.
To understand how they are different, you need to know Default Initialization, Direct List Initialization, Aggregate Initialization, Default Member Initialization, List Initialization, Value Initialization, Zero Initialization. https://blog.the-pans.com/cpp-initialization/
It does, which one can argue it’s an implementation detail. The differences I mentioned above eg sharding, transaction boundary, secondary indices, etc. should be generally applicable to a non-relational db and not unique to TAO. I could be wrong though; as I know little about other graph dbs.
It would probably be more productive to compare RDB and Graph with certain workload examples (OLTP, OLAP, joins, scans, etc.).
This is a great topic. I have been working on TAO for many years. I am not very familiar with other graph databases; I assume fundamentally they are more or less the same. Here are some differences between RDB and a graph db IMHO,
1. sharding and transaction boundary
2. Secondary index support
3. How “join” works (eg. give me a list of my friends who follows Justin Bieber)
You’re right that graph db is very easy to use a lot of the times.
The tweet is certainly loaded, hence the point of this HN post lol.
First of all there's std::function, which uses Type Erasure https://blog.the-pans.com/type-erasure/. It means std::function<void(int)> can be the type of anything callable that takes an int and returns void (lambda, function pointer, object with operator() overload, etc.). Notice they are of different types! Hence Type Erasure.
How std::function manages its memory is poorly specified. But the standard at least states that if it's initialized from a function pointer (free, no capture), it's guaranteed that it won't allocate. https://en.cppreference.com/w/cpp/utility/functional/functio...
> When the target is a function pointer or a std::reference_wrapper, small object optimization is guaranteed, that is, these targets are always directly stored inside the std::function object, no dynamic allocation takes place.
In this case, std::function is trivially copyable. However, there's no way to know this at compile time, exactly because the type is erased in std::function.
Well if this is an improvement or not depends on the use case. E.g. std::function does exactly this.
What it achieves is exactly erasing the type (conforming to an affordance). The cost is definitely there. You pay vtable lookup when using std::function.