Теория языков программирования

Расширяемость языков

Kotlin extension functions и Swift protocols - это не просто syntactic sugar. Это фундаментально новый способ расширять чужой код без наследования. LSP изменил как создаются языки - IDE поддержка больше не требует команды IDE-разработчиков.

  • **rust-analyzer**: LSP сервер для Rust. Один сервер -> поддержка в VS Code, IntelliJ, Neovim, Emacs, Helix. 5M+ пользователей
  • **Arrow (Kotlin FP library)**: использует extension functions для добавления функциональных операторов к стандартным типам. monoid(), traverse() прямо на List<T>
  • **TypeScript language server**: используется в VS Code, но также в Vim, Emacs, Sublime. Microsoft открыл LSP - теперь конкурирующие редакторы используют их сервер

Перегрузка операторов

Перегрузка операторов позволяет определить поведение стандартных операторов (+, -, *, ==, <) для пользовательских типов. Делает код математически интуитивным для числовых типов, векторов, матриц. Python использует dunder методы (__add__, __mul__).

Злоупотребление перегрузкой создаёт непонятный код. Python datetime + timedelta - интуитивно. C++ Matrix << Vector - непонятно. Правило: перегружай только если оператор семантически очевиден для типа.

Когда перегрузка операторов оправдана, а когда нет?

Протоколы и Type Classes

Протоколы (Swift/Elixir) и Type Classes (Haskell) - способ определить интерфейс без наследования. Любой тип может реализовать протокол ретроактивно - даже встроенные типы. Это мощнее ООП интерфейсов.

Что такое ретроактивная conformance и почему это мощнее ООП наследования?

Extension Methods

Extension methods (C#, Swift, Kotlin) позволяют добавлять методы к существующим типам без наследования и без изменения оригинального кода. Это форма ретроактивного расширения без полного protocol системы.

Чем Kotlin extension functions отличаются от реального добавления метода в класс?

Language Server Protocol

LSP (Language Server Protocol) - стандарт для коммуникации между IDE и language-specific серверами. Microsoft разработал для VS Code в 2016. Теперь любой язык с LSP реализацией получает IDE поддержку в 100+ редакторах.

IDE поддержка нового языка - огромная работа на годы

С LSP: реализовать language server достаточно для поддержки в VS Code, Neovim, Emacs, IntelliJ, Sublime. Это несколько месяцев, не лет

Gleam (новый функциональный язык) имел LSP поддержку с первого стабильного релиза. Раньше это было немыслимо для молодого языка

Какую проблему решает LSP?

Итоги

  • **Перегрузка операторов**: для математических типов - интуитивно. Избегать семантически неясных операторов
  • **Протоколы и type classes**: ретроактивная conformance без наследования. Любой тип можно сделать Describable/Show
  • **Extension methods**: статические методы с синтаксическим сахаром. Нет доступа к private - это статический dispatch
  • **LSP**: устраняет n*m проблему IDE интеграции. Один language server -> поддержка в 100+ редакторах

Связанные темы

Расширяемость связана с типами и метапрограммированием:

  • ООП теория — Протоколы vs наследование - два разных подхода к полиморфизму
  • Type-safe API — Phantom types и branded types - расширение через систему типов

Вопросы для размышления

  • Rust traits = Haskell type classes = Swift protocols. Все три решают одну проблему по-разному. Как они отличаются по expressiveness и когда это важно?
  • LSP изменил экономику создания языков. Раньше успех нового языка зависел от качества IDE плагина. Сейчас - от качества language server. Как это повлияло на появление новых языков?
  • Extension methods в Kotlin - синтаксический сахар над статическими функциями. Haskell type classes - генерируют dict-passing в runtime. Какой подход лучше и почему?

Связанные уроки

  • fl-03-grammars
Расширяемость языков

0

1

Войти