Рубиновые блоки / Java-замыкания в C

Я пытался понять, как работают блоки Ruby, и для этого я пытался реализовать их в C.

Один простой способ реализовать замыкания - это передать a void*во вмещающий стек в замыкание / функцию, но блоки Ruby, похоже, также обрабатывают операторы return и break из области, в которой используется этот блок.

loop do
  break i if (i >= 4000)
  i *= 2
end

Я думаю, что одно из предложений замыканий для Java работает так же.

Итак, как бы вы реализовали Ruby-блоки / Java-замыкания в C?

21.08.2008 13:17:50
«Итак, как бы вы реализовали Ruby-блоки / Java-замыкания в C?» По крайней мере, до выхода Java 7 не существует такого понятия, как Java-замыкания.
Rafa Castaneda 30.01.2010 00:23:52
Да, именно поэтому я сказал "закрытие предложений для Java" прямо перед этим.
Julio César 3.02.2010 02:06:49
3 ОТВЕТА
РЕШЕНИЕ

Понятие замыканий требует понятия контекстов. Контекст С основан на стеке и регистрах ЦП, поэтому для создания блока / замыкания необходимо иметь возможность корректно (и повторно вводить) манипулировать указателем стека и сохранять / восстанавливать регистры по мере необходимости.

То, как это делается интерпретаторами или виртуальными машинами, заключается в том, чтобы иметь contextструктуру или нечто подобное, а не использовать стек и регистры напрямую. Эта структура отслеживает стек и, возможно, некоторые регистры, если вы разрабатываете виртуальную машину на основе регистров. По крайней мере, это самый простой способ сделать это (хотя и немного менее производительный, чем на самом деле правильное отображение).

10
26.12.2011 02:00:48

В рубрике "Rails with Passion" есть хороший набор слайдов по Ruby Blocks:

Ruby_Blocks.pdf

Это охватывает представление блока, то, как они передают аргументы и выполняются, и даже дальше в такие вещи, как объекты Proc. Это очень четко объяснено.

Тогда может быть интересно посмотреть, как ребята из JRuby справились с этим при анализе на Java. Посмотрите на источник в Codehaus .

2
22.08.2008 12:07:59

Я на самом деле не реализовал ничего из этого, поэтому возьмите это с мешком соли.

Закрытие состоит из двух частей: среды данных и среды кода. Как вы сказали, вы, вероятно, можете передать void * для обработки ссылок на данные. Вероятно, вы могли бы использовать setjmp и longjmp для реализации нелинейных переходов потока управления, которые требуются в Ruby break.

Если вы хотите замыкания, вы, вероятно, должны программировать на языке, который на самом деле их поддерживает. :-)

ОБНОВЛЕНИЕ: интересные вещи происходят в Clang. Они прототипировали закрытие для C. http://lists.cs.uiuc.edu/pipermail/cfe-dev/2008-August/002670.html может оказаться интересным чтением.

3
4.09.2008 04:57:20