I think the [destrucure input] binding form is perfectly acceptable, akin to clojure.core.match and other libraries. Your original destructuring-case is close if not fine already. It’s idiomatic for destructuring within let and other binding forms (for, loop, etc), so it would be familiar to the casual observer. Bind the thing on the right to the thing on the left, in this case only if the case matches the predicate on the right. In this case, you’re using a specific semantics of binding that uses pattern matching and type predicates. If you go that route, you end up with a more flexible macro-based approach
(destructuring-case (some-function-call)
[[a [b c] & d] (Boolean [a d] String b)]
(do (println [:first])
(println [a b c d]))
[[a b] (Boolean a (or String Boolean) b)]
(do (println [:second])
(println [a b])))))