Hacker News Digest

Тег: #racket

Постов: 9

Structure and Interpretation of Classical Mechanics (2014) (tgvaughan.github.io)

Классическая механика в интерпретации Сассмана и Виздомса представлена как вычислительная дисциплина, где математические структуры реализуются через программирование. Второе издание неофициальной HTML-версии книги MIT охватывает лагранжеву и гамильтонову механику, твердые тела и канонические преобразования, предлагая читателям глубокое понимание фундаментальных физических законов через призму вычислений.

Книга уникальна своим подходом к механике: она использует Scheme для реализации физических концепций, исследует такие темы как принцип стационарного действия, уравнения Эйлера-Лагранжа, тензор инерции и теорему Нётер. Особое внимание уделяется вычислительным методам анализа механических систем, включая поверхности сечения, экспоненциальное расхождение и теорему Лиувилля, что делает текст одновременно теоретическим и практическим руководством для изучающих классическую механику с вычислительной точки зрения.

by the-mitr • 27 октября 2025 г. в 04:27 • 96 points

ОригиналHN

#scheme#racket#mit#classical-mechanics#lagrangian-mechanics#hamiltonian-mechanics#computational-physics

Комментарии (37)

  • Обсуждение вращается вокруг книги SICP и её влияния на образ мышления, а также вокруг трудностей запуска примеров кода и альтернативных реализаций.
  • Участники обсуждают, как лучше всего подойти к изучению фундаментальных концептов, и какие инструменты (например, Scheme в Racket или scmutils в MIT Scheme) лучше всего подходят для этого.
  • Также поднимается вопрос о том, как современные технологии и подходы могли бы облегчить обучение и взаимодействие с такими фундаментальными концептами.
  • Некоторые участники делятся личными историями о том, как они познакомились с книгой и как она повлияла на их мышление и подход к программированию.
  • Обсуждается идея написать современный аналог "Structure and Interpretation of Classical Mechanics" и "Structure and Interpretation of Quantum Mechanics" с использованием современных инструментов и подходов.

Delimited Continuations in Lone Lisp (matheusmoreira.com)

Lone Lisp теперь поддерживает ограниченные продолжения — мощный механизм управления потоком выполнения. Это позволяет сохранять и восстанавливать состояние вычислений в определённых точках, что открывает путь к реализации генераторов, обработки исключений и других сложных конструкций. Пример кода демонстрирует, как control и transfer работают вместе: (control ...) захватывает контекст, а (transfer ...) передаёт управление, позволяя гибко манипулировать выполнением.

Изначально проблема возникла при реализации итераций: из-за рекурсивной природы интерпретатора и управления стеком на уровне C было невозможно контролировать поток. Решение потребовало переосмысления архитектуры — вместо байткода или трансформаций в стиле продолжений автор выбрал подход, сохраняющий списковую структуру Lisp. Это сложный, но фундаментальный шаг, вдохновлённый классическими работами вроде SICP.

by matheusmoreira • 03 октября 2025 г. в 05:52 • 104 points

ОригиналHN

#lisp#delimited-continuations#control-flow#functional-programming#ocaml#racket#haskell#java#fibers#concurrency

Комментарии (8)

  • Wat реализует стек вызовов в пользовательском пространстве для поддержки ограниченных продолжений, что позволяет создавать исключения, ветвление и файберы.
  • Вопрос о практическом применении ограниченных продолжений за пределами хобби-проектов и их реальном использовании в промышленности.
  • Примеры использования в Ocaml 5 (библиотека Eio), Haskell (GHC, работа приостановлена) и Racket (стандартная модель для обработки ошибок и прерываний).
  • Java использует ограниченные продолжения как основу для своих новых "зеленых" потоков (виртуальных потоков).
  • Обсуждение потенциальных сфер применения, таких как встраиваемые системы.

Why I chose Lua for this blog (andregarzia.com)

Автор перевел свой блог с Racket на Lua, чтобы снизить сложность и обеспечить долгосрочную стабильность. Основная причина — разочарование в быстро меняющихся экосистемах вроде JavaScript и Ruby, где постоянные обновления и ломающие изменения усложняют поддержку. Lua привлек медленным развитием: между версиями 5.1 (2006) и 5.4 (2020) различия минимальны, а язык требует лишь компилятора C89.

