LINUX.ORG.RU

Интерактивный удаленный шелл и горячая замена кода

 , ,


0

4

Доброго времени суток, ЛОР

Хочется найти CL/Scheme реализацию которая умеет Erlang-подобный удаленный шел, и возможность замены кода без остановки системы. На сколько понимаю, со вторым особых проблем не должно быть, а для первого пока нагуглил только запуск окружения в screen, что мне не нравится. Может еще подскажет кто платформы с подобным функционалом? Сейчас в голову только Erlang и приходит.

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

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

В эрланге, горячая замена намного лучше организована с точки зрения продакшена.

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

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

Обновлять работающее приложение с помощью замены единиц трансляции

Тогда минимальной единицей будет модуль. Придется, также, перезагружать и зависимые модули в случае изменения интерфейса искомого модуля. Кстати, в случае хаскеля чем-то и проще: все побочные эффекты помечены. Осталось за малым: реализовать переход из состояние в состояние' :)

я не представляю как он может быть реализован в GHC с его заточенностью на модули

Динамической линковкой. Благо и ABI, и хороший линковщик присутствуют.

Кстати, с чего ты взял, что ghci не умеет компилировать нативный код? Очень даже умеет, но дебаггер не работает, да.

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

CL - отличный язык, но полное говно как платформа

За несколько килобаксов есть хорошие платформы...

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

CL - отличный язык, но полное говно как платформа

За несколько килобаксов есть хорошие платформы...

Пока потыкал SBCL и AlegroCL. Второе не вызвало ощущение платформы, хотя вроде и должно (тот же Racket пока оставил более приятное впечатление)... Но возможно это все от недостатка знаний и понимания как с этой платформой работать.

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

Осталось за малым: реализовать переход из состояние в состояние' :)

Допустим, в модуле A есть функция f, которая определяет, например, разбор какого-нибудь маршрута из URI. И вот, в запущенном приложении обнаруживается, что этот разбор работает криво - хочется поправить эту f, при этом остальные функции этого и других модулей должны пользоваться новой версией f. Если обновить весь модуль A, то, да, все функции модуля A будут использовать новую версию f, но разве (в нынешнем GHC) функции других модулей станут использовать новые функции (в том числе f) из нового модуля A? Пока что при обновлении группы файлов GHCi сбрасывает сессию (сбрасывает все определения и переменные) и загружает всё снова, с перекомпиляцией изменённых модулей, на работающих приложениях новые определения никак не сказываются. Это должен быть какой-то новый механизм, когда модуль подменяется всё должно быть заморожено, функции переписаны, но по тем же адресам (либо PIC + dlclose + dlopen) и потом запущено снова.

Динамической линковкой.

То есть будет склад soшек в tmpfs?

Кстати, с чего ты взял, что ghci не умеет компилировать нативный код?

А как? Например, чтобы foldl (+) 0 [0 .. 1000000000] отработал нормально (так как компилятор такое оптимизирует)?

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

Т.е. как только ты начинаешь работать со сторонней не-лисп библиотекой, просить что-то серьезное у ОС, то начинаются НЮАНСЫ.

В эрланге, горячая замена намного лучше организована с точки зрения продакшена.

А можно примеров? Какие могут быть проблемы с FFI и горячей заменой у, например, SBCL на linux-е и 64 битах?

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

В SLIME предполагается работать через ssh туннель.

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

А можно примеров? Какие могут быть проблемы с FFI и горячей заменой у, например, SBCL на linux-е и 64 битах?

Вопрос на этот счет: я пока ничего не увидел про версионирование кода, тоесть про работу существующих клиентов на старой версии, а новых - на новой. Есть какие-то ссылки чтобы прояснить этот вопрос?

С FFI предполагаю проблемы в районе i/o, хотя это пока теория.

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

я пока ничего не увидел про версионирование кода

В смысле, есть ли возможность узнать версии используемых библиотек и реализации? Есть cl:lisp-implementation-version и asdf:component-version (в ASDF точно так же можно узнать лицензию, имя/емайл автора и т.п.).

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

когда модуль подменяется всё должно быть заморожено

Понятно дело. Но в хаскеле это без проблем: сборщик мусора же, и объекты под учетом опять же. А вот как быть со всякими IO? Здесь без ad-hoc процедур миграции не обойтись.

