В свободное от C# время ощущаю необходимость попрактиковаться в Common Lisp. Уже попробовал себя в хаскеле, F# и Scala. Там было моделирование и движок системы совместного редактирования, но я не вижу больших перспектив их развития. В каких задачах можно еще себя попробовать?
Когда-то получил математическое образование. Так что, задачи своей сложностью не пугают. Главное, чтобы было интересно, а если еще с перспективой, то, вообще, здорово. Короче, ищу вашего совета.
Ну вы скажете тоже "подкиньте задачку". Нужно же хоть какой-то набор параметров указать, а то вопрос очень абстрактный ...
Ну ок ;) Вот вам задачка:
Взять популярный на сегодняшний web-сервер Hunchentoot и добавить в него код для поддержки горизонтального расширения (причём так, чтобы это было без головной боли). Справитесь? ;)
А что означает горизонтальное расширение? И меня больше интересуют задачи, где высокая доля самостоятельного решения. Где больше нужно создавать самому.
Горизонтальное расширение, это если есть у вас допустим комп с веб-сервером с такой-то производительностью и вам надо чтобы при необходимости вы могли увеличивать её простым добавлением компов (нодов), т.е. добавили комп увеличили производительность в два раза, добавили ещё два - увеличили в четыре раза. И так столько, сколько нужно (теоритечески) Ну конечно на практике, хрен там будет 2, 4 раза. Но всё-таки. В жизни обычно бывает так, что гораздо дешевле купить ещё один хост/сервак/системник, чем заказывать/разрабатывать супер-сверх-быстрое-высокотехнологичное решение. Но для этого необходима возможность горизонтального расширения.
Насчёт высокой доли самостоятельного решения, понятно. Но так или иначе всё равно же придётся пользоваться разными api. Иначе это будет просто технологическая развлекаловка. Или может вы этого и хотите? Тогда в принципе всё равно что писать. Ну напишите хотя бы "Искусственный Разум" что ли. А если серьёзно, ну блин, выберито что-нибудь что по вкуснее. Ну реализуйте какой-нибудь протокол, nfs, ftp, kerberos, который на CL пока ещё никто не реализовал.
Спасибо за разъяснения и идею. Буду думать.
maxima:
рефакторинг, слышал, что код там старый и в некоторых местах требует преобразования, может быть уже не актуально.
вывод графики в файл, используя, например, vecto.
embedded режим, т.е. возможность встроить maxima в свою common lisp программу.
возможно реализация кватернионов:)
Но, действительно, конкретизируйте.
С Максимой игрался недавно. Хороший продукт. Но меня больше интересует создание чего-то нового, чем дополнение существующих решений.
Например, я бы довел систему совместного редактирования от работающего прототипа (Silverlight/WPF, но не люблю винду) до вполне презентабельного графического редактора, но там нужен CAPI за отдельную плату, а такое дорогое хобби устраивать себе неохота. Как бы там ни было, в этой задаче присутствует challenge. Еще есть перспективы, хотя довольно туманные в связи c перенасыщенностью данного рынка.
Тогда остается что-нибудь несвязанное с GUI. Написать какой-нибудь специализированный сервер приложений, конвертор или шлюз для какого-нибудь востребованного протокола. Но увы, моя фантазия тут меня подводит. Не достает практики в таких областях. Знаю только, что нужны challenge и перспективы.
Могу предложить совместно порботать над проектом, который давно хотел сделать, но никак не доходили руки начать — преобразователь между разными (всеми!) форматами сериализации (
https://github.com/vseloved/reformat). Ну и, разумеется, как побочный эффект — легкая сериализация/десериализация во все эти форматы из Common Lisp.
Подробности могу изложить в личном письме вечером (нужно время, чтобы все записать).
Для затравки, вот список того, что хотелось бы поддерживать:
- JSON
- BSON
- AVRO
- XML
- Thrift
- Protocol Buffers
- MessagePack
- YAML
- ASN.1
- BERT
- CSV
- INI
- Apple Plist
Звучит заманчиво. Здесь моя почта и один небольшой проект на хаскеле:
https://github.com/dsorokinВ контексте поднятой темы возник у меня вот такой вопрос: существует ли абстрактный список библиотек для абстрактного языка, который необходимо должен присутствовать для того, чтобы конкретный язык жил полной жизнью (не могу придумать более подходящий эпитет).
Если есть, то было бы неплохо его посмотреть, и даже вывесить на видном месте, чтобы каждому были ясны цели и задачи. А если нет, так может стоит его создать?
А какие подходы применять к этому? ASN.1 выглядит самым общим по крайней мере расширение на xml у них было.У меня все бродит желание сделать обобщеный сетевый стек на базе asn.1 или чего то подобного.
UI, БД, сетевые протоколы включая api к web-сервисам, файловые форматы, парсеры.Токаж детальный список несделаного сам по себе малоинтересен. А вытягивать обобщеный уровень закрывающий всю область, тяжело даже на уровне постановки задачи.
Синтаксический анализ pdf. Выделить из сегментов текста заголовки, абзацы, формулы, сноски, колонтитуллы.
> Синтаксический анализ pdf
Есть в cl-pdf
В CL так погано с библиотеками, что стоит заняться неинтересной задачкой, как сразу же вылезет куча интересных.
> В CL так погано с библиотеками
В чем "поганость" заключается? Очень часто слышу что с библиотеками плохо, но в чем плохо до сих пор понять не могу. Но я на Lispworks. Вижу что делают на sbcl, со стороны там с библиотеками тоже все хорошо.
> В чем "поганость" заключается?
В том, что у библиотек сильно страдает качество. Например: нету нормального аналога lex/yacc; то, что есть -- фигня полная (по сравнению с lex/yacc).
Вот, кстати, и задачка. Нужен нормальный lex на CL.
А какой смысл вообще что-то делать в области библиотек, если нет никакого понятия о том, что это такое, если неизвестно ни текущее состояние, ни конечная цель? Просто чтоб развлечься? Тогда уж лучше игры писать - хоть никому не придется расплачиваться за недобросовестность и несознательность автора.
> А вытягивать обобщеный уровень закрывающий всю область, тяжело даже на уровне постановки задачи.
А то, что трудно - разве должно отталкивать, если хочется сделать что-то действительно полезное?
Пока у меня складывается такое впечатление, что на Коммон Лисп библиотеки развиваются по принципу "у других есть - давайте сделаем и у нас". Согласитесь, что это не lisp way. И последствия такого подхода явно нехорошие - копировать не успевается, копии получаются плохие. А ведь, возможно, многие из этих библиотек реально не нужны.
Я думаю, что вопрос нужно решить теоретически. И если его первым решат для Лисп - это будет очередное подтверждение его величия. :)
Хотя, я, честно говоря, надеялся, что мне дадут ссылку на какого-нибудь классика.
> Слишком сложно.
Не слишком. Если не заморачиваться с регулярными выражениями. Они-то не обязательны.
Думаю, можно родить что-то интересное если отталкиваться, например, от ESRAP.
Гы. У меня озарение: ниша esrap -- лексический анализ. А я-то -- дурень -- пихал его на роль полноценной замены lex+yacc.
> В том, что у библиотек сильно страдает качество.
Так это общеглобальная проблема, присущая всем языкам программирование, не только для Common Lisp. Написать качественну библиотеку очень (!) и очень сложно для любого языка/пролатформы. Везде есть шум и мусор.
Плюс бывает такая непонятная фигня: как пример, давно я написал немного кода под CL для Lispworks. Выложил ограниченно в интернет (больше так не делаю. по причинам описанным далее). На днях смотрю google, а там две новые бибилиотеки для CL полностью основанные на моем коде. Но я никогда не подразумевал что тот мой код утащат в библиотеки, так как тот код не готов быть библиотекой (и еще долго будет не готов). Тем не менее благодря лицензии open source код переехал в мини "бибилиотеки" на git хостинг.
> Например: нету нормального аналога lex/yacc; то, что есть -- фигня полная (по сравнению с lex/yacc).
Может он просто никому не нужен кто пишет на CL? (как я вижу, в реальных задачах проще использовать s-expressions и втроенный ридер, чем изобретать новый синтаксис и парсить его). Плюс lex/yacc писался под С, возможно что парадигмы C насаживать на CL не есть правильное решение.
Думаю, что было бы полезно иметь для CL внешний тайчекер. Вот и задачка.
Тайпчекер? Может быть ошибаюсь, но мне кажется, что для динамического языка задача такой же сложности как и написание интерпретатора.
Я не специалист в этой области, поэтому по поводу сложности ничего сказать не могу.
Можно начать с малого. Даже простой тайпчекер будет очень полезен. Он должен выискивать возможные ошибки с типами на стадии компиляции рекомендательного порядка.
> Может он просто никому не нужен кто пишет на CL? (как
я вижу, в реальных задачах проще использовать s-expressions и втроенный
ридер, чем изобретать новый синтаксис и парсить его).
Я бы рад, но кроме eDSL есть ещё и внешний мир. И нужны парсеры для кучи всего. (В моём случае это CSS3)
> Плюс lex/yacc писался под С, возможно что парадигмы C насаживать на CL не есть правильное решение.
Парадигмы к C не имеют никакого отношения. Это классика.
Есть такая вот штучка http://www.txl.ca/
Может пригодится
По поводу type checker'a. Чем не устроили штатные (declare (type ...)), (declaim (type ...)) и (declaim (ftype ...)), а также (deftype ...) ? sbcl вполне нормально разруливает, всякую-разную типизацию при необходимости (которую совершенно не стоит пихать везде и всюду!)
; SLIME 2011-08-18
CL-USER> (defun foo (i) (declare (integer i)) i)
FOO
CL-USER> (defun goo (x) (foo 'a) x)
CL-USER>
Компилятор ничего не говорит о возможной ошибочности вызова foo внутри тела goo на стадии компиляции.
Было бы замечательно, если бы внешний тайпчекер предупреждал о возможной ошибке.
выше я привел пример для sbcl (под винду). Может быть у меня sbcl неправильный. Не знаю.
Нужна правильная декларация типа. В данном случае:CL-USER> (declaim (ftype (function (integer) t) foo))
; No value
CL-USER> (defun foo (i)
i)
FOO
CL-USER> (defun goo (x)
(foo 'a)
x)
; in: LAMBDA NIL
; (FOO 'A)
;
; caught WARNING:
; Asserted type INTEGER conflicts with derived type (VALUES (MEMBER A) &OPTIONAL).
; See also:
; The SBCL Manual, Node "Handling of Types"
;
; compilation unit finished
; caught 1 WARNING condition
GOO
>Нужна правильная декларация типа.
На форуме есть хорошая статья про различие динамических и лексических переменных http://lisper.ru/articles/cl-vars
Может решитесь на подобную про declare, declaim и proclaim?
Да, такая статья была бы полезна. Хотя бы в части декларирования типов.
Между делом - глобальные лексические переменные в CL есть (по крайней мере в SBCL, за соотв. стандарту не ручаюсь):
(intern "MY-VAR")
(setf my-var 100)
(defun f() (1+ my-var))
(f) => 101
(let ((my-var 200)) (f)) => 101
>Между делом - глобальные лексические переменные в CL есть...
Нет.
Синтаксис
оператора let :
let ({var | (var [init-form])}*) declaration* form* =>
result*где
results---the
values returned by the
forms.
То есть: (let ((my-var 200)) (f)) => 101 - вернул результат последней вызванной формы (
that is, the body of a let is an implicit progn ->тело let - неявный progn). Первой и последней вызывается определённая в топ-левеле
f, не имеющая никакого отношения к локальной
my-var.
Об этом, кстати, сообщает компилятор в варнинге:
*
(let ((my-var 200)) (f))
101
Столько слов, а в чём смысл? Я лишь привёл пример в котором, если бы my-var была динамической то её связывание в форме let повлияло бы на вычисление формы (f). Это просто пример, в котором показано что можно связывать символ со значением, которое будет иметь "глобальный смысл", при этом символ не будет представлять динамическую переменную. Пусть будет такая формулировка, если вас не устраивает термин "глобальная лексическая переменная".
Это не глобальная лексическая переменная, а просто глобальная. Смотри здесь
http://www.nhplace.com/kent/CL/Issues/proclaim-lexical.html про то, что обычно переменные ищутся либо DG (динамически, затем глобально), либо L (локально), но неопределённые переменные в интерпретаторе ищутся как LDG. Из-за L, let my-var 200 устанавливает значение переменной в своей лексической среде, которая, есественно, f недоступно, поэтому он берёт глобальное значение.
(setq a 1) ; a определена для поиска в LDG
(let ((a 10)) (locally (declare (special a)) a)) ; special устанавливает область поиска в DG
(proclaim '(special a)) ; теперь область становится DG и для let
(let ((a 10)) (locally (declare (special a)) a)) ; let сработал в D
Хотя согласен, что можно называть такую переменную глобальной лексической, имея в виду, что хотя есть всего три взаимоисключающих способа существования связи переменной (глобыльный, динамический и лексический), такая переменная будет дополнительно связываться скорее как лексическая, чем как динамическая. Если бы предложение по ссылке выше приняли, в CL были бы стандартные глобальные лексические переменные LG (что для логической полноты приятно, но едва ли полезно).
Очистка образа от неиспользуемого кода, к примеру в sbcl , была бы полезна.
Да, иметь в наличии tree-shaker, было бы круто. Осталось убедить в этом разработчиков SBCL. Если нет серьёзного опыта работы с Лиспом и знаний о внутренностях SBCL, взваливать такую работу на плечи, слишком лихо.
может заплатить им, я бы отдал баксов 100
Хе:) От сотни зелёных они не откажутся, но и планы свои вряд ли поменяют - недавно за 2-3 месяца (вроде бы) они собрали больше 16 касарей баксов, так что 100$ им погоды не сделает:) http://www.indiegogo.com/SBCL-Threading-Improvements-1
Кстати в списке желаний числится tree-shaker: https://bugs.launchpad.net/sbcl/+bug/759417
Если добавить аргументации, то может прислушаются когда-нибудь:)