Блог работает по старинке — через CGI-скрипты, с SQLite в качестве базы и шаблонизацией Mustache. Несмотря на кажущуюся архаичность, автор ценит простоту, минимальное количество зависимостей (около десяти) и возможность писать собственные легковесные библиотеки. Ключевой вывод: блог — это пространство для экспериментов, где можно отказаться от модных инструментов в пользу того, что действительно работает и приносит удовольствие.

by nairadithya • 02 октября 2025 г. в 16:58 • 186 points

ОригиналHN

#lua#racket#javascript#ruby#sqlite#mustache#cgi#hugo#python

Комментарии (135)

  • Предложение возродить создание собственных движков для блогов как учебного проекта для инженеров из-за его низкого риска и возможностей для экспериментов.
  • Обсуждение выбора Lua как стабильного и минималистичного языка для веб-разработки, несмотря на его недостатки (1-based индексация, разрыв между версиями, мало стандартных библиотек).
  • Критика сложности современных стеков для блогов и аргументы в пользу простых решений: статические генераторы (Hugo), чистый HTML или минимальные скрипты (Python, Lua).
  • Упоминание альтернативных технологий и подходов: Redbean, Perl, Caddy, XSLT, Web Components, Fennel, OpenResty и другие.
  • Подчёркивание важности личного выбора, удовольствия от процесса и независимости от внешних сервисов при создании блога.

Knotty: A domain-specific language for knitting patterns (t0mpr1c3.github.io) 🔥 Горячее

Knotty — это предметно-ориентированный язык (DSL) для описания вязальных паттернов, реализованный в Racket. Он позволяет программировать схемы вязания, используя код вместо традиционных графических или текстовых инструкций. Основная идея заключается в автоматизации создания сложных узоров, что упрощает работу дизайнеров и энтузиастов.

Язык предоставляет модули для ввода-вывода данных, примеры кода и справочник, облегчая освоение и применение. Knotty демонстрирует, как нишевые DSL могут решать специализированные задачи, сочетая программирование с ремеслом.

by todsacerdoti • 25 сентября 2025 г. в 06:13 • 323 points

ОригиналHN

#racket#domain-specific-language#functional-programming#automation#diy

Комментарии (49)

  • Обсуждение исторических связей между программируемыми ткацкими станками (Жаккардовы машины) и современными компьютерами.
  • Восхищение проектом как примером элегантного и практичного инженерного решения, продолжающего исторические традиции.
  • Размышления о параллелях между вязанием и функциональным программированием, где физические ограничения сравниваются с системой типов.
  • Интерес к современным DIY-станкам для вязания и возможностям автоматизации создания узоров с помощью ИИ.
  • Шуточные комментарии об ожиданиях увидеть что-то другое (например, терминальный эмулятор) и отсылки к поп-культуре.

Scream cipher (sethmlarson.dev) 🔥 Горячее

В Unicode существует больше символов, обозначающих «латинскую заглавную букву A», чем букв в английском алфавите. Это наблюдение вдохновило на создание «шифра крика» — замены каждой буквы на один из вариантов A с диакритическими знаками. Например, фраза «SCREAM CIPHER» превращается в «ǠĂȦẶAẦ ĂǍÄẴẶȦ», что выглядит как набор кричащих символов.

Функции SCREAM и unscream реализуют прямое и обратное преобразование, сохраняя при этом регистр и игнорируя не-буквенные символы. Такой подход демонстрирует игривое использование Unicode для создания визуально эффектного, но семантически тривиального шифрования.

by alexmolas • 18 сентября 2025 г. в 09:22 • 284 points

ОригиналHN

#unicode#encryption#python#javascript#racket#rot13#cryptography

Комментарии (97)

  • Представлена кодировка zalgo256 с использованием комбинирующих символов Unicode для создания "кричащего" шифра, аналогичного моноалфавитной замене.
  • Обсуждаются юмористические и практические аспекты шифра, включая сравнение с ROT13, отсылки к XKCD и потенциальное применение для обхода ограничений длины строк.
  • Участники делятся своими реализациями на разных языках (Python, JS, Racket) и идеями по скрытию данных с помощью невидимых символов или эмодзи.
  • Поднимаются вопросы безопасности, указывается на отсутствие криптостойкости и обсуждаются технические детали работы с графемными кластерами в Unicode.
  • Шифр вызвал оживлённую реакцию, включая шутки о "песчаных людях" из Star Wars и создание чат-ботов для кодирования.

