It can be both. Here is one example that provides the how instead of the what:
https://www.rfc-editor.org/rfc/rfc5321.html#section-3.1
A lot of declarative languages do a lot of hard work designing an imperative kernel that will support the declarative construct. It just takes skill to separate the two together, just like it takes skill to split code between states, interfaces and implementations.