list->init(); → list->init(list);
list.init(); → list.init(&list);
[1] https://sentido-labs.com/en/library/cedro/202106171400/#back...I normally avoid the function pointer overhead, which can be done with _Generic:
#define append(VEC, START, END) _Generic((VEC), \
Vec_float*: append_Vec_float, \
Vec_str*: append_Vec_str, \
Vec_cstr*: append_Vec_cstr \
)(VEC, START, END)
https://sentido-labs.com/en/library/cedro/202106171400/#loop...But list->init(list) might be a simpler solution for most cases, and compatible with C89/C99.
git clone -b self https://github.com/Sentido-Labs/cedro.git
cd cedro
make bin/cedro # Just “make” will build cedrocc etc.
bin/cedro - <<' EOF' # Mind the indentation.
#pragma Cedro 1.0 self
list->init();
list.init();
list->append(123);
list.append(123);
EOF
The “self” flag after “#pragma Cedro 1.0” activates the “self” macro, because it should not be done by default.Result:
list->init(list);
list.init(&list);
list->append(list, 123);
list.append(&list, 123);
I’ll try it out for a few days and if it works well in practice I’ll document it and merge it into master.You followed the path of C++.
To some extent yes, I know about cfront.
This is just another iteration on that old idea.
Which is fine! Should be interesting.
> using a function pointer has unnecessary overhead
This is true, it's inefficient. But for a lot of application, also irrelevant at performance level, and would provide a good abstraction.
Traits are like interfaces in OOP languages (simplified), the equivalent of a class would be a struct + all the impls of that struct. And that thing cannot be extends, a struct is fixed when defined and nobody can extend it, you can use composition that is the correct to me way to go.
Traits describe the methods implemented, and you can override with specific implementations or inherit the default, from a level up.
It got a bad reputation because it was abused. Bad practice is using inheritance when a tuple or a map would suffice.
Inheritance (from implementation, I've nothing against implementation of interfaces or inheritance from abstract base classes) has a ton of problems, more importantly the fact that it makes the code more difficult to understand and to evolve.
Composition on the other hand is something more natural, even if we think about real life: you don't usually take an object and "extend" it, you take multiple object and use them together to build something!
I don't know why we need to be so judgmental about it.
I think inheritance is especially good if you have an interface (in the OO sense, like some languages use an "interface" keyword for), but you have some common or default methods, which a specific implementation may or may not override, or maybe there is some boiler plate or tedium where the most common implementation might belong in a base class. I think this is handy for something like a device driver.
> has a ton of problems
this may be a good reference with examples (and some good dose of nuance) on the subject:https://blog.gougousis.net/oop-inheritance-what-when-and-why...
Right... There is an animal in a dog.
You can do this structure in C, but more common is the struct of function pointers which avoids a level of indirection at the cost of object size.
And how do you for example, create an array of objects, like one can easily do in c++?