Lower level than that. Languages should have marshaling support. Marshaling is a low-level byte-pushing operation for which efficient hard machine code can be generated.
I'd suggest offering two forms of marshalling - strongly typed and non-typed. Strongly typed marshaling means sending a struct to something that expects exactly that struct. That will usually be another program which is part of the same system. Structs should be able to include variable-length items for this purpose, so you can send strings. Checking involves something like function signature checking at connection start. This should have full compiler support.
Non-typed marshalling includes JSON and protocol buffers. The data carries along extensive description information, and the sender and recipient don't have to be using exactly the same definition.
Both are needed. Non-typed marshalling is too slow for systems which are using multiple processes for performance. Typed marshalling is too restrictive for talking to foreign systems.
I don't disagree but during my career I've found surprising amount of cases where ASN.1 and its practical encodings like DER, BER and PER work impressively well.
Human readability however has always been the selling point of terrible formats like XML and JSON.
Not sure how can a binary-compact format ever account for that. Maybe excellent cross-platform tools that allow you to inspect and modify the binary-compact format wherever it is? (I mean not only standalone CLI and GUI software; I also mean native browser support in the Dev Tools space and going down the line in the future -- transparent support for the format[s] natively in the programming languages / VMs themselves.)
I'd suggest offering two forms of marshalling - strongly typed and non-typed. Strongly typed marshaling means sending a struct to something that expects exactly that struct. That will usually be another program which is part of the same system. Structs should be able to include variable-length items for this purpose, so you can send strings. Checking involves something like function signature checking at connection start. This should have full compiler support.
Non-typed marshalling includes JSON and protocol buffers. The data carries along extensive description information, and the sender and recipient don't have to be using exactly the same definition.
Both are needed. Non-typed marshalling is too slow for systems which are using multiple processes for performance. Typed marshalling is too restrictive for talking to foreign systems.