Обновить
32
Александр Артёменко@Svetlyak

Пользователь

27
Подписчики
Отправить сообщение

Да, забыл сказать. С недавних пор Ultralisp поддерживает не только формат метаданных Quicklisp, но и CLPI. CLPI, это альтернатива Quicklisp, формат данных используемый в Common Lisp Package Manager (https://www.clpm.dev/)

Да именно так.

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

А ещё, в нём можно делать свои "дисты". Например ты в такой дист можешь включить форки каких-то библиотек, которые нужны только тебе. В общем дисте они не будут видны.

К примеру, в такой дист я начал собирать расширения для Lispworks: https://ultralisp.org/dists/lispworks В Quicklisp их в принципе не включат, потому что туда включают только проекты, которые компилируются под SBCL.

Я на Common Lisp пилю аналог питоновского PyPi: https://ultralisp.org. Это хостинг для более чем тысячи CL библиотек, куда можно в несколько кликов добавлять новые прямо с GitHub.

Ну и ещё есть на гитхабе десятки небольших CL библиотек в организации https://github.com/40ants/, если конечно можно считать их pet-прожектами.

Для этого надо запустить процесс кодогенерации и напечатать получившийся результат. Например в REPL.

Есть такой Python пакет – «meta». В нём есть утилиты для работы с AST, в том числе и для печати AST дерева. Можно использовать его.

В этом туториале можно почитать подробнее: macropy3.readthedocs.io/en/latest/ast.html

А в Common Lisp, к примеру, раскрытие макросов встроено в язык и в IDE. Его можно вот так вызвать из REPL:

;; Сначала определим макрос:
CL-USER> (defmacro trace-forms ((&optional (stream t))
                        &body body)
           `(progn ,@(loop for form in body
                           collect `(format ,stream "~S -> ~S~%"
                                            ',form
                                            ,form))))
TRACE-FORMS

;; Вот так он работает:
CL-USER> (trace-forms ()
           1
           :foo
           "bar"
           (+ 1 3))
1 -> 1
:FOO -> :FOO
"bar" -> "bar"
(+ 1 3) -> 4
NIL

;; А так можно посмотреть,  в какой код он раскрывается:
CL-USER> (macroexpand-1
          '(trace-forms ()
            1
            :foo
            "bar"
            (+ 1 3)))
