Во-первых, не от гугла, гугл ее только купил, во-вторых - какая именно часть там написана на CL?
Раз купил значит от Google. И по крайней мере один из разработчиков SBCL имеет адрес, заканчивающийся на @google.com. Значит уже и SBCL от Google.
Я не знаю какая там часть на CL, но та часть, что есть - является реальной программой на Common Lisp. Поэтому не надо балаболить про отсутствие реальных систем на CL. Вот ещё одна большая программа на CL http://www.ncbi.nlm.nih.gov/pubmed/26182406. Называется elPrep. Просто для того, чтобы создавать программы на CL руки должны быть не из задницы, и голова должна быть на плечах.
Не LDB, но тоже загадочная ошибка. Добился нагрузочным тестированием на одну и ту же страницу. Если в один поток, то этот код прекрасно работает и из SQL данные выдаёт корректно.
CORRUPTION WARNING in SBCL pid 10056(tid 140737272018688):
Memory fault at f7522260 (pc=0x7ffff6567c5e, sp=0x7ffff31ad220)
The integrity of this image is possibly compromised.
Continuing with fingers crossed.
192.168.2.3 monk [2015-08-31 21:10:22] "GET /jobs/finished HTTP/1.1" 200 - "-" "
Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Firefox/38.0 Iceweasel/3
8.2.0"
[2015-08-31 21:10:22 [ERROR]] While accessing database #<POSTGRESQL-DATABASE loc
alhost/monk/monk OPEN {10060C7983}>
with expression "SELECT JOBS_ACTIVE.END_DATE,JOBS_ACTIVE.BEG_DATE,JOBS_ACTIVE.
PAID,JOBS_ACTIVE.HOURS,JOBS_ACTIVE.JOB,JOBS_ACTIVE.ORG,JOBS_ACTIVE.ID FROM JOBS_ACTIVE ORDER BY JOBS_ACTIVE.BEG_DATE":
Error NIL / ошибка SSL: bad decompression
has occurred.
Backtrace for: #<SB-THREAD:THREAD "hunchentoot-worker-192.168.2.3:55689" RUNNING {1002F64323}>
В обоих трейсах видно, что проблемы в кишках SBCL. Пробуй на последнем SBCL, a также друг х реализациях. Какбы CL, как яп здесь не причем — все проблемы в библиотеках и конкретных реализациях. В твоей ракете библиотеки может больше отполированны, так как из коробки да и с одной реализацией.
Пробуй на последнем SBCL, a также друг х реализациях.
Пробовал. На том сервере SBCL уже раз шесть обновлялся. Других — это каких?
Какбы CL, как яп здесь не причем — все проблемы в библиотеках и конкретных реализациях.
Разумеется. В данном конкретном случае cl-sql-postgresql при многопоточной работе портит сам SBCL (может, так как FFI).
В твоей ракете библиотеки может больше отполированны, так как из коробки да и с одной реализацией.
В ракете за счёт другого подхода к многопоточности выстрелить себе в ногу намного сложнее. И в place и в thread нельзя случайно запортить переменную из чужого потока. FFI внутри thread из-за кооперативной многозадачности с точки зрения внешней библиотеки выполняется в одном потоке. Например, делая биндинг к GTK в SBCL мне явно приходилось выделять отдельный поток для GTK и следить, чтобы из других потоков ни одна функция GTK не вызывалась. А в Racket без проблем делаю thread, который пишет напрямую в значение прогресс-бара, пока основная программа заполняет остальные элементы в той же форме.
То есть все функции (и библиотеки!) в Racket по-умолчанию thread-safe. А в CL наоборот. Если разработчик библиотеки явно не озаботился блокировками вокруг всех setf и вызовов FFI, то будет плохо.
Из наиболее активных: Clozure CL. Из коммерческих можно даже взять LispWorks personal edition для тестирования, хотя не уверен, работает ли там CL-SQL.
Какбы CL, как яп здесь не причем — все проблемы в библиотеках и конкретных реализациях.
С такими рассуждениями можно зайти дальше и вспомнить, что ANSI Common Lisp, как язык, вообще не поддерживает многопоточность. Поэтому, каким бы красивым или навороченным язык не был, вся реальная сила именно в реализациях. Поэтому для тех, кто делает реальный софт на CL, лучшим выбором является LispWorks или ещё более дорогущий Allegro.
И в place и в thread нельзя случайно запортить переменную из чужого потока.
Ну так правильно, ведь place - весьма ограниченная возможность параллелизма (в терминологии рэкетиров), а thread в Racket - это просто «green thread», а потому, это не настоящие трэды. Т.е. это действительно другой подход - с помощью «кастрации» :-)
То есть все функции (и библиотеки!) в Racket по-умолчанию thread-safe. А в CL наоборот. Если разработчик библиотеки явно не озаботился блокировками вокруг всех setf и вызовов FFI, то будет плохо.
Ну, как бы, да. И в C и в C++ такая же ситуация, как и в CL. Racket берёт на себя больше, чем вышеупомянутые языки. Может быть, в большинстве случаев, это удобно, но не всегда. Руки должны быть развязаны, если они, как говорилось, растут не из задницы :-)
Например в LispWorks довольно хорошая документация, где оговариваются эти моменты.
Но всё равно приходится использовать внешние библиотеки. Не верю я, что в составе Lispworks будут биндинги к GTK, Oracle и MongoDB.
Поэтому с моей точки зрения нормальные потоки как раз в Racket, где я их могу использовать с той же лёгкостью, что и в Erlang и не бояться, что всё рассыпется при повышении нагрузки.
В минусе можно считать невозможность одновременного исполнения двух FFI вызовов. Но если такая необходимость действительно есть, то я уже показывал, что можно через FFI и pthread использовать:
Руки должны быть развязаны, если они, как говорилось, растут не из задницы :-)
Интересно, почему же тогда в CL так противятся добавлению call/cc. Его отсутствие связывает руки гораздо сильнее.
С точки зрения Racket (и Scheme вообще) если что-то можно сделать надёжно, то лучше делать надёжно, а не предоставлять опасные возможности «на всякий случай». Также, если что-то делается, то оно должно иметь документированные однозначные последствия для любого ввода.
Вот, например, почему я не стал делать iterate для Racket (было такое желание):
* (iter (for i in '(1 2 3)) (collecting i) (when (> 1 2) (finally (princ "o"))))
o
(1 2 3)
Несмотря на то, что (> 1 2) явно ложь, finally выполняется. Причём из документации явно это не следует.
И в C и в C++ такая же ситуация, как и в CL. ... Руки должны быть развязаны, если они, как говорилось, растут не из задницы :-)
Кстати, если брать именно Racket, то руки развязаны полностью благодаря нормальному FFI. То есть я могу выполнять любые функции Си, причём free после malloc можно заставить выполнять сборщик мусора. А также можно, например, передать в Сишный qsort любую функцию вида (lambda (x y) ...).
Интересно, почему же тогда в CL так противятся добавлению call/cc. Его отсутствие связывает руки гораздо сильнее.
Я думаю, что противится то некому, потому что никому не нужно перерабатывать стандарт. Никому. И тем, кто реально может это сделать (т.е. у кого есть большие деньги), и тем, что только лишь является фонатами. Попробуй скажи какому-нибудь известному в сообществе лисперов персонажу о том, что стандарт уже устарел. Попробуй скажи, что обновление стандарта поспособствует привлечению новых пользователей и приближению Common Lisp к мэйнстриму (как это произошло с выходом C++11. Ведь до его выхода, C++ утрачивал свою популярность. Поэтому абсолютно правильным было решение о выпуске новых стандартов каждые 4 года.) Так вот, любой лиспер-бородач испытает батхёрт и ответит одно заветное слово: «ненужно». Он будет рассказывать тебе о Quicklisp, о куче библиотек, о SLIME о куче реализаций, но только не о том, что стандарт Common Lisp нуждается в переработке. Поэтому Racket выглядит более современным, чувствуется, что над ним работают. Но от того же складывается впечатление, что Racket - это большой академический эксперимент, полигон для пробы новых идей.
Кстати, если брать именно Racket, то руки развязаны полностью благодаря нормальному FFI. То есть я могу выполнять любые функции Си, причём free после malloc можно заставить выполнять сборщик мусора.
Ну вот, опять же, хороший пример того, насколько важна качественная реализация, а не красивые теоретические выкладки.
LispWorks, судя по доке, всё это умеет. В CCL тоже хороший FFI, причём в обе стороны.
А также можно, например, передать в Сишный qsort любую функцию вида (lambda (x y) ...).
А вот в SBCL с этим проблемы. По крайней мере, в официальной доке сказано что «Calling Lisp functions from C is sometimes possible, but is extremely hackish and poorly supported as of SBCL 0.7.5.»
Так что на месте автора, вместо банального обзора библиотэк, которыми он называет «экосистему Common Lisp», и которые может самостоятельно исследовать любой проф. программист, лучше бы сделал обзор реализаций Common Lisp и призывал бы к объединению усилий для создания единой, но качественной реализации. Чего умалчивать удручающее состояние реализаций с кучей нерешённых проблем?
Не верю я, что в составе Lispworks будут биндинги к GTK, Oracle и
Зачем гтк, когда у LispWorks есть крутой кроссплатформенный CAPI? И да, на юниксах они рисуют с помощью гтк.
Из коробки есть CommonSQL, с которого лепили пародию — CL-SQL. Поддерживаются oracle, MySQL, Postgres, microsoft sqlserver и odbc из коробки. Полная поддержка ORM, на которой также базируется экспертная система с прологом — knowledgeworks.
MongoDB.
Сейчас начали перебираться назад на SQL+SSD. Nosql стали менее нужны.
С sbcl вообще беда, вроде пилят активно, но с каждой фичей вносят кучу багов. Притом основные нужные фичи, озвученные выше, отсутствуют. Дрочат на перформанс ценой стабильности рантайма :). Clozure CL более аккуратный что ли.
С sbcl вообще беда, вроде пилят активно, но с каждой фичей вносят кучу багов.
Пилят, пилят, никак не выпилят. Попробуй сделать что-то вроде grep 'FIXME' -R * или grep 'KLUDGE' -R * в корневом каталоге исходников SBCL. Удивишься :-)
Притом основные нужные фичи, озвученные выше, отсутствуют. Дрочат на перформанс ценой стабильности рантайма :). Clozure CL более аккуратный что ли.
Не знаю как в CCL, но главная беда с SBCL, на мой взгляд в том, что там нет плана разработки. Вернее, там план такой: фиксить баги, зарегистрированные на launchpad (порой, десять лет тому назад) и делать «улучшения» по личному усмотрению (либо для личного фана, либо для конкретного продакшена). Если взглянуть на коммиты, там полно всяких «micro optimization». Как будто «micro optimization» это важнее тысяч 'FIXME' и 'KLUDGE'. Т.е. SBCL - это какой-то хакерский продукт для тех, кто хочет возиться с реализацией снова и снова и снова и снова и снова. Те, кто просто хочет выражать свои идеи на Common Lisp лучше использовать LispWorks. Не даром тот же Edi Weitz наплодил хороший софт именно на LispWorks, попутно став профессором математики. Время не тратил на хакинг SBCL, а работал с хорошим продуктом. Коммерческим, каким и должен быть, по сути, хороший софт. :-)
Попробуй скажи какому-нибудь известному в сообществе лисперов персонажу о том, что стандарт уже устарел.
При чём тут стандарт? Вот есть sb-thread:make-thread — его нет в стандарте. Или тот же FFI. Для реализации call/cc необходима только поддержка со стороны реализации создать замыкание от текущей точки программы.
Так вот, любой лиспер-бородач испытает батхёрт и ответит одно заветное слово: «ненужно».
Ну да. Я пытался поднимать вопрос про call/cc и слышал в ответ именно это. Мол есть cl-cont и потоки, а всё остальное от лукавого. При том, что cl-cont ужасно тормозит, а потоки глючат в половине библиотек.
А в остальном, смысла менять именно Стандарт нет. Синтаксис меняется библиотекой. Возможности (потоки, FFI, продолжения, отладчик, ...) реализуются на уровне реализаций платформы.
Но от того же складывается впечатление, что Racket - это большой академический эксперимент, полигон для пробы новых идей.
Не сказал бы, что там идеи особо новые. http://docs.racket-lang.org/release/HISTORY.txt показывает скорее эволюционное развитие. Фактически, отличие от старой Scheme (которая ненамного моложе Common Lisp'а) только в быстром компиляторе и достаточно большом количестве библиотек.
Опять «ненужно». Вот поэтому я и ушёл на Racket. Там в качестве ответов либо «сделай: метод такой-то» либо «так делать нельзя, ибо вредно» с обоснованием (например, на предложение сделать аналог safety=0).
А вот в SBCL с этим проблемы. По крайней мере, в официальной доке сказано что «Calling Lisp functions from C is sometimes possible, but is extremely hackish and poorly supported as of SBCL 0.7.5.»
Это было давно. Основная проблема в том, что в CL нельзя передать произвольную лямбду. Надо писать
Судя по http://www.lispworks.com/documentation/lw70/FLI/html/fli-18.htm пункт 3.1.3, не умеет создавать указатели на объект, который можно собрать сборщиком мусора. Должно быть так: bytes в Racket — я могу этот массив передавать в любую функцию на Си, но при этом сам массив под управлением сборщика мусора. Мне не надо явно вызывать foreign-free. В CL в таких случаях приходится копировать из array в foreign-array и обратно. Ну или отслеживать время жизни данных как в Си.
При чём тут стандарт? Вот есть sb-thread:make-thread — его нет в стандарте. Или тот же FFI. Для реализации call/cc необходима только поддержка со стороны реализации создать замыкание от текущей точки программы.
Потому что только стандарт может обязать разработчиков реализации сделать описываемую стандартом возможность языка. Это во-первых. А во-вторых, современный стандарт делает возможным писать переносимые программы, которые с меньшей вероятностью будут тормозить или глючить. То, что make-thread нет в стандарте - это беда т.н. «экосистемы» Common Lisp. В C++ трэды появились в C++11, в C11 появились, а в Common Lisp - нет. В третьих, обновленный стандарт вызывает куда больше чувство, что язык живой и современный, чем стопицотная статейка про «экосистему» и те же самые доморощенные библиотэчки. После выхода C++11 все запомнили фразу Страуструпа «C++ сейчас ощущается как новый язык». Потом был C++14, потом будет C++17 и т.д. И это вносит ощущение стабильности и уверенности, что язык будет развиваться и это развитие будет контролироваться не шайкой олдфагов с IRC, комитетом по стандартизации. Так что стандарт - это большая сила. :-)
А в остальном, смысла менять именно Стандарт нет. Синтаксис меняется библиотекой. Возможности (потоки, FFI, продолжения, отладчик, ...) реализуются на уровне реализаций платформы.
Пойми, пока определённой возможности не будет в стандарте, тебе так и будут отвечать «ненужно». И будут правы, потому что того, чего нет в стандарте - «ненужно» по определению. То, что в конкретных реализациях есть конкретные возможности является заслугой конкретных разработчиков, которые реализовали эти возможности по собственной прихоти, а не потому, что это было «нужно». :-)
Ну и сравни с GTK. В CAPI tree-view многоколоночсти нет, раскраски горизонтальных полосок нет, поиска нет... Вот для этого и нужен биндинг к GTK. Чтобы если чего-то не хватило в кросс-платформенном GUI, то можно было вытащить из него указатель на объект GTK и использовать всю мощь тулкита.
Что-то оно очень CLIM напоминает... Как на этом чуде простейший TreeView сделать с тремя колонками? Наподобие такого:
А чего же ты пример с TreeView на Racket не привёл? :-) Неужто потому, что TreeView в гуишной либе Racket попросту нет? А вот в LispWorks CAPI TreeView как раз есть :-) Вообще говоря, гуишная либа Racket примитивненькая. У LispWorks намного богаче. А в Qt - ещё богаче :-)
только стандарт может обязать разработчиков реализации сделать описываемую стандартом возможность языка.
Да ну? Можешь назвать широко распространённую версию Common Lisp без потоков, FFI, слабых ссылок и финализаторов?
современный стандарт делает возможным писать переносимые программы, которые с меньшей вероятностью будут тормозить или глючить
Вполне хватает bordeaux-thread, CFFI и trivial-garbage. Можно их считать стандартом де-факто.
В C++ трэды появились в C++11, в C11 появились, а в Common Lisp - нет.
В случае Си вообще неясно, зачем включать потоки в стандарт языка, если есть POSIX.
После выхода C++11 все запомнили фразу Страуструпа «C++ сейчас ощущается как новый язык». Потом был C++14, потом будет C++17 и т.д. И это вносит ощущение стабильности и уверенности, что язык будет развиваться и это развитие будет контролироваться не шайкой олдфагов с IRC, комитетом по стандартизации.
Обратная сторона: C++ с каждой версией всё тяжелей (для изучения, для реализации). Может повторить судьбу PL/1. Тот тоже контролировался «не шайкой олдфагов с IRC». А в результате все ушли на Си.
Должно быть так: bytes в Racket — я могу этот массив передавать в любую функцию на Си, но при этом сам массив под управлением сборщика мусора. Мне не надо явно вызывать foreign-free.
Да ну? Можешь назвать широко распространённую версию Common Lisp без потоков, FFI, слабых ссылок и финализаторов?
Я говорю про *обязать*. То, что в большинстве реализаций есть потоки (с разным API), FFI (везде по-разному, в SBCL так вообще только Lisp->C) говорит лишь о том, что кто-то когда-то соизволил это сделать. Именно соизволил. Проснулся однажды и подумал: «а не сделать ли мне... для фана». :-)
Вполне хватает bordeaux-thread, CFFI и trivial-garbage. Можно их считать стандартом де-факто.
То, что становится стандартом де-факто, в приличном обществе должно стать стандартом де-юре. Это «принцип протоптанных дорожек».
В случае Си вообще неясно, зачем включать потоки в стандарт языка, если есть POSIX.
Совершенно ясно. Умные дяди из комитетов ANSI C и ANSI C++ понимают, что зависят друг от друга. Поэтому и стандарты новые написали как бы совместно. Молодцы.
Обратная сторона: C++ с каждой версией всё тяжелей (для изучения, для реализации). Может повторить судьбу PL/1. Тот тоже контролировался «не шайкой олдфагов с IRC». А в результате все ушли на Си.
Ну и кто же это ушёл на Си? Я не люблю цепепе, но с выходом C++11 я отчётливо вижу рост его популярности. И все это видят. И все это связывают с выходом нового стандарта. А ведь всегда был тот же великий и ужасный boost, в котором были и трэды, и смартпоинтеры и ещё много чего. Только вот именно после выхода C++11 цепепе стал снова набирать популярность.
Это, опять же, эволюция. «Consistent with those aims, purely pattern-based macros work with the new expander the same as with the old one, except for unusual macro patterns within a recursive definition context.». Ещё есть https://github.com/samth/pycket — если будет успешен, то Racket, возможно, сменит JIT компилятор.