For reference (for the "parse transform" approach in Erlang):
https://github.com/rabbitmq/erlando - it doesn't look maintained, but it's probably still usable; otherwise, you might get some inspiration from the code :) This also (ab)uses list comprehension syntax:
write_file(Path, Data, Modes) ->
Modes1 = [binary, write | (Modes -- [binary, write])],
do([error_m ||
Bin <- make_binary(Data),
Hdl <- file:open(Path, Modes1),
Result <- return(do([error_m ||
file:write(Hdl, Bin),
file:sync(Hdl)])),
file:close(Hdl),
Result]).
(if one of the calls returns `{error, Reason}` tuple, the execution terminates and the tuple is returned; otherwise, `{ok, Value}` tuple is unpacked)