LINUX.ORG.RU

Clojure 1.9

 , hickey,


1

5

Clojure 1.9 наконец-то вышел.

Версия 1.9 содержит две главные новые возможности — интеграция с spec и cli-утилиты.

spec — это библиотека для описания структур данных и функций с поддержкой валидации, деструктурирования, документации, отчета об ошибках, генерации тестовых данных и обобщенной генерации тестов.

spec интегрируется в Clojure через две новые библиотеки:

Такая модуляризация облегчает обновление spec независимо от релиз-цикла Clojure.

Инструменты командной строки предоставляют быструю и лёгкую установку, Clojure REPL (!!!), использование Maven и локальных зависимостей, функциональный API для управления classpath.

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

>>> Оригинал новости

★★★

Проверено: tailgunner ()
Последнее исправление: cetjs2 (всего исправлений: 3)

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

Я так понимаю, Clojure пошла по стопам Python к поддержке опциональной типизации?

Честно говоря spec и статическая типизация это совершенно разные вещи, даже не пойму зачем их сравнивают. Самое досадное что это сравнение озвучивается в том числе и со стороны некоторых clojure-разрабов - типа смотрите какая у нас крутая штука - гораздо лучше этой вашей статической типизации, что конечно неверно.

Если хочется лютой статической типизации то есть например достаточно одиозный Lux (с интересными идеями кстати).

Вариант с опциональной типизацией a-la typed racket - это typed clojure и core.typed, которые скорее мертвы чем живы.

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

Это ошибка компилятора? Не?

В clojure (и зачастую в лисп-семействе) понятие стадии компиляции несколько размыто

Конкретно это:

java.lang.String cannot be cast to java.lang.Number

Ошибка времени выполнения, код вида

(defn foo []
  (+ "asd" 1))

вполне себе вычислится и упадёт во время вызова функции foo

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

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

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

А вообще очень хорошая практика - писать очень короткие фунции, не более 5 строк, кложа ведь функциональный язык.

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

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

откуда эта блажь про «5 строчек»

это для языков где хорошо продуманна композабельность, а не про питоны

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

Вот дерьмо. Но в билдере-то целое должно приводиться к String?

Не в рамках системы типов, так что не приводиться (coerce), а преобразовываться (convert)

Конкретно «Hello » + 1 - это сахар времени компиляции и на систему типов не влияет

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

Я повторю ссылку: https://clojure.org/guides/weird_characters

Часть списка - ридер-макросы, которые вообще говоря опциональны, часть - соглашения по именованию функций (суффиксы ?, !, спец-функции >! <! из core.async).

С @ #' #" лично у меня проблем нет, есть небольшие претензии к читаемости ридер-макроса #() для анонимных функций. Я предпочитаю использовать полный синтаксис (fn [v]) в сложных случаях.

Unquoting, splicing, reading conditionals нужны редко, ну а больше я не вижу к чему можно придираться.

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

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

Ну и напоследок парочка неплохих докладов для тех кому интересны темы разработки ПО

1. По поводу привязанности к выбору парадигмы ЯП/системы типов (сюда же и синтаксис):

https://www.youtube.com/watch?v=ROL58LJGNfA

2. По поводу роли динамических/статических языков для построения систем

https://www.youtube.com/watch?v=x9pxbnFC4aQ

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

откуда эта блажь про «5 строчек»

это для языков где хорошо продуманна композабельность, а не про питоны

Это какие такие языки? Можно посмотреть примеры, желательно средних/крупных проектов, а не вычисления ряда Фибоначчи?

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

Конкретно «Hello » + 1 - это сахар времени компиляции и на систему типов не влияет

Если «сахар», то никаких больше вопросов. В «сахарок» можно любую абстракцию загнать.

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

Это какие такие языки?

clojure, scala, ruby, java 8+, всякое хаскелле-подобное говнецо

Можно посмотреть примеры

да, можно

oxo
()

Ничего не имею против Clojure.

Только кто его использует реально?

Вопросы на собеседовании будут не по Clojure, а типа «как реализован HashMap?»

