Я пытался понять, как работают блоки Ruby, и для этого я пытался реализовать их на C.
Один простой способ реализовать замыкания - передать void* во включающий стек в замыкание / функцию, но блоки Ruby, похоже, также обрабатывают операторы return и break из области, в которой используется блок.
loop do
break i if (i >= 4000)
i *= 2
end
Я думаю, что одно из предложений по закрытию для Java работает так же.
Итак, как бы вы реализовали Ruby-блоки / Java-замыкания на C?
Да, именно поэтому я прямо перед этим сказал «закрытие предложений для Java».




Концепция замыканий требует концепции контекстов. Контекст C основан на стеке и регистрах ЦП, поэтому для создания блока / закрытия вам необходимо иметь возможность управлять указателем стека правильным (и повторно входимым) способом и сохранять / восстанавливать регистры по мере необходимости.
Интерпретаторы или виртуальные машины делают это так, чтобы иметь структуру context или что-то подобное, а не использовать стек и регистры напрямую. Эта структура отслеживает стек и, возможно, некоторые регистры, если вы разрабатываете виртуальную машину на основе регистров. По крайней мере, это самый простой способ сделать это (хотя и немного менее производительный, чем на самом деле правильно отображать объекты).
В рамках курса "Rails with Passion" есть хороший набор слайдов по Ruby Blocks:
Это охватывает представление блока, то, как они получают переданные аргументы и выполняются, и даже дальше, в таких вещах, как объекты Proc. Это очень ясно объяснено.
Тогда может быть интересно посмотреть, как ребята из JRuby справились с этим при синтаксическом разборе на Java. Взгляните на источник на кодхаус.
Я на самом деле ничего из этого не реализовал, так что относитесь к этому с мешком соли.
В завершение есть две части: среда данных и среда кода. Как вы сказали, вы, вероятно, можете передать void * для обработки ссылок на данные. Вероятно, вы могли бы использовать setjmp и longjmp для реализации нелинейных переходов потока управления, которые требуются для Ruby break.
Если вам нужны замыкания, вам, вероятно, следует программировать на языке, который действительно их поддерживает. :-)
ОБНОВЛЕНИЕ: в Clang происходят интересные вещи. Они создали прототип замыкания для C. http://lists.cs.uiuc.edu/pipermail/cfe-dev/2008-August/002670.html может оказаться интересным чтением.
«Итак, как бы вы реализовали Ruby-блоки / Java-замыкания на C?» По крайней мере, пока не будет выпущена Java 7, такого понятия, как закрытие Java, не существует.