Блоки Ruby / закрытие Java в C

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

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

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

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

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

«Итак, как бы вы реализовали Ruby-блоки / Java-замыкания на C?» По крайней мере, пока не будет выпущена Java 7, такого понятия, как закрытие Java, не существует.

Rafa Castaneda 30.01.2010 03:23

Да, именно поэтому я прямо перед этим сказал «закрытие предложений для Java».

Julio César 03.02.2010 05:06
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
6
2
1 291
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

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

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

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

Ruby_Blocks.pdf

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

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

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

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

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

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

Другие вопросы по теме