Live data from Hacker News

Protobuffers Are Wrong (2018)

reasonablypolymorphic.com

201–210 of 321 posts

Re: Protobuffers Are Wrong (2018)

#201
post #190

I'm starting to wonder if some of those bad design decisions are symptoms of a larger "cultural bias" at Google. Specifically the "No Compositionality" point: It reminds me of similar bad designs in Go, CSS and the web platform at large. The pattern seems to be that generalized, user-composable solutions are discouraged in favor of a myriad of special constructs that satisfy whatever concrete use cases seem relevant…

It works both ways. General constructs tend to become overly abstract and you end up with sneaky errors in different places due to a minor change to an abstraction.

Like the old adage, this is just a matter of preference. Good software engineering requires, first and foremost, great discipline, regardless of the path or tool you choose.

Re: Protobuffers Are Wrong (2018)

#202

Protobuf's original sin was failing to distinguish zero/false from undefined/unset/nil. Confusion around the semantics of a zero value are the root of most proto-related bugs I've come across. At the same time, that very characteristic of protobuf makes its on-wire form really efficient in a lot of cases. Nearly every other complaint is solved by wrapping things in messages (sorry, product types ). Don't get the enum…

> Protobuf's original sin was failing to distinguish zero/false from undefined/unset/nil.

It's only proto3 that doesn't distinguish between zero and unset by default. Both the earlier and later versions support it.

Proto3 was a giant pile of poop in most respects, including removing support for field presence. They eventually put it back in as a per-field opt-in property, but by then the damage was done.

A huge unforced mistake, but I don't think a change made after the library had existed for 15 years and reverted qualifies as an "original sin".

Re: Protobuffers Are Wrong (2018)

#203
post #200

