4 ms·
Hmm, the OCaml could be a lot shorter: let rec fold_channel f acc chan = match input_line chan with | line -> fold_channel f (f line acc) chan
by gsg 11y ago
Hmm, the OCaml could be a lot shorter:
let rec fold_channel f acc chan =
match input_line chan with
| line -> fold_channel f (f line acc) chan
| exception End_of_file -> acc
let comma = Str.regexp ","
let values_of_line line =
List.map float_of_string (Str.split comma line)
let sum_channel chan =
let folder line tot = List.map2 (+.) tot (values_of_line line) in
fold_channel folder (values_of_line (input_line chan)) chan
let sum_and_print_file filename =
let chan = open_in filename in
sum_channel chan |> List.map string_of_float |> String.concat "," |> print_string;
close_in chan
let () =
match Sys.argv with
| [|_; filename|] -> sum_and_print_file filename
| _ -> failwith "Exactly 1 filename must be given"
This is also a bit faster, and almost all of the difference is because I hoisted the Str.regexp ",". I suspect using a split-on-character operation would make a bit more difference there, but of course the spartan OCaml stdlib lacks such a function.
- gsg 11y agoOops, breaks on empty files. I should have matched on the input_line chan in sum_channel to catch End_of_file - damn exceptions. print_string should also be print_endline to match the original.
- ignoramous 11y agoAlso, is doing flow control using exceptions an acceptable pattern in the OCaml world? Like in Java: try { print(awesomeObj.getSomeState()); } catch(NullPointerException npe) { awesomeObj = AwesomeObj.getInstance(); } would be considered very bad. You would instead be expected to do: if (awesomeObj == null) awesomeObj = AwesomeObj.getInstance(); print(awesomeObj.getSomeState()); (how do you <code-wrap> stuff on here?)
- gsg 11y agoYes. Various parts of the stdlib are intended to be used by catching Not_found or End_of_file or whichever exception happens to be relevant. It's not what I would have done. (Mark text as code by putting it on a fresh line with two or more spaces in front. I don't think there is a way to do this inline.)
- reblochon 11y agoWhile being done in the standard library, several big libraries alternative (Core, Batteries...) prefer wrapping everything in an `option` type instead of raising an exception. Wrapping in an option avoids forgetting about catching the exception.
- kenko 11y agoIt's always weird to me when people talk about using exceptions for control flow. Exceptions are, pretty much explicitly, a control flow mechanism. That's what they do, they transfer control from one place to another. It's like people are getting hung up on the name.
- ignoramous 11y agoExceptions, in Java land at least, are very costly (think interrupts and context switching). To do flow control using them is shooting yourself in the foot.