Умники, которые умничают по поводу лямбда-исчисления, замыканий и подхвостовой рекурсии, быстро опускаются простейшими вопросами типа «напишите компаратор, используя новые возможности Java 8».

90% нахватавшихся поверхностных знаний соискателей-кульхацкеров c позором выносятся этим вопросом.

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

core> (+ «строка» 12)

java.lang.String cannot be cast to java.lang.Number

Это ошибка компилятора? Не?

Не. Вот, смотри:

Clojure 1.8.0
Java HotSpot(TM) 64-Bit Server VM 1.8.0_91-b14
>  (defn foo [] (+ "xx" 1))
=> #'user/foo
>  (foo)
ClassCastException java.lang.String cannot be cast to java.lang.Number  clojure.lang.Numbers.add (Numbers.java:128)
>
tailgunner ★★★★★
()
Ответ на: комментарий от anonymous

Я повторю ссылку: https://clojure.org/guides/weird_characters

Часть списка - ридер-макросы, которые вообще говоря опциональны, часть - соглашения по именованию функций (суффиксы ?, !, спец-функции >! <! из core.async).

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

Меня вот удивительно раздражает питон - своей многословностью, засильем знаков подчёркивания и self

А меня Python раздражает динамической типизацией. Так что, с моей точки зрения, Clojure - это такой Python со скобочками.

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

Знаю.

гораздо сложнее происходит адаптация мышления

Я думаю, эта фраза говорит больше о состоянии системы образования.

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner
* (defun foo () (+ "xx" 1))
; in: DEFUN FOO
;     (+ "xx" 1)
; 
; caught WARNING:
;   Constant "xx" conflicts with its asserted type NUMBER.
;   See also:
;     The SBCL Manual, Node "Handling of Types"
; 
; compilation unit finished
;   caught 1 WARNING condition

FOO
* 


Спасибо тебе, SBCL

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

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

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

Васян, вот ты сейчас на голубом глазу пытаешься мне втереть, что jvm что-то знает про java.lang.String?

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

ты сейчас на голубом глазу пытаешься мне втереть, что jvm что-то знает про java.lang.String?

Нет. Я показываю, что ты не знаешь разницы между ошибкой времени компиляции и ошибкой времени исполнения. Знает JVM о java.lang.String или нет - нерелевантно (но JVM знает, естественно).

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

время исполнения - это байткод выполняется на jvm. Откуда там информация о типах?

Most of the extant JVM instruction set is statically typed - in the sense that method calls have their signatures type-checked at compile time, without a mechanism to defer this decision to run time.

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

кложа вроде не умеет сама делать байт-код? Она генерит код на ява, который компилится родным компилятором. Вот он и дает такие ошибки. Не?

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

Я, по-вашему, себе скор отращивал, чтобы по ссылкам бегать, как мальчишка?

Лучше бы ты знание языка отращивал.

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

время исполнения - это байткод выполняется на jvm. Откуда там информация о типах?

Почитай о том, что такое байткод, неуч.

tailgunner ★★★★★
()
Последнее исправление: tailgunner (всего исправлений: 1)
Ответ на: комментарий от tailgunner

Ну все ж получше, такие ошибки быстрее проявляются.

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

Ну почитала. Как я и писала: «Большинство существующих инструкций JVM имеют статическую типизацию. Сигнатуры методов в местах их вызова проверяются во время компиляции. Механизм переноса этой проверки на время выполнения отсутствует.»

«проверяются во время компиляции», Васян. Не? Компилятор разве не проверит, что для функции «+», один операнд не число?

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

время исполнения - это байткод выполняется на jvm. Откуда там информация о типах?

Почитай о том, что такое байткод, неуч.

Ну почитала

Я рад, что у тебя больше нет вопросов о том, откуда JVM знает имя класса. Продолжение лекции - за деньги.

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

Какого языка? Ни Java, ни Clojure мне не нужны, а русским владею на достаточно хорошем уровне.

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

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

anonymous
()

