Les langages Ocaml et Haskell sont issus du langage ISWIM, décrit dans le célèbre article de Peter Lendin "Les 700 prochains langages de programmation". Dans celui-ci, l'auteur, à partir du langage LISP, crée un nouveau langage de programmation et, notamment, introduit des mots let
- clés , and
et where
, qui sont largement utilisés dans les langages de la famille ML. Tôt ou tard, tout esprit curieux, engagé dans la programmation fonctionnelle, se pose une question: pourquoi le mot-clé where
largement utilisé dans Haskell n'a-t-il pas pris racine dans Ocaml ?
De mon point de vue, cela est principalement dû aux différences de sémantique de ces langages, à savoir la nature impérative-énergétique d'Ocaml et la pureté-paresse de l'évaluation en Haskell (qui sont directement et fortement liées aux caractères impurs / purs de ces langues).
Ces deux expressions, let
et where
, sont dérivées du (let ...)
langage LISP, qui a deux variantes de cette forme spéciale: (let ...)
et (let* ...)
. La variante (let* ...)
diffère en ce que toutes les liaisons dans le bloc se produisent séquentiellement et peuvent dépendre les unes des autres:
(let* ((x 3)
(y (+ x 2))
(z (+ x y 5)))
(* x z))
Dans certains dialectes de Scheme, les déclarations de variables peuvent être automatiquement réorganisées par l'interpréteur, il devient donc inutile de les écrire dans le "bon" ordre. Les deux options de reliure, let ... in
et where
correspondent à cette option "avancée" (let* ...)
. Cependant, Ocaml utilise un mot-clé pour séparer les "liaisons parallèles" and
, tandis que Haskell les met simplement dans un bloc.
Si vous regardez exclusivement l'essence des choses, vous pouvez voir que les expressions let ... in
et where
diffèrent sous deux aspects: l'endroit où la liaison est placée et le nombre d'expressions dans le bloc.
Noms contraignants avant et après utilisation.
- let ... in
, , where
:
let x = 1 in
x + 1
z = x + 1
where x = 1
, let ... in Ocaml, , , / . ,
let x = Printf.printf "Hello ";
"World!"
in
Printf.printf "%s" x
. top-level Ocaml, , open
let () = ...
, where non-strict Haskell, term/graph reduction. , where
, :
main = putStrLn (x ++ y)
where x = "Hello "
y = "World!"
z = undefined
: x
y
, . z
, - .
x
, y
, z
let ... in
, Haskell, - z
, . , do
, let
.
shadowing
C let ... in
, Ocaml, Haskell, . where
- :
let x = 1 in
let y = 1 in
x + y
z = x + y
where x = 1
y = 1
, , , , , , "shadowing". Ocaml shadowing , :
let x = 1 in
let x = x * 10 in
x * x
, , :
x := 1;
x := x * 10;
return x*x;
Haskell, where
, "", shadowing , . shadowing , top-level , - non-strict . , Haskell
x = x + 1
.
shadowing Ocaml Haskell , Ocaml , Ocaml Haskell (backpack , - t
M
Ocaml ).
Ocaml , -, (.mli) (.ml). , , -, , top-level , . - , Ocaml top-level , . , let ... in (., report_constructor_mismatch https://github.com/ocaml/ocaml/blob/trunk/typing/includecore.ml#L212 )
Haskell , . , , - , , top-level . , where shadowing.
, , - Clean.
, , where
, let ... in
"-", , . , , , Haskell , Ocaml .
, Ocaml, Stdlib
where , , , . , List.mapi
List.rev_map
. , , Ocaml , , - graph rewriting . , Ocaml where
, , Haskell let ... in
.
Ainsi, comme de bons travaux d'ingénierie, les langages Ocaml et Haskell créent une synergie de syntaxe et de sémantique. Lignes directrices contraignantes let
et where
jouer un rôle, en mettant l'accent sur l'accent psevdoimperativnuyu linéaire et le modèle de performance «paresseux» (réduction graphique). Ils fonctionnent également bien avec votre style d'écriture d'application préféré et le système de module associé.