Есть ли побочный эффект от использования подстановочного знака подчеркивания в команде let (т. е. let _ = in) в OCaml?

При использовании OCaml я почти всегда использую подстановочный знак подчеркивания в let _ = exp, особенно когда важен не результат exp, а вычисление внутри него. Например:

let _ = print_endline "abc" in
...
let _ = a := !a + 1 in
...
let _ = do_some_thing ... in

Итак, мне просто интересно, есть ли какой-либо побочный эффект от широкого использования let _ = ...?


person Trung Ta    schedule 14.03.2015    source источник


Ответы (3)


Побочным эффектом являются раздражающие ошибки, которые нужно отслеживать в вашем программном обеспечении в будущем. Проблема с let _ = заключается в том, что он будет молча игнорировать частичные приложения, которые вы намеревались сделать полными. Предположим, вы пишете следующее:

let f a b = ...
let _ = f 3 4

И что в будущем вы добавите аргумент к f:

let f a b c = ...

Выражение let _ = f 3 4 по-прежнему будет молча компилироваться, и ваша программа не будет вызывать функцию, оставляя вас в недоумении, что происходит. Гораздо лучше всегда разрешать () и использовать ignore, когда вам нужно игнорировать неединичный результат:

let () = ignore (f 3 4)
let () = print_endline "abc"

Использование let _ = ... следует считать плохим стилем.

person Daniel Bünzli    schedule 14.03.2015
comment
Побочным эффектом являются раздражающие ошибки, которые нужно отслеживать в вашем программном обеспечении в будущем. Не могу не согласиться. Какой смысл использовать строго типизированный язык, если он явно запрещает компилятору делать что-либо полезное с типами, как это делает использование последовательностей let _ = …? - person Michaël Le Barbier; 14.03.2015
comment
Это не игнорируется молча: печатается предупреждение 5. - person PatJ; 14.03.2015
comment
Не с уровнями предупреждений OCaml по умолчанию. - person Daniel Bünzli; 14.03.2015

Нет, нет абсолютно никаких последствий для интенсивного использования let _ =. Компилятор не добавляет имя в глобальную среду, поскольку вы его не указали.

person Pascal Cuoq    schedule 14.03.2015

Целью let является привязка значений к идентификаторам. Если вы делаете только побочные эффекты, лучше заключить их в блок begin .. end. В твоем случае:

begin
    print_endline "abc";
    a := !a + 1;
    do_some_thing ();
end
person Jürgen Hötzel    schedule 14.03.2015
comment
Это работает, только если предыдущая фраза заканчивается маркером ;;. - person Planar; 16.03.2015