"И назову ее лямбда..." - 2

топ 100 блогов ru_declarative — 27.01.2010 Часть в общем вторая к этому вот:

http://kouzdra.livejournal.com/327847.html
X-Posted: http://lj.rossia.org/users/kouzdra/813843.html
X-Posted: http://community.livejournal.com/ru_declarative/94117.html

Итак: что на самом деле происходит в 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



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

Оставить комментарий

Предыдущие записи блогера :
Архив записей в блогах:
Сегодня, 26 сентября 2019 года, всё прогрессивное человечество отмечает 50-летие со дня выхода "Abbey Road" - 12-го студийного альбома британской группы The Beatles, который вышел 26 сентября 1969 года. И я решил не проходить мимо этой даты в своей рубрике и рассказать о "Here Comes ...
30 марта 1973 года вышел "Sextant" - одиннадцатый студийный альбом Херби Хэнкока, выпущенный лейблом Columbia. Это последний альбом секстета эпохи Мвандиши с участием саксофониста Бенни Мопена, трубача Эдди Хендерсона, тромбониста Джулиана Пристера, басиста Бастера Уильямса и ...
Вдруг из подворотни Страшный великан, Рыжий и усатый Та-ра-кан! Таракан, таракан, Тараканище! Помните, в 90-х были передачи, где герои проходили различные испытания? Одним из испытаний было проползти по какому-нибудь ящику с личинками и жуками... В общем, герои должны были пережить ...
Паспорт в Украине выдавали по достижению 16 лет. С 1 января 2016 года, паспорт будут выдавать с 14 лет. Внутренний паспорт в Украине выдавали в течение 30 дней. С 1 января 2016 года будут выдавать в течение 10 дней. С нового года вместо бумажных паспортов-книжечек советского образца ...
Первый день лета встретил нас дождиком :) 1 июня — не только первый день лета, но и международный день детей. А ещё — всемирный день родителей. О как! Сколько праздников мы знаем, ...