а прямо из кложуровского репла поставить зависимости? прямо так, без deps файла можна? мелочь, а приятно

oxo
()

Версия 1.9 содержит две главные новые возможности — интеграция с spec и cli-утилиты.

Вот это замечательно.

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

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

Скорее это был ответ на претензии к «ужасному» синтаксису и в целом по теме обсуждения а не на конкретный вопрос по поводу количества закорючек.

А меня Python раздражает динамической типизацией. Так что, с моей точки зрения, Clojure - это такой Python со скобочками.

И да и нет, с одной стороны связка Python + C чем-то похожа на связку Clojure + Java, но у питона, есть ряд серьёзных недостатков:

  • Меньшая производительность
  • Отсутствие многопоточности
  • Беднее сам язык, меньше выразительности и меньше возможностей расширения языка.

У clojure также есть следующие плюсы

  • Доступ к библиотекам Java
  • Наличие компилятора для JavaScript - ClojureScript
  • REPL-driven разработка (впрочем давно не работал с питоном, возможно с тех пор что-то поменялось и REPL стал более востребован в разработке)

Поэтому если есть потребность/необходимость в JVM, то Clojure выигрывает у питона сильно. Если же JVM даром не нужна, то тогда всё не так однозначно.

Я думаю, эта фраза говорит больше о состоянии системы образования.

Честно говоря не очень понял, причём тут система образования, проблема скорее в инерции мышления. Мой опыт показывает, что чем больше человек программировал на Java (особенно если это единственный язык на котором он писал), тем сложнее ему даётся переход на Clojure конкретно и на использование других подходов/парадигм в частности.

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

Только кто его использует реально?

В России единицы, может десятки, в остальном мире распространённость пошире, но разумеется уступает тем же Java и Python.

Вопросы на собеседовании будут не по Clojure, а типа «как реализован HashMap?»

Люди, которые задают на собеседовании вопросы типа «Сколько бакетов создаётся в дефолтной реализации HashMap в Java 1.8» вызывают у меня большое удивление, т.к. эту информацию всегда можно посмотреть в справке и нет никакого смысла запоминать её.

Ну и вообще по поводу ниши Clojure и смысла от её применения. Clojure - это один из немногих языков, при использовании которого ты занимаешься решением конкретной задачи, а не битвой с компилятором и/или стэком библиотек, применяемым в проекте.

При этом объём кода получается небольшим, сам код получается понятным, что сильно помогает в процессе ревью и отладки. Идиоматичный подход обеспечивает очень тонкие слои абстракции, что крайне положительно сказывается на потреблении ресурсов, а также позволяет достаточно легко судить о поведении системы в целом, разработка через REPL позволяет получить очень короткий цикл «внёс изменение -> увидел результат», что опять таки повышает производительность труда. Хорошая производительность позволяет писать код не на выброс, а сразу под использование в продакшене. При этом язык достаточно гибкий, что позволяет «гнуть» его под свои задачи, не навязывает какую-то одну «единственно правильную» парадигму - у нас в проекте неплохо уживаются и ООП и ФП и махровая императивщина.

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

Ну и конечно такой немаловажный фактор как строки в резюме - в нашей стране мало кто из работодателей оценит «опыт разработки на языке Clojure» как большое конкурентное преимущество.

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

связка Python + C чем-то похожа на связку Clojure + Java, но у питона, есть ряд серьёзных недостатков

Если в нативном линуксе Python фактически безальтернативен и его приходится использовать, даже несмотря на динамическую типизацию, то на JVM есть другие высокоуровневые языки - Scala, Groovy (в котором статическая типизация есть уже давно). Так что лично я не стал бы писать на Clojure ничего большого по причинам типизации, а для скриптования Java-кода взял бы Groovy.

если есть потребность/необходимость в JVM, то Clojure выигрывает у питона сильно

Конечно.

гораздо сложнее происходит адаптация мышления

Я думаю, эта фраза говорит больше о состоянии системы образования.

Честно говоря не очень понял, причём тут система образования

