[zeromq-dev] C++ interface
Martin Sustrik
sustrik at 250bpm.com
Wed Jan 20 09:05:40 CET 2010
Hi Asko,
>>> I worked on this today - mostly learning the details of the man pages.
>>> I'm not asking for this to be included, but maybe you want to have a
>>> look. The C++ interface as now can be improved essentially, imho.
>>
>> Changing the API is the most sensitive topic around. It affects
>> basically everyone so we have to be careful here before moving any
>> changes upstream.
>
> Sure. That's why I brought it up rather hastily, since 2.0 is still in
> beta. I don't really mind either way, since it's so easy to have our own
> C++ binding (just a modded version of the one file).
Exactly.
>> * - better error messages
>>
>> The improvement we can introduce straight ahead IMO is adding throw
>> specifications to individual functions. It improves the code and at
>> the same time there are no backward compatibility issues.
>
> Throw mentions in C++ prototypes are actually rather useless. They don't
> really guarantee anything - net has discussions on this. So I'd prefer
> "no" on this.
>
> Google found i.e. this:
> http://stackoverflow.com/questions/1037575/why-arent-exceptions-in-c-checked-by-the-compiler
AFAIU exception specification would amount to an assert ensuring that no
"strange" exception will be thrown by C++ wrapper. You are right.
There's no much use from that (aside of self-documenting purposes).
Let's leave it as is.
>> * - enums instead of flag ints
>>
>> The problem here are name collisions. Stripping off the ZMQ prefix
>> leaves us with constants such as "rate", "swap" or "sub" which are
>> likely to collide with identifiers defined elsewhere (with "using
>> namespace zmq"). It's also worth looking at other language bindings.
>> Ideal solution would preserve the syntax accross the languages while
>> still keeping namespacing stuff clear.
>
> Ah, didn't think of "using" here. True. Then again I don't ever use
> "using" except for for "std".
>
> The reason for enums would be that compiler IDEs in my understanding
> help one select the right values for such calls. At least Visual C# does
> that on the C# side. I find using ints for this kind of issues disturbing.
>
> One solution can be to change the C side ints into enums instead, with
> the current names.
I haven't thought of auto-complete. Using enums instead of defines would
work. The tradeoff is changing the ABI though.
>> * - set methods instead of use of enums or ints
>>
>> Set methods would mean adding new code to each language binding each
>> time new socket option is introduced. That's extremely hard to manage
>> as there's no single person to understand _all_ the language bindings.
>> Thus adding new socket option would turn into major managerial task.
>
> Yes, but it would make the use of the features convenient. Just think
> about it.
Rethought it and answer is still no. Socket options are primary
extensibility mechanism. Introducing this kind of feature would mean
that language binding maintainers would be able to block individual
releases for unilimited periods of time. With 10+ language bindings (not
really there yet, but be there shortly IMO) it would hurt the release
process badly, even fatally.
>> * - use of 'zmq::pollitem' instead of C 'zmq_pollitem_t' (more
>> covering up C details)
>>
>> There's following line in the current trunk:
>>
>> namespace zmq {
>> typedef zmq_pollitem_t pollitem_t;
>> }
>
> True, but that forces one to fill in the structures by hand. Use of C++
> struct and constructors i.e. covers up the dual zmq-or-posix sockets
> thingy.
Ah. Ok. Got it. I've missed it's an actual class, not just a typedef.
The zmq_poll thing is kind of unfinished. It was added to the API
recently and it's not even supported in Java, Python and Ruby binding.
So what should be done IMHO is to propose a conceptual design for
polling API that would work for at least C++, Java, Lisp, Python and Ruby.
> This all seems very understandable, for the interfaces coming from the
> "bottom up". C implementation rules, and decides things. What would now
> help is actually making code using the bindings and trying to make it as
> simple and convenient (in the particular language) as can be. That is,
> coming back "top down". I think the zmq usage needs that.
Yes.
> If it's a managerial problem then maybe each binding should have a
> person named to be responsible for it.
> What is important though, is to
> agree on the logical presentation together, so that documentation needs
> only be done one. Ruby, Python, C++ should all be conceptually same.
Exactly. See the note above.
> Don't get me wrong. I like zmq and am going to be using it much. That's
> exactly why I want to throw in my opinions and observations, to help
> make the product great.
Sure and thanks for that!
>> * - error handling for 'zmq::poll()' (was missing!!)
>>
>> Ack.
Ok. Let me fix that.
>> * - added 'const' to methods not changing the object
>>
>> That can make sense at particular points (let's discuss them one by
>> one), but in overall the semantics of const/non-const-ness in 0MQ is
>> more complex than what C++ "const" technique is able to describe. For
>> example, when copying a message (zmq_msg_copy) the content of the
>> message is shared by 2 zmq::message_t instances. Thus, modification to
>> non-const object may cause const object to be modified. Etc.
>
> I noticed that. There are ways to make this splendidly nice, however.
Feel free to propose semantics for constness in 0MQ. If it makes sense
we can get it in. The problems you would have to address are:
1. context and socket are non-assignable, making any attempt to define
constness/non-constness on its functions somehow artificial and arbitrary.
2. Because of shared content issue, constness semantics of message
object is pretty complex and difficult to tame.
> I can help by crafting "as fine as can be" C++ binding, in my opinion.
> There's absolutely no need for you to take it in, until completely
> pleased with the results. But I wanted you to be aware of these issues.
> I don't think I'll be the only one pointing them out.
In overall, I believe we have different goals here. My goal is to keep
the binding as simple as possible (as you would expect from someone who
has to maintain large codebase) while your goal is to make the user
interface as pleasant to use as possible, even to the extent of building
a non-trivial "usability framework" on top of underlying C API.
Maybe the right solution would be to create a separate "C++ binding on
steroids" project maintained by yourself that we can link to from 0MQ
web page. That way you can experiment with the binding without having to
care about backward compatibility, managerial issues etc. In the ideal
case C++ users would gradually shift from raw C++ binding to your
project and once it has reasonable user & developer base, we can merge
it back to 0MQ proper.
Thoughts?
Martin
More information about the zeromq-dev
mailing list