LINUX.ORG.RU

Clojure 1.1

 , ,


0

0

Вышла новая версия языка программирования Clojure. Clojure является динамически типизируемым и компилируемым языком общего назначения для JVM и CLR. Изменений много. Среди них:

  • поддержка примитивных массивов (primitive array generators)
  • chunked-последовательности
  • futures, предназначенные для асинхронных вычислений
  • promises для обмена данными между тредами
  • pre- и post условия для функций
  • новое пространство имён

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

>>> Подробности

★★★★

Проверено: maxcom ()
Последнее исправление: maxcom (всего исправлений: 1)

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

> Я начинаю догадываться, кажется. Вы - тролль, да?

Я это про вас знал ещё при фразе «Как вы этот код вообще понимаете?!?»

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

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

Странно. У меня эта «несуществующая у людей» привычка появилась всего за пару дней. По распечатке.

/me завидует Алексу Отту, который находит в себе силы промолчать.

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

> Очевидно, вы не умеете правильно расставлять отступы.

Если отступы абсолютно необходимы - то тогда не нужны скобочки.

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

> Ну или в жабе инструментингом который сведет попытки создавать неконтролируемые сайдэффекты к КакогоХренаТыДелаешьException.

Это ж надо отслеживать не только IO, но и попытки изменить глобальное состояние — хз, можно ли такое провернуть, да ещё и без больших потерь производительности. Да и в продакшне лучше отключить — может там логгинг какой-нибудь безобидный.

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

> Тут уже поуказывали, а еще потому, что позволяет пейсать код прямо в AST

Ты так говоришь, будто «пейсать код в AST» - это что-то хорошее.

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

А они и не обязательны в ECMAscript. Нужны только если есть несколько выражений на одной строке.

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

>Ты так говоришь, будто «пейсать код в AST» - это что-то хорошее.

Это как минимум круто :)

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

Как я мог забыть! И зачем в С эти арифметические операторы, которые лишний раз усложняют синтаксис и вносят в язык *программирования* такую бесполезную *математическую* сущность, как приоритет операторов? Лучше было бы сделать их такими же функциями, как и, например, writef.

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

Да да да, и тогда получится Лисп.

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

Это как минимум круто :)


Не. Его, AST, анализировать удобно. И еще удобней, когда оно совпадает с синтаксисом.

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

Тебе не удобно - не программируй. Мне, вот, на Java не удобно и в Винде... А другим в Линухе... Никто не неволит.

Кстати, на той же жабе без навороченной ИДЕ пейсать грустно (это если твой закидон насчет текстового редактора с навороченной подсветкой блоков)

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

>ну примитивные массивы - не самое главное, они и до этого были, просто надо было явно типы данных писать....

Давно? Помню какое-то время назад в форуме с примитивными массивами отправляли туда, «куда Макар телят не гонял»... =)

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

На мой взгляд на жабе при навороченной ИДЕ писать также весьма грустно. Особенно когда сама ИДЕ на жабе и большой проект.

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

>> твоя работа состоит в анализе AST?

Иногда - да.

Вот именно - «иногда». А пялиться на AST приходится постоянно. Не, я понимаю, ты привык и тебе нравится.

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

ну по состоянию на конец 2008-го года, оно уже было. все-таки часто востребованная фича, много жабовских классов с массивами работает, а не с коллекциями

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

>ну по состоянию на конец 2008-го года, оно уже было

