功能语言中的部分评估和函数内联有什么区别? [英] What's the difference between partial evaluation and function inlining in a functional language?

查看:137
本文介绍了功能语言中的部分评估和函数内联有什么区别?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道:


  1. 函数内联就是用函数定义替换一个函数调用。

  2. 部分评估是在编译时评估程序的已知(静态)部分。

两个使用命令式语言,如C,其中操作符与函数不同。然而,在像Haskell这样的函数式语言中,函数式语言中两者之间是否有区别?操作符也是函数?



函数式内联的唯一区别是可以选择性执行部分程序,而对整个程序进行部分评估(即 vs )?



这两种优化技术之间的语义差异是什么?

解决方案




  • 之间的区别在编译器(甚至是预处理器)已知的给定的一组运算符和函数上计算常量表达式,它发生在编译时间。例如。编译器将 print(2 * 2)编译为 print(4)。这并不意味着仅限于运算符表达式,例如 print(sqrt(2.0)

  • 部分评估,这是一个更广泛的概念,编译器可以认识到可以将 print(myfunc(2))转换为 print(c) code>其中 c 是调用 myfunc(2)的结果, em> specialization time )调用 myfunc(2)来确定 c 。如果 myfunc 有副作用,比如擦掉自己的硬盘而不是程序用户,那么错误的做法是错误的,因此编译器需要某种注解或属性来知道它是什么时候允许/期望(例如C ++ 11's constexpr



内联是一个不相关的概念,内联函数调用意味着用calle d功能。这个正文没有被评估过。


在C这样的命令式语言中,两者之间有区别,其中操作符与函数不同。然而,在Haskell这样的函数式语言中,操作符是函数还是有区别的吗?

这种独特性(操作符与函数)纯粹是句法,与内联和部分评估之间的差异无关:

带有运算符的函数调用和表达式都可以在C中内联和编译时评估。编译时评估仅限于一组固定的运算符和函数(主要是运算符,但这是历史意外)上的表达式

这两个概念在Haskell中都是有意义的。


  • 内联: ghc has { - #INLINE其中 f 不能递归,原因很明显,

  • 部分评估:this通常被推广到超级编译,其中不仅基类型的表达式转换,但甚至功能,例如将 map f(map g xs )转换为 map(f。g)xs )。它可以(但不必)也可以内联。 模板Haskell 是在编译时(明确)评估程序的一部分的另一种方法。 / li>


标题问题的答案是这样的:内联和部分评估之间的区别与函数和运算符之间的区别没有关系,在功能语言方面与在C方面大体相同。由于副作用,部分评估在C中可能更困难(请参阅上面的擦除硬盘)

I know that:

  1. Function inlining is to replace a function call with the function definition.
  2. Partial evaluation is to evaluate the known (static) parts of a program at compile time.

There is a distinction between the two in imperative languages like C, where operators are distinct from functions. However, is there any difference between the two in functional languages like Haskell where operators are functions too?

Is the only difference between the two that function inlining can be performed on selective parts of a program whereas partial evaluation is performed on the entire program (i.e. vs )?

What are the semantic differences between the two optimization techniques?

解决方案

There is a difference between

  • evaluating constant expressions over a given set of operators and functions known by the compiler (or even preprocessor), which happens at compile time . E.g. the compiler compiles print(2*2) as print(4). This needs by no means to be limited to operator expressions, as you seem to imply (e.g. print(sqrt(2.0))
  • partial evaluation, which is a broader concept. A compiler could realise that print(myfunc(2)) could be transformed into print(c) where c is the result of calling myfunc(2). It could then (at "specialisation time") call myfunc(2) to determine c. Of course, this will go badly wrong if myfunc has side-effects, like wiping one's own hard disk instead of the program user's. Hence the compiler needs some sort of annotation or attribute to know when this is allowed/desired (e.g. C++11's constexpr)

Inlining is an unrelated concept. Inlining a function call means replacing the call by the body of the called function. This body is not evaluated.

There is a distinction between the two in imperative languages like C, where operators are distinct from functions. However, is there any difference between the two in functional languages like Haskell where operators are functions too?

This distinctness (operators vs. functions) is purely syntactic, and is unrelated to the difference between inlining and partial evaluation:

Both function calls and expressions with operators can be inlined and compile-time evaluated in C. Compile-time evaluation is restricted to expressions over a fixed set of operators and functions (mostly operators, but that is historical accident)

Both concepts make sense and are distinct in Haskell.

  • Inlining: ghc has {-# INLINE f #-}, where f cannot be recursive, for obvious reasons,
  • Partial evaluation: this is usually generalised to Supercompilation where not only expressions of base type are transformed, but even functions, e.g. transforming map f (map g xs) into map (f . g) xs). It can (but need not) do inlining as well. Template Haskell is another way to (explicitely) evaluate part of a program at compile-time.

The answer to your title's question is thus: the difference between inlining and partial evaluation has nothing to do with the difference between functions and operators, and is much the same in functional languages as it is in C. Partial evaluation is probably more difficult in C because of side effects (cf the wiped hard disk above)

这篇关于功能语言中的部分评估和函数内联有什么区别?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