Какая разница между частичной оценкой и функцией встраивания в функциональный язык?

Я знаю, что:

  • Функциональная вставка - это замена вызова функции с помощью определения функции.
  • Частичная оценка - это оценка известных (статических) частей программы во время компиляции.

Существует различие между ними в императивных языках, таких как C, где операторы отличаются от функций. Однако существует ли разница между этими двумя функциональными языками, такими как Haskell, где операторы также являются функциями?

Единственное различие между этими функциями заключается в том, что функциональная вставка может выполняться на выборочных частях программы, тогда как частичная оценка выполняется по всей программе (т.е. vs )?

Каковы семантические различия между двумя методами оптимизации?

Ответы

Ответ 1

Существует разница между

  • оценка константных выражений по заданному набору операторов и функций, известных компилятору (или даже препроцессору), который происходит во время компиляции. Например. компилятор компилирует print(2*2) как print(4). Это отнюдь не должно ограничиваться выражениями оператора, как вы, кажется, подразумеваете (например, print(sqrt(2.0))
  • частичная оценка, которая является более широкой концепцией. Компилятор мог понять, что print(myfunc(2)) можно преобразовать в print(c), где c является результатом вызова myfunc(2). Затем он может (в "время специализации" ) вызвать myfunc(2), чтобы определить c. Конечно, это будет плохо ошибочно, если myfunc имеет побочные эффекты, например, вытирая собственный жесткий диск, а не пользователь программы. Следовательно, компилятору нужна какая-то аннотация или атрибут, чтобы знать, когда это разрешено/желательно (например, С++ 11 constexpr)

Вложение - это несвязанная концепция. Вставка вызова функции означает замену вызова телом вызываемой функции. Этот орган не оценивается.

Существует различие между ними в императивных языках, таких как C, где операторы отличаются от функций. Однако существует ли разница между этими двумя функциональными языками, такими как Haskell, где операторы также являются функциями?

Эта отчетливость (операторы против функций) является чисто синтаксической и не связана с разницей между вложением и частичной оценкой:

Оба вызова функций и выражения с операторами могут быть проиндексированы и вычислены во время вычисления. C. Оценка времени компиляции ограничена выражениями по фиксированному набору операторов и функций (в основном операторов, но это историческая авария)

Обе концепции имеют смысл и различны в Haskell.

  • Вложение: ghc имеет {-# INLINE f #-}, где f не может быть рекурсивным, по понятным причинам,
  • Частичная оценка: обычно это обобщается на Supercompilation, где преобразуются не только выражения базового типа, но даже функции, например. преобразуя map f (map g xs) в map (f . g) xs). Он может (но не обязательно) делать встраивание. Шаблон Haskell - это еще один способ (явно) оценить часть программы во время компиляции.

Таким образом, ответ на ваш вопрос с заголовком: разница между вложением и частичной оценкой не имеет ничего общего с разницей между функциями и операторами и практически одинакова на функциональных языках, чем в C. Частичная оценка, вероятно, больше трудно в C из-за побочных эффектов (например, вытертый жесткий диск)