But why do you need serialization? Because the data structure on disk is not the same as in memory. Arthur Whitney's k/q/kdb+ solved this problem by making them the same. An array has the same format in memory and on disk, so there is no serialization, and even better, you can mmap files into memory, so you don't need cache! He also removed the capability to define a structure, and force you to use dictionary(structu…

[deleted]

Re: Protobuffers Are Wrong (2018)

#204

With these serialization libraries, do any of them have a facility that allows you to specify a wire format and an application format, with recipes for converting one to the other? I haven't used these very seriously but a problem I had a while back was that that the wire format was not what the applications wanted to use, but a good application format was to space-inefficient for wire. As far as I could see there wa…

If you care about network bandwidth you can compress before sending, as virtually all web applications do. Then you don't need to worry much about the space efficiency of the application format.

Of the wire format you mean? I compress it and still need to care about the space efficiency of the wire format beyond that. Compression ratio does improve a lot when not doing our own, end result is significantly larger. Also it becomes also significantly slower because more data to process which is possibly the bigger problem.

It's probably not like most web application, it's hardware data loggers that produce about hundreds of millions to billions of events per second (each with minimum about 4 bytes of wire format and maximum roughly 500 bytes).

Re: Protobuffers Are Wrong (2018)

#205
post #19

Protocol buffers suck but so does everything else. Name another serialization declaration format that both (a) defines which changes can be make backwards-compatibly, and (b) has a linter that enforces backwards compatible changes. Just with those two criteria you’re down to, like, six formats at most, of which Protocol Buffers is the most widely used. And I know the article says no one uses the backwards compatible…

Not widely used but I like Typical's approach https://github.com/stepchowfun/typical > Typical offers a new solution ("asymmetric" fields) to the classic problem of how to safely add or remove fields in record types without breaking compatibility. The concept of asymmetric fields also solves the dual problem of how to preserve compatibility when adding or removing cases in sum types.

I'm really hoping Typical will catch on, as I quite like the design. One important gap right now is the lack of Go and Python support.

Re: Protobuffers Are Wrong (2018)

#206
post #190

I'm starting to wonder if some of those bad design decisions are symptoms of a larger "cultural bias" at Google. Specifically the "No Compositionality" point: It reminds me of similar bad designs in Go, CSS and the web platform at large. The pattern seems to be that generalized, user-composable solutions are discouraged in favor of a myriad of special constructs that satisfy whatever concrete use cases seem relevant…

It works both ways. General constructs tend to become overly abstract and you end up with sneaky errors in different places due to a minor change to an abstraction. Like the old adage, this is just a matter of preference. Good software engineering requires, first and foremost, great discipline, regardless of the path or tool you choose.

If there are errors in implementation of general constructs, they tend to be visible at their every use, and get rapidly fixed.

Some general constructs are better than the others, because they have an algebraic theory behind them, and sometimes that theory was already researched for a few hundred years.

For example, product/coproduct types mentioned in the article are quite close to addition and multiplication that we've all learned in school, and obey the same laws.

So there are several levels where the choice of ad-hoc constructs is wrong, and in the end the only valid reason to choose them is time constraints.

If they had 24 years to figure out how to do it properly, but they didn't, the technology is just dead.

Re: Protobuffers Are Wrong (2018)

#207
post #68

Previous discussions: * https://news.ycombinator.com/item?id=18188519 * https://hn.algolia.com/?q=%22Protobuffers+Are+Wrong%22 I guess I'll, once again, copy/paste the comment I made when this was first posted: https://news.ycombinator.com/item?id=18190005 -------- Hello. I didn't invent Protocol Buffers, but I did write version 2 and was responsible for open sourcing it. I believe I am the author of the "manifesto"…

> Real-world practice has also shown that quite often, fields that originally seemed to be "required" turn out to be optional over time

how often? as practiced by who, and where?

> 2. You actually do not want a oneof field to be repeated!

> How do you make this change without breaking compatibility? Now you wish that you had defined your array as an array of messages, each containing a oneof, so that you could add a new field to that message. But because you didn't, you're probably stuck creating a parallel array to store your new field. That sucks.

Nice, "explain to me how you're going to implement a backward-compatible SUM in the spec-parser that doesn't have the notions needed. Ha! You can't! Told you so!"

> But because you didn't, you're probably stuck creating a parallel array to store your new field. That sucks.

Not really, `oneoff token` is isomorphic to `oneoff (token unit)` and going from the former to the latter doesn't require binary encoding change at all, if the encoding is optimal. Getting from `oneoff (token unit)` to `oneoff (token { linepos })`, depending on the binary encoding format you design, doesn't require you making changes to the parser's runtime, as long as the parser takes into account that `unit` is isomorphic to the zero-arity-product `{}`, and since both `{}` and `{ linepos }` can be presented with a fixed positional addressing, you get your values in a backward-compatible way, but under a specific condition: the parser library API provides `repeated (oneoff )` as a non-materialised stream of values , so that the exact interpretation of happens at a user's calling site, according to the existing stated protocol spec: if it says ` = token`, then `list (repeated (oneoff (token { linepos })))` is isomorphic to `list (repeated (oneoff token))` in the deployed version of the protocol that knows nothing about the line positions, so my endpoints can send you either of:

    * Version 0: [len][oneoff_bincode][token_arr]

    * Version 1: [len][oneoff_bincode_sum][token_arr][unit]

    * Version 2: [len][oneoff_bincode_sumprod][token_arr][prod_arr]

    * Version 3: [len][oneoff_bincode_sumprod_sparse][token_arr][presence_arr][prod_arr]

Re: Protobuffers Are Wrong (2018)

#208
post #176

Earlier quoted context omitted.

> If you see some statements like below on the serialization topic: > Make all fields in a message required. This makes messages product types. > Then it is fair to raise eyebrows on the author's expertise. It's fair to raise eyebrows on your expertise, since required fields don't contribute to b/w incompatibility at all, as every real-world protocol has a mandatory required version number that's tied to a direct par…

What you describe using many completely unnecessary mathematical terms is not only not found in “every real-world protocol”, but in fact is something virtually absent from overwhelming majority of actually used protocols, with a notable exception of the kind of protocol that gets a four digit numbered RFC document that describes it. Believe it or not, but in the software industry, nobody is defining a new “version nu…

> What you describe using many completely unnecessary mathematical terms

Unnecessary for you, surely.

> Believe it or not, but in the software industry, nobody is defining a new “version number” with “strictly defined algebra” when they want to add a new field to an communication protocol between two internal backend services.

Name a protocol that doesn't have a respective version number, or without the defined algebra in terms of the associated spec clarifications that accompany the new version. The word "strictly" in "strictly defined algebra" has to do with the fact that you cannot evolve a protocol without strictly publishing the changed spec, that is you're strictly obliged to publish a spec, even the loosely defined one, with lots of omissions and zero-values. That's the inferior algebra for protobuf, but you can think it is unnecessary and doesn't exist.

Re: Protobuffers Are Wrong (2018)

#209
post #65

I too was using PBs a lot, as they are quite popular in the Go world. But i came to the conclusion that they and gRPC are more trouble than they are worth. I switched to JSON, HTTP "REST" and websockets, if i need streaming, and am as happy as i could be. I get the api interoperability between various languages when one wants to build a client with strict schema but in reality, this is more of a theory than real life…

I am very partial to msgpack. It has routinely met or exceeded my performance needs and doesn’t depend on weird code generation, and is super easy to set up. Something that I don’t see talked about much with msgpack, but I think is cool: if your project doesn’t span across multiple languages, you can actually embed those language semantics into your encoder with extensions. For example, in Clojure’s port of msgpack o…

Indeed, the support is widespread across languages. OTOH, using compression, like basic gzip, for http responses, turns the text format into binary format and with http2 or http3 there is no overhead like it would be with http1. so in the end the binary aspect of these encoders might be obsolete for this use case, as long as one uses compression.

Re: Protobuffers Are Wrong (2018)

#210
post #15

I share the author's sentiment. I hate these things. True story: trying to reverse engineer macOS Photos.app sqlite database format to extract human-readable location data from an image. I eventually figured it out, but it was: A base64 encoded Binary Plist format with one field containing a ProtoBuffer which contained another protobuffer which contained a unicode string which contained improperly encoded data (for e…

That's horrendous. For some reason I imagine Apple's software to be much cleaner, but I guess that's just the marketing getting to my head. Under the hood it's still the same spaghetti.

Yeah, the problem is Apple and all the other contemporary tech companies have engineers bounce around between them all the time, and they take their habits with them.

At some point there becomes a critical mass of xooglers in an org, and when a new use case happens no one bothers to ask “how is serialization typically done in Apple frameworks”, they just go with what they know. And then you get protobuf serialization inside a plist. (A plist being the vanilla “normal” serialization format at Apple. Protobuf inside a plist is a sign that somebody was shoehorning what they’re comfortable with into the code.)

Post reply on HN