On Nov 15, 7:57 am, Greg Copeland <[EMAIL PROTECTED]> wrote:

> The interface really needs some tweaking too.
> From the tutorial:
>     phone_number->set_number(number);
>
> That's overly complicated. That should read as:
>     tutorial::Person::PhoneNumber* phone_number = person->add_phone
> ( number );
>
> Or better yet:
>     tutorial::Person::PhoneNumber* phone_number = person->add_phone
> ( number, type );
>
> Like I said, I'm just getting started but I've already identified some
> PB short comings. Hopefully PB will continue to improve over time.  I
> may yet create my own tool but until then, I'll be playing more with
> PB to get a feel for additional pros and cons. I may yet create my own
> tool but


Hmmm. I'm not sure what happened, but my post was destroyed. Perhaps
firefox sneezed or I hit something right before I submitted. Sorry
about that. Sorry again for I'm replying to my self.

As for the counter XML argument, I believe it to be fairly weak. Yes,
XML is more verbose yet I'd gladly trade it for not having to manually
enumerate each and every field in PB-IDL when 99+% its obvious and
needlessly tedious. Additionally, Google's own comments to require a
pure python implementation is justification alone to use XML as the
IDL rather than the PB-IDL. It is the same argument. XML is ubiquitous
in just about every language's library that matters. It can be readily
validated, has *many* rich tools, and regardless of the
implementation's performance, its only a compile time cost, never a
runtime cost - save only for perhaps dynamic message generation at
runtime. And even then, that's unlikely to be a performance issue for
any well written application. Once you consider the number of XML
editors and the number of users which can already, manually, easily
grok a well structured format like XML, its difficult to imagine the
need for yet another IDL (PB-IDL). Doubly so once once you consider
IDLs represents an almost ideal use-case for XML in the first place.

And believe me, that's saying a lot from me considering I believe XML
is one of the most overused technologies to date. In fact, I'd argue
XML is commonly used where is makes absolutely no sense what so ever
to even be considered for a project, let alone become the ubiquitous
interface - in whatever form it takes.

> The interface really needs some tweaking too.
> From the tutorial:
>     phone_number->set_number(number);

Should read:
tutorial::Person::PhoneNumber* phone_number = person->add_phone() ;
phone_number->set_number(number);

And while I'm at it, I'll go ahead and offer a couple more comments.

"Message Type" is frequently mentioned in the documentation yet there
appears to be no available message type information available; as is,
no message type is available. Rather, there are message instances and
message classes which are referred to as types. I say this because
there does not appear to be anything which actually specifies a type
as commonly understood from a protocol perspective. The closest thing
I have identified would be a user created field which requires manual
population. Perhaps a default value would help reduce human errors,
but that seems kludged at best. If I'm even close here, there is no
such thing as a "message type" in PBs; only classes and instances.

Also, I may have identified a significant weakness which may in it
self be a complete show stopper. Please tell me I'm wrong. It appears
there exists no mechanism to automatically generate message types or
parse multiple potential messages from an ambiguous stream or buffer.
The tutorials are really lacking here too as they only deal with
single message classes at any given time; almost entirely negating the
need for something like PB in the first place. There currently exists
no examples which address this issue. At least none that I've found.
Some of the documentation directly addresses the issue but I've yet to
see it provide a real solution without lots of additional work.

Let's say I have three message classes whereby their sizes alone make
message disambiguation impossible. I have a single input stream. How
can I automatically do something like the following pseudo code.

// Factory invokes the handler registered for a given message type
factory.register( Msg1, handler1 ) ;
factory.register( Msg2, handler2 ) ;
factory.register( Msg3, handler3 ) ;
...
factory << stream ; // I don't know of any existing factory - nor have
I found one
factory.dispatch() ; // invoke the proper message handler

Or maybe something like this:

Message *baseMsg = factory << stream ; // I don't know of any existing
factory - nor have I found one
switch( baseMsg.type() ) {
   case msg1.type:
      Msg1 *msg = reinterpret_cast<Msg1 *>( baseMsg ) ;
      break ;

   case msg2.type:
      Msg2 *msg = reinterpret_cast<Msg2 *>( baseMsg ) ;
      break ;

   case msg3.type:
      Msg3 *msg = reinterpret_cast<Msg3 *>( baseMsg ) ;
      break ;
}

// Let our registered handler for the given message be invoked
myReactor.dispatch( msg ) ;

At best, it appears we have to do something like the following, which
is rather error prone.

enum MsgType {
   MSG1,
   MSG2,
   MSG3
}

Message Msg1 {
   required int32 field = 1 ;
}

Message Msg2 {
   required int32 field = 1 ;
}

Message Msg3 {
   required int32 field = 1 ;
}

Message BaseMessage {
   required MsgType type = 1 ;
   optional Msg1 = 2 ;
   optional Msg2 = 3 ;
   optional Msg3 = 4 ;
}

Followed by some peeking on the stream and a switch case which looks
something like the following on the receiving side. Which really isn't
that bad.
BaseMessage baseMsg ;
baseMsg.ParseFromIstream( &stream ) ;

switch( baseMsg.type() ) {
   case MSG1:
      Msg1 *msg1 = baseMsg.Msg1() ;
      break ;

      Msg2 *msg2 = baseMsg.Msg2() ;
      break ;

      Msg3 *msg3 = baseMsg.Msg3() ;
      break ;

}

The problem I have is on the sending side, I'm forced to do the
following which is highly error prone.
BaseMsg baseMsg ;
baseMsg.set_type( MSG1 ) ;
Msg1 *msg1 = baseMsg.addMsg1() ;

Notice the last options have become almost procedural in basis and are
fairly lengthy and error prone to boot - especially compared to like
the highly OO-desired options provided above. Unlike what I originally
stated above, it's not entirely clear to me a default value for the
message type is even an option here. Hopefully this brings home the
point, as far as I can tell, PB has no concept of a message type; only
classes and instances. I know I've read extensions are suppose to help
here, but it's not entirely clear to me exactly how it helps ease
these pains as there still is no message type.

Lastly, to make matters worse, given the above, every time I add or
revise a message type, all code which references *any* message is
forced to recompile even if it is dependant on a message which did not
change. For large and/or complex projects, that's very undesirable. I
suppose PIMPL may help there. Perhaps you have a more elegant solution
at hand via extensions and includes?

I suppose if we ignore these last couple of critiques, much of my OO-
desires can ultimately be created on top of PB, but given these are
typical use cases, one expects these basics to be provided up front.
After all, if it is not doing this work for us, not much more effort
is required to create our own tool which does all this for us, while
providing additional safety in code and increased usability. That's
seems like more than a fair trade in time.

Are there any plans to address these usability issues? Am I simply all
wet here and overlooking the obvious?

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Protocol Buffers" group.
To post to this group, send email to protobuf@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/protobuf?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to