Anonymous recursive functions in Racket (github.com)

Репозиторий показывает, как в Racket писать анонимные рекурсивные функции без letrec и имен.
Ключевая идея — Y-комбинатор: лямбда получает себя как аргумент и вызывает его для следующего шага.

(define Y
  (λ (f)
    ((λ (x) (x x))
     (λ (x) (f (λ (a) ((x x) a)))))))

((Y (λ (fact)
      (λ (n)
        (if (zero? n) 1 (* n (fact (sub1 n)))))))
 5) ; 120

Такой приём работает для любой рекурсии: факториал, fib, обход списков и т.д.

by azhenley • 04 сентября 2025 г. в 00:39 • 80 points

ОригиналHN

#racket#scheme#functional-programming#recursion#y-combinator#lambda-calculus#clojure#python#go#github

Комментарии (37)

  • Обсуждение началось с примера анонимной рекурсии на Racket; оказалось, что код совместим с любым R6RS-Scheme, включая проект scheme-rs.
  • Участники сравнили подходы: в Clojure нужен явный recur, в Racket хвостовые вызовы оптимизируются автоматически.
  • Кто-то спросил, стоит ли брать Racket для повторного изучения ФП; советуют почитать «zen of Racket» и быть готовым к узкой, но мощной экосистеме.
  • Появились порты идеи на Python и Go (через Y-комбинатор), но часть людей предпочла бы обычный цикл для отладки.
  • Сообщество предупреждает: в нишевых языках придётся уметь докручивать библиотеки «с нуля» и держать редких специалистов.

Recto – A Truly 2D Language (masatohagiwara.net)

Recto — язык, где код — это вложенные прямоугольники. Он не читается сверху вниз, а воспринимается пространственно: структура и рекурсия задаются формой, а не текстом.

Идея

Большинство языков — линейны: слова идут одно за другим. Recto отказывается от этой традиции и возвращается к древним «картам мыслей» — пиктограммам, звёздным картам, схемам. Главное требование к языку:

  1. Понятен человеку и машине.
  2. Может быть создан человеком и машиной.

Линейность не обязательна: можно представить «приложение», где жест или выражение лица превращается в сетку эмодзи, и всё работает.

Примеры

  • Hello Recto — прямоугольник, внутри которого текст Hello Recto.
  • Арифметика — прямоугольники-числа и операторы встраиваются друг в друга, образуя выражения.
  • Факториал — рекурсивный прямоугольник ссылается на себя.

Почему это важно

Recto показывает, как можно писать, парсить и мыслить кодом без строк и файлов. Он открывает путь к языкам, где значение рождается из формы, а не последовательности символов.

Попробовать: Recto Pad | Google Colab | GitHub

by mhagiwara • 12 августа 2025 г. в 15:06 • 131 points

ОригиналHN

#recto#programming-languages#path#befunge#hexagony#orca#racket#unreal-blueprints#emit

Комментарии (58)

  • Участники обсуждают Recto как «2D-язык», но многие считают его всё же 1D с «скобками и лишними шагами».
  • Поднимаются примеры других 2D/3D-языков: PATH, Befunge, Hexagony, Orca, Unreal Blueprints, Racket 2d.
  • Спор о том, считать ли нотный стан или речь по-настоящему многомерными; автор статьи настаивает на их 1D-основе.
  • Предлагаются улучшения: полноценная графическая среда, Unicode-рамки, поддержка VR/AR, именованные параметры.
  • Упомянуты эксперименты с «временем» как измерением (EmiT, ICFPC 2024).
  • Автору пожелали сил в борьбе с раком и скинули ссылки на GoFundMe и CaringBridge.

Compiling a Lisp: Lambda lifting (bernsteinbear.com)

Переписал Ghuloum-туториал на Python (~300 строк). Убрал читалку S-выражений и бинарный код — теперь текстовая ассемблерная печать.

Lambda-lifting требует:

  • знать связанные переменные;
  • собирать свободные переменные лямбд;
  • накапливать создаваемые code-объекты.

Связывают let и lambda; для них обновляем окружение.

Lifter

class LambdaConverter:
    def __init__(self):
        self.labels = {}

    def convert(self, expr, bound, free):
        match expr:
            case int() | Char() | bool():
                return expr
            case str() if expr in bound or expr in BUILTINS:
                return expr
            case str():
                free.add(expr)
                return expr
            case ["if", t, c, a]:
                return ["if",
                        self.convert(t, bound, free),
                        self.convert(c, bound, free),
                        self.convert(a, bound, free)]

lift_lambdas запускает обход и возвращает (labels …).

Lambda

Лямбда:

  • связывает параметры;
  • выделяет код;
  • захватывает внешнее окружение.

Пример:

(lambda () x)  ; x свободна

превращается в

(labels ((f0 (code () (x) x)))
  (closure f0 x))

Даже если x связан снаружи, внутри лямбды он считается свободным.

by azhenley • 10 августа 2025 г. в 22:35 • 146 points

ОригиналHN

#python#lisp#compiler#lambda-lifting#racket#scheme#c#c++#cuda#artificial-intelligence

Комментарии (15)

  • Участники рекомендуют три современные книги по компиляторам, вдохновлённые статьёй Ghuloum: «Writing a C Compiler» (Sandler), «Essentials of Compilation» на Racket и Python (Siek).
  • Обсуждали «lambda lifting»: преобразование, выносящее замыкания наверх, уменьшая их размер вплоть до полного исчезновения.
  • Уточнили, что «lambda lifting» в статье связан с разделом 3.11 о сложных константах в Scheme.
  • Разбирали, почему современный ИИ использует Python, а не Lisp: удобство как «клея» для C++/CUDA, упадок доли рынка Lisp и смена парадигмы ИИ.

Why tail-recursive functions are loops (kmicinski.com)

Хвостовая рекурсия превращает рекурсию в цикл: компилятор заменяет вызов на безусловный jmp, поэтому стек не растёт.

Обычная рекурсия кладёт промежуточные значения в стек, тратит O(n) памяти и вытесняет кэш.
Цикл же держит результат в аккумуляторе, использует O(1) памяти и линейное время.

Ключевое правило хвостовой рекурсии:
вызов должен быть последним выражением функции. Тогда компилятор может выбросить текущий фрейм и передать управление напрямую.

Пример суммы списка

Обычная версия:

(define (sum l)
  (if (empty? l) 0
      (+ (first l) (sum (rest l)))))

Хвостовая версия:

(define (sum l acc)
  (if (empty? l) acc
      (sum (rest l) (+ acc (first l)))))

Аргументы l и acc перезаписываются «на месте», как переменные цикла.

Упражнение 1 — счётчик чётных/нечётных:

(define (even-odd l [e 0] [o 0])
  (if (empty? l) (cons e o)
      (let ([x (first l)])
        (if (even? x)
            (even-odd (rest l) (add1 e) o)
            (even-odd (rest l) e (add1 o))))))

Упражнение 2 — сглаживание дерева:
используйте аккумулятор-список и обход в обратном порядке, чтобы сохранить хвостовой вызов.

by speckx • 08 августа 2025 г. в 15:10 • 115 points

ОригиналHN

#recursion#tail-call-optimization#racket#functional-programming#algorithms

Комментарии (121)

  • Теоретически хвостовая рекурсия и циклы эквивалентны: любую хвостовую рекурсию можно превратить в цикл (и наоборот), но взаимно-рекурсивные функции требуют дополнительной работы.
  • На практике циклы чаще проще для чтения и не ломают стек, тогда как хвостовая рекурсия нуждается в оптимизации (TCO), которую не все языки поддерживают (Python, V8 её нет).
  • Некоторые языки (Scala, Clojure, F#) дают компромиссные конструкции (@tailrec, recur), сохраняющие функциональный стиль и гарантирующие отсутствие переполнения стека.
  • Вместо явной хвостовой рекурсии часто достаточно высокоуровневых комбинаторов вроде fold/map, но они не всегда позволяют досрочный выход и могут расходовать O(N) памяти.
  • Участники сходятся во мнении: владеть обоими подходами полезно, выбор зависит от языка, задачи и привычек команды.