In js/ts-land going from unknown type to known one normally means:
1. JSON.parse(...) string to json value
2. runtime assert it ie. with [0] which is a form of parsing but on json input as opposed to string parsing
In other words, when dealing with jsons, it's better to work on combinators over json values than combinators over string – the code is much more terse, natural and performant.
This can be seen as a form of tokenization, where the JSON objects are trees of tokens.
But that said, a more apt comparison is going from text to JSON in the first place (which is not trivial to do fast, and has issues when it comes to stream parsing).
There are enormous advantages to using JSON for storing structured application data though, mostly so you don't have to worry about writing a parser for it.
Hi Josh! "Parse, don't validate" is one of my favourite programming blog posts of all time. Between Nom and Serde, I find it very easy to use that approach in Rust.
Serde is good for self-describing formats like JSON, YAMK, TOML etc. At least that's what I use it for. Nom isn't necessary for them!
Nom is good for protocols where you need to know the schema in advance. E.g. a binary key-value store, where the binary in the key and value has to be deserialised into some special rules.
Nom can also handle bit-level parsers very easily. It's easier to use the parsers in nom::bits than remembering all the bit-shifting tricks I haven't used in five years.
But I'm not an expert on Serde, I suspect it can do bit-level too. I've never written my own Serde library, I just use crates like serde-json.
Comments
This is a similar take to https://lexi-lambda.github.io/blog/2019/11/05/parse-don-t-va..., which goes into more detail on why "structured" is a requirement.
(Hi Adam!)
In js/ts-land going from unknown type to known one normally means:
1. JSON.parse(...) string to json value
2. runtime assert it ie. with [0] which is a form of parsing but on json input as opposed to string parsing
In other words, when dealing with jsons, it's better to work on combinators over json values than combinators over string – the code is much more terse, natural and performant.
[0] https://github.com/appliedblockchain/assert-combinators
This can be seen as a form of tokenization, where the JSON objects are trees of tokens.
But that said, a more apt comparison is going from text to JSON in the first place (which is not trivial to do fast, and has issues when it comes to stream parsing).
There are enormous advantages to using JSON for storing structured application data though, mostly so you don't have to worry about writing a parser for it.
Hi Josh! "Parse, don't validate" is one of my favourite programming blog posts of all time. Between Nom and Serde, I find it very easy to use that approach in Rust.
As a beginner to both, when do you find yourself reaching for one instead of the other? Or do you use nom when deserializing with serde?
Serde is good for self-describing formats like JSON, YAMK, TOML etc. At least that's what I use it for. Nom isn't necessary for them!
Nom is good for protocols where you need to know the schema in advance. E.g. a binary key-value store, where the binary in the key and value has to be deserialised into some special rules.
Nom can also handle bit-level parsers very easily. It's easier to use the parsers in nom::bits than remembering all the bit-shifting tricks I haven't used in five years.
But I'm not an expert on Serde, I suspect it can do bit-level too. I've never written my own Serde library, I just use crates like serde-json.
I use Serde when it's a common format that already has implementations for Serialize/Deserialize, and nom/peg when it's a custom format.
You mean "Parse, don't validate" right?
Oops, yes