I’ve been exploring closures and I found them to be very accommodating but I also found they can obfuscate the code if you rely on them too much.
Here’s an example I’ve been working on that embraces closures. It provides a ‘cool’ solution to a tricky problem but it also makes it very hard to understand the intent of the code.
The function dropElement takes a list and function to match an element in the the list and returns a type of ('a * 'a list) option. If the function(dropElement) finds a match in the list it will return that element and the list minus the found element.
given a list [1;2;3;4;5;6;7;8;9;10;]
and the match condition element = 4
the returned value will be Some(4, [1;2;3;5;6;7;8;9;10])
let dropElement matchElem lst = let rec dropElemAux lst func = match lst with |  -> None | hd::tl -> if (matchElem hd) then Some(hd, (func tl)) else dropElemAux tl (fun t -> func (hd::t)) in dropElemAux lst (fun d -> d) let ans = dropElement ((=)4) [1;2;3;4;5;6;7;8;9;10;] let () = match ans with | None -> print_endline "No element matched" | Some (elem, lst) -> print_endline(string_of_int elem); print_newline(); List.iter (fun x -> print_endline(string_of_int x)) lst
Now the above code works but I find it very confusing and I wrote it.