Yes, it is possible. The two publicly-available related packages for
the binary parsing parts of protocl I recall:
* Tony Garnock-Jones's `bitsyntax`:
https://github.com/tonyg/racket-bitsyntax
* Roman Klochkov's `binary-class`:
https://docs.racket-lang.org/binary-class/index.html
https://groups.google.com/forum/#!msg/racket-users/hx71t8kgnx0/QwBFtLKvBxoJ
If anyone wants to work more on binary parsing/writing
DSLs/mini-languages, two popular formats to test your abstractions might
be TIFF and EXIF (you need them for JPEG file metadata). And a media
container format like Ogg or MP4. And IP packets, and the encoding of
TCP. The Bittorrent format might be easy to start with. At some point,
take a look at Google protocol buffers (though you'd want a separate
language for that, perhaps that expands to your more general binary
language). You'll often have to deal with things like reading a small
number of bytes that signal how to parse some of the immediately
following bytes (like a type tag or a length). Some, like parsing EXIF
metadata, require reading numbers that are like memory addresses or
offsets in the input or part of the input, and then
dereferencing/jumping&returning. Sometimes you'll have pairs or
tuples. What they usually *don't* require is a parser with more than 1
token lookahead or backtracking, maybe because these binary formats are
usually designed for fast machine processing rather than to be
human-readable. Handwritten code for parsing some of these is in
"
http://www.neilvandyke.org/racket/mediafile/".
Once you get beyond parsing real-world protocol binary formats, the
other aspects of protocols get more complicated, and I think you'll
often need a general-purpose (or at least Turing-complete) language.
However, for a particular protocol, or class of protocols you identify,
you might be able to come up with a DSL that expresses everything, and
which is easier to verify. You might also have a DSL layer that almost
exactly matches the formal specification for the protocol (though it's
usually not that easy, and specs usually get fuzzy on important details).
Oh yeah, if you're working on high-performance binary parsing, consider
having your minilanguage expand to code that avoids copying or
allocating new objects. So, say, instead of the usual reading from an
input port and returning values it allocates, it reads (perhaps from a
Racket `bytes?`) and performs imperative actions that the programmer has
specified in terms of the minilanguage, perhaps as a fold. For folding
examples, see Oleg Kiselyov's SSAX or
"
http://www.neilvandyke.org/racket/json-parsing/". And if you find
yourself considering using `call/cc`, strongly consider using
multithreading or something else instead.