| |||
![]()
|
![]() ![]() |
![]()
X-Post: http://kouzdra.livejournal.com/328862.h X-Post: http://community.livejournal.com/ru_dec Часть в общем вторая к этому вот: http://kouzdra.livejournal.com/327847.h X-Posted: http://lj.rossia.org/users/kouzdra/8138 X-Posted: http://community.livejournal.com/ru_dec Итак: что на самом деле происходит в O'Caml при необходимости реализовывать частичное применение: Там есть две группы встроенных функций caml_curryN и caml_applyN, которые преобразуют ар-ность функций: примерно в таком смысле (на примере n=3): caml_curry_3 fn = fun a -> fun b -> fun c -> fn a b c Только, в отличие от того, что компилятор сгенерит для этого текста (а сгенерит он все ту же тернарную функцию, код для этих функций генерируется компилятором "вручную" при сборке исполняемого модуля и получается "список" ссылающихся друг на друга одноместных замыканий - в прямом соотвествии с текстом. Про caml_applyN: caml_apply_3 fn a b c = fn a b c А вот тут хитро: реально-то caml_apply_3 смотрит на указанное в замыкании число аргументов функции - если оно равно 3 - то он немедленно применяет fn к этим аргументам "напрямую" (адрес fn лежит в замыкании, создаваемом caml_curryN). Если же нет - то вызывает "поодиночке" столько замыканий, сколько надо - то есть "буквально" реализует синтаксис (((fn a) b) c). То есть реальный код для примера из конца предыдущего поста let compose = fun f -> fun g -> fun x -> f (g x) let sp = compose succ pred Будет: .long 3319 compose_closure: .long caml_curry3 .long 7 -- 3 аргумента .long compose _main: movl $camlMain, %ecx movl $pred_closure, %ebx movl $succ_closure, %eax call caml_apply2 movl %eax, camlMain + 4 -- сохранение результата-замыкания compose: -- повтор из предыдущего поста subl $4, %esp movl %eax, 0(%esp) movl %ecx, %eax movl (%ebx), %edx call *%edx movl 0(%esp), %ebx movl (%ebx), %ecx addl $4, %esp jmp *%ecx Вот в таком вот разрезе. Зачем это надо - точно сказать не возьмусь: гипотезы две - либо по результатам изысканий с профайлером там лучше, либо есть какие-то заморочки с полиморфизмом (весьма вероятно, кстати, |
||||||||||||||
![]() |
![]() |