Show HN: Kent Dybvig's Scheme Machine in 400 Lines of C (Heap-Memory Model)
Виртуальная машина для языка Scheme реализована на C с использованием кучи для хранения пар. Основана на модели из работы Дабвига «Three Implementation Models for Scheme», что делает её компактным учебным примером интерпретатора Lisp-подобных языков.
Лексический анализатор разбивает входную строку на токены, а парсер строит из них списковые структуры через функцию cons. Пары хранятся в статическом массиве text, что упрощает управление памятью. Поддерживаются базовые конструкции: атомы, списки, цитирование через апостров. Вывод структур реализован рекурсивно с учётом точечной нотации.
Комментарии (40)
- Обсуждение производительности и особенностей различных реализаций Scheme, включая Chez Scheme, MIT Scheme и другие.
- Упоминание роли Кента Дибвига как создателя Chez Scheme и его влияния как преподавателя и исследователя.
- Вопросы о технических деталях и возможных ошибках в представленном коде, включая проблемы с указателями и порядком вычислений.
- Идеи о бутстраппинге компиляторов и интерпретаторов, включая использование LLM для генерации ассемблерного кода.
- Общие положительные отзывы о минималистичных и элегантных реализациях Scheme, таких как обсуждаемый код.
How Ruby executes JIT code
Где живёт JIT-код
Ruby не выбрасывает байт-код — он остаётся в ISEQ. В структуре метода поле jit_entry либо NULL (интерпретатор), либо адрес скомпилированной машинной функции. Байт-код нужен для деоптимизации.
Как Ruby запускает JIT
Перед каждым вызовом метода VM проверяет jit_entry. Если указатель не нулевой — переход на него, иначе обычный интерпретатор. Одна проверка, один jmp.
Когда компилировать
ZJIT ждёт 25 вызовов для профилирования и 30 для компиляции (числа настраиваются). Пока счётчик jit_entry_calls не достигнет порога, метод работает в байт-коде.
Почему возвращаются к интерпретатору
JIT делает упрощающие предположения (типы, классы). Если они нарушаются — контроль возвращается к байт-коду, который всегда корректен. Это «деоптимизация»: быстро, но безопасно.
Комментарии (20)
- Участники обсуждают, возможно ли ускорить Ruby с помощью фонового JIT, который постепенно перекомпилирует методы по мере накопления профильной информации (tiered compilation уже есть в .NET и JS-движках).
- Предложен снимок «прогретой» VM для мгновенного старта, но проблема — глобальное состояние C-библиотек; Emacs делает это через unexec.
- MRI Ruby не распараллеливает потоки и не дружит с JIT: язык позволяет динамически менять классы, что ломает оптимизации.
- Альтернатива — JRuby/TruffleRuby на JVM, но они теряют часть динамики и накладывают ограничения JVM.
- Соглашение: Ruby вряд ли догонит Java по скорости из-за динамической типизации и дизайна языка.
Lisp interpreter with GC in <750 lines of Odin (and <500 lines of C)
Проект LISP
Репозиторий krig/LISP заархивирован 28 авг 2025 г. и доступен только для чтения.
Разработка перенесена на Forgejo.
Комментарии (32)
- Участники обсудили, что минималистичность Lisp объясняется простотой синтаксиса (s-выражения) и всего трёх базовых форм: quote, cond, lambda.
- @krig показал свой 750-строчный интерпретатор на Odin, подчеркнув, что это учебный проект, а не продакшн-решение.
- Появились вопросы по синтаксису Odin (различие := и =), а также замечания о скорости и полезности такого «игрушечного» кода.
- Упомянули полезные ссылки: оригинальную статью Маккарти, объяснение Грэма, описание semi-space GC от Andy Wingo.
- Некоторые участники поделились личными впечатлениями о создателе Odin и культуре обсуждений вокруг языка.