Let's say I have the following function to get numeric values from a byte buffer:
(defn get-from-bytebuffer
([^ByteBuffer buffer width endianness]
(let [buffer-endianness (.order buffer)]
(.order buffer endianness)
(cond
(= width 1) (.get buffer)
(= width 2) (.getShort buffer)
(= width 4) (.getInt buffer)
(= width 8) (.getLong buffer))
(.order buffer buffer-endianness))))
The user can specify the endianness of the number being read. To keep side effects to a minimum, the function first gets the current byte ordering of the buffer, sets it to the one indicated by the user, then restores the old endianness. The problem with this is that the value of the last expression in the body of the let
is the value of the let
expression, but I need the value of the cond
. More generally, I have some prologue/epilogue code around an expression but I want the result of the expression to be returned (be the value of the enclosing expression.)
The easy workaround that I came up with simply binds the value of the cond
in another let expression, then has that as the last expression like so:
(defn get-from-bytebuffer-fix
([^ByteBuffer buffer width endianness]
(let [buffer-endianness (.order buffer)]
(.order buffer endianness)
(let [result (cond
(= width 1) (.get buffer)
(= width 2) (.getShort buffer)
(= width 4) (.getInt buffer)
(= width 8) (.getLong buffer))]
(.order buffer buffer-endianness)
result))))
But this feels kludgy. Does Clojure have an idiomatic/"proper" way of surrounding an expression with some prologue/epilogue code and then returning the value of that expression?