То есть будет склад soшек в tmpfs?

Зависит. По идее, dlopen/dlclose самый простой и прямолинейный путь... Но что мешает использовать oшки без системной процедуры динамической линковки? Таблица символов есть, формат позволяет прозрачно хранить любую мета-информацию, вплоть до самих исходников. И самое главное, даже под виндой - COFF.

Например, чтобы foldl (+) 0 [0 .. 1000000000] отработал нормально

Запустить на чем-нибудь из Top500. Отработает за вменяемое время.

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

проблемы с FFI и горячей заменой

С горячей заменой, скорее всего, никаких. А вот с сохранением в образ и последующим восстановлением, возникнут.

Хотя предположим, что старая версия кода испортила состояние внешней библиотеки. Например, напутала с указателями и часть памяти повредилась.

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

я пока ничего не увидел про версионирование кода

Потому что её нет. Строго говоря, горячей замены код в CL нет. Есть возможность «перевычислить». Это предназначено для интерактивной разработки, а не для обновления кода на рабочих серверах. Обычно можно достаточно безопасно вносить небольшие изменения в работающую систему и это часто бывает удобным. Но в случае больших изменений я предпочитаю перезагрузить систему. В критических ситуациях (космическая станция в сотнях миллионов миль от земли) можно вносить и большие изменения, но это довольно рискованно и требует участия «мастера».

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

Запустить на чем-нибудь из Top500. Отработает за вменяемое время.

$ cat foo.hs
main = print $ foldl (+) 0 [0 .. 1000000000] 
$ ghc --make foo.hs -O2 -ddump-simpl-stats
...
10 UnfoldingDone
  1 GHC.Base.build
  1 System.IO.print
  1 GHC.TopHandler.runMainIO
  1 GHC.Base.$
  1 GHC.List.foldl
  1 Main.main
  1 System.IO.print1
  1 GHC.Show.$fShowInteger_$cshow
  1 GHC.Enum.$fEnumInteger_$cenumFromTo
  1 lvl_s1M3
...
$ time ./foo
500000000500000000

real	0m43.317s
user	0m42.454s
sys	0m0.834s
quasimoto ★★★★
()
Ответ на: комментарий от Macil

А вот с сохранением в образ и последующим восстановлением, возникнут.

Я как-то сохранял образы с FFI (gtk, iolib) - проблем не было. Только под виндой были (с gtk), не знаю как там сейчас обстоят дела.

Например, напутала с указателями и часть памяти повредилась.

И новой версии достались порченые буфера с foreign стороны? При этом код успешно обновился, то есть проблема только в том, что память можно испортить с лисповой стороны, даже без всякого горячего обновления. У SBCL есть недокументированная возможность практиковать что-то вроде erlang-ских драйверов - весь FFI код который работает с сишными типами (и с памятью) пишется с сишной стороны, подключаются заголовки SBCL и пишутся функции принимающие и отдающие уже лисповые объекты (описанные в тех заголовках), потом с лисповой стороны строится FFI уже к таким, более безопасным, функциям.

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

CCL - сравним с SBCL (но медленнее), на Linux-е, наверно, у него нет каких-то преимуществ перед SBCL.

Лучше дебаггер, понятнее сообщения об ошибках, меньше багов, особенно по части i/o. В общем, все прелести реализации, которую двигает одна контора, предлагая коммерческую поддержку и сама же клепая на заказ софт, используя свой dog food.

Я не так давно StumpWM начал с CCL собирать, ибо в SBCL опять нагнали регрессий. А что там было в районе 1.0.6 - лютый ужас.

mv ★★★★★
()

Хочется найти CL/Scheme реализацию которая умеет Erlang-подобный удаленный шел, и возможность замены кода без остановки системы.

Java такое умеет. Так что, возможно, и Clojure. Нет? :)

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

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

Твое мнение по предмету, в котором ты не разбираешься - тоже говно полное ;)

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

для моих целей изкоробочный ерланг подходит полностью, изкоробочный асбтрактный CL

Имей в виду, что Эрланг, как язык - игрушка по сравнению с CL.

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

В смысле, есть ли возможность узнать версии используемых библиотек и реализации? Есть cl:lisp-implementation-version и asdf:component-version (в ASDF точно так же можно узнать лицензию, имя/емайл автора и т.п.).

