There seem to be 3 ways you can make a library that works with data structures inside.
Functional
You have no classes.
Pros: Data structure can be stable. You don’t have to use pre and post_upgrade.
Cons: You have to provide types and auxiliary functions when using it. Example:
BTree.insert<Text, Blob>(mystore, Text.compare, key, val)
Class
You use classes.
Pros: You have easy-to-use syntax. Example:
mystore.insert(key, val);
Cons: They can’t be stable. You have to upgrade using pre and post_upgrade
Class+
You have a class that accepts memory from outside.
Pros: You can make it stable. You have easy-to-use syntax. Example:
mystore.insert(key, val);
Cons: If you have nested structures (BTree inside BTree) this will bring overhead, so you should use the functional style if you want to spend fewer cycles. But that’s a rare case.
How to transform Class into Class+
Before:
After:
Usage:
stable let some_stored = MyLib.init<Text>();
let some = MyLib.Class(?some_stored, Text.hash)
// then inside functions...
some.put(key, val);
You can also use it without the stable memory coming from outside
let my = MyLib.Class(null, Text.hash);
my.put(key, val);
Your Class is not losing any of its capabilities and doesn’t get less performant (correct me if I am wrong), but gains the ability to be stable. This is the typical case when you use it in the body of your actor. If you don’t instantiate new classes in a loop (which you may do if you have nested structures) then you will not lose significant performance. Otherwise, you are creating a lot of objects with a bunch of functions and then leaving them to be garbage collected.
It’s probably not news for many, but I wanted to put it here because only ~10% of the libraries use Class+
If you think there are some disadvantages to this, let me know @claudio @timo @skilesare
Who is using Class+ (probably there are more)
https://github.com/nomeata/ic-certification by @nomeata
https://mops.one/certified-http and https://mops.one/rxmodb by me
The base libraries: TrieMap, HashMap, Buffer, RBTree can be converted to Class+ with few lines of code, but you may not want to do that for backward compatibility reasons.