-
PG: Postgres-related libraries for Clojure
The PG project holds a set of packages related to PostgreSQL. This is a breakdown of my unsuccessful attempt to write a PostgreSQL client in pure Clojure (stored in the
_
directory). Although I didn’t achieve the goal, some parts of the code are now shipped as separated packages and might be useful for someone.At the moment, the most interesting modules are
pg-copy
andpg-copy-jdbc
thatCOPY
the data using the binary Postgres format which is faster than CSV.Table of Contents
-
Свое
Иногда в фирме пишут велосипеды даже с учетом того, что есть открытые библиотеки. Раньше я по-разному к этому относился, а теперь пришел к компромиссу.
С одной стороны, кустарные поделки напрягают меня как разработчика. Устраиваясь в фирму, меньше всего хочется встретить свою ORM, свой роутинг или шаблонную систему. Обычно это глючный код, написанный по принципу “потому что можем”. Хочется работать с популярными библиотеками, у которых документация, сообщество, канал в Слаке.
С другой стороны, свои решения продвигают фирму на рынке и в сообществе. Это привлекает разработчиков, служит рекламой, упрощает найм. В вакансиях можно указать, что задание должно быть сделано именно на этих библиотеках, потому что на них построены решения фирмы.
Правда, чтобы это работало, фирма должна как можно раньше выкладывать свои решения в open source. Это то же самое, что с ребенком: если вечно держать его взаперти, будет вред. Библиотека должна быть на Гитхабе, должно быть сообщество, словом — фирма должна как можно сильнее пиарить свой код, чтобы считаться центром идей в своей области. И программисты будут в нее стремиться.
Удивляет порой, что у фирмы есть неплохие решения, но они киснут в приватных репозиториях — без документации, без развития. Что бы не выложить их в паблик? Я вообще не припомню кода, который нельзя было бы опубликовать именно по причине кражи бизнеса. За любым кодом стоит понимание его командой и видение будущего. Скачав исходники Яндекса вы не сделаете новый Яндекс. Единственное опасение — это ошибки и низкий уровень кода, за который стыдно. Именно это и лечит open source: его код сразу готов к жизненным трудностям.
Бесит, когда делаешь тестовое задание на популярных библиотеках, а в команде говорят: забудь, чему тебя учили, у нас своя атмосфера. Ребят: свою атмосферу нужно проталкивать вовне! Задавать стандарты, вовлекать людей, а не держать в тайне от мира. Вы что-то скрываете, а скрывать нечего.
-
Уровень
Пока мир сходит с ума по искусственному интеллекту, всплакну о низком уровне разработчиков. Подкатило, нужно выплеснуть.
Ситуация: разработчик пишет функцию
get-by-id
, чтобы достать сущность из базы. Не моргнув глазом, он передает ее вmap
на пять тысяч элементов. Это, на минутку, один запрос, а запросов может десятки в секунду. Подобные вещи приходится ловить в code review и объяснять, что один запрос лучше, чем пять тысяч.Идет 2023 год, а программисты пишут SQL конкатенацией строк. В порядке вещей код на два экрана с
format
,str
иjoin
, который ни понять, ни отладить. Полученный запрос уходит в базу, и дай бог, чтобы оно работало. Если передать nil или пустой список, получим битый SQL, потому что автор этого не предусмотрел. И конечно, инъекции во все поля.Почему-то программисты не могут записать и получить данные из базы. Им нужна ORM, и чтобы она сразу мапилась на REST. Получается километр глючного кода без документации и поддержки. Автор ORM отлынивает от задач под видом ее доработки. Часть команды уходит в партизаны: работают с базой через SELECT и UPDATE в обход ORM. Так спокойней, главное чтобы автор ORM не зашел в пулл-реквест.
Разработчики игнорируют линтеры. Проект уже не раз сменил команду, люди пишут в разных редакторах, и ни у кого он толком не настроен. Кривые отступы, экраны закомментированного кода, неиспользуемые импорты и переменные. Это в порядке вещей.
Программисты не доводят дело до конца, хотя в бóльшей степени это упрек руководству. Например, у кого-то задача, чтобы была документация Swagger. Человек пишет генератор json-файла, покрывает тестами, все готово. Осталось захостить, чтобы документацию увидели клиенты. Но прилетает горящая задача или девопс-инженер уходит в отпуск. В итоге документация есть, но ее никто не видит. Задача не достигнута, время потрачено зря, но это никого не смущает. Недостигнутые цели я вижу постоянно.
Сюда же относятся висящие пул-реквесты. Открываешь борду и видишь у кого пять, а у кого семь пул-реквестов. Зачем программист писал код, если его не принимают? Если бы он смотрел Ютуб, эффект был бы тот же. Почти во всех системах можно задать auto-expire, не говоря уж о ботах, которых полно.
Беда с локальным окружением. Программисту лень потратить день на
docker-compose.yaml
, чтобы сервисы работали локально. Приходится объяснять, что локальный ресурс лучше стейджинга где-то в Амазоне.Иной программист генерит айдишники для базы вручную. Берет рандом от 0 до 9999 и густо перчит номером треда, числом миллисекунд и фазой Луны. И это работает в проде.
Программисты любят кокетничать, что уперлись в базу: терабайты данных, не вывозит нагрузку, все дела. При этом в базу уходят кривейшие запросы, а сама она превратилась в свалку, потому что там хранят кэш, логи S3 и черт знает что.
У программистов туго с отладкой. Под отладкой я имею в виду остановку кода на середине, чтобы выяснить локальные переменные. Это могут единицы. Остальные либо ставят принты и мотают экраны логов, либо вообще сдаются. Иные заявляют, что в божественной Кложе отладчик не нужен. Это вообще за гранью.
И наконец, главное: карго-культ. Так писали до нас, так пишем и мы. Кривой нейминг? Дурацкая организация кода? Ничего, консистенси важнее. И хотя прошлый разраб видел Кложу второй раз в жизни, все следуют его бредовым начинаниям.
Все это я видел даже когда писал на Дельфи и 1С до прихода в промышленную разработку. Меняются лица, а косяки остаются с нами. Конечно, я их тоже совершал, но будучи записанными, они переживаются легче.
Все, отпустило, работаем дальше.
-
Помощь Chat GPT
Сегодня я столкнулся с “помощью” Chat GPT, а точнее — его необдуманным применением.
Я немного занимаюсь Латехом, и когда верстал книгу, решал массу технических вопросов. Что-то вышло изящно, а что-то нет: работает, но коробит душу. Хочу закрыть эти недостатки в будущем.
Добрые люди подсказали группу в Телеграме, где тусят любители Латеха. Зашел туда и задал наболевший вопрос про жирный шрифт в minted. Через какое-то время один пользователь (судя по био, женщина), скинула ответ с примером на Латехе. Я горячо поблагодарил и побежал пробовать.
Запускаю — ошибка, что нет такого-то свойства. Ладно, думаю, устарели пакеты. Обновил все под чистую. Запускаю — то же самое. Что же это за свойство? Полез в документацию пакета, а там его вообще нет. Пакет ничего не знает об этом свойстве.
Посмотрел на ответ свежим взглядом и понял — это Chat GPT (вчера вечером мозги были уже не те). Во-первых, в нем повествовательный стиль: “обратите внимание”, “вы можете” и так далее. От первого лица в Телеграме так не пишут. Во-вторых, в копипасте я нашел артефакты, свойственные интерфейсу Chat GPT. В частности, название языка перед участком кода (python, latex). Их всегда забывают вычистить при копировании ответа целиком.
Что тут можно сказать? История не нова. Помните сервисы вопросов и ответов на Яндексе и Мейл.ру? Раньше домохозяйки копировали с Википедии. Теперь то же самое, только научились пользоваться Chat GPT. Понимаю, почему на StackOverflow запретили им пользоваться — можно засрать сервис нерабочим кодом без какой-либо ответственности.
Лишний раз убеждаюсь в том, о чем писал недавно. Chat GPT — это никакой не интеллект. Это языковая модель, которая производит текст, максимально близкий к вопросу. Ей неважно, работает код или нет, у нее другие метрики. А мне, наоборот, важно. Мне платят за код, который не только выглядит хорошо, но и работает хорошо. Единственный способ проверить код — запустить его и предъявить результат работы. Этого Chat GPT не может, и поэтому мне с ним не по пути.
-
Выпадашки
Бич современного интерфейса — это выпадающие элементы, которые я называю “выпадашками”. Часто упоминаю их, когда пишу об интерфейсе, и вот пора сделать отдельный пост.
Я не люблю выпадашки по одной причине: почти всегда в интерфейсе хватает места, чтобы уместить скрытые элементы. Непонятно почему дизайнер прячет их от меня, оставляя три точки или гамбургер. Приходится кликать, чтобы узнать, что под ними.
Типичный пример — форма комментариев на Хабре. Действие “Ответить” выражено текстом, к этому вопросов нет. Затем идет иконка закладки. Далее выпадашка, под которой ссылка, редактирование и жалоба. Зачем было их прятать? Места хватит и для иконок, и для текстовых ссылок.
Пользуясь случаем, замечу, что у выпадашки адская разреженность. Ее можно было сжать в два раза без какого-либо ущерба.
Другой пример — форма закладок на том же Хабре. Закладки бывают двух типов: статьи и комментарии. Почему переключалка сделана в виде выпадашки? Что мешало расположить элементы по горизонтали: Статьи / Комментарии?
Выпадашки пришли к нам с мобильных устройств. Там мало места, поэтому приходится что-то прятать. Но почему пользователь десктопа должен страдать? Кому-то лень добавить проверку на разрешение или прописать стиль. В итоге на мониторе места столько, что влезет несколько страниц книги, но кнопки спрятаны под выпадашку.
Впрочем, и на Айпаде я видал интерфейсы, когда на весь экран пустота и в правом верхнем углу жалкое многоточие.
Из недавнего: в англоязычной Википедии обновился интерфейс. Конечно, самое нужное убрали под выпадашку. Если раньше на язык достаточно было кликнуть, то теперь он заботливо спрятан в выпадающее меню.
Выпадашки ради выпадашек. У меня есть инструмент — значит, воспользуюсь, неважно нужен он или нет. К сожалению, сегодня для выпадашки даже не нужен Джаваскрипт, хватает обычного CSS, и это только усугубляет положение.
С ростом экрана дизайнер не знает, как им воспользоваться. Поэтому искусственно раздувает интерфейс: больше отступы, крупнее иконки, половину кнопок под выпадашку. Скрытая профессиональная импотенция.
Обычно желаешь таким дизайнерам всяческих наказаний, но сейчас у меня хорошее настроение, и хотелось бы закончить на позитивной ноте. Если вы дизайнер интерфейсов и часто пользуетесь выпадашкой — займитесь физическим и печатным дизайном. У предметов и бумаги почти не бывает выпадающих элементов, а если они и есть, то их тяжело и дорого делать: во-первых, дольше процесс, а во-вторых, оторвутся на раз-два.
Со временем придет ясность, что все элементы можно расположить, не пряча один под другой. Но это требует усилий над собой.
-
Clojure + GraalVM framework for AWS Lambda
Lambda is a small framework to run AWS Lambdas compiled with Native Image.
Motivation & Benefits
There are a lot of Lambda Clojure libraries so far: a quick search on Clojars gives several screens of them. What is the point of making a new one? Well, because none of the existing libraries covers my requirements, namely:
- I want a framework free from any Java SDK, but pure Clojure only.
- I want it to compile into a single binary file so no environment is needed.
- The deployment process must be extremely simple.
As the result, this framework:
- Depends only on Http Kit and Cheshire to interact with AWS;
- Provides an endless loop that consumes events from AWS and handles them. You only submit a function that processes an event.
- Provides a Ring middleware that turns HTTP events into a Ring handler. Thus, you can easily serve HTTP requests with Ring stack.
- Has a built-in logging facility.
- Provides a bunch of Make commands to build a zipped bootstrap file.
Installation
Leiningen/Boot:
[com.github.igrishaev/lambda "0.1.1"]
Clojure CLI/deps.edn:
com.github.igrishaev/lambda {:mvn/version "0.1.1"}
-
Заменят ли ИИ разработчиков и почему? Если да, то на каких задачах?
Меня попросили ответить на вопросы из заголовка. Думал, будет абзац, но как обычно вышла простыня. Впрочем, мысли об ИИ были уже давно, и это отличный повод собрать их в статью.
Что ж, если коротко, то нет: ИИ, который у нас сегодня, не заменит программистов. Волноваться незачем, продолжайте работу. Если вы учитесь на программиста и испытываете тревогу, успокойтесь и продолжайте. Никакие чаты и боты программистам не угрожают. А также журналистам, учителям и вообще — любым профессионалам своего дела.
Да, про ИИ говорят и пишут из каждого утюга. Но важно знать, что информационная волна всегда сильнее повода, который ее вызвал. Изданиям нужен трафик, а люди склонны экстраполировать: если сегодня бот написал Тетрис, то через год он сделает Киберпанк. Увы, это не так.
Причина моего скепсиса в том, что все помощники и боты слабы в деталях. У меня есть колонка Яндекса, она прекрасно играет музыку и говорит погоду. Но ее крайне легко ввести в ступор. Например, играет песня, и я хочу послушать альбом, которому она принадлежит (пусть даже первый, если их несколько). Однако этой функции не предусмотрено: какую бы фразу я ни высказал — перейди к альбому, включи альбом, из какого это альбома, — Алиса не понимает. Хотя в мобильном приложении это одна кнопка “show album”.
-
Такой же
Наверное, вы слышали вопрос о корабле, заданный еще до нашей эры. Если постепенно заменить в корабле все детали, будет ли это тот самый корабль?
Проблема в том, что на вопрос отвечают, не разобравшись с определениями. Если не договориться, что значит “тот же самый”, можно спорить весь день, имея в виду не то, о чем думает оппонент.
В программировании эта проблема известна: равенство не означает “то же самость”. В современных языках есть отдельные операторы для сравнения указателей и сравнения значений. Хорошие языки пытаются избежать путаницы и сводят две эти вещи к одной. Например, если коллекции неизменяемы, то их можно сравнить в лоб, не заботясь о ссылках. Кроме того, хеш неизменяемой коллекции рассчитывается один раз при создании. Из-за этого сравнение не делает полный обход, а сводится к равенству двух чисел.
Еще один довод в адрес “то же самости” — это мы сами. Тело человека обновляется постоянно. Скелет меняется за три года, а у кожи, волос и ногтей срок исчисляется днями. Жидкости поступают и выходят.
Мы сегодня и мы три года назад — это разный набор атомов. Тот человек, что изображен в паспорте, уже сотни раз обновил каждую клетку организма. Однако ни у кого нет сомнений, что человек в паспорте и вы — один и тот же. Просто потому что так удобней.
Поэтому и корабль, в котором обновили все доски, тот же самый. Если, конечно, понимать под “тем же самым” то, что удобно большинству.
Забавный эпиграф к библиотеке re-frame8:
This, milord, is my family’s axe. We have owned it for almost nine hundred years, see. Of course, sometimes it needed a new blade. And sometimes it has required a new handle, new designs on the metalwork, a little refreshing of the ornamentation … but is this not the nine hundred-year-old axe of my family? And because it has changed gently over time, it is still a pretty good axe, y’know. Pretty good.
Вкратце: господин, этот топор служит нашей семье девять столетий. Иногда ему меняли рукоять, а иногда клинок. Но поскольку это делали постепенно, это все тот же топор.
В этом и проявляется забавное свойство “той же самости”: если ее размазать по времени, предмет будет тем же самым (менять ручку и клинок раз в сто лет). Если потерять топор и заказать новый, это будет другой топор.
Принцип плавных изменений очень полезен. Например, ничто не бесит так сильно, как внезапное обновление интерфейса. Хорошо, когда его плавно меняют в нужном русле.
Команда может саботировать новые правила, если их слишком много. Внедряйте по одному с интервалом в месяц.
Добавить линтер в огромную кодовую базу кому-то покажется невозможным. А нужно всего ничего: задать список путей, которые подвергаются линтингу, и плавно его наращивать.
В завершение — пазл, который висит у меня на стене (Яцек Йерка):
-
Письма Notion
К сожалению, в компании, где я работаю, пользуются Ноушеном. Это сплошная боль, потому что к Ноушену у меня нулевая терпимость — бесит каждый элемент, каждая кнопка и анимация. Постепенно собираю коллекцию их косяков, чтобы запостить разом, но сегодня не удержался от нового прокола.
Итак, я написал текст в Ноушене и попросил руководство обсудить. На следующий день открываю почту на телефоне и вижу штук 20 уведомлений от Ноушена: пошли комментарии. Тыкаю, чтобы прочитать. А письма, сюрприз, выглядят так:
Не знаю какой это кегль — второй или третий — но прочесть эти письма физически невозможно. Нужно зрение орла или увеличительное стекло. Словом, с телефона я ничего не прочел и смог это сделать только когда сел за комп с 4к-монитором.
И вот опять, смотрите: сапожник без сапог. Как мы помним, Дропбокс, программа для работы с файлами, не умеет показывать файлы. А Ноушен, программа для текста, не может показать текст. Разработчики, вы вообще своим Ноушеном пользуетесь? Если бы я там работал, то в первый же день открыл бы тикет и долбил им каждый спринт — ваши сраные письма не читаются. Поправьте стили. Высылайте plain text вместо HTML, он мне нахрен не сдался. Просто чтобы можно было прочесть текст.
Директор Ноушена без конца гонит какую-то графоманию, которую постят на Хакер-ньюз и Хабре. Подобно Грефу внедряет искусственный интеллект и машинное обучение (которые дают пустую строку). И при этом никто сделает нормальный шрифт в письмах. Просто стыд.
-
Эта удивительная Clojure: что на ней разрабатывают, чем она отличается от других языков и подходит ли для входа в программирование
Эта статья была написана для одного издания, но по ряду причин ее не опубликовали. Размещаю здесь, чтобы материал не пропал. В подготовке статьи участвовали:
- Павел Пеганов и Иван Гришаев, программисты;
- Маша Даровская, редактор.
Мы расспросили разработчиков на Clojure из сообщества clojure_ru. Выясняли, как применяют язык, что на нём пишут, легко ли на нём программировать.
Что программируют на Clojure
Павел: сфера применения Clojure в техническом плане — в основном веб и серверные приложения. На успешно работающий Clojure-код можно посмотреть, например, в продуктах Metabase и Penpot, их исходный код открыт.
Но постепенно язык проникает и в другие области. ClojureScript работает в браузерах и других средах для JavaScript, с помощью проекта Esprit его уже запускают на микроконтроллерах, а сейчас развивают ClojureDart, чтобы захватывать мир Flutter. Конечно, не все эксперименты в итоге «взлетят», но такое разнообразие работающих проектов показывает, что применимость языка ограничена скорее настроениями разработчиков, чем самим языком.
Если говорить о предметных областях, то в вакансиях и проектах с Clojure, о которых слышу я, эмпирически кажется, что финтеха больше, чем прочих. Даже компания, поддерживающая Clojure, Cognitect, принадлежит банку Nubank. Но кроме финтеха областей тоже хватает.
Иван: сфера применения Clojure широка, она решает те же задачи, что Java, Python и другие языки. На ней пишут сетевые сервисы, бэкенд веб- и мобильных приложений. Clojure подходит для обработки данных из разных источников — баз данных, очередей, HTTP API — и часто служит их оркестратором.
Существует ClojureScript — компилятор кода на Clojure в JavaScript. С его помощью создают браузерный фронтенд и мобильные приложения на базе React Native.
Код на Clojure можно скомпилировать при помощи GraalVM и native image, получив бинарный файл. С этим подходом пишут утилиты командной строки, интерпретаторы, AWS Lambda и многое другое.