LINUX.ORG.RU

Какашки в Common Lisp


7

4

Предлагаю учёным мужам в этом топике собрать и обсудить проблемы в языке Common Lisp. Кому что не нравится?

Мне категорически не нравится реализация методов в CLOS. Метод в нём - это специализированная общая функция (дженерик), просто функций, присущих только данному классу, нет. При создании метода автоматически создаётся дженерик, если он ещё не был создан. Дженерик виден во всём пакете, и все специализации должны соответствовать его сигнатуре. На практике это приводит к тому, что почти сразу появляется проблема несоответствия сигнатур у методов разных классов. Можно, конечно, разнести классы по разным пакетам, но это влечёт за собой больше неудобств, чем решает. Пока весь код - ваш, под вашим контролем, это особой проблемы не представляет, но представьте, что классы плодит куча разных людей?

Не нравится неполная интеграция CLOS в язык: распознавание класса в CLOS для стандартных лисповских типов ещё работает, но не для своих типов, объявленных через deftype.

Ну и вообще CLOS жирноват для 90% задач. Не говоря уж про MOP, который почти никем не используется, а если и используется, то для решения проблем с кривостями CLOS, либо просто книжку AMOP обчитался и повредился умом.

Не нравится реализация пакетов (неймспейсов). Удобно иметь вложенные пакеты, но их нет. Возможность задания никнейма для пакета в самом пакете - членовредительская, ибо каждый гомо сапиенс для своей мегабиблиотеки задаёт двух-, трёхбуквенный никнейм. Букв в общепринятой латинице и так мало (опустим перечень адских пыток, которым после смерти будут подвергнуты те, кто пишет комментарии не на английском языке или вообще использует не-ASCII алфавит для идентификаторов), так ещё количество их кобминаций ограничено любовью человеков к акронимам и красивым сокращениям.

Не нравится отсутствие стандартных средств рефлексии/интроспекции лексического окружения. Лексэнвы эти есть во всех реализациях, но стандартного способа работы с ними нету. Нужда в этой фенечке шкурная, и широкими массами не востребована, но всё же.

loop - какашка. Это не лисп. Точка.

Встроенный макроязык в format - тоже какашка. Я каждый раз после двухдневного перерыва лезу в документацию или старый код, чтобы вспомнить, как форматировать число с плавающей запятой. В общем-то, перенаворочен format. И всякой ерунды в него набито, типа автоматического окончания у числительных, но которое работает только для аглицкого языка.

unwind-protect - хорошо, но от попыток человеком сэмулировать продолжения для CL хочется икать. Такие trade-off вполне понятны, но лучше бы unwind-protect ограничили.

Ну и более мелкие ляпы в стандарте, типа (elt sequence index), но (nth index list).

Да, этот пост написан в Емаксе, запущенно под лисповым оконным менеджером человеком, получающем деньги за написание лиспокода :)

★★★★★
Ответ на: комментарий от bik

> посмотрите на реализацию олега киселева

Я пытался читать пару статей, где он был соавтором - дальше второй страницы у меня тупо не хватает ума %)

tailgunner ★★★★★
()
Ответ на: комментарий от quasimoto

Фейл. Тебя просили сделать с замыканиями - а ты сделал с макросами. Алсо (funcall (funcall n '++) 5) -> ((n '++) 5) (если схемка). Ну и кстати можно внутреннюю лямбду вызывать в самом макросе и писать просто (n '++ 5).

anonymous
()
Ответ на: комментарий от tailgunner

Вообще можешь посмотреть любое ООП для схемы (там и CLOS есть) - оно на макросах со структурами/замыканиями и сделано.

anonymous
()
Ответ на: комментарий от tailgunner

И чем удобнее обычного класса с четко определенным интерфейсом?

Это ты первый попросил велосипед с квадратными колёсами.

Пост был к тому, что у функции в её локальном окружении (то что называется «замыкание» и размещается в куче) может лежать что угодно - сколько-то переменных, сколько-то функций; первое мы можем объединить в структурный тип («объект»), второе использовать как сообщения. А с каррированными функциями всё получается гораздо чище, т.е. для нужд примитивных (в смысле, простеньких) объектов с сообщениями обычного лямбда исчисления хватает.

Но вот если говорить о модели объектов с сообщениями в духе Эрланга, т.е. с параллельными сообщениями... Как ты относишься к тому, что в рамках пи-исчисления (модель для erlang/jocaml подобных систем) можно выразить лямбда-исчисление, но не наоборот? :)