(PROGN
 (FORMAT T "~S -> ~S~%" '1 1)
 (FORMAT T "~S -> ~S~%" ':FOO :FOO)
 (FORMAT T "~S -> ~S~%" '"bar" "bar")
 (FORMAT T "~S -> ~S~%" '(+ 1 3) (+ 1 3)))
T
Да, так бывает. Нужно соблюдать баланс.
С помощью макросов можно сложные вещи делать более простыми в использовании.

Так же можно оптимизировать код под конкретную зада, собирая функции из AST по кусочкам.

Это такой же инструмент, как например ООП. Просто другой.
Он открывает новые возможности для людей, обладающих фантазией.
У меня, кстати, есть ещё одна разработка – скрипт, который проходится по всем форкам и ищет несмердженные в апстрим ветки. Про такое тоже можно как-то напоминать владельцу основного репозитория. В форках иногда попадаются полезные доработки, которые люди по разным причинам не превращают в пуллы и не вливают в апстрим.
Хотя странно. Я сейчас поставил Firefox Quantum 66.0.3 (64-битный). И у меня проблема не воспроизвелась, ни в обычной вкладке, ни в incognito режиме (где он написал:

Ресурс на «https://mc.yandex.ru/metrika/watch.js» был заблокирован, так как включена блокировка содержимого.[Подробнее] 12forks.com
Ресурс на «https://yandex.ru/clck/click» был заблокирован, так как включена блокировка содержимого.[Подробнее] 12forks.com


Может быть дело в каких-то дополнительных плагинах? Что-нибудь вроде адблока или ещё чего-то такого?
Очень может быть что так. Похоже на ошибку в Яндекс Формах и том, как они используют Метрику. Я уже передал информацию о проблеме разработчикам.

Спасибо за помощь!
Говоря про регистрацию, я имел в виду, что автор пулла или репозитория могут быть не зарегестрированы в моём сервисе, и даже не знать про него. Бот может прийти в любой пулл и покомментить, что пулл похоже подтухает :)
Валерий, скажи пожалуйста какой у тебя браузер?
Какого рода бот?

Такой, который будет сам находить забытые PR и напоминать о них даже без регистрации автора пулла или репозитория?
Интересно. Я сейчас перепроверил и в Chrome всё ОК. Какой у тебя браузер?
Только закладки не спасут от того, что эти задачи будут мешаться, когда ты будешь (в рамках второго пункта) пробегаться по всему списку в поисках того, на каком моменте какая задача застряла.
Да, главное – чтобы удобно было.
Сейчас мой MVP берёт весь список пуллов и тикетов и разбивает их на несколько категорий:

* Тикеты в которых есть новые комменты с момента, когда я последний раз там что-то писал или создал тикет (тут же показывается число этих комментов, а в веб-версии можно будет отображать их самих + дать возможность тут же ответить)
* Тикеты в которых давно не было активности. Пока MVP пишет лишь время с последнего коммента, но опять же, можно последние комменты и форму ответа подтянуть или сделать кнопки для быстрых ответов с шаблонами, типа: «Please, review my pull».
* Пуллы в коорых есть мердж конфликты.
* Тикеты которые я по каким-то причинам решил отложить до лучших времён + заметка для меня самого, с указанием причины. Например там можно написать, что сейчас пока времени нет на этот проект, и «отложить его на месяц». Спустя заданное время он автоматически появится в одном из списков описанных выше.

Вот такими вещами он может отличаться. И я уверен, что можно ещё много чего придумать.
Так бывает, что эти уведомления теряются в общем потоке писем. В этом и суть того, проекта который я тут описываю – показывать на одной странице в удобном виде все действия, которые тебе нужно совершить, чтобы работа по всем пуллам и тикетам двигалась вперёд.

Читать уведомления на почту конечно же надо. Но я могу читать только свои письма, и не могу повлиять на то, как их разбирают мейнтейнеры библиотек. И если мейнтейнер уведомление пропустил, то нужно как-то ему напомнить о себе. Как это сделать? Ведь гтихаб не присылает на почту напоминалку о том, что ты вот писал две недели назад коммент в таком то пулле, но там тебе никто так и не ответил. А мой сервис сможет делать и это тоже.
Спасибо за коммент.

На лиспе в наших краях много не пишут потомучто тут нет среды для его развития.

Среда не появится, если её не создать. Этим надо заниматься – писать тулинг, улучшать библиотеки, создавать компании, которые будут использовать эту экосистему. Я понемногу этим занимаюсь.

Вообще dsl можно и на функциях построить. Язык же может быть сколь угодно странным. К примеру, ORM Django или SQLAlchemy предоставляют DSL позволяющий определять модели данных и делать запросы выполняя цепочки методов.

Правилами вычисления аргументов. У функции аргументы вычисляются, как правило, в определённом порядке. В в случае DSL могут не вычисляться вовсе, а как-то трансформироваться в код, например.


К примеру, loop макрос определяет язык для итерации по коллекциям и такой простой код:


DBAAS> (loop for i in '(1 2 3 4 5)
             when (evenp i)
               collect i)

Разворачивается в более сложную конструкцию, где некоторые аргументы макроса будут вычислены (1 2 3 4 5) и (evenp i), а другие использованы для генерации кода реализующего бизнес-логику. В результате получится нечто вроде этого:


(block nil
  (let ((i nil) (#:loop-list-827 '(1 2 3 4 5)))
    (declare (type list #:loop-list-827))
    (sb-loop::with-loop-list-collection-head (#:loop-list-head-828
                                              #:loop-list-tail-829)
      (tagbody
       sb-loop::next-loop
        (sb-loop::loop-desetq i (car #:loop-list-827))
        (sb-loop::loop-desetq #:loop-list-827 (cdr #:loop-list-827))
        (if (evenp i)
            (sb-loop::loop-collect-rplacd
             (#:loop-list-head-828 #:loop-list-tail-829) (list i)))
        (when (endp #:loop-list-827) (go sb-loop::end-loop))
        (go sb-loop::next-loop)
       sb-loop::end-loop
        (return-from nil
          (sb-loop::loop-collect-answer #:loop-list-head-828))))))

Информация

В рейтинге
7 684-й
Откуда
Россия
Работает в
Зарегистрирован
Активность