Я смотрел на Clojure только мельком, но не вижу в ней ничего принципиально нового. Если адаптация мышления происходит сложно - значит, когда-то чего-то не объяснили.

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

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

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

Clojure

Не нужен. (Удивительно: уже на две страницы обсуждения, а до сих пор никто этого не сказал.)

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

Не бывает таких языков. Вообще. Даже если взять что-нибудь сверх-убогое, в котором заблудиться в принципе невозможно (DSL какой-нибудь, или древний бейсик с номерами строк, хотя и в нём кажись бреда хватало), будешь биться с убогостью.

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

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

библиотек нет

Все java библиотеки в твоем распоряжении. Это было одной из задач при дизайне языка.

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

Ок, значит опять-таки будет битва: с java-библиотеками. :)

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

Метапрограммирование

Единственное преимущество лиспов над другими языками - это мощная макросистема в ущерб читаемости кода. Но так ли часто нам нужно в реальной жизни мета программирование, причём такими жертвами?

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

Не бывает таких языков. Вообще. Даже если взять что-нибудь сверх-убогое, в котором заблудиться в принципе невозможно (DSL какой-нибудь, или древний бейсик с номерами строк, хотя и в нём кажись бреда хватало), будешь биться с убогостью.

Из всех языков что я использовал clojure ближе всего подходит к этой категории, и дело не в убогости. Автор языка любит подчёркивать разницу между simple и easy (можно посмотреть его доклад Simple Made Easy) и стремился сделать clojure в первую очередь simple.

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

Библиотек-то как раз полно благодаря JVM, нет фреймворков, т.к. они не удовлетворяют критериям KISS. Есть ряд легковесных взаимозаменяемых компонентов реализованных в виде библиотек, которые довольно просто склеиваются вместе в приложение.

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

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

можно посмотреть его доклад Simple Made Easy

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

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

Посмотри-ка на Kubernetes

1. Первая же ссылка - на хабр, в первом же абзаце статьи: «В механизме Kubernetes много движущихся частей и способов их настройки» — т.е. инструмент уже не простой.

2. Оно решает очень узкую задачу. Будь оно даже простым, по каждой фигне на узкую задачу - в сумме набежит далеко не фигня. Разве что если ты делаешь тривиальную молотилку данных без особых требований, но я говорил про «написать сложное».

3. Я говорил про закон о несуществовании серебряной пули. Означает ли твоё возражение, что Kubernetes - серебряная пуля? Если да, мои поздравления: мало кому в жизни везёт найти оную. Если нет, значит я тут распинаюсь как дурак, отвечая на обыкновенную демагогию.

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

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

Kubernetes написан на Go. Go - простой как палка инструмент. Т.е.

Фундаментальный закон физики не обойти никак: на простых инструментах ты сложного не напишешь

4.2

Твои пункты ваще не понял, тебе надо книги писать.

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

Кстати, когда пишешь спложное, сплошь и рядом случаются ситуации

Ты сам что-нибудь сложное в своей жизни написал, чтобы открывать здесь рот?

SunOS написана с помощью vi и сс, это очень простые инструменты.

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

Ты сам что-нибудь сложное в своей жизни написал, чтобы открывать здесь рот?

Тут понятие сложности у всех свое.

Кто то рыдает кровавыми слезами, проклинает динамические языки, говоря, что нельзя на них написать ничего сложного, а сам при этом кое как выкакивает что то чуть дальше ушедшее от hello world(ну например бложик, даже без категорий сообщений, просто плоский до предела).

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

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

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

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

SunOS - очень сложный проект, даже по современным меркам.

Я не отрицал этого ни одним словом.

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

Лучшие вещи, вообще, были сделаны в достаточно аскетичных условиях.

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

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

Это я эмоционально ответила на слова малолетнего недоумка «на простых инструментах ты сложного не напишешь» :)

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

4.2

А по-русски для неместных?

Твои пункты ваще не понял,

Сочуствую. И что же в них непонятного?

тебе надо книги писать.

Скорее тебе надо книги читать. Для развития способности к пониманию написанного.

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