Кстати, как это добро наследовать?

А что ты подразумеваешь под наследованием? Аггрегацию? Тогда так и собирать (как будто там настоящие структурные типы - по крайней мере хватит для ({}, id({}))). Или то странное из C++? Про то странное я ничего не знаю.

quasimoto ★★★★
()
Ответ на: комментарий от anonymous

Фейл.

Возведи мой фейл в квадрат и повесь себе на шею :)

Макрос там для «красившести», генирирует он обычное замыкание.

Алсо (funcall (funcall n '++) 5) -> ((n '++) 5) (если схемка). Ну и кстати можно внутреннюю лямбду вызывать в самом макросе и писать просто (n '++ 5).

Ну поздравляю, чё.

quasimoto ★★★★
()

Что мне еще не нравиться :

1. Макросы. Макросы это хорошо, но их используют в 99% там где не нужно, где можно обойтись простыми функциями. Из-за такого обилия использования макросов в каждой малой библиотеки свой DSL, поэтому порой трудно понять что код, так как уже не CL, а новый язык имеем для проекта.

2. Пакетный менеджер. asdf это может и хорошо, но не так хорошо как может быть; все таки asdf создавался на коленках как хак.

3. Quicklisp Quicklisp усугубит пробему с библиотеками для CL. Так как с помощью quicklisp можно поставить любую библиотеку быстро, то со временем получиться, что в коде будет использоваться множество других библиотек, которые тащят за собой еще вагон библиотек — спасибо за это простоте установке новых библиотек с помощью ql. Вместо quicklisp нужно делать репозитарий стандартных библиотек, которые нужны на данный момент CL, причем такие библиотеки нужно писать на subset of CL, то есть использовать базовые функии и примитивы из стандарта CL и не использовать сторонии библиотеки (alexandria, iterate, etc); как пример, вместо loop использовать do и т.д.

4. Реализации CL. По существу, существует только одна относительно вменяемая реализаци CL на данный момет. Это Lispworks. Все остальные реализации CL «панкуют» в разных ипостасиях.

anonymous
()
Ответ на: комментарий от anonymous

Ага. Но без #' лучше ведь.

Я ж не против. Но вопрос ценой в 2 значка как бы не принципиальный (хотя, funcall это конечно трагедия).

Зачем?

А зачем писать #' и функоллы, если можно не писать?

Ты же сам сказал, что нельзя (в CL).

можно не писать?

Нельзя - это ж на схему придётся переходить :)

Короче, весь разговор свёлся к тому, что «схемка» лучше CL.

quasimoto ★★★★
()
Ответ на: комментарий от quasimoto

>> И чем удобнее обычного класса с четко определенным интерфейсом?

Это ты первый попросил велосипед с квадратными колёсами.

Я его не у тебя просил, а у человека, спросившего «какой сакральный смысл в объектной системе вообще, если язык замыкания поддерживает?».

Кстати, как это добро наследовать?

А что ты подразумеваешь под наследованием? Аггрегацию?

Нет, под «наследованием» я понимаю наследование. Внезапно, да?

Или то странное из C++?

А так же Явы, Смоллтока и 100500 ООП-языков.

Про то странное я ничего не знаю.

Вернись в башню из слоновой кости, или где ты там обитаешь.

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

Я его не у тебя просил, а у человека, спросившего «какой сакральный смысл в объектной системе вообще, если язык замыкания поддерживает?».

Ну вот, а я зачем-то писал.

Нет, под «наследованием» я понимаю наследование. Внезапно, да?

А так же Явы, Смоллтока и 100500 ООП-языков.

Всегда казалось, что наследование в духе таких языков это нечто довольно плохо очерченное с точки зрения чистоты абстракций. По крайней мере ряд независимых вещей смешаны в кучу - агрегация (это ведь про типы данных), полиморфизм (это для группирования функций с конкретными сигнатурами в методы с расширенными сигнатурами), инкапсуляция (это вообще про систему модулей) и какой-то из механизмов наследования (который даже может не удовлетворять LSP).

