> Sorry Richard I should have elaborated a bit more. > I guess there are a couple of examples in the literature, but one of them > comes to my mind, consider the following code snippet: > > let fd = Unix.open "myfile1" ... in > let fd = Unix.open "myfile2" ... in > ... (some code) > Unix.close fd > > This causes a file descriptor leak that is hard to detect statically in > general.
If you mean detect statically by a _program_, then this makes absolutely no difference. A static analyzer could alpha rename the term so that each name is unique or work with De Bruijn indexes without changing the complexity of the problem. If you mean detect statically by a _programmer_ then yes, variable shadowing can be a good tool to write obfuscated code. > As a rule of thumb, I think it's better to give different conceptual objects > different variable names, which also improves self-documentation. Agreed. (I'm sure also got caught at least once by something like your first example). > Within nested scopes, all objects declared with a let-binding are usually > distinct > conceptually. Not necessarily. I think what Łukasz mentions about incrementally transformed values and cognitive burden is very true and in these cases I wouldn't consider name recycling a bad style. One example is working with a purely functional datastructure like Set.t where you need to perform a few applications before getting to the only value you are interested in. The alternative would be to simply not name the intermediate results, it may be possible but sometimes writing the sequence of application explicitly by a serie of lets makes the presentation and the code clearer [1]. Best, Daniel [1] Somewhat related is point-free style programming of which haskellers are very fond of. A little bit of it is nice, but I think it sometimes makes the cognitive burden too high. There's a balance between conciseness and readability. Somehow programmers are obsessed by the former at the detriment of the latter, but a good balance is needed. This example (from this [2] wikipedia page) speaks for itself : mf criteria operator list = filter criteria (map operator list) vs mf = (. map) . (.) . filter I'm sure we all agree the former is easier to grasp. [2] http://en.wikipedia.org/wiki/Point-free_programming -- Caml-list mailing list. Subscription management and archives: https://sympa-roc.inria.fr/wws/info/caml-list Beginner's list: http://groups.yahoo.com/group/ocaml_beginners Bug reports: http://caml.inria.fr/bin/caml-bugs