LINUX.ORG.RU

Clojure 1.2

 , , ,


1

0

После 8 месяцев напряжённой работы вышла новая версия языка Clojure — 1.2. Clojure — Lisp'образный язык общего назначения, работающий на платформах JVM и .Net и отличающийся более функциональным подходом и специальными средствами для упрощения разработки параллельного кода.

В новой версии очень много изменений, из которых особо стоит отметить следующие:

  • Введены протоколы (protocols) и типы данных (datatypes), позволяющие создавать новые абстракции и полиморфные функции. При этом производительность гораздо выше, чем при использовании мультиметодов;
  • Расширена деструктуризация структур данных, о которой я уже писал;
  • В составе языка введено несколько новых пространств имен, функции которых были перенесены из clojure-contrib. Сюда относятся функции для работы со строками, repl, pretty printer, ввод/вывод Java, и т.д.;
  • Расширен набор функций для работы с последовательностями;
  • Добавлена поддержка аннотаций Java, что позволяет использовать соответствующий функционал различных фреймворков;
  • Много изменений, связанных с улучшением производительности кода;
  • Для указания метаданных теперь вместо #^ используется просто ^.

Статья Введение в Clojure была частично обновлена описанием новых возможностей (кроме протоколов, которые будут чуть позже).

>>> Полный список изменений

★★★★★

Проверено: catap ()

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

Мутабельный код тяжело параллелить

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

На plt scheme написан продукт Дозор-Джет с сотнями инсталяций по России и СНГ

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

>> Мутабельный код тяжело параллелить

Если подходить к его написанию спустя рукава.

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

У нас сейчас в проекте на C++ большой выигрыш в скорости за счет избавления от лишних локов в пользу создания read-only «переменных». И это был обдуманный шаг. Плюс уменьшилось количество race conditions...

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

Единственная полезная фича немутабельных структур данных - транзакционность на халяву. Иногда это бывает очень полезно. Только вот для этого никаких ФЯ на фиг не надо, и на C++ или Java все то же самое делать можно в разы удобнее.

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

> Если подходить к его написанию спустя рукава.

Согласен. А когда подходят с толком, получаются чистые функции и немутабельные структуры данных.

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

> К тому же не ясна судьба Mono с точки зрения патентных преследований со стороны Microsoft.

Патентные преследования Моно со стороны Майкрософт существуют исключительно на ЛОРе. -)

Reaper ★★ ()

Лучше бы они туда отладчик/стек трейсер нормальный впихнули

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

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

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

> Патентные преследования Моно со стороны Майкрософт существуют исключительно на ЛОРе.

Читал Microsoft Community Promise - ничего не понял.

Вроде как разрешили делать реализация стандартов и привели список. Но что с патентами - по прежнему не ясно.

sign ()

Бывают новости, в которым по субжу можно угадать автора. Для меня это работает в случае двух человек - AP & ott.

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

А жаба надежна?

А жаба надежна?
Только не смешите мои тапочки.

vbv ()

>конкуррентного кода.
Учимся выговаривать «р»?

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

>В чем смысл связывать себя по рукам отказываясь от мутабельности???

Лучше попытайся оправдать свою нужду в этом. Нафиг оно те надо?

только не надо рассказывать про транспаретность кода и отсутсвие ситуаций типа «неизвестно кто присвоил глобальной переменной», это к мутабельности не относитс


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

Иммутабельность - решает.

Далее - ленивые структуры данных. Можно строить map/filter проекции не парясь что в процессе итерирования по проекции влруг что-либо изменится в коллекции. Кто видел ConcurrentModificationException на всяких списках в простых казалось бы вещах на многозадачности - тот в цирке не смеется, особенно учитывая что вычислить сволочь которая это сделала весьма затруднительно - потому что падает как раз другой тред которы детектит что его итерация более невалидна.

Иммутабельность решает и здесь.

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

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

>Если подходить к его написанию спустя рукава.

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

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

>и на C++ или Java все то же самое делать можно в разы удобнее.

Одна из необходимых вещей для немутабельных структур - хвосторекурсивная оптимизация. Нихрена это не удобнее строить их там где ее нет.

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

Такие вещи, как графические и звуковые редакторы, игры и многое др. являются мутабельными по определению. И распаралелить там есть что. А вот делать это немутабельными средствами мягко говоря не удобно. Немутабельность не панацея совсем.

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

> Можно строить map/filter проекции не парясь что в процессе итерирования по проекции влруг что-либо изменится в коллекции

А сможет ли подобный подход сработать в случае, к примеру, файла, в который пишут/читают разные потоки?

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

>> Можно строить map/filter проекции не парясь что в процессе итерирования по проекции влруг что-либо изменится в коллекции

А сможет ли подобный подход сработать в случае, к примеру, файла, в который пишут/читают разные потоки?

И работа с внешним миром всё равно требует синхронизации.

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

Учишь так JVM-зависимые языки, учишь... а потом - БАЦ! И JVM становится закрытой (в плане исходников) платформой (например).

И чо?

jre явы открыто, пиши jvm сам и лицензируй у оракла.

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

Может .NET на Java залабать ?

Ты хоть сам понял. что сказал?

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

>> А сможет ли подобный подход сработать в случае, к примеру, файла, в который пишут/читают разные потоки?

И работа с внешним миром всё равно требует синхронизации.

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

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

>> Лучше попытайся оправдать свою нужду в этом. Нафиг оно те надо?

Производительность за счет in-place изменений данных.