В этом смысле странно просить пример объектов/сообщений на замыканиях (или объектов/сообщений в LC) и потом просить что-то там отнаследовать.

Возвращаясь к CL - там (в отличии от любого из 100500 ООП-языков) инкапсуляция осуществляется с помощью пакетов, ad-hoc полиморфизм отделён (диспетчеризация, мультиметоды), а классы - обычные структурные типы которые легко агрегировать, и также можно использовать довольно очевидный механизм наследования.

А вообще наследование должно делаться в духе deriving.

Про то странное я ничего не знаю.

Вернись в башню из слоновой кости, или где ты там обитаешь.

Да я правда не знаю )

quasimoto ★★★★
()

>Да, этот пост написан в Емаксе, запущенно под лисповым оконным менеджером человеком, получающем деньги за написание лиспокода :)


Разницу между исключением и прерыванием сможешь объяснить - «человек получающий деньги за написание липсокода» ?

bukinist
()
Ответ на: комментарий от anonymous

«схемка» лучше CL.

Видишь, ты сам пришел к этому выводу.

У меня для этого недостаточно эмпирических данных - схемка на уровне «читал SICP» и «взял Racket напосмотреть».

Но CL используют не потому что это язык с самым рациональным дизайном - есть гораздо более продуманные языки.

Scheme не многим лучше, на самом деле, - нет границы между детерминированным и индетерминированным кодом.

quasimoto ★★★★
()
Ответ на: комментарий от Donnie_Darko

> а можно поподробнее на этом месте?

В профиль ему загляни :)

anonymous
()
Ответ на: комментарий от quasimoto

> Но CL используют не потому что это язык с самым рациональным дизайном

Верно! А раз нет причин использовать CL - значит и не нужно его использовать.

anonymous
()
Ответ на: комментарий от Donnie_Darko

а можно поподробнее на этом месте?

Любой язык с академическим прошлым, который его (прошлое) перерос.

Scheme более продуман - стандарт Scheme составляли с установкой «сделать язык с небольшим, но мощным ядром, наиболее рациональным образом» (в рамках его динамической типизации, конечно). А Common Lisp с установкой «собрать как можно больше крутых фич из всех этих лиспов» (что были на момент стандартизации). Ну то есть «академический» язык и «промышленный» - понятно какой из них лучше продуман. Но если говорить «более фичастый», то тут, наверное, Common Lisp и настроения на comp.lang.lisp подтверждают это догадку :)

Если брать статически типизированные языки общего назначения - Haskell более продуман.

quasimoto ★★★★
()
Ответ на: комментарий от anonymous

> От этого вида наследования отказались в f#. Сознательно.

защищенное может и не особо нужно, а вот как все-таки сделать приватное наследование через замыкание?

или если вопрос не ясен, как сделать наследование реализации (против наследования интерфейса)?

и кстати, кинь линк на обоснование этой меры в f#

www_linux_org_ru ★★★★★
()
Ответ на: комментарий от anonymous

Верно! А раз нет причин использовать CL - значит и не нужно его использовать.

Неверно :) Индустрия любит c и c++, php и python - если до кого первой докатится, то до CL. А абстракции несоразмерные задачам не приживаются.

quasimoto ★★★★
()
Ответ на: комментарий от tailgunner

> И кстати, как с помощью замыкания сделать объект с несколькими методами? Примерчик, пжалста.

ну это-то вполпинка

грубо говоря объектом класса тут является фрейм стека, и два метода — это две (как бы) локальные функции, отданные наружу

флейм «замыкания против классов» давно следовало провести :-)

www_linux_org_ru ★★★★★
()
Ответ на: комментарий от anonymous

нету человеческого способа положить в слот переменной локально определенную рекурсивную функцию.

Анафорическая лямбда позволяет.

(defmacro alambda (parms &body body)
    `(labels ((self ,parms ,@body))
        #'self))

(alambda (x)
    (* x (self (- x 1))))
k_andy ★★★
()
Ответ на: комментарий от quasimoto

>если до кого первой докатится, то до CL

Поздно. Они упустили свой шанс. Единственным шансмом лиспа в индустрии пока остается Clojure.

А все дело в позиции титанов CL. Да и Стандарт давно уже пора пересматривать.

Macil ★★★★★
()
Ответ на: комментарий от mv

>А какой сакральный смысл в объектной системе вообще

Интерфейсы. Иерархическая декомпозиция. Концепция класс-как-модуль.

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

Macil ★★★★★
()
Ответ на: комментарий от bukinist

Разницу между исключением и прерыванием сможешь объяснить - «человек получающий деньги за написание липсокода» ?

В каком контексте?

mv ★★★★★
() автор топика
Ответ на: комментарий от k_andy

Я и не сомневался, что найдется какой-нибудь костыль. CL - это вообще такая свалка костылей.

anonymous
()
Ответ на: комментарий от anonymous

Scheme - говно, недостойное внимания. Если речь о написании более-менее серьезных вещей, а не очередного способа подсчета факториалов через жопу.

Макросы - уебищны, стейт компилятора и рантайма разделен. Этого уже хватает чтобы не воспринимать схемовые макросы всерьез. Гигиена - вторая причина(хотя есть плюс - можно скакать ебанашкой на форумах и трындеть о «чистоте» и прочем никому, в real world, не нужном говне).

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

ОО-систем сравнимых с CLOS в схемах - опять же, нет. Есть, правда, пара не слишком удачных попыток, которые тормозят как говно.

Рантаймы и компиляторы убоги - тормоза, тормоза, жор памяти(ну при старте, конечно, схемы обычно не отжирают под 30 мегов, учитывая что стандартные библиотеки у них - кот нассал, но в процессе работы жрут так, что SBCL нервно курит в сторонке).

Системы обработки исключений, по сравнению с CL Condition System, убоги и уебищны - хорошо если «как в жабе», а то ведь с продолжениями нормальные системы обработки исключений невозможны в принципе.

Вообще, стандартная схема убога, в стандартном R пусть даже 6RS - нихуя нет, ну вообще нихуя, практически. Переносимых библиотек - ~нуль. И compatibility layers для implementation-specific вещей, в т.ч, тоже нихуя, почему-то, нет(наверное все заняты срачами на форумах и написанием дебильных статей о чем-то типа попыток запихнуть алгебраические типы в динамический язык).

anonymous
()
Ответ на: комментарий от anonymous

Вообще, Clojure тоже говно, заранее надо сказать.
Синтаксический сахар над жабкой, не более. Ну и тормоза еще, конечно.
Лисп это в первую очередь метаязыковая среда, рантайм, динамическая виртуальная машина, а потом уже скобки. А какой у Clojure рантайм? Вот-вот.

Единственный живой и применимый на практике диалект лиспа - Common Lisp, и это единственный диалект, у которого есть будущее(в том плане что развитие семейства языков «Lisp» пойдет в будущем по пути улучшения CL, и выкидывания из него всякого старья, а не по пути схемы или вышеописанного сахарка над JVM)

anonymous
()
Ответ на: комментарий от anonymous

А вот и лавсанчик пожаловал. Но как-то слабо. Я думал, лучше будет. Теряешь хватку :(

anonymous
()
Ответ на: комментарий от anonymous

Common Lisp - говно, недостойное внимания. Если речь о написании более-менее серьезных вещей, а не очередного способа подсчета факториалов через жопу.

Макросы - уебищны, стейт компилятора и рантайма общий. Этого уже хватает чтобы не воспринимать CL'овские макросы всерьез. Отсутствие гигиены - вторая причина (хотя есть плюс - можно скакать ебанашкой на форумах и трындеть о «настоящих макросах» и прочем никому, в real world, не нужном говне).

Продолжения - отсутствие продолжений это такой пиздец, который означает что язык всерьез воспринимать нельзя. Ну, с другой стороны, тут опять же плюс - можно везде кричать о «практической направленности» языка, которую якобы должно демонстрировать отсутствие фич, для исследования которых выдаются гранты и пишутся докторские.

ОО-систем сравнимых с CLOS по уебищности - опять же, нет. Есть, правда, пара слишком уж неудачных попыток, которые приближаются к CLOS по тормознутости и переусложненности - но все не то.

Рантаймы и компиляторы убоги - тормоза, тормоза (без деклараций на каждый чих хоть сколько-нибудь оптимальный код не генерируется в принципе, уж сразу бы сделали статическую типизацию - хули мозги ебать?), жор памяти (мало того, что при старте отжирают под 30 мегов, так еще и в процессе работы жрут так, что любая Scheme курит в сторонке).

Системы обработки исключений, по сравнению с продолжениями, убоги и уебищны - хорошо если «как в жабе», а то ведь без возможности адекватно контролировать control-flow, нормальные системы обработки исключений невозможны в принципе.

Вообще, Common Lisp убог, в стандарте - куча ненужной, кривой костылеобразной и работающей хорошо, если через раз, хуеты. Переносимых библиотек - ~нуль. И compatibility layers для implementation-specific вещей, в т.ч, тоже нихуя, почему-то, нет(наверное все заняты срачами на форумах и демонстрированием неосиляторства статей о попытках ввести алгебраические типы в динамический язык).

anonymous
()
Ответ на: комментарий от www_linux_org_ru

> и кстати, кинь линк на обоснование этой меры в f#

(1) google protected modificator f# Petricek site://stackoverflow.com

а вот как все-таки сделать приватное наследование через замыкание?

как сделать наследование реализации (против наследования интерфейса)?

(2) Приватное наследование есть, наверное, только в плюсах. Костыль какой-то. Подпорка.

anonymous
()
Ответ на: комментарий от anonymous

> с продолжениями нормальные системы обработки исключений невозможны в принципе.

Неправда. Возможны. Просто вводим второе продолжение для обработки исключений. Пример: f# async.

anonymous
()

ленивости! чтобы можно было писать что-то типа

 
(select (make-element (filter '(1 2 3) #'oddp)))

pseudo-cat ★★★
()
Ответ на: комментарий от anonymous

>А какой у Clojure рантайм?

Рантайм у Clojure называется JVM. И, к сожалению, CL'овский рантайм ей сиииильно сливает.

Ведь мы же не путаем яву и JVM, правда?

Common Lisp, и это единственный диалект, у которого есть будущее


Будущее у CL будет только в одному случае: если кто-то из титанов CL откроет свою лисп-систему.

Macil ★★★★★
()
Ответ на: комментарий от Macil

> Будущее у CL будет только в одному случае: если кто-то из титанов CL откроет свою лисп-систему.

Зачем? Им и так хорошо платят. На эти деньги, между прочим, они работают над очень нужными CL фичами. Если отдать ее опенсорсу, то хорошую лисп-систему привратят в какашку. За все надо платить.

anonymous
()
Ответ на: комментарий от anonymous

да и для софтварной конторы пара тысяч зеленых за хорошую лисп-систему не такая уж большая сумма.

anonymous
()
Ответ на: комментарий от anonymous

> Неправда. Возможны. Просто вводим второе продолжение для обработки исключений.

С продолжениями все гораздо веселее - можно навесить фреймы на каждый функциональный вызов, а при исключении вылетать в debug-mode, в котором можно будет свободно перемещаться вверх по стеку, менять любые переменные контекста, хотпатчить ф-и (например можно захотпатчить ф-ю, потом вернуться по стеку до места ошибки и руками в репле сэмулировать корректную работу ф-и, после чего продолжить выполнение программы). В общем mast have для всякого рода марсоходов.

anonymous
()
Ответ на: комментарий от anonymous

Макросы - уебищны, стейт компилятора и рантайма разделен.

Именно для этого они и создавались, именно в этом их сила. Если они тебе кажутся не нужными - не пользуйся.

true_admin ★★★★★
()
Ответ на: комментарий от anonymous

mast have

«мачты имеют», как трогательно

shty ★★★★★
()
Ответ на: комментарий от Macil

Рантайм у Clojure называется JVM. И, к сожалению, CL'овский рантайм ей сиииильно сливает.

Крайне спорное утверждение. В Clojure, например, такого крутого сигнального протокола нет.

mv ★★★★★
() автор топика
Ответ на: комментарий от anonymous

C++ - говно, недостойное внимания. Если речь о написании более-менее серьезных вещей, а не очередного способа подсчета факториалов через жопу.

Метапрограмирование - уебищно, стейт компилятора по-просту отсутствует. Этого уже хватает чтобы не воспринимать плюсовые темплейты всерьез. Отсутствие вывода полиморфного аргумента - вторая причина (хотя есть плюс - можно скакать ебанашкой на форумах и трындеть о «широчайших возможностях» и прочем никому, в real world, не нужном говне).

Продолжения - отсутствие продолжений это такой пиздец, который означает что язык всерьез воспринимать нельзя. Ну, с другой стороны, тут опять же плюс - можно везде кричать о «практической направленности» языка, которую якобы должно демонстрировать отсутствие фич, для исследования которых выдаются гранты и пишутся докторские.

ОО-систем сравнимых с системой плюсов по уебищности - опять же, нет. Есть, правда, пара слишком уж неудачных попыток, которые приближаются к ней по количеству костылей, ненужных фич и идиотских решений дизайна - но все не то.

Рантаймы и компиляторы убоги - тормоза, тормоза (без анальных оптимизаций с выдрачиванием каждого байтика хоть сколько-нибудь быстрый код просто не генерируется), жор памяти (один хер приходится использовать аналоги GC, но только убогие и тормозные, на основе подсчета ссылок. сделали бы уж нормальный GC - хули мозги ебать?).

Системы обработки исключений, по сравнению с продолжениями, убоги и уебищны - хорошо если «как в жабе», а то ведь без возможности адекватно контролировать control-flow, нормальные системы обработки исключений невозможны в принципе.

Вообще, C++ убог, в стандарте - куча ненужной, кривой костылеобразной и работающей хорошо, если через раз, хуеты. Переносимых библиотек - ~нуль, темплейто-говно компилируется только после ритуальных плясок. И compatibility layers для implementation-specific вещей, в т.ч, тоже нихуя, почему-то, нет(наверное все заняты срачами на форумах и демонстрированием неосиляторства статей о попытках ввести алгебраические типы в динамический язык).

anonymous
()
Ответ на: комментарий от mv

> Крайне спорное утверждение. В Clojure, например, такого крутого сигнального протокола нет.

Понятно, имелось ввиду, что рантайм CL сливает в производительности. У джавы ведь самая примитивная вм из всех хоть сколько-то известных, насколько я вкурсе.

anonymous
()
Ответ на: комментарий от anonymous

Понятно, имелось ввиду, что рантайм CL сливает в производительности. У джавы ведь самая примитивная вм из всех хоть сколько-то известных, насколько я вкурсе.

Тоже спорное утверждение. SBCL, особенно для x86-64, blinding fast.

mv ★★★★★
() автор топика
Ответ на: комментарий от anonymous

> Будущее у CL будет только в одному случае: если кто-то из титанов CL откроет свою лисп-систему.

Зачем? Им и так хорошо платят. На эти деньги, между прочим, они работают над очень нужными CL фичами. Если отдать ее опенсорсу, то хорошую лисп-систему привратят в какашку. За все надо платить.

это система с положительной обратной связью, если что: открываем систему (пусть базовые функции, да хотя бы для институтов, а то franz inc., к примеру, просит 500-1000$ за 1 рабочее место для университетов на 1 год - правда класс?) -> повышаем популярность lisp -> работодатели смотрят что можно найти соответствующего специалиста не на марсе починяющего марсоход, а уже рядом -> повышается количество проектов на lisp -> покупают больше лицензий на систему (2-5k$, как тут справедливо заметли, - не проблема для коммерческой фирмы чуть больше ларька) -> profit!

но, к сожалению, пока работает «советский подход» в его наихудшей инкарнации - «сам не гам и другим не дам», пусть лучше сгниёт, но они пользоваться этим будут только после того как заплатят денежку...

так что ждём

shty ★★★★★
()
Ответ на: комментарий от shty

открываем систему (пусть базовые функции, да хотя бы для институтов

LispWorks personal - полностью базовый LW, но с ограниченным хипом и продолжительностью непрерывной работы 5 часов.

mv ★★★★★
() автор топика
Ответ на: комментарий от mv

> Понятно, имелось ввиду, что рантайм CL сливает в производительности. У джавы ведь самая примитивная вм из всех хоть сколько-то известных, насколько я вкурсе.

Тоже спорное утверждение. SBCL, особенно для x86-64, blinding fast.

эм, понимаю что шутаут не показатель конечно, но всё же

shty ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.