б&я, как время летит... :(

ладно, значит надо ещё раз на неё (него? :) пристально посмотреть

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

> ну make-array был и в версии 1.0. Сейчас можно просто писать (byte-array ..) вместо (make-array Byte/TYPE ...)

И это нельзя было сделать макросом? Понадобилось вмешательство разработчиков языка?

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

> Как, впрочем, и фигурные скобки (и begin/end) и круглые скобки в заголовках функций.
Вот так люди и приходят к тому, что питон рулит

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

Ш! Не спугни! Я их уже почти убедил, а ты тут пришел и с плеча рубишь!

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

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

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

>что это простая оптимизация производительности

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

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

> ну generic make-array с явным указанием типов нормально работал...

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

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

>> Как, впрочем, и фигурные скобки (и begin/end) и круглые скобки в заголовках функций.

Вот так люди и приходят к тому, что питон рулит


В питоне уже можно вызывать функции так? my-func arg1 arg2

Да и значащие отступы тоже не нужны.

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

при этом, часто неявной многопоточности...

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

>очередной тормозной недоязычок?

Он не тормозной. Он компилируется, а для оптимизации можно типы задавать явно.

из них и одного питона хватит, больше не нужно

Clojure больше на haskell смахивает, он не из этой песочницы.

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

В Erlang нормальная много-поточность? Erlang динамический?

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

>Он не тормозной. Он компилируется,

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

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

>а ссылочки не осталось? было бы интересно почитать

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

Ну объявил ты фукнцию с параметром структурного типа :

def f[A <: {def mymethod()}](a:A) = a.mymethod()

и вызвал ее с правильным параметром - компилятор мамой поклялся что правильно - а сгенерировать то он что может? В jvm нельзя инвоукнуть метод который не объявлен в интерфейсе или классе - нету такой байткодной инструкции, и потому там генериться что-то типа a.getMethod(«mymethod»).invoke(a).

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

Вот когда выйдет da-vinci vm - тогда всем сильно полегчает. Хотя работа для авторов компиляторов (особенно динамических языков) остается в области генерирования грамотного кода работы с примитивами и т.д.

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

>а ссылочки не осталось? было бы интересно почитать

нет

вчера полез полазить по форуму... То, что нужно не нашёл - нашёл другое: где-то в августе-сентябре один чел создал небольшой проектик а-ля clojure-benchmark, в котором попытался реализовать несколько тестов из shootout на clojure, java, sbcl и что-то там ещё... Что-то результаты очень грустные были для clojure. Правда, с тех пор проект не обновлялся.

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

>а сгенерировать то он что может?

могли для таких случаев подправить ClassLoader, который бы «на лету» по спецификации генерил «служебные» классы (структуры, лямбды, прочую мелочь), обеспечивая «преемственность» таких классов во всём коде.

Вот когда выйдет da-vinci vm...


В 7-ке (да, develop-версия) уже довольно давно есть invoke-dynamic, и даже в ASM реализован. Но, на сколько я помню, автор clojure гвоздями прибил к ней предыдущую версию asm-а. Наверное его покусала какая-то зависимость какого-то проекта от сторонних библиотек.

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

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

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

>могли для таких случаев подправить ClassLoader,

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

И шаманства с класслоадерами и байткодами ограничивают облась применения очень сильно. А так скала завелась на том же андроиде с полпинка.


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

>кложура генерит вспомогательные классы, из которых и зовет функции.

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

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

>Для этого надо вообще просканировать все необходимые в таком случае интерфейсы

зачем? Пришлёл запрос на класс, в имени которого «заманглино» его описание - вернул класс. Один раз при первом «упоминании». Всё.

в класслоадере в общем случае нет метода получения всех доступных классов.


Зачем тебе «все»? Тебе в каждом случае нужен один конкретный.

И шаманства с класслоадерами и байткодами ограничивают облась применения очень сильно.


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

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

> зачем? Пришлёл запрос на класс, в имени которого «заманглино» его описание - вернул класс.

Потому что есть у меня класс String. Давно загруженный. Тут загружается класс с методом:

def xxxx[A <: {def substring(Int):String }] (s:A) = s.substring(4);

и где-то есть вызов:

x.xxxx(«aaaa»)

Ну и что тут уже сделаешь? Поздо метаться.

«Шаманство к байткодами» необходимо любому компилятору (для JVM) - не?


Шаманство с байткодами налету. Если взять что-то немного более отличное от java.exe (applets, webstart, dalvik) - то уже не везде просто подсунуть байткод манипуляции, а под далвиком они вообще идут мимо кассы - там другая VM.

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

>Потому что есть у меня класс String. Давно загруженный. Тут загружается класс с методом:

def xxxx[A <: {def substring(Int):String }] (s:A) = s.substring(4);


Может я чего-то не догоняю? Генерим (можно в рантайме, можно и при компиляции - просто надо «договориться» о «месте» для «служебных» классов) служебный класс (абстрактный или интерфейс), содержащий объявление метода substring(Int):String. Генерим (при компиляции) «анонимный» класс, унаследовав от «служебного», с конкретной реализацией.

и где-то есть вызов:


x.xxxx(«aaaa»)


Надо ещё неявное преобразование строки в класс а-ля >А, т.е. в наследника нашего «служебного» класса - не?

Ну и что тут уже сделаешь? Поздо метаться.


Что значит «уже»? Весь этот код будет-же компилироваться - не?

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

>Шаманство с байткодами налету.

Можно «преодолеть», генеря «служебные классы» с одним «путём» и запихивая в свои (причём разные) jar-ки (и производные) - оверхед по хранению копий, но это интерфейсы - много места не займут. Баг это или фича - не знаю, но JVM нормально работает с классами, имеющими «один путь», но находящимися в разных jar-ах (правда, если это не гарантируется - потом можно схлопотать «облом»).

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