Итак, я пытаюсь изучить F #, и, изучая новые вещи, мне нравится смотреть на IL, чтобы увидеть, что происходит под обложками. Недавно я прочитал о Currying, очевидном фундаменте языка.
В соответствии с F # для удовольствия и прибыли при создании следующей функции:
let addItems x y = x + y
Что действительно происходит, есть две отдельные функции аргументов, которые создаются.
let addItems x =
let subFunction y =
x + y
subFunction
и когда вы вызываете функцию с помощью addItems 5 6, порядок операций выглядит следующим образом
-
addItems вызывается с аргументом 5
-
addItems возвращает subFunction
- subFunction вызывается с аргументом 6
- subFunction имеет аргумент 5 в области видимости, поэтому он добавляет и возвращает сумму 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 можно четко видеть, что создается одна статическая функция, которая принимает два аргумента и возвращает Int32.
Итак, мой вопрос в том, почему расхождение? Это не первый раз, когда я видел ИЛ, который не джив с документацией...