Most functional languages have a type safe printf / sprintf (i.e. OCaml, F#, Haskell) which is similar to the effect you get in Idris: the types required to apply the function are statically analyzed from the format string.
Edit (links):
OCaml: https://caml.inria.fr/pub/docs/manual-ocaml/libref/Printf.ht...
F#: https://msdn.microsoft.com/en-us/visualfsharpdocs/conceptual...
Haskell: https://hackage.haskell.org/package/base-4.9.1.0/docs/Text-P...