This is just a quicky to start off the day. I often write fatal error
message using a combination of Printf.eprintf ;;
exit 1 ;; failwith ;; assert false ;;``` etc ... For example to throw
a fatal exception with a message I would write the overly verbose
failwith (Printf.sprintf "this is a fatal error in module %s" modulename)
I see these idioms everywhere and I find them a bit ugly...
If we use Printf.kprintf we can write the statement above in a bit more compact way as:
let fatal fmt = Printf.kprintf failwith fmt ;
Moreover, we add a label to the function fatal and instantiate it once in every module we can get a localize error message for free. Something like :
let fatal label fmt =
let l = Printf.sprintf "Fatal error in module %s: " label in
Printf.kprintf (fun s -> failwith (l^s)) fmt
;;
val fatal : string -> ('a, unit, string, 'b) format4 -> 'a = <fun>
# let local_error = fatal "module" ;;
val local_error : ('_a, unit, string, '_b) format4 -> '_a = <fun>
# local "aaaa %d %d" 1 1;;
Exception: Failure "Fatal error in module module: aaaa 1 1".
# local_error "message %d %d" 1 1;;
Exception: Failure "Fatal error in module module: message 1 1".
It would be awesome to have a localized version in the source code as
with assert , but I don't think this is possible to do in a generic
way. Something like :
Exception: Failure "Fatal error in module module (line 144, 63):
message 1 1".
I guess this can be done with camlp4. We can catch the line and column like :
let (line,col) =
try assert false
with Assert_failure ("", line, col) -> (line,col)
and then feed this info in fatal . Maybe I’ll get 5 mins to write this macro. This cannot be done statically as the line reported of assert false will always be the same …