ocaml% функция идентичности - PullRequest
       11

ocaml% функция идентичности

8 голосов
/ 13 декабря 2011

Мне интересно, зачем нам нужна функция типа "% identity", которая такая же, как let a = a. Собирается ли улучшить производительность, используя его?

Я ввожу фантомную типизацию в моей программе, вызывая функции идентификаторов много раз для преобразования типов, любопытно, может ли "% identity" уменьшить накладные расходы.

Ответы [ 2 ]

11 голосов
/ 13 декабря 2011

Функция %identity является частью реализации, а не частью языка OCaml.Он сообщает компилятору (по сути), что ничего не нужно делать, чтобы изменить параметр функции на ее возвращаемое значение.Другими словами, он говорит компилятору продолжать использовать то же значение, но менять свое представление о типе.При неправильном использовании он в основном аннулирует все отличные гарантии безопасности системы типа OCaml.Также, конечно, не гарантируется работа в любых других реализациях языка (включая будущие выпуски компилятора INRIA).

Возможность встраивания компилятора OCaml уже должна гарантировать, что для идентичности не будет сгенерирован кодфункции.Поэтому я бы порекомендовал вам просто продолжать их использовать.

Обновление

Чтобы ответить на несвязанный вопрос в комментариях .... Предположим, у вас есть композиция функций и идентификаторfunction:

let (<<) f g x = f (g x)
let id x = x

Далее приведены функции для добавления элементов списка, умножения элементов списка и составления всех функций в списке:

# let sum l = List.fold_right (+) l 0;;
val sum : int list -> int = <fun>
# let product l = List.fold_right ( * ) l 1;;
val product : int list -> int = <fun>
# let composition l = List.fold_right (<<) l id;;
val composition : ('a -> 'a) list -> 'a -> 'a = <fun>

Примеры:

# sum [2; 3; 5; 7];;
- : int = 17
# product [2; 4; 17];;
- : int = 136
# let mx = composition [(+) 1; ( * ) 10];;
val mx : int -> int = <fun>
# mx 2;;
- : int = 21

Дело в том, что 0 является тождеством для сложения, 1 для умножения и id для композиции функции.id полезен все время, так же как 0 и 1.

2 голосов
/ 13 декабря 2011

Использование %identity в качестве внешнего примитива может и уменьшит накладные расходы, связанные с оценкой закрытия (fun x -> x) каждый раз, когда оно применяется.

Особый случай компиляторов OCaml для примитивов %: bytecomp/translcore.ml связывает каждый из них со специальным встроенным узлом AST (в случае %identity он сопоставляется с Pidentity);компиляторы сопоставляют узел и упрощают выражение, к которому он применяется.В случае нативного компилятора соответствующие строки:

  • asmcomp/closure.ml строки 197 и сс .: упрощение %identity, применяемое к постоянному аргументу самого аргумента:

    begin match p with
      Pidentity -> make_const_int x
    | Pnegint -> make_const_int (-x)
    
  • asmcomp/cmmgen.ml строка 1047 и сс .: упростить %identity как LHS приложения для прямой оценки аргумента:

    match p with
      (* Generic operations *)
        Pidentity ->
          transl arg
    

Компилятор байт-кода имеет аналогичные правила упрощения для примитива.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...