patternMinor
Is this use of (let ... and ...) in OCaml poor style?
Viewed 0 times
thispoorocamlstyleletanduse
Problem
In other languages, I prefer to arrange source files so that simpler and more widely useful concepts are introduced before implementation details, and I try where possible to make complex implementation details top-level functions so that I can separate them out and let the main function read like a high-level algorithm description.
OCaml obviously has an interface/source distinction, but even with a sparse well-documented interface like
I've been tempted to do things like
Is this poor style? Does it affect the ability of IDE-users to navigate source files?
OCaml obviously has an interface/source distinction, but even with a sparse well-documented interface like
type t
(** Blah blah blah *)
val important_operator : t -> t -> t
(** Blah blah blah *)I've been tempted to do things like
let rec important_operator a b =
let a', b' = foo a b in
let a', b' = iterate_until_convergence (=)
(fun (a, b) -> bar (baz a b))
(a', b') in
merge a', b'
(* Implementation details *)
and foo a b = ...
and bar x = ...
and baz a b = ...
and merge a b = ...Is this poor style? Does it affect the ability of IDE-users to navigate source files?
Solution
It's not idiomatic OCaml indeed.
You would write this code as follows:
Of course, you don't need to only use nested functions, you can also define
- "and" is an effective way to say "watch out for mutual recursion".
- OCaml encourages you to use nested functions instead! As The Structure of OCaml programs says: "Nested functions are, however, very useful and very heavily used in OCaml."
You would write this code as follows:
let important_operator a b =
let foo a b = ... in
let bar x = ... in
let baz a b = ... in
let merge a b = ... in
let a', b' = foo a b in
let a', b' = iterate_until_convergence (=)
(fun (a, b) -> bar (baz a b))
(a', b') in
merge a', b'Of course, you don't need to only use nested functions, you can also define
bar or baz before defining important_operator. OCaml tends to only use functions that were defined "earlier", so using and for this is abusing the system.Code Snippets
let important_operator a b =
let foo a b = ... in
let bar x = ... in
let baz a b = ... in
let merge a b = ... in
let a', b' = foo a b in
let a', b' = iterate_until_convergence (=)
(fun (a, b) -> bar (baz a b))
(a', b') in
merge a', b'Context
StackExchange Code Review Q#15558, answer score: 5
Revisions (0)
No revisions yet.