Я не о том немного. Меня интересует могут ли две генерации одного кода жить в рабочем образе?

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

Имей в виду, что Эрланг, как язык - игрушка по сравнению с CL.

Я выше писал что как язык CL прекрасен, только у него с батарейками плохо

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

Твое мнение по предмету, в котором ты не разбираешься - тоже говно полное ;)

Я не отрицал что все пока очень субъективно и от малого количества опыта :) А есть что по делу сказать: где живут качественные библиотеки? что принято использовать для C10k на CL?

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

Потому что её нет. Строго говоря, горячей замены код в CL нет. Есть возможность «перевычислить». Это предназначено для интерактивной разработки, а не для обновления кода на рабочих серверах. Обычно можно достаточно безопасно вносить небольшие изменения в работающую систему и это часто бывает удобным. Но в случае больших изменений я предпочитаю перезагрузить систему. В критических ситуациях (космическая станция в сотнях миллионов миль от земли) можно вносить и большие изменения, но это довольно рискованно и требует участия «мастера».

Раз ты появился в теме, то спрошу: как у твоего restas с работой под нагрузкой в контексте C10k? особо интересует большое количество подключений с относительно низкой активностью, а то выше писали про поток на подключение что вызывает у меня сомнения в том что это больше чем игрушка для ненагруженной системы.

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

Че совсем тупой/слепой/ленивый (нужное подчеркнуть)? Носом всегда тыкать надо? http://www.gnu.org/software/kawa/Projects.html

Ну и? Большая часть полумертвые вещи. Говорит ли это о том что кава плохо пахнет? Думаю не очень. Но и о том что это хороший инструмент тоже не говорит. Опять же, я про личный опыт спрашивал.

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

Я выше писал что как язык CL прекрасен, только у него с батарейками плохо

Не боись, твою задачу начинающий лиспер ради ознакомления с REPL за день до чего-то запускающегося и работающего напишет.

Опытный лиспер swank прикрутит.

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

Java такое умеет. Так что, возможно, и Clojure. Нет? :)

Обновление кода весьма ограничено в силу особенностей JVM. А про шелл можно подробностей? То что я видел - больше технологии мониторинга системы.

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

Не боись, твою задачу начинающий лиспер ради ознакомления с REPL за день до чего-то запускающегося и работающего напишет.

Ты про (loop (eval (read))) ? Или я что-то упустил? Опять же вопрос был про то, чтобы получить из коробки не написав.

Из опыта написания такого: у меня есть шелл для С поверх libllvm. Для собственного развития - хорошо, для надежной платформы - слишком много багов в данный момент :)

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

А есть что по делу сказать: где живут качественные библиотеки?

Библиотеки для чего? Работающие (по-крайней мере, компилирующиеся) библиотеки живут в quicklisp.

что принято использовать для C10k на CL?

Не знаю, я c10k ни на каком языке не решал. Вероятно, в iolib есть доступ к epoll'у и т.п., используемых для c10k.

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

Не боись, твою задачу начинающий лиспер ради ознакомления с REPL за день до чего-то запускающегося и работающего напишет.

Опытный лиспер swank прикрутит.

Да и REPL'ом задача не ограничена. Лучше подскажи что масово используется для работы с http? Смотреть в сторону iolib или еще что-то? И что лучше посмотреть в сторону паралелизма: потоки или корутины с точки зрения производительности? Или еще есть какие-то техники для этого в CL?

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

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

Библиотеки для чего? Работающие (по-крайней мере, компилирующиеся) библиотеки живут в quicklisp.

регекспы, потоки, mq (у тебя вроде есть либа для 0mq, ты ее еще поддерживаешь?), бд - couchdb, работа с сетью?

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

Ты про (loop (eval (read))) ? Или я что-то упустил?

REPL уже встроен, можно просто по ssh подключаться, слать лиспокод и читать ответы.

Опять же вопрос был про то, чтобы получить из коробки не написав.

Ты не сказал, что тебе нужно.

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

Опять же вопрос был про то, чтобы получить из коробки не написав.

http с какой стороны? Впрочем, я тут не советчик. Но в топике есть специалисты.

И что лучше посмотреть в сторону паралелизма: потоки или корутины с точки зрения производительности? Или еще есть какие-то техники для этого в CL?

Посмотри в сторону Clojure, у него более активное коммьюнити и, как следствие, больше библиотек. Язык по сравнению CL коряв (на гнилом фундаменте дом не построишь), но это можно сказать про любой мейнстримный язык.

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

регекспы

cl-ppcre

потоки

Какие потоки? Которые треды, то boreaux-threads. Есть ещё библиотеки для futures, но я не использовал.

mq (у тебя вроде есть либа для 0mq, ты ее еще поддерживаешь?)

Нет, забил. Их охватило энтерпрайз-безумие, 64 бита на длину сообщения... Мы даже хотели в железе zmq сделать, но мы наносекунды считаем, а другие в zmq-коммьюнити даже не знают, какая это степень...

Есть форки или полностью переделанные, часть из них мертва, но что-то есть. В quicklisp недавно прилетело что-то, по крайней мере.

Есть библиотека для amqp, de.setf.amqp зовётся. 1-0 на вряд ли поддерживает, но 0-8 и, может быть, 0-9 есть.

Есть CLERIC.

бд - couchdb

Много их.

работа с сетью?

iolib или встроенное в имплементацию твоего выбора. Для Lispworks использую встроенный comm для tcp и левый lispworks-udp.

Если у тебя нет цели оценить блеск и нищету конкретно Common Lisp, то возьми Clojure. Common Lisp на вряд ли уже оклемается.

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

http с какой стороны? Впрочем, я тут не советчик. Но в топике есть специалисты.

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

Посмотри в сторону Clojure, у него более активное коммьюнити и, как следствие, больше библиотек. Язык по сравнению CL коряв (на гнилом фундаменте дом не построишь), но это можно сказать про любой мейнстримный язык.

Это то что поверх JVM? Из JVM-языков меня пока больше Scala привлекает, но у нее свои проблемы.

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

И зачем тебе это?

Больше привычка к хорошему из Erlang, плюс удобство разворачивания и подключения нод и работа с ними. Или CL для такого не совсем удобен?

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

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

Я, как уже писал, http и веб стараюсь избегать. По библиотекам можешь смотреть cliki.net, есть и серверы, и клиенты, но в каком состоянии, и как хорошо с ними работается - без понятия. Б-г миловал, так сказать ;)

Это то что поверх JVM? Из JVM-языков меня пока больше Scala привлекает, но у нее свои проблемы.

Позволь поинтересоваться: а сколько JVM-языков ты знаешь? =)

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

Если у тебя нет цели оценить блеск и нищету конкретно Common Lisp, то возьми Clojure. Common Lisp на вряд ли уже оклемается.

Спс, посмотрю что оно из себя представляет. Хотя мне интересно как раз попробовать CL для себя пока, а по результатам уже делать выводы.

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

Позволь поинтересоваться: а сколько JVM-языков ты знаешь? =)

Я знаю JVM && DalvikVM байткод )) Работал в продакшене с Java/Scala. Игрался с Groovy/Groovy++. JRuby/JPython можно учесть, хотя они не то чтобы совсем JVM языки. Плюс еще в фоновом режиме за Kotlin слежу

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

Больше привычка к хорошему из Erlang, плюс удобство разворачивания и подключения нод и работа с ними.

Должна же быть у Эрланга какая-то ниша? ;)

Для чего нужно версионирование кода я не особо понимаю.

Параллельное программирование в CL не очень. В стандарте языка никакого параллелизма нет. Есть обёртки над системными тредами, есть eager future, неживые вариации map/reduce и мёртворождённые поделки типа одной моей, но лёгкого распараллеливания одной директивой препроцессора, как на сишечке с MPI, нет. Единообразного доступа к окружению исполнения (environment) в стандарте языка нет, все делают, как могут (или не могут), прозрачно распределённый и портабельный лиспокод с неявным параллелизмом особо не попишешь. Для неявного параллелизма нужно уметь собирать зависимости кода, который на стороне должен исполниться, и подготавливать удалённое окружение для исполнения этого кода. Для этого нужна приличная интроспекция и возможность улучшения окружения (коряво-то как augmented environment звучит).

Можно, правда, взять одну реализацию типа SBCL или LW, и написать своё, но это писать надо, а перед этим неслабо в теорию темы врубиться.

Или CL для такого не совсем удобен?

CL сам по себе очень мощный, но стандарт завис с середины 90-х (а, фактически, с середины-конца 80-х), фронта работ никакого нет, народа мало. Если степени просветления достиг, то всю эту фигню и сам за день-два напишешь (есть у нас такой дядечька - от веб-фреймворка и nosql на собственной объектной системе, до компиляторов HDL клепает), но большинство разработчиков при изучении новой темы подходит к вопросу весьма утилитарно: есть ли батарейки? В таком случае выбирать живомёртвую платформу, пахнущую то ли розами, то ли мертвецами, не надо.

У CL был бы шанс, если во второй половине 90-х Lispworks или Franz свои офигенные, в общем-то, компиляторы открыли. Но, увы...

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

Меня интересует могут ли две генерации одного кода жить в рабочем образе?

Этого нет. Но если вспомнить как версионирование делается в gcc - можно написать my-defun, my-funcall, my-apply и т.п. (или переопределить обычные такие функции и макросы в специальном пакете cl-versioning) которые будут следить за префиксами (суффиксами) версий у символов. Это конечно до рабочего и общего решения нужно пилить, но суть в том, что возможно, CL тут ничем не ограничивает.

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

что принято использовать для C10k на CL?

Кстати, нужно заметить, что, например, c500 (< c1k) это уже хорошо если это честные 500 конкурентных (в том числе медленных) клиентов на честном железе и реальном же канале (не на lo) - это примерно уровень википедий и твиттеров (у википедии сотни тысяч запросов в секунду и при этом сотни серверов - так и получается). Хорошо, конечно, если можно больше. У nginx, например, latency может на порядок отличаться от latency «настоящего» сервера который выполняет отдачу динамического контента и соединения с БД, что позволяет ему (nginx) по полной использовать bandwidth, не тратить процессорное время и обслуживать сразу несколько бакэндов. От базы данных, от апача с пхп или от hunchentootа с лиспом такой скорости трудно ожидать.

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

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

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

но, справедливости ради, стоит заметить что эта система - по сути маршрутизатор, и особой вычислительной нагрузки на нее нету.

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

можно ContextL заюзать

Может быть, не знаю про него. Я говорил про элементарную вещь вроде

(defpackage #:versioning)

(defvar versioning::*version-prefix*)

(defun versioning::versify (symbol)
  (alexandria:symbolicate versioning::*version-prefix* '- symbol))

(defmacro versioning::defun (name args &body body)
  `(defun ,(versioning::versify name) ,args ,@body))

(defun versioning::funcall (function &rest args)
  (apply #'funcall (versioning::versify function) args))

(defmacro versioning::with-versioning (version form)
  `,(let ((versioning::*version-prefix* version))
      (macroexpand-1 form)))

(defmacro versioning::with-version-prefix (version &body body)
  `(let ((versioning::*version-prefix* ',version))
     ,@body))

(versioning::with-versioning 0.0.1
  (versioning::defun foo ()
    (princ 1)))
; 0.0.1-FOO

(versioning::with-versioning 0.0.2
  (versioning::defun foo ()
    (princ 2)))
; 0.0.2-FOO

(versioning::with-version-prefix 0.0.1
  (versioning::funcall 'foo))
; 1
; 1

(versioning::with-version-prefix 0.0.2
  (versioning::funcall 'foo))
; 2
; 2

хотя тут может быть сколько угодно «а что если», на которые трудно отвечать.

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

Я как-то сохранял образы с FFI (gtk, iolib) - проблем не было.

Наверное потому что состояние хранилось на стороне лисп-системы.

Или SBCL умеет сохранять в образ и сишную кучу?

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

ghc --make foo.hs -O2 -ddump-simpl-stats

А разве это чем-то отличается от ghci -f-object-code?

Правда да, в таком режиме он мусорит oшками в текущий каталог.

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

Или SBCL умеет сохранять в образ и сишную кучу?

Нет, этого он не делает, с сишной кучей нужно что-то делать руками в init/exit hooks, так что да, проблемы тут могут быть.

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

Боевой проект на Erlang или это так на поиграться? Я вот тут тыкаю Clojure, годнота неимоверная. На Scala теперь не смотрю ибо противно от его дикого синтаксиса. Хотел поглядеть на Erlang, но я так понял его в основном используют как клей между модулями на C.

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