As linguagens Ocaml e Haskell são descendentes da linguagem ISWIM, descrita no famoso artigo de Peter Lendin "As próximas 700 linguagens de programação". Nele, o autor, a partir da linguagem LISP, cria uma nova linguagem de programação e, em particular, apresenta palavras-chave let
, and
e where
, que são amplamente utilizadas nas linguagens da família ML. Mais cedo ou mais tarde, qualquer mente curiosa, engajada na programação funcional, tem uma pergunta: por que a palavra where
- chave amplamente usada em Haskell não criou raízes em Ocaml ?
Do meu ponto de vista, isso se deve principalmente às diferenças na semântica dessas línguas, ou seja, a natureza imperativa-energética de Ocaml e a pureza-preguiça da avaliação em Haskell (que estão direta e fortemente relacionadas aos caracteres impuros / puros dessas línguas).
Ambas as expressões, let
e where
, são derivadas da (let ...)
linguagem LISP, que possui duas variantes desta forma especial: (let ...)
e (let* ...)
. A variante (let* ...)
difere porque todas as ligações no bloco ocorrem sequencialmente e podem depender umas das outras:
(let* ((x 3)
(y (+ x 2))
(z (+ x y 5)))
(* x z))
Em alguns dialetos de Scheme, as declarações de variáveis podem ser reordenadas automaticamente pelo interpretador, portanto, torna-se desnecessário escrevê-las na ordem "correta". Ambas as opções de ligação, let ... in
e where
correspondem a essa opção "avançado" (let* ...)
. No entanto, Ocaml usa uma palavra-chave para separar "ligações paralelas" and
, enquanto Haskell simplesmente as coloca em um bloco.
Se você olhar exclusivamente para a essência das coisas, verá que as expressões let ... in
e where
diferem em dois aspectos: o local onde a ligação é colocada e o número de expressões no bloco.
Nomes de ligação antes e depois do uso.
- 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
.
Assim, como bons trabalhos de engenharia, as linguagens Ocaml e Haskell criam uma sinergia de sintaxe e semântica. Diretrizes de ligação let
e where
desempenham um papel, enfatizando o modelo de desempenho psevdoimperativnuyu linear e "preguiçoso" (redução do gráfico). Eles também funcionam bem com seu estilo de escrita de aplicativo preferido e sistema de módulo associado.