Когда ты в наружу возвращаешь некий список чего либо

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

Далее - ленивые структуры данных. Можно строить map/filter проекции не парясь что в процессе итерирования по проекции влруг что-либо изменится в коллекции.

При чем здесь ленивость?

Кто видел ConcurrentModificationException на всяких списках в простых казалось бы вещах на многозадачности - тот в цирке не смеется,

Тот плохо учил матчасть.

Можн конечно обкладываться мьютексами, синхронизациями, возвращать копии списков внаружу

А что, при немутабельных данных назад вовзращаются модифицированные списки??? Элементарный пример вставки элемента в дерево приводит к его полному копированию. В любом учебнике Хаскеля этот пример есть...

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

Во многом, конечно, с вами согласен, но касательно оптимизации хвостовой рекурсии в C++ читать здесь — http://ridiculousfish.com/blog/archives/2010/07/23/will-it-optimize/

Большинство реализаций JVM, опять же, стековые штуки, поэтому с рекурсией там, в принципе, неплохо.

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

>> Одна из необходимых вещей для немутабельных структур - хвосторекурсивная оптимизация. Нихрена это не удобнее строить их там где ее нет.

GCC умеет делать TCO, например, и если уж припрет, то можно и на C++ писать в стиле «немутабельные данные». Вопрос в том умеет ли это делать программист. Если язык ничего кроме немутабельных данных не предлагает, ограничивая программиста, то ему (программисту) ничего другого не остается, как «натягивать» любую задачу на язык с одной предлагаемой возможностью.

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

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

> выделять один процесс на работу с файлом

А разруливание потенциальных проблем одновременного чтения/записи руками делать? Или есть какие-то языковые, встроенные механизмы?

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

У процесса в Эрланге есть очередь сообщений, которую он последовательно обрабатывает.

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

> А разруливание потенциальных проблем одновременного чтения/записи руками делать? Или есть какие-то языковые, встроенные механизмы?

У вас один процесс отвечает за работу с файлом. Остальные посылают ему сообщения. Гарантирована обработка одного сообщения единовременно. Остальные ставятся в очередь. Как раз это и сделано для разруливания таковых ситуаций. Точнее для предотвращения их появления.

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

>Элементарный пример вставки элемента в дерево приводит к его полному копированию.
Ложь

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

> Гарантирована обработка одного сообщения единовременно

Вот эту гарантию я должен сам, врукопашную обеспечивать?

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

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

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

Вот эту гарантию я должен сам, врукопашную обеспечивать?

Не понял о чем ты. Процесс как бы код свой последовательно выполняет:

loop() ->
    receive 
        {op1, Params} -> 
            <Code>; 
            loop(); 
        _ -> oops
end. 

Ресивом вытаскиваешь сообщение из ящика своего — обрабатываешь — опять из ящика сообщение тянешь и тд.

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

Спрошу заодно. В каком-нибудь языке кроме Эрланга реализован binary pattern matching? Ибо жутко удобная штука для парсинга хитрожопых сетевых протоколов, но в то же время от недостатков языка временами плакать хочется.

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

>но в то же время от недостатков языка временами плакать хочется.
что-то кроме жуткой документации, repl'a и юникода в голову сходу ничего не приходит. Ну еще может не очень веселая ситуация с hipe. м?

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

> Вот эту гарантию я должен сам, врукопашную обеспечивать?

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

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

HIPE, который частенько отнюдь не High Performance, я пока вообще в расчет не беру.

Ну а так, синтаксис для работы с record'ами просто убийственный, особенно когда вложенность нужна. С драйверами для доступа к СУБД при работе на Unix-системах тоже не всё хорошо. Родных драйверов, пригодных для работы, кот наплакал. Можно конечно и через ODBC сделать, и ноды на С написать специально для работы с базой, но как-то это все через одно место.

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

> что-то кроме жуткой документации, repl'a и юникода в голову сходу ничего не приходит. Ну еще может не очень веселая ситуация с hipe. м?

Переменных же там нету, и циклов. А также мьютексы непонятно куда втыкать))

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

> Процесс как бы код свой последовательно выполняет

Тогда хорошо.

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

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

В обсуждаемой поделке, clojure, тоже никакой полноценной хвостатой рекурсии нет, кроме как на уровне одной функции. Потому что в JVM этого говна нет и не надо.

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

> Ну а так, синтаксис для работы с record'ами просто убийственный, особенно когда вложенность нужна. С драйверами для доступа к СУБД при работе на Unix-системах тоже не всё хорошо. Родных драйверов, пригодных для работы, кот наплакал. Можно конечно и через ODBC сделать, и ноды на С написать специально для работы с базой, но как-то это все через одно место.

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

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

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

> jre явы открыто, пиши jvm сам и лицензируй у оракла.

Google так и сделал. Помогло им это?

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

> GCC умеет делать TCO

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

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


т.е. все пишите на Common Lisp? :3

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

> В случае я явой его надо еще реализовать.

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

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

>> jre явы открыто, пиши jvm сам и лицензируй у оракла.

Google так и сделал. Помогло им это?


Когда на Dalvik можно будет исполнять байткод, скомпилированный javac - поможет.

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

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

Я в этом ни капли не сомневался, что они там есть. Их только надо прикрутить. А в erlang все уже прикручено - пользуйся.

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

нет, в ФЯ полного копирования не происходит - новые структуры эффективно используют предыдущие данные. Это только в С++ для гарантии неизменяемости надо скопировать весь объект

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