为什么 F# 不将柯里化编译成单独的函数?
Why doesn't F# Compile Currying into Separate Functions?
所以我正在尝试学习 F#,并且在学习新事物时我喜欢查看 IL 以了解幕后发生的事情。我最近读到有关 Currying 的内容,这是该语言的一个明显基础。
根据 F# for fun and Profit 创建以下函数时:
let addItems x y = x + y
真正发生的是创建了两个单参数函数。
let addItems x =
let subFunction y =
x + y
subFunction
并且当您使用 addItems 5 6 调用函数时,操作顺序如下
addItems 使用参数 5
调用
addItems returns subFunction
- 使用参数 6 调用子函数
- subFunction 在范围内有参数 5,所以它添加 returns 5 和 6 的总和
所有这一切表面上听起来都很好。但是,当您为此查看 IL 时,它讲述了一个不同的故事。
.method public static int32 testCurry(int32 x,
int32 y) cil managed
{
.custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 02 00 00 00 01 00 00 00 01 00 00 00 00 00 )
// Code size 5 (0x5)
.maxstack 8
IL_0000: nop
IL_0001: ldarg.0
IL_0002: ldarg.1
IL_0003: add
IL_0004: ret
} // end of method Sandbox::testCurry
我们可以在 IL 中清楚地看到,创建了一个带有两个参数和 returns Int32 的静态函数。
所以我的问题是,为什么会出现差异?这不是我第一次看到与文档不一致的 IL...
So my question is, why the discrepancy?
就行为契约而言,实际编译的 IL 不需要,实际上也不应该重要。通过编译为单个函数,调用在 JIT/runtime 级别得到明显更好的优化。
"what is really happening here..." 不一定是实际发生的情况,更多的是 "how this should be reasoned about when writing and using F# code is..."。底层实现应该可以根据需要自由更改,以充分利用运行时环境。
所以我正在尝试学习 F#,并且在学习新事物时我喜欢查看 IL 以了解幕后发生的事情。我最近读到有关 Currying 的内容,这是该语言的一个明显基础。
根据 F# for fun and Profit 创建以下函数时:
let addItems x y = x + y
真正发生的是创建了两个单参数函数。
let addItems x =
let subFunction y =
x + y
subFunction
并且当您使用 addItems 5 6 调用函数时,操作顺序如下
addItems 使用参数 5
调用
addItems returns subFunction
- 使用参数 6 调用子函数
- subFunction 在范围内有参数 5,所以它添加 returns 5 和 6 的总和
所有这一切表面上听起来都很好。但是,当您为此查看 IL 时,它讲述了一个不同的故事。
.method public static int32 testCurry(int32 x,
int32 y) cil managed
{
.custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 02 00 00 00 01 00 00 00 01 00 00 00 00 00 )
// Code size 5 (0x5)
.maxstack 8
IL_0000: nop
IL_0001: ldarg.0
IL_0002: ldarg.1
IL_0003: add
IL_0004: ret
} // end of method Sandbox::testCurry
我们可以在 IL 中清楚地看到,创建了一个带有两个参数和 returns Int32 的静态函数。
所以我的问题是,为什么会出现差异?这不是我第一次看到与文档不一致的 IL...
So my question is, why the discrepancy?
就行为契约而言,实际编译的 IL 不需要,实际上也不应该重要。通过编译为单个函数,调用在 JIT/runtime 级别得到明显更好的优化。
"what is really happening here..." 不一定是实际发生的情况,更多的是 "how this should be reasoned about when writing and using F# code is..."。底层实现应该可以根据需要自由更改,以充分利用运行时环境。