I'm evaluating binding a C++ project of mine in Erlang. My project uses templates and method overloading massively, so it's not uncommon to have something like this:
template <typename T, class Iterator = BufferIterator<T> >
class Buffer
{
public:
[...]
private:
[...]
};
I've heard that the computational model in Erlang is a bit different from "traditional" programming languages. In Erlang a node seems to be a first class component with messages that flows from a Node from another. In this scenario, is possible, for example: "This is a list of int. Send it to the C++ node, which will convert it into a Buffer<int> object, perform some operations on it, and them convert back the result into a new Erlang list"?
I've seen on the web some project like tinch++, it seems promising but not stable at all.
Every kind of tips, link or code snippet would be very appriciated.
Thanks in advance, A.
See the Interoperability Tutorial.
For interfacing with C and C++, you don't need to create a node. Port drivers or NIFs (natively implemented functions) may be a better choice. At any rate, your C++ node/port driver/NIF will receive messages/arguments from Erlang as a specific data structure: ETERM, ErlDrvTerm, or ERL_NIF_TERM. Then you check what the term looks like (e.g. if it's a list of ints), and can convert it to whatever you need.
Related
I now this is bit weird title but I hope you will understand what I am asking about. Few months back I worked on Interpreter program in python and that was kind of great but now I want to implement same in C++ but doing so is offering great problems to me as C++ is type strict.
Lets start of from what I did in my python program. First I created a Lexer that would separate everything into tokens (key-value pair) and I wrote a Parser which will convert a arithmetic grammar into Operation Nodes as BinaryOpNode, UnaryOpNode, and NumberNode. ex- (-2+7)^3 will be converted into AST as a Binary Node having left node as another Binary Node, operator as POW(power) and right node as Number node of 3. Left Node of this node is Binary Node whose Left Node is Unary Node (MINUS and a Number Node 2), opeartor as PLUS and Right Node as Number Node 7.
I did this by identifying expression, term and factor. I have wrote a Lexer in C++ but having problem in Parser. Please help me to do same in C++.
What I have done so Far??
I tried something weird but kind of working. I created a class BinaryOpNode with two void* members for Right and left Node, A Enum member for operation between Rt and Lt node. Now two another boolean members for both nodes which would help to now what type of void* Lt and Rt are? Are they UnaryOpNode or BinaryOpNode(default). This will help me to typecast the Node into respective types.
However I am not satisfied with my results as they look like less optimized and also I can't keep track of NumberNode this way.
Please Help me. THANKS IN ADVANCE
What you are looking for is polymorphism. That is, code that a programmer writes, and does different things depending on the types of the things it operates on.
C++ supports a bewildering array of ways to do polymorphism.
The most supported kind is inheritance based virtual polymorphism. In this, you create a base class:
struct INode {
virtual ~INode() {}
};
and add in common operations to it, making those common operations pure-virtual:
struct INode {
virtual ~INode() {}
virtual std::vector<INode*> GetChildren() const = 0;
};
This requires that you work with pointers instead of object instances.
In this system, if you know the type of an object, you can use dynamic_cast<RealType*>(iNodePointer) to get a pointer to the object as an instance of that type. It returns nullptr if the types don't match. This lets you access the methods you have in the descended type that aren't in the base interface.
A second kind of polymorphism is std::variant based. This is a closed set of types, which parsers often have.
using AnyNode = std::variant<Node::BinaryOp, Node::UnaryOp, Node::Number>;
here you use std::visit to operate on the concrete type instead of dynamic_cast, and your parse tree is value-based instead of pointer-based.
There is some pain when you want a node to have inside itself a vector of AnyNode.
A third way is std::function type-erasure style. Here you write your own polymorphic system that takes objects of arbitrary type and wraps their operations up in a value-semantics wrapper.
A forth option is CRTP static polymorphism. This isn't suitable to build a dynamic parse tree, but it can be used to help implement some of the above.
A fifth option is aspect oriented std::function operation bundles.
A sixth option is manual function table tweaking, basically reimplementing the C++ vtable solution manually as if you are in C, but in C++. This can permit you to have features similar to other OO-languages.
A seventh option is to write up a signals-slots system and send messages to your objects.
There are almost certainly more.
The easiest solution is probably to first learn about inheritance and virtual functions in C++ (the first option above). I personally would probably write a parse tree using std::variant at this point, but if you probably don't know enough C++ at this point to practically do that.
I'm looking for a data structure which behaves similar to boost::property_tree but (optionally) leaves the get/set implementation for each value item to the developer.
You should be able to do something like this:
std::function<int(void)> f_foo = ...;
my_property_tree tree;
tree.register<int>("some.path.to.key", f_foo);
auto v1 = tree.get<int>("some.path.to.key"); // <-- calls f_foo
auto v2 = tree.get<int>("some.other.path"); // <-- some fallback or throws exception
I guess you could abuse property_tree for this but I haven't looked into the implementation yet and I would have a bad feeling about this unless I knew that this is an intended use case.
Writing a class that handles requests like val = tree.get("some.path.to.key") by calling a provided function doesn't look too hard in the first place but I can imagine a lot of special cases which would make this quite a bulky library.
Some extra features might be:
subtree-handling: not only handle terminal keys but forward certain subtrees to separate implementations. E.g.
tree.register("some.path.config", some_handler);
// calls some_handler.get<int>("network.hostname")
v = tree.get<int>("some.path.config.network.hostname");
search among values / keys
automatic type casting (like in boost::property_tree)
"path overloading", e.g. defaulting to a property_tree-implementation for paths without registered callback.
Is there a library that comes close to what I'm looking for? Has anyone made experiences with using boost::property_tree for this purpose? (E.g. by subclassing or putting special objects into the tree like described here)
After years of coding my own container classes I ended up just adopting QVariantMap. This way it pretty much behaves (and is as flexible as) python. Just one interface. Not for performance code though.
If you care to know, I really caved in for Qt as my de facto STL because:
Industry standard - used even in avionics and satellite software
It has been around for decades with little interface change (think about long term support)
It has excellent performance, awesome documentation and enormous user base.
Extensive feature set, way beyond the STL
Would an std::map do the job you are interested in?
Have you tried this approach?
I don't quite understand what you are trying to do. So please provide a domain example.
Cheers.
I have some home-cooked code that lets you register custom callbacks for each type in GitHub. It is quite basic and still missing most of the features you would like to have. I'm working on the second version, though. I'm finishing a helper structure that will do most of the job of making callbacks. Tell me if you're interested. Also, you could implement some of those features yourself, as the code to register callbacks is already done. It shouldn't be so difficult.
Using only provided data structures:
First, getters and setters are not native features to c++ you need to call the method one way or another. To make such behaviour occur you can overload assignment operator. I assume you also want to store POD data in your data structure as well.
So without knowing the type of the data you're "get"ting, the only option I can think of is to use boost::variant. But still, you have some overloading to do, and you need at least one assignment.
You can check out the documentation. It's pretty straight-forward and easy to understand.
http://www.boost.org/doc/libs/1_61_0/doc/html/variant/tutorial.html
Making your own data structures:
Alternatively, as Dani mentioned, you can come up with your own implementation and keep a register of overloaded methods and so on.
Best
The standard method of creating a new element type in plugin is gobject-style "derivation" from GstElement type with all this gobject magic, like this.
I'm writting a project in C++ which use GStreamer with some elements specialized for my purpose. I've written several plugins in the way mentioned above, but I'm not satisfied with the code, since too much of it is just to met gobject requirements.
I consider using gstreamermm. Is it possible to create a new type of elements with C++-style derivation from Gst::Element? I mean something like:
class MyElement: public Gst::Element
{
...
}
It would be much prettier solution (assuming I'm already using gstreamermm and C++ in the plugin).
Of course we need a real gobject type, that have unique type id and so on.
As I didn't find anything suitable, I patched gstreamermm so it allows such element registration. See https://github.com/peper0/gstreamermm-plugins It is not tested well up till now, but seems to work in several basic cases. Bug reports and feature-requests would be appreciated.
Notice: my patch isn't authorized in any way by gstreamer or gstreamermm developers, so it may broke some design assumptions made in these projects.
I was reading the GoF book and in the beginning of the prototype section I read this:
This benefit applies primarily to
languages like C++ that don't treat
classes as first class objects.
I've never used C++ but I do have a pretty good understanding of OO programming, yet, this doesn't really make any sense to me. Can anyone out there elaborate on this (I have used\use: C, Python, Java, SQL if that helps.)
For a class to be a first class object, the language needs to support doing things like allowing functions to take classes (not instances) as parameters, be able to hold classes in containers, and be able to return classes from functions.
For an example of a language with first class classes, consider Java. Any object is an instance of its class. That class is itself an instance of java.lang.Class.
For everybody else, heres the full quote:
"Reduced subclassing. Factory Method
(107) often produces a hierarchy of
Creator classes that parallels the
product class hierarchy. The Prototype
pattern lets you clone a prototype
instead of asking a factory method to
make a new object. Hence you don't
need a Creator class hierarchy at all.
This benefit applies primarily to
languages like C++ that don't treat
classes as first-class objects.
Languages that do, like Smalltalk and
Objective C, derive less benefit,
since you can always use a class
object as a creator. Class objects
already act like prototypes in these
languages." - GoF, page 120.
As Steve puts it,
I found it subtle in so much as one
might have understood it as implying
that /instances/ of classes are not
treated a first class objects in C++.
If the same words used by GoF appeared
in a less formal setting, they may
well have intended /instances/ rather
than classes. The distinction may not
seem subtle to /you/. /I/, however,
did have to give it some thought.
I do believe the distinction is
important. If I'm not mistaken, there
is no requirement than a compiled C++
program preserve any artifact by which
the class from which an object is
created could be reconstructed. IOW,
to use Java terminology, there is no
/Class/ object.
In Java, every class is an object in and of itself, derived from java.lang.Class, that lets you access information about that class, its methods etc. from within the program. C++ isn't like that; classes (as opposed to objects thereof) aren't really accessible at runtime. There's a facility called RTTI (Run-time Type Information) that lets you do some things along those lines, but it's pretty limited and I believe has performance costs.
You've used python, which is a language with first-class classes. You can pass a class to a function, store it in a list, etc. In the example below, the function new_instance() returns a new instance of the class it is passed.
class Klass1:
pass
class Klass2:
pass
def new_instance(k):
return k()
instance_k1 = new_instance(Klass1)
instance_k2 = new_instance(Klass2)
print type(instance_k1), instance_k1.__class__
print type(instance_k2), instance_k2.__class__
C# and Java programs can be aware of their own classes because both .NET and Java runtimes provide reflection, which, in general, lets a program have information about its own structure (in both .NET and Java, this structure happens to be in terms of classes).
There's no way you can afford reflection without relying upon a runtime environment, because a program cannot be self-aware by itself*. But if the execution of your program is managed by a runtime, then the program can have information about itself from the runtime. Since C++ is compiled to native, unmanaged code, there's no way you can afford reflection in C++**.
...
* Well, there's no reason why a program couldn't read its own machine code and "try to make conclusions" about itself. But I think that's something nobody would like to do.
** Not strictly accurate. Using horrible macro-based hacks, you can achieve something similar to reflection as long as your class hierarchy has a single root. MFC is an example of this.
Template metaprogramming has offered C++ more ways to play with classes, but to be honest I don't think the current system allows the full range of operations people may want to do (mainly, there is no standard way to discover all the methods available to a class or object). That's not an oversight, it is by design.
Actually, this question seems to have two parts:
How to implement pattern matching?
How to implement send and receive (i.e. the Actor model)?
For the pattern matching part, I've been looking into various projects like App and Prop. These look pretty nice, but couldn't get them to work on a recent version (4.x) of g++. The Felix language also seems to support pattern matching pretty well, but isn't really C++.
As for the Actor model, there are existing implementations like ACT++ and Theron, but I couldn't find anything but papers on the former, and the latter is single-threaded only [see answers].
Personally, I've implemented actors using threading and a thread-safe message queue. Messages are hash-like structures, and used these together with a number of preprocessor macros to implemented simple pattern matching.
Right now, I can use the following code to send a message:
(new Message(this))
->set("foo", "bar")
->set("baz", 123)
->send(recipient);
And the following to do simple pattern matching (qDebug and qPrintable are Qt-specific):
receive_and_match(m)
match_key("foo") { qDebug("foo: %s", qPrintable(m->value("foo").toString())); }
or_match_key("baz") { qDebug("baz: %d", m->value("baz").toInt()); }
or_match_ignore
end_receive
However, this looks a bit hackish to me, and isn't very robust.
How would you do it? Did I miss any existing work?
As for the Actor model, there are
existing implementations like ACT++
and Theron, but I couldn't find
anything but papers on the former, and
the latter is single-threaded only.
As the author of Theron, I was curious why you believe it's single-threaded?
Personally, I've implemented actors
using threading and a thread-safe
message queue
That's how Theron is implemented.. :-)
Ash
One of the important things about erlang is how the features are used to make robust systems.
The send/recieve model is no-sharing, and explicitly copying.
The processes themselves are lightweight threads.
If you did desire the robust properties of the erlang model, you would be best to use real processes and IPC rather than threads.
If you want robust message passing though you may end up wanting to serialize and deserialise the contents. Especially with type safety.
Pattern matching in C++ isn't always pretty but there will be a good pattern for this - you will end up creating a dispatcher object that uses some form of polymorphism to get what you want.
Although if you are not careful you end up with xml over pipes :)
Really, if you want the erlang model you really want to use erlang. If there are slow bits, I'm sure you can augment your program using a foreign function internet.
The problem about re-implementing parts, is you won't get a good cohesive library and solution. The solutions you have already don't look much like C++ anymore.
I'm currently implementing an actor library for C++ called "acedia" (there's nothing yet about it on google) that uses "type matching". The library is a project for my master thesis and you can send any kind of data to an actor with it.
A small snippet:
recipient.send(23, 12.23f);
And on the recipient side you can either analyze the received message like this:
Message msg = receive();
if (msg.match<int, float>() { ... }
... or you can define a rule set that invokes a function or method for you:
void doSomething(int, float);
InvokeRuleSet irs;
irs.add(on<int, float>() >> doSomething);
receiveAndInvoke(irs);
It's also possible to match both on type and on value:
Message msg = receive();
if (msg.match<int, float>(42, WILDCARD) { ... }
else if (msg.match<int, float>() { ... }
The constant "WILDCARD" means, that any value will be acceptet. Pass no arguments is equal set all arguments to "WILDCARD"; meaning that you only want to match the types.
This is certainly a small snippet. Also you can use "case classes" like in Scala. They are comparable to "atomics" in erlang. Here is a more detailed example:
ACEDIA_DECLARE_CASE_CLASS(ShutdownMessage)
ACEDIA_DECLARE_CASE_CLASS(Event1)
ACEDIA_DECLARE_CASE_CLASS(Event2)
To react to the defined case classes you can write an actor like this:
class SomeActor : public Actor
{
void shutdown() { done = true; }
void handleEvent1();
void handleEvent1();
public:
SomeActor() : done(false) { }
virtual void act()
{
InvokeRuleSet irs;
irs
.add(on<ShutdownMessage>() >> method(&SomeActor::shutdown))
.add(on<Event1>() >> method(&SomeActor::handleEvent1))
.add(on<Event2>() >> method(&SomeActor::handleEvent2))
;
while (!done) receiveAndInvoke(irs);
}
};
To create a new actor and start it, all you have to write is:
Acedia::spawn<SomeActor>();
Although the library not even reached beta stadium the shown snippets work and i have a first application running on it. One major goal of the library is to support distributed programming (also across a network).
Your question is a while ago, but if you're interested in it: let me know! :)
You can mimic the behavior using Qt's signal/slot mechanism, especially since Qt's signal/slot supports multithread.
I would definitely be interested in looking at your "acedia" library and would love to help in any way that I could. Erlang has some wonderful constructs and C++ could definitely benefit from such a library.
Today I hostet the library at sourceforge: https://sourceforge.net/projects/acedia/
As I said before it's an early release. But feel free to critique it!
Today, if you want erlang style robust actors in C++, and pattern matching,
maybe Rust is the answer.
Of course this wasn't around publically when the OP asked ~5years ago, and as of april 2014 it still isn't v1.0 yet - but its been progressing very well and is definitely stabilizing, enough of the language core is stable I think.
And ok its not C++, but it has the same approach to memory management as C++, except that it supports lightweight tasks with no shared memory by default (then provides controlled library features for sharing - "Arc");
It can directly call (and directly expose) 'extern C' functions. You can't share templated library headers with C++ - but you can write generics that mimick C++ collection classes (and vica versa) to pass references to data-structures across.