Pull to refresh

Несколько причин освоить CL даже если вы не планируете писать на нем в будущем

Reading time3 min
Views7.8K
Наверное, эту статью стоило опубликовать перед предыдущими двумя, в этом моем цикле про Common Lisp, но лучше уж поздно, чем никогда.

Когда-то давно, когда я читал статьи Пола Грэма, и только начинал изучать CL, я довольно скептически относился к утверждению о том, что лисп позволяет понять другие языки лучше, да и вообще, программист, знающий CL, выучит любой другой язык максимум за пару недель, и будет на нем писать еще лучше, чем на нем пишет большинство людей, знающих этот язык уже пару лет.

Но сейчас я пришел к выводу, что это утверждение всё же верно.

Поверьте.
Новых идей в языках программирования не появлялось с середины 90х, то есть как раз с момента стандартизации Common Lisp.

Если вы возьмете в руки одну из современных реализаций CL, такую как SBCL, более-менее разберетесь со стандартным ANSI CL и его расширениями, предоставляемыми реализацией, то вы постигнете и поймете от и до такие парадигмы программирования, как:
  • Императивная и ее вариации (в CL даже goto есть! а уж остальные средства управления control flow в нем заруливают аналоги из всех других языков)
  • Структурная (без комментариев)
  • Объектно-ориентированная и ее вариации (От замыканий до CLOS)
  • Функциональная(CL поощряет локализировать побочные эффекты и писать по возможности без них)
  • Событийно-ориентированная (которая сводится к коллбэкам, то есть объектам функций)
  • Обобщенная (см. в конце статьи про полиморфизм)
  • Метапрограммирование (ведь это лисп! Сама программа есть объект языка)
  • До определенной степени, параллельное программирование
  • И так далее, и тому подобное — используя средства языка, которые прямо реализуют предыдущие парадигмы, и скрепляя все макросами, CLOS и condition system, вы сможете внести в язык что угодно, начиная с логической парадигмы и встроенного пролога, и заканчивая визуальным программированием.


Я прямо утверждаю, что все мейнстримные языки, и в особенности, объектно-ориентированные, являются подмножествами CL, просто со своим синтаксисом и некоторыми ограничениями в области типизации(система типов CL очень проста, но в то же время, бесконечно мощна и неразрешима в полном виде даже в динамике).

В принципе, это верно даже для Си, так как я на своем опыте убедился, что работа с FFI и встроенным ассемблером помогает понять Си и обычные ассемблеры больше, чем даже работа с ними самими.

Многие функциональные, в том числе эзотерические, языки, после знакомства с CL не будут смотреться такими уж эзотерическими, и будут в принципе, как на ладони.

До определенной степени, современные реализации CL помогут разобраться с общими для всех языков техниками оптимизации кода, со многими низкоуровневыми концепциями(см. выше про Си), с многопоточным программированием, и вообще с параллелизмом(все знают откуда у Google взялась идея MapReduce?), и даже с принципами построения сложных систем(хотя это, конечно, больше приходит с опытом).

Я говорю только про языки и общие концепции программирования, не говорю про конкретные фреймворки и библиотеки, и какие-либо вещи, ортогональные собственно языковым концепциям, но возможно, вы также будете продуктивнее осваивать их, замечая паттерны, знакомые вам по лиспу, и поэтому структурируя информацию быстрее. Лично мне как-то давно некоторый опыт с CL помог лучше понять суть и назначение XML, а как-то еще — помог разобраться с организацией и общими принципами построения графических интерфейсов и GUI-фреймворков.

Еще есть хаскель, да, который, говорят, тоже «просветляет». Но лично я считаю хаскель некоторым синтаксическим сахаром над парочкой базовых концепций, которые на самом деле доступны и в лиспе, только в более общем, и, от этого, менее заметном, и естественно, менее обязательном, виде. Эти концепции:
  • Паттерн-матчинг(ну ADT, да, но ADT по сути нужны только для паттерн-матчинга), который суть разновидность динамической множественной диспетчеризации.
  • Ленивость, которая сводится к потокам(streams) и замыканиям.
  • Полиморфизм(который, по сути, и является причиной наличия в хаскеле всей этой шелухи с типами). Параметрический полиморфизм это, концептуально, подмножество динамической типизации, а ad-hoc — диспетчеризации по типам(которая в лиспе может достигаться как банальными if+typep, так и более мощными механизмами, типа CLOS). Кто-то скажет — но ведь в хаскеле он в compile-time! Да, но я не считаю это чем-то таким особенным — если припрет, можно и макросов написать, и перенести операции над типами в compile-time и в лиспе(и нет, для этого не надо будет изобретать новый язык «поверх» CL, просто надо будет работать с объектами «лексических окружений», которые, хотя конкретный их формат в стандарте не оговорен, во всех основных реализациях присутствуют и информацию о типах предоставляют), правда тогда придется работать только с подмножеством системы типов CL, так как в общем виде она неразрешима даже в динамике, как я уже выше говорил.

Tags:
Hubs:
+69
Comments49

Articles