Myna: Monospace typeface designed for symbol-heavy programming languages 🔥 Горячее 💬 Длинная дискуссия
Представлен шрифт Myna — моноширинный типографский шрифт, специально разработанный для программирования с обилием символов. Авторы создали его с фокусом на улучшении читаемости кода за счет оптимального распределения пространства между символами и четкого отображения специальных знаков.
Шрифт поддерживает широкий набор символов, включая математические обозначения, операторы и диакритические знаки, что делает его универсальным инструментом для разработчиков. Проект открыт на GitHub, где доступны файлы шрифта и документация по его использованию.
Комментарии (169)
- Обсуждение началось с обсуждения шрифта Iosevka и его особенностей, включая то, что он не поддерживает лигатуры, что вызвало обсуждение о том, что такое лигатуры и как они влияют на читаемость кода.
- Участники обсуждали, что такое "язык, насыщенный символами", и какие языки программирования могут быть отнесены к этой категории, включая Perl и Haskell.
- Обсуждались проблемы с отсутствием поддержки Unicode в шрифтах, и как это влияет на работу с различными языками программирования.
- Участники обсуждали, что такое "моношириный" и "пропорциональный" шрифт, и как они влияют на читаемость кода.
- В конце обсуждение перешло к тому, что выбор шрифта для кода - это вопрос личных предпочтений, и что важно найти баланс между эстетикой и функциональностью.
Why I love OCaml (2023) 🔥 Горячее 💬 Длинная дискуссия
Автор делится своим опытом работы с различными языками программирования, объясняя, почему OCaml стал его любимым языком. Он начал с Haskell, который оценил за функциональное программирование и статическую типизацию, но столкнулся с его сложностью и медленной компиляцией. Позже он попробовал Go, который понравился своей простотой, скоростью компиляции и хорошими инструментами, но разочаровал многословностью обработки ошибок и отсутствием функциональных возможностей. OCaml, по мнению автора, сочетает в себе лучшее из обоих миров: функциональные конструкции, статические гарантии, быструю компиляцию, простую семантику выполнения и отличную документацию. Особо отмечается, что OCaml компилируется в один статический бинарный файл, как Go, но при этом имеет более мощную систему типов и REPL. Автор считает, что создатели OCaml обладают хорошим вкусом, а язык представляет собой идеальный баланс между простотой и выразительностью.
Комментарии (267)
- OCaml не стал мейнстримом из-за синтаксиса, отсутствия нативных библиотек и слабой экосистемы, но его идеи (pattern-matching, type inference, algebraic data types) уже давно живут в Rust, Swift, TypeScript и даже Go.
- Фактически OCaml — это «нативный» вариант F#, но без .NET-экосистемы, а F# — это OCaml без его синтаксиса и с .NET вместо OCaml-стандартной библиотеки.
- Попытка ReasonML привнести более C-подобный синтаксис вместо ужасающего синтаксиса OCaml закончилась тем, что Facebook забросил проект, а вся индустрия JS-инструментов осталась без единого стандарта.
- Попытка Facebook-а внедрить Reason вместо TypeScript внутри Facebook показала, что даже если синтаксис и не является проблемой, то отсутствие единого стандарта для сборки и пакетов в JS-мире оставляет язык без шанса.
- Несмотря на то, что OCaml — это язык с 25-летней историей, он не имеет ни мультиплатформенной сборки, ни нормального менеджера пакетов, ни нормального REPL, что делает его неподготовленным к работе вне Unix-подобных систем.
Control structures in programming languages: from goto to algebraic effects
Книга Ксавье Леруа исследует эволюцию управляющих конструкций в языках программирования, от ранних операторов goto до современных алгебраических эффектов. Работа представляет собой историческое путешествие по дизайну языков, уделяя особое внимание механизмам контроля выполнения программ. Книга охватывает структурированное программирование 1960-х, генераторы и корутины в императивных языках, а также продолжения и операторы контроля в функциональных языках.
Книга разделена на четыре части: управляющие конструкции для императивных языков, операторы контроля для функциональных языков, от исключений к алгебраическим эффектам и обработчикам, а также рассуждения о контроле и эффектах. Особую ценность представляют многочисленные примеры кода на разных языках — от Fortran и Algol 60 до OCaml и Haskell. Работа сочетает историю, практические примеры и теорию, предлагая оригинальный сравнительный взгляд на языки программирования и обширное введение в алгебраические эффекты — современную область исследований в PL.
Комментарии (29)
- Критика исключений как "glorified come from", сравнение с POSIX сигналами и setjmp/longjmp.
- Дискуссия о checked исключениях в Java vs подход "ошибки как данные" для ожидаемых сбоев.
- Вопрос производительности алгебраических эффектов и ответ: реализация возможна через монады, оптимизирована в OCaml 5.
- Упоминание Xavier Leroy как автора CompCert, LinuxThreads и ключевой фигуры OCaml/Rocq.
- Шутка про INTERCAL и "come from" как пример необычного синтаксиса.
GHC now runs in the browser 🔥 Горячее
GHC теперь может работать полностью на стороне клиента в браузере через WebAssembly, демонстрируя значительный прогресс в разработке GHC WASM бэкенда. Это позволяет создавать интерактивные Haskell playground прямо в браузере без необходимости серверной части. Однако реализация имеет ограничения: используется байткод интерпретатор вместо компиляции в WASM, а cabal не поддерживается из-за отсутствия поддержки процессов. Для использования сторонних пакетов требуется предварительная компиляция через wasm32-wasi-cabal.
Проект сталкивается с некоторыми техническими вызовами, включая необходимость загрузки и извлечения около 50MB корневой файловой системы, что может вызывать временные зависания интерфейса. В некоторых браузерах, таких как Brave и Safari, возникают дополнительные проблемы с работой веб-воркеров. Тем не менее, эта технология открывает возможности для создания полностью интерактивных онлайн-курсов по Haskell и других веб-приложений, написанных на Haskell, работающих непосредственно в браузере пользователя.
Комментарии (119)
- Обсуждение началось с вопроса о том, что WASM-версия GHC действительно запускает код в браузере, но не решает проблемы «бутстрапа» и воспроизводимых сборок, что делает Haskell невозможным для включения в дистрибутивы.
- Участники обсудили, что язык всё ещё жив, но отсутствие возможности полностью собрать его из исходников делает его «мертвым» с точки зрения дистрибутивов.
- Появились сомнения в том, что Haskell всё ещё актуален, и обсуждались ресурсы для изучения языка и практического применения.
- Также обсудили, что WASM-порт GHC демонстрирует прогресс бэкэнда, но не затрагивает проблему полного порта компилятора на новую архитектуру.
- В конце обсуждение сошлось на то, что язык всё ещё используется в продакшене и имеет практическое применение, а также что WASM может быть полезен не только в браузере, но и в других сценариях.
Free applicatives, the handle pattern, and remote systems
Команда Bellroy автоматизировала работу с ERP-системой, где каждый запрос к API требует предварительных шагов — например, чтобы создать запись, нужен ID другой сущности, что требует дополнительных запросов.
Умный подход: вместо цепочки запросов "запроси A, затем с результатом запроси B" они используют аппликативные функторы. Эти структуры позволяют собрать все нужные запросы в один пакет (отсюда "free applicative"), отправить их разом и потом разобрать ответы, сопоставляя каждый с исходным запросом.
Так они избегают проблем "callback hell" и сохраняют код декларативным. Например, вместо ручной обработки каждого ответа они описывают граф запросов через Free Applicative, а исполнение — дело интерпретатора, который может батчить запросы и парсить ответы.
Особенно изящно это работает с "handle pattern", где каждая операция (типа "получить цену товара") представлена как handle, а реализации могут быть разными (реальная БД vs. мок для тестов). Аппликативы же позволяют комбинировать эти handles в сложные запросы, оставаясь агностичными к источнику данных.
В итоге, Bellroy получает код, где бизнес-логика описана как композиция handles, выполнение оптимизировано (батчинг, кеширование), а тесты пишутся просто — подменой handles на заглушки.
Комментарии (24)
- Bellroy, известный своими кошельками и аксессуарами, использует Haskell и Nix, что вызывает удивление и вопросы о масштабе и прибыльности компании.
- Пользователи обсуждают, как компания, которая начиналась как производитель кошельков, может позволить себе такой стек технологий.
- Обсуждение также затрагивает вопрос о том, как язык программирования и инструменты разработки могут влиять на продукт и его качество.
- Участники также обсуждают, как компания, которая начиналась как производитель кошельков, может позволить себе такой стек технологий.
- В конце, участники обсуждения приходят к выводу, что, возможно, это просто "разработчики, которые ушли в бизнес кошельков", и это может быть просто пример того, как красивые вещи могут появиться из самых неожиданных мест.
Why study programming languages (2022)
Новый язык программирования стоит создавать, если он позволяет выразить идеи или концепции, которые невозможно или неудобно описывать в существующих языках. Это не просто вопрос синтаксиса или семантики, но и всей экосистемы, включающей библиотеки, инструменты и сообщества. Например, Python ценят за богатство библиотек, делающих его универсальным, а Go — за простую модель параллелизма. Таким образом, язык программирования определяется синтаксисом, семантикой и экосистемой, которые вместе открывают новые направления для исследования и творчества. Создавайте смелые, даже непрактичные языки, чтобы исследовать неизведанное, а не просто решать известные задачи.
Комментарии (89)
- Обсуждение показало, что причины создания языков — от необходимости новых концептов до «потому что можем» — сильно варьируются, но не всегда очевидны.
- Участники подчеркнули, что «новые» идеи, такие как модель владения в Rust или ленивые вычисления в Haskell, на самом деле восходят к исследованиям, которые не были новыми, но вопрос в том, что языки не могут их реализовать без нарушения обратной совместимости.
- Обсуждение затронуло вопрос о том, что влияние LLM на будущее языков программирования может быть преувеличено, и что важнее всего — это удобство и эргономика, а не только синтаксис или парадигма.
- Участники также обсудили, что выбор языка часто диктуется не техническими, а социальными факторами, такими как доступность библиотек и инструментов.
- В конце обсуждение сошлось на то, что хотя языки и умирают, но их идеи часто переживают их и влияют на следующие поколения.
Delimited Continuations in Lone Lisp
Lone Lisp теперь поддерживает ограниченные продолжения — мощный механизм управления потоком выполнения. Это позволяет сохранять и восстанавливать состояние вычислений в определённых точках, что открывает путь к реализации генераторов, обработки исключений и других сложных конструкций. Пример кода демонстрирует, как control и transfer работают вместе: (control ...) захватывает контекст, а (transfer ...) передаёт управление, позволяя гибко манипулировать выполнением.
Изначально проблема возникла при реализации итераций: из-за рекурсивной природы интерпретатора и управления стеком на уровне C было невозможно контролировать поток. Решение потребовало переосмысления архитектуры — вместо байткода или трансформаций в стиле продолжений автор выбрал подход, сохраняющий списковую структуру Lisp. Это сложный, но фундаментальный шаг, вдохновлённый классическими работами вроде SICP.
Комментарии (8)
- Wat реализует стек вызовов в пользовательском пространстве для поддержки ограниченных продолжений, что позволяет создавать исключения, ветвление и файберы.
- Вопрос о практическом применении ограниченных продолжений за пределами хобби-проектов и их реальном использовании в промышленности.
- Примеры использования в Ocaml 5 (библиотека Eio), Haskell (GHC, работа приостановлена) и Racket (стандартная модель для обработки ошибок и прерываний).
- Java использует ограниченные продолжения как основу для своих новых "зеленых" потоков (виртуальных потоков).
- Обсуждение потенциальных сфер применения, таких как встраиваемые системы.
`std::flip`
std::flip — это малоизвестная утилита из стандартной библиотеки C++ в заголовке <functional>, которая принимает вызываемый объект и возвращает его аналог с обратным порядком параметров. Она особенно полезна для переворачивания предикатов, например, чтобы проверить, является ли один узел дерева потомком другого, создав функцию is_descendant_of через std::flip(is_ancestor_of), что зеркально отражает логику предка.
Идея пришла из функционального программирования: аналоги есть в Haskell, PureScript, OCaml и других языках, а также в библиотеках вроде Boost.Hana и Ramda. В сочетании с std::not_fn она позволяет выражать все операторы сравнения через один базовый предикат, упрощая generic-алгоритмы — например, проверку обратной сортировки или реализацию upper_bound через lower_bound. Это элегантный инструмент для сокращения кода и повышения его переиспользуемости.
Комментарии (97)
- Сомнения в существовании
std::flipв C++ и критика его потенциального имени и нишевости. - Обсуждение недостающих для функционального стиля элементов C++: сопоставление с образцом и унифицированный синтаксис вызова.
- Критика сложности предложенной реализации
flipи её потенциальной бесполезности или опасности. - Дебаты о практической полезности функции
flipи её аналогов в других языках. - Обсуждение проблем представления геоданных и применимости
flipкак потенциального источника ошибок.
Effect Systems vs. Print Debugging: A Pragmatic Solution
Системы эффектов в языках программирования, такие как в Flix, строго контролируют побочные действия вроде вывода в консоль, что мешает привычной отладке с помощью println. Ложь системе эффектов через unchecked_cast приводит к проблемам: компилятор удаляет «бесполезный» код без видимых эффектов или ломает семантику при оптимизациях.
Flix ищет прагматичный баланс между строгостью и удобством, предлагая временные решения для отладки без нарушения гарантий. Например, вводят функцию dprintln, которая обманывает систему эффектов, но рискует быть удалённой оптимизатором. Ключевой вывод: языки должны позволять гибкость там, где она нужна, без компромисса с безопасностью.
Комментарии (35)
- Обсуждается подход Flix к типизации эффектов, включая системные (например, Debug) и возможность создания пользовательских эффектов.
- Рассматриваются целевые use-case языка: платформенная независимость, совместимость с JVM/Java, применение в бэкенде и академические цели.
- Поднимаются вопросы о практичности системы эффектов: необходимость для оптимизаций, потенциальная избыточность и сложность.
- Обсуждается проблема автоматической параллелизации и оптимизации, включая риски переупорядочивания или удаления операций ввода-вывода.
- Упоминаются аналогичные реализации в других языках (Haskell, Koka, Roc, Effekt) и их эволюция в моделировании эффектов.
How to stop functional programming (2016)
Статья иронично описывает ситуацию, когда разработчика заставляют отказаться от функционального программирования из-за жалоб коллег. Менеджер принимает «техническое решение» запретить ФП, чтобы избежать конфликтов, и автор пытается следовать указанию, намеренно добавляя побочные эффекты в код.
Пример с функцией userCoworkers показывает, как чистый код постепенно усложняется: сначала добавляется мутабельная коллекция, затем логирование. Юмор в том, что даже с побочными эффектами метод остаётся чистым снаружи, а задание «просто вернуть число» ставит под вопрос, как вообще избежать функциональных подходов. Финальный совет — спросить у менеджера, как сложить числа без чистых функций — подчёркивает абсурдность таких запретов.
Комментарии (62)
- Важность написания читаемого кода с учетом целевой аудитории (уровня навыков читателей) и необходимости согласования стиля в команде.
- Критика восприятия функционального программирования (ФП) как исключительно сложного, с указанием, что проблема часто в неидиоматичном коде, излишне длинных цепочках методов или специфических особенностях языков (например, Haskell), а не в ФП как парадигме.
- Необходимость обучения, код-ревью и парного программирования для внедрения сложных концепций и выравнивания уровня команды, особенно при использовании нишевых языков (например, Scala).
- Споры о балансе между простотой (для младших разработчиков) и продвинутыми практиками, где чрезмерное упрощение может привести к посредственному коду, а сложность — к проблемам читаемости.
- Роль менеджмента в разрешении конфликтов через технические решения, которые могут ограничивать инструменты или стили (например, запрет ФП), иногда без глубокого понимания причин проблемы.
Death to type classes
Смерть классам типов!
Числа пасутся? Функторы поют? Нет — это ложь элит. Backpack вместо классов: сигнатуры модулей, а не class.
signature Functor (Functor, map) where
data Functor a
map :: (a→b) → Functor a → Functor b
Реализация для Maybe:
module Functor.Maybe where
type Functor = Maybe
map f (Just x) = Just (f x)
map _ Nothing = Nothing
Cabal: сигнатуры в library, реализации в library impl. Подмена через mixins:
mixins: death (Functor.Sig as Functor.Maybe)
Можно много реализаций в одном проекте: List, Maybe, IO — всё живёт рядом, без {-# LANGUAGE RebindableSyntax #-} не обойтись.
Итог: вместо классов — модули, вместо инстансов — реализации. Композиция через Backpack, а не instance.
Комментарии (67)
- Обсуждение сфокусировано на статье о Haskell, которая исследует альтернативный способ структурирования кода с использованием расширения Backpack, малоизвестного даже в сообществе Haskell.
- Многие комментаторы отмечают, что материал сложен для понимания и требует глубоких знаний как Haskell, так и модульной системы OCaml, что делает его недоступным для широкой аудитории.
- Поднимается вопрос о целевой аудитории: уместно ли публиковать узкоспециализированные посты на платформе с разнородной аудиторией и следует ли ожидать критики от тех, кто не входит в целевую группу.
- Одна из центральных тем — сравнение подхода Backpack с более традиционными для Haskell концепциями, такими как тип-классы, и обсуждение их преимуществ и недостатков.
- Некоторые участники дискуссии выражают скептицизм по поводу практической полезности Backpack, отмечая, что он почти не используется в реальных проектах.
- В комментариях также встречаются шутки и отсылки к мемам о сложности функционального программирования и его концепций (монад, функторов).
The Expression Problem and its solutions (2016)
Проблема выражений и её решения
Проблема выражений: нужно добавлять новые типы данных и новые операции без изменения старого кода.
В ООП-языках легко добавлять типы (наследование), но сложно — операции (менять интерфейс).
В функциональных языках наоборот: легко добавлять функции, сложно — варианты данных.
Пример на C++
Базовый класс Expr с двумя методами: Eval() и ToString().
Новый тип — просто новый класс-наследник.
Новая операция — правим базовый класс и все наследников, нарушая OCP.
Функциональный подход (Haskell)
Типы данных и функции разведены:
data Expr = Constant Double | BinaryPlus Expr Expr
eval (Constant x) = x
eval (BinaryPlus a b) = eval a + eval b
Добавить операцию легко: пишем новую функцию.
Добавить вариант Expr — правим сам тип и все функции, pattern-match’и которых его затрагивают.
Как быть
- Визитор (ООП) — двойная диспетчеризация, но код всё равно растёт.
- Мультиметоды (CLOS, Clojure) — выбор по типу всех аргументов, код не трогается.
- Type-class / протоколы (Haskell, Clojure) — «открытые» функции, реализуемые вне исходного модуля.
- Tagless-final / finally-tagless — выразить язык как набор операций, интерпретаторы добавляются без изменения AST.
Итог: ни один стиль не побеждает; выбираем язык и технику, которая даёт нужную сторону расширяемости.
Комментарии (69)
- Суть проблемы: нужно добавлять новые типы данных и новые операции без переписывания старого кода и без потери статической безопасности.
- Классический подход: O·T матрица — каждая операция реализуется для каждого типа; при росте O или T взрывается boilerplate.
- Языковые решения:
– трейты/impl в Rust, typeclass в Haskell, протоколы в Swift позволяют добавлять операции «сбоку»;
– enum (суммарные типы) упрощают добавление операций, но затрудняют новые варианты данных. - Продвинутые техники: tagless-final, object algebras, data types à la carte, multiple dispatch, visitor-pattern.
- Ограничения: «сиротское правило», отсутствие виртуальных extension-методов, необходимость заранее знать все комбинации при раздельной компиляции.
- Вывод: идеального языка нет; выбор зависит от того, что важнее — расширять типы или операции — и насколько нужна статическая типизация.
I'm working on implementing a programming language all my own
Я пишу свой язык Baba Yaga — чисто из любви к эстетике кода. Рабочий интерпретатор есть, но полноценной среды пока нет; планирую браузерный «бесконечный холст» в духе Smalltalk.
Язык — эксперимент ради удовольствия: неизменяемость, функциональный стиль, минимальный синтаксис, базовые «батарейки». Это Toki Pona для Haskell.
Синтаксис и типы
Объявления переменных и функций одинаковы; скобки не нужны, каррирование бесплатно.
transport : "Chicken House"
add : x y -> x + y
add5 : add 5
Базовые неизменяемые типы: Int, Float, String, Bool, List, Table.
numbers : [1, 2, 3]
person : {name: "Lucy", age: 23}
Типы можно указать явно; без аннотаций всё проверяется только во время вызова.
Управление потоком
Единственный способ — when (pattern matching). Нет if/else или switch.
describe : x ->
when x is
0 then "Zero"
_ then "Something else"
processUser : user ->
when user is
{name: n, age: a, active: true} -> "Adult: " .. n
_ -> "Unknown"
Пример: жизнь Конвея уже работает.
Комментарии (36)
- Участники делятся опытом создания языков: @codr7 показал фреймворк Shi, @aldousd666 рассказал о своих интерпретаторах, начавшихся в 2006-м.
- Разгорелся спор о синтаксисе: одни хвалят «:» для присваивания, другие защищают «=» как уже устоявшийся символ.
- Кто-то предлагает отказаться от точек с запятой, кто-то считает их полезным разделителем.
- Обсуждаются математические корни обозначений: одни считают «=» сравнением, другие — утверждением.
- Предлагаются альтернативы: «:=», «<-», «=>», а также идея вызывать функции в порядке чтения.
Unexpected productivity boost of Rust 🔥 Горячее 💬 Длинная дискуссия
Rust повышает производительность разработки, несмотря на сложность.
Ключевые факторы:
- Жёсткий компилятор ловит ошибки до запуска, уменьшая время отладки.
- Модель владения устраняет гонки и утечки памяти, снижая количество багов.
- Инструменты: Cargo, Clippy, rustfmt и rust-analyzer ускоряют цикл «написание → проверка → запуск».
- Сообщество предлагает качественные крейты и быструю помощь.
- Производительность кода сравнима с C/C++, но без segfault и UB.
В итоге меньше времени тратится на отладку, больше — на новые функции.
Комментарии (433)
- Автор статьи рассказал, как Rust позволяет безболезненно рефакторить большие кодовые базы благодаря строгой типизации и проверкам компилятора.
- Многие участники согласились, что статическая типизация (Rust, Haskell, OCaml-подобные языки) повышает уверенность при изменениях, особенно в многолюдных проектах.
- Часть комментаторов считает сравнение с TypeScript «нечестным»: TS компилируется в JS и наследует его недостатки, а приведённый баг с
window.location.href— это особенность DOM, а не языка. - Некоторые отметили, что Rust тоже не идеален: async/синхронные блокировки, медленная компиляция и «множество способов сделать одно и то же» могут снижать удобство.
- Общий вывод: преимущество Rust в безопасности и рефакторинге особенно заметно на больших проектах, но язык требует времени на изучение и не всегда лучше «классических» статически типизированных альтернатив.
Git-Annex
git-annex — управляет большими файлами в git, не храня их содержимое. Поддерживает синхронизацию, резервное копирование, шифрование и работу офлайн.
Для любителей командной строки — полный функционал; для остальных — git-annex assistant превращает всё в простую синхронизацию папок.
Быстрый старт
Ключевые темы
Примеры
Архиватор Боб хранит данные на множестве отключённых дисков. git-annex показывает, где лежит нужный файл, и позволяет безопасно переупорядочивать дерево. Ночью cron-команды добавляют новое и отслеживают дубликаты.
Кочевница Алиса синхронизирует ноутбук, USB-диск, сервер и облако как git-удалённые репозитории. В самолёте или кафе она выбирает, что скачать, что удалить, а при подключении всё автоматически сливается обратно.
Комментарии (51)
- git-annex отлично подходит для персонального управления большими файлами на множестве носителей, включая офлайн-диски, и гарантирует контроль целостности.
- Пользователи жалуются на сложность освоения, «тяжёлый» Haskell-стек зависимостей и проблемы с плагинами облачных провайдеров.
- В много-юзерных репозиториях «магические» ветви git-annex плохо масштабируются; для коллаборации чаще выбирают Git-LFS.
- Крупные репо (десятки ТБ и сотни тысяч файлов) замедляются до минут ожидания на каждую операцию, особенно при дефолтных «параноидальных» проверках.
- Git-annex и LFS решают разные задачи: первый — распределённое резервное хранение, второй — версионирование больших файлов в dev-репозиториях.
Typechecker Zoo
Проект «Zoo» — мини-реализации самых влиятельных статических систем типов последних 50 лет. Начнём с простых и дойдём до зависимых типов. Всё пишем на Rust — просто потому что удобно и забавно строить чисто функциональные языки на не-функциональном.
Это не учебник, а выходные развлечение. За теорией и доказательствами смотрите TAPL, ATTAPL, PFPL и оригинальные статьи (ссылки в приложении). Здесь же — грязные детали реализации: структуры данных, AST, логика, всё, что можно осилить за уик-энд.
Код — идиоматичный Rust с полноценным парсером и тестами (lalrpop, logos, ariadne). Примеры урезаны, но понятнее продакшен-реализаций. Парсинг и MLIR считаем решёнными задачами, поэтому не фокусируемся на них.
Четыре «зверька»:
- Algorithm W (775 строк) — классический Hindley–Milner, полиморфный λ-исчисление.
- System F (1090 строк) — второе λ-исчисление, параметрический полиморфизм, Mini-OCaml.
- System F-ω (3196 строк) — высшие рода, паттерн-матчинг, дататипы, Haskell-lite.
- Calculus of Constructions (6000 строк) — иерархия универсумов, индуктивные типы, крошечный Lean.
MIT-лицензия, хобби-проект. Нашли опечатку — присылайте pull-request.
Комментарии (24)
- Пользователи хвалят Elaboration Zoo как полезный ресурс для изучения нормализации по вычислению и вывода неявных переменных.
- Просят аналогичный «зоопарк» для линейных типов и предлагают добавить быстрый вариант Hindley–Milner из OCaml.
- Автору советуют включить тёмную тему для блоков кода и рассмотреть простой однонаправленный type-checker в духе Featherweight Java.
- Уточняют, что присутствие индуктивных типов делает реализацию ближе к CIC, но Lean всё же сильнее за счёт аксиомы выбора.
- Картинки с животными вызывают путаницу; большинство считают их просто AI-орнаментом без смысловой нагрузки.
An engineer's perspective on hiring 💬 Длинная дискуссия
Почему наём — боль
Компании теряют время: 9 раундов, охота за «трендовыми» разрабами, не могут отличить программиста от LLM. Кандидаты страдают: лучшие разрабы (Rust, Haskell) проваливают стресс-интервью, рекрутеры называют их «не-технарями», а потом пропадают на месяцы.
Каким должен быть хороший процесс
- Различать сеньора и маркетолога с ChatGPT.
- Применимо к работе: код, архитектура, ревью, документация.
- Долгосрочно: люди не взаимозаменяемы, уход дорого, специализация под стек выучивается за месяц.
- Экономно: инженерное время дорого.
- Уважительно: неуважение отпугивает лучших.
- Вкус: быстрое, но грязное решение — долгий долг команде; «клей» (поддержка коллег) множит продуктивность.
Почему популярные форматы не работают
-
Live-coding / LeetCode
Не различают, не про работу, уничтожают уважение и вкус, дорогие при многократных раундах. -
Take-home
Легко сгенерировать ChatGPT, неуважительны к времени кандидата, отпугивают сильных. -
Проектирование архитектуры
Лучше: ChatGPT не пройдёт, близко к реальной работе, можно оценить вкус и командное влияние.
Комментарии (171)
- Современные «интервью» больше похожи на серию экзаменов, чем на профессиональный разговор.
- Многие считают, что достаточно 1-2 коротких встреч или пробы через контракт «temp-to-perm», чтобы понять, подходит ли человек.
- Популярные live-coding и leetcode почти не отражают реальную работу и отбирают не тех специалистов.
- Лучше обсуждать реальные задачи, ревьюить существующий код или решать мелкий баг в паре — это ближе к ежедневным обязанностям.
- Кандидаты теряют время и энергию на домашние задания и 9-часовые циклы, поэтому всё чаще «интервьюируют» и сами компании.