Type composition and mutation library

Started by
4 comments, last by frob 10 years, 2 months ago

Hi,

I'm still gathering interest, comments, questions, suggestions and reviews for a library I'm developing.

It basically allows you dynamic type composition and mutation in C++. It's called Boost.Mixin (it's for boost, but not part of boost yet) and it's vaguely similar to Ruby's mixins.

Code is here: https://github.com/iboB/boost.mixin
Docs are here: http://ibob.github.io/boost.mixin/

There has been a forum topic on the subject before here but it failed to generate much interest. Hopefully I'll get more this time :)

It's only when you look at ants with a magnifying glass on a sunny day, that you realise just how often they burst into flames.

Advertisement

I've read through the docs and through portions of the code.

Maybe there is something there, but I'm just not seeing it.

As your docs point out, it provides an alternative way to do something the language already does.

You can already do this through virtual functions, function pointers, and similar methods. If those are too slow or too bulky, you are correct that can use the CRTP. That makes it less bulky and also removes virtual dispatch. If those don't work, the language offers RTTI functionality and there are multiple existing reflection-style libraries that you can rely on.

This seems to take the overhead of reflection, the indirection of std::function<>, and the bulk of nearly empty fixed-length arrays, all of it with a run time cost rather than compile time cost.

I really don't see what actual problems this solves. The examples in your documentation were not really compelling.

I want to give you the benefit of the doubt. What actual real-world problem has this solved? What are some actual use examples in live, shipping, production code?

Er, the language doesn't do runtime type composition or mutation.

The CRTP type type composition is static and doesn't give you polymorphism on its own.

The runtime cost Boost.Mixin adds can only matter in very performance intensive scenarios which would suffer from any type of polymorphism. The fact that the a use case in the library is a couple of nanoseconds slower than a similar case with virtual calls or std::function, is negligible.

It solves the classic composition vs inheritance problem with none of their shortcomings - like coupling and excessive dependencies, combinatorial explosion of types, multiple points for change.

Internally instead of keeping the object type information stored per object, it has type info instances that the objects point to. In huge systems, the memory saved by such an approach may be significant.

It doesn't bind the concept of interface to a class, allowing you to have classes that are responsible for multiple interfaces, parts of an interface, or parts of multiple interfaces.

It allows you to very easily create optional dynamic library plugins for your software that change the behavior of your objects.

I also gives you multicast messages, which is a whole new way of thinking about polymorphism. It is a bit like signals, but it's per object. An example of a multicast message could be something like getRenderingParts. A function the engine calls after it has determined which objects are to be rendered in this frame. In most objects this message would be handled by Model (static geometry), AnimatedModel, and such. Now there comes the moment where you need to add quests and some characters need to visually indicate that they are quest givers. With this multicast message we have no problems. We introduce the mixins QuestGiver or InteractiveObject and they start supplying the rendering system with the appropriate data. Then we need to create auras or buff/debuff indications. Again, no problem. We add a mixin called RPGEffects to an object that can have such, and it seamlessly continues to work appropriately.

It gives you mutation rules - which can be used to "translate" a type into another type. This may be beneficial if you have a client-server architecture, where the objects exist in parallel. With a mutation rule, you can easily translate a client type to a server type (removing rendering mixins, adding database storage ones) and vice versa.

It's only when you look at ants with a magnifying glass on a sunny day, that you realise just how often they burst into flames.

I guess I'm still having a hard time seeing it. Maybe it is just too many years of doing things under the existing patterns.

Has it been used in any actual professional code? The Boost people like that.

I am working, along with 3 other programmers, on a closed source project - a 2d tactics mobile game that's still under development - with it and, having met no problems using it (performance or design), it has proved useful many times in defining the game's logic. The code is clean and readable. Making changes (even rare big ones) is easy and concentrated, and one of the main bonuses is that you can very easily temporarily disable or change entire parts of the game for testing.

For example having all attacks deal 1 damage is literally 1 line of code with 1 file being recompiled after the change. This is useful when you only want to see the visualization of the attacks and not worry about units dying.

Disabling the graphics is, again, 1 line of code. The battle simulation tool, which simulates many battles with no visualization for balancing purposes, is the game executable with a special command line parameter.

Adding a new type of unit is really easy. The game wasn't supposed to have flying units, but when it was decided that we need to add such, it took 1 programmer only a couple of hours to add them (and this was relatively late in the development). Having the functionality that concerns one feature to be concentrated in one physical location in the code is really helpful, and the library makes this very easy.

As a whole, we're quite happy with Boost.Mixin.

I intend to create a simple open source RPG game when I have more time (probably after June this year) mainly to serve as a demo project for the library (and with less focus in the art, story-line and balance).

As for what the boost people think of it, I'm not sure. Most of the feedback I've had so far has been positive. But it's been, surprisingly, very little.

I've had 6 people respond to my boost mailing lists posts with positive initial impressions. Throughout various forums including this one I've had about 10 other people with feedback with only two who had a negative one, including yours. I had a presentation of the library in Bulgaria on Open Fest 2013 (November), and the response from the audience has been positive. I have some early adopters who use it in some pet projects and who, for now, seem to be satisfied. Also, as you can see, it has more than 20 stars in GitHub.

Still most people just ignore it, it seems. Compared with other new libraries and ideas in the Boost mailing list, this one is fairing rather poorly in the quantity of comments, but fantastically in comment quality as there are no negative ones. Quite strange actually smile.png

It's only when you look at ants with a magnifying glass on a sunny day, that you realise just how often they burst into flames.


Still most people just ignore it, it seems. Compared with other new libraries and ideas in the Boost mailing list, this one is fairing rather poorly in the quantity of comments, but fantastically in comment quality as there are no negative ones. Quite strange actually smile.png

I can understand why.

Most of the things in Boost have a very clear need. When I go through the list of boost libs they have a name and a single-sentence description. From that single line description I can almost instantly imagine a case where the library would be useful. I can easily imagine them as the software equivalent of precut lumber or prefab wall panels. These are things that people regularly do at thousands of businesses on a daily basis.

This one, though, mimics many existing ways to accomplish very similar behavior. One glance at the library's summary early in the thread and I came up with five frequently-encountered alternatives. Maybe it is just the naming or a weakly-worded description. I see the two and I don't immediately imagine places I can apply the library.

The lack of bad comments is encouraging. From what I saw nothing immediately jumped out as being wrong. There were some questionable but easily changed things like the fixed sizes provided by config.hpp constants for so many things, and the abundant use of macros, but it isn't strictly wrong.

It is an interesting solution. It has some potential, and I readily admit it could be useful to some people's problems.

So while I want to be encouraging, my result is mostly mildness. It is a solution to something, and the fact that there are many frequently-encountered alternatives does mean there is potential for standardization. Maybe we are looking at the next prefabricated wood floor, both providing an unexpected opportunity and solving a problem most people didn't know they had. I don't see anything wrong with the solution, but nothing about it makes me personally jump for joy, shouting "That is exactly the solution I need!".

Maybe someone else sees it as a fit to their game?

This topic is closed to new replies.

Advertisement