Better to use "and" or "in" when chaining "let" statements?
I realize this is probably a silly question, but...
If I'm chaining a bunch of let
statements which do not need to know each other's values, is it better to use and
or in
?
For example, which of these is preferable, if any:
let a = "foo"
and b = "bar"
and c = "baz"
in
(* etc. *)
or
let a = "foo" in
let b = "bar" in
let c = "baz"
in
(* etc. *)
My intuition tells me the former ought to be "better" (by a very petty definition of "better") because it creates the minimum number of scopes necessary, whereas the latter is a scope-within-a-scope-within-a-scope which the compil开发者_如何学运维er/interpreter takes care to note but is ultimately unimportant and needlessly deep.
My opinion is that in
is better. The use of and
implies that the definitions are mutually dependent on each other. I think it is better to be clear that this is not the case. On the other hand, some OCaml programmers do prefer and
for very short definitions, where the slightly more compact notation can appear cleaner. This is especially true when you can fit the definitions on a single line:
let a = "foo" and b = "bar" in
The answer to the question "which is better?" only really makes sense when the interpretations do not differ. The ML family of languages (at least SML and OCaml) have both a parallel initialization form (and
) and a sequential, essentially nested-scope form (in
) because they are both useful in certain situations.
In your case the semantics are the same, so you are left to answer the question "what reads best to you?" and maybe (if this is not premature) "which might be executed more efficiently?" In your case the alternatives are:
For the
and
case: evaluate a bunch of strings and do a parallel binding to three identifiers.For the
in
case: bindfoo
toa
, then bindbar
tob
, then bindbaz
toc
.
Which reads better? It is a toss up in this case because the outcome does not matter. You can poll some English speakers but I doubt there will be much preference. Perhaps a majority will like and
as it separates bindings leaving the sole in
before the expression.
As to what executes more efficiently, I think a good compiler will likely produce the same code because it can detect the order of binding will not matter. But perhaps you have a compiler that generates code for a multicore processor that does better with and
. Or maybe a naive compiler which writes all the RHSs into temporary storage and then binds them, making the and
case slower.
These are likely to be non-essential optimization concerns, especially since they involve bindings and are probably not in tight loops.
Bottom line: it's a true toss-up in this case; just make sure to use parallel vs. sequencial correctly when the outcome does matter.
I would say in is better because it reduces scope and better expresses intent. If I see all these defintions chained together in a shared scope manner I would be under the impression that it was done for a reason and would be looking for how they effect each other.
It's the same as the difference between let
and let*
in Lisp, I believe.
let*
(similar in functionality to the in..in..
structure - the second structure in your question) is sometimes used to hide imperative programming since it guarantees sequential execution of expressions (see what Paul Graham had to say about let* in On Lisp).
So, I'd say the former construct is better. But the truth is, I think the latter is more common in the Ocaml programs I have seen. Probably just easier to use in letting one build on previously named expressions.
精彩评论