Size: a a a

2020 March 01

a

akater in Lisp Forever
Vλadimir (Hawthorne the Toolmaker)
День добрый и вопрос вам как эксперту.
Есть вот такая форма которая мне очень нравится:

(defmacro mk-calculation (plist &body body)
 `(let ((params ,plist)
        (runner-string (quote ,@body))
        (status 'new))
    (labels ((all-params () params)
             (get-param (key) (getf params key))
             (set-param (key val) (setf (getf params key) val))
             (get-status () status)
             (set-status (sym) (setf status sym)))
      (lol:dlambda
       (:get (key) (get-param key))
       (:status () status)
       (:show-runner () runner-string)
       (:run () (progn ,@body
                       (setf status 'finished)))
       (t () (cons (cons 'calculation status) (list params)))))))


А именно: замыкание вокруг списка параметров (любых там), который должен быть обработан команой :run, в принципе один раз и с кучей сайд-эффектов. Чтобы можно было сериализовать и перезапускать это чудо, в runner-string пишется quote еще не скомпилированного body; в labels опред. сеттеры для стэйта этого_конкретного_объекта.

А вопрос, почему такой подход называют "quick AND dirty", и какой профит можно ожидать от использования CLOS+MOP вместо него?
Это quick and dirty

• потому, что если понадобится расширять это дело, то могут начаться проблемы, и полноценное читаемое их решение приведет к переимплементации части CLOS или, может быть, к имплементации struct'ов, но не настолько эффективной как встроенные struct'ы. При этом бонусы по эффективности по ср. с CLOS таким подходом можно получить, это да.

• потому что, например, число аргументов в «методах» не учитывается в dlambda, хотя могло бы, и в результате этого этим интерфейсом легче воспользоваться так, что это вызовет ошибку, причем сообщение о ней будет малоинформативным. С CLOS или struct'ами это не так.

Чтоб ответить на вопрос «как выглядела бы альтернатива с CLOS», я все-таки спрошу: как именно предлагается производить сериализацию?
источник

V(

Vλadimir (Hawthorne the Toolmaker) in Lisp Forever
akater
Это quick and dirty

• потому, что если понадобится расширять это дело, то могут начаться проблемы, и полноценное читаемое их решение приведет к переимплементации части CLOS или, может быть, к имплементации struct'ов, но не настолько эффективной как встроенные struct'ы. При этом бонусы по эффективности по ср. с CLOS таким подходом можно получить, это да.

• потому что, например, число аргументов в «методах» не учитывается в dlambda, хотя могло бы, и в результате этого этим интерфейсом легче воспользоваться так, что это вызовет ошибку, причем сообщение о ней будет малоинформативным. С CLOS или struct'ами это не так.

Чтоб ответить на вопрос «как выглядела бы альтернатива с CLOS», я все-таки спрошу: как именно предлагается производить сериализацию?
Спасибо! Насчет »как именно предлагается производить сериализацию?
желательно совсем надолго запихивать её в базу данных, вместе с параметрами
источник

a

akater in Lisp Forever
Vλadimir (Hawthorne the Toolmaker)
Спасибо! Насчет »как именно предлагается производить сериализацию?
желательно совсем надолго запихивать её в базу данных, вместе с параметрами
это понятно; я к тому, что сами computations будут сериализовывать данные при каждом изменении параметра? Потому что если нет, то вообще все состояние можно хранить в этой самой базе, а в таком случае то, какой она будет, не влияет на дизайн той части, где мы выбираем между dlambda и clos/structs.
источник

V(

Vλadimir (Hawthorne the Toolmaker) in Lisp Forever
Да, именно - все состояние желательно держать в базе
источник

a

akater in Lisp Forever
Vλadimir (Hawthorne the Toolmaker)
Да, именно - все состояние желательно держать в базе
Я имею в виду вот что: если сами computations не управляют сериализацией, то слово «чтобы» в «чтобы можно было сериализовать» необоснованно, и мы не должны вообще обсуждать возможности сериализации если хотим сделать рациональный выбор между дизайном «куча замыканий и макросов» и дизайном «CLOS, structs». Сериализовать можно (или нельзя) совершенно независмо от этого.

Если сами computations должны управлять сериализацией или хотя бы уметь ей управлять, то я сильно подозреваю, что лучше опираться на готовые решения, а они скорее всего будут активно использовать CLOS. Это будет Rucksack, или Elephant, или что-то на основе внешних реляционных баз. Но можно придумать что-то еще в стиле quick and dirty, например, добиться того чтоб замыкания и данные просто лежали в fasl'ах. Но это не будет совместимости с другими компьютерами и другими Лиспами, и вообще я не знаю, что там можно надежно хранить.

Если не должны, то подход через dlambda может оказаться в целом удачным. Но судя по тому, что Вы можете написать (quote ,@body) и не заметить, что что-то не так, то наверное будет много приключений (но я считаю, так и надо: CL для больших сложных задач, а ошибки в целом прощает).
источник

a

akater in Lisp Forever
@hawthorne_a Сериализация это непросто. Я могу порекомендовать гл. 21 “Persistence” в книге Edi Weitz “Common Lisp Recipes”, она короткая и дает представление о перспективах. Но вообще было бы надежнее найти кого-то, кто уже лично успешно проделывал сериализацию (ну либо попросту заплатить за AllegroCache).
источник

ХЛ

Хороший Лисичко in Lisp Forever
А что вы можете сказать про Meta-object protocol?
источник

V(

Vλadimir (Hawthorne the Toolmaker) in Lisp Forever
akater
Я имею в виду вот что: если сами computations не управляют сериализацией, то слово «чтобы» в «чтобы можно было сериализовать» необоснованно, и мы не должны вообще обсуждать возможности сериализации если хотим сделать рациональный выбор между дизайном «куча замыканий и макросов» и дизайном «CLOS, structs». Сериализовать можно (или нельзя) совершенно независмо от этого.

Если сами computations должны управлять сериализацией или хотя бы уметь ей управлять, то я сильно подозреваю, что лучше опираться на готовые решения, а они скорее всего будут активно использовать CLOS. Это будет Rucksack, или Elephant, или что-то на основе внешних реляционных баз. Но можно придумать что-то еще в стиле quick and dirty, например, добиться того чтоб замыкания и данные просто лежали в fasl'ах. Но это не будет совместимости с другими компьютерами и другими Лиспами, и вообще я не знаю, что там можно надежно хранить.

Если не должны, то подход через dlambda может оказаться в целом удачным. Но судя по тому, что Вы можете написать (quote ,@body) и не заметить, что что-то не так, то наверное будет много приключений (но я считаю, так и надо: CL для больших сложных задач, а ошибки в целом прощает).
Спасибо, я понял что объяснил неаккуратно. Computations не должны управлять сериализацией, и вообще весь дизайн специально такой абстрактный: единожды исполняемая форма над списком параметров + статус её выполнения (+ строка самой формы до компиляции, чтоб через много времени можно было создать и "выполнить" такой же объект).
источник

a

akater in Lisp Forever
Короче, главное — данные не потерять, а переписать dlambda'ы можно будет легко если что. Но вот если они сами еще и пишут и читают данные, то переписать может оказаться затратно. Это скорее догадка.
источник

V(

Vλadimir (Hawthorne the Toolmaker) in Lisp Forever
Не "такой же", а "похожий". Как минимум нужно еще не давать setf-ать уже присутствующие поля. По-хорошему еще класть в params хэши от всех бинарников, которые задействованы в процессе. Ну и все что пока приходит в голову.
источник

a

akater in Lisp Forever
Хороший Лисичко
А что вы можете сказать про Meta-object protocol?
Мы? :-) Я могу сказать, что мне нередко хочется использовать возможности MOP, ну я и использую. В числе утилит, которые себе автоматически подгружаю, есть copy-instance и mapslots. Читал AMOP; мне кажется, у нее репутация абстрактной и сложной книги, но незаслуженная. Но мне в принципе кажется, что в Common Lisp очень мало интроспекции (но в остальных языках и средах еще меньше, видимо), для меня MOP или его аналог это нечто естественно желанное.
источник

ХЛ

Хороший Лисичко in Lisp Forever
akater
Мы? :-) Я могу сказать, что мне нередко хочется использовать возможности MOP, ну я и использую. В числе утилит, которые себе автоматически подгружаю, есть copy-instance и mapslots. Читал AMOP; мне кажется, у нее репутация абстрактной и сложной книги, но незаслуженная. Но мне в принципе кажется, что в Common Lisp очень мало интроспекции (но в остальных языках и средах еще меньше, видимо), для меня MOP или его аналог это нечто естественно желанное.
А почему не используете?
источник

a

akater in Lisp Forever
Хороший Лисичко
А почему не используете?
Все использую, там нету «не».
источник

ХЛ

Хороший Лисичко in Lisp Forever
akater
Все использую, там нету «не».
А, извиняюсь, очитался
источник

a

akater in Lisp Forever
Vλadimir (Hawthorne the Toolmaker)
Не "такой же", а "похожий". Как минимум нужно еще не давать setf-ать уже присутствующие поля. По-хорошему еще класть в params хэши от всех бинарников, которые задействованы в процессе. Ну и все что пока приходит в голову.
«Не давать setf'ать присутствующие поля» — можно сделать через CLOS.
источник

a

akater in Lisp Forever
akater
«Не давать setf'ать присутствующие поля» — можно сделать через CLOS.
В смысле, буквально это можно сделать через CLOS. (И это не требует MOP.) Обходным путем, без CLOS, в точности это не сделаешь: придется использовать не-setf.
источник
2020 March 02

a

akater in Lisp Forever
akater
В смысле, буквально это можно сделать через CLOS. (И это не требует MOP.) Обходным путем, без CLOS, в точности это не сделаешь: придется использовать не-setf.
Нужно написать before-метод для (setf your-slot) и проверить некоторые corner cases
источник

V(

Vλadimir (Hawthorne the Toolmaker) in Lisp Forever
akater
В смысле, буквально это можно сделать через CLOS. (И это не требует MOP.) Обходным путем, без CLOS, в точности это не сделаешь: придется использовать не-setf.
Сделаешь ведь: set-param определенный через labels пусть проверяет на nil, а тот что во вне выдает (object :get) заставить работать с копией.
источник

a

akater in Lisp Forever
Vλadimir (Hawthorne the Toolmaker)
Сделаешь ведь: set-param определенный через labels пусть проверяет на nil, а тот что во вне выдает (object :get) заставить работать с копией.
Это значит «не давать set-param'ить присутствующий слот», я об этом: «придется использовать не-setf»
источник

V(

Vλadimir (Hawthorne the Toolmaker) in Lisp Forever
Ну да. А в случае с clos т.к. набор params-список произвольный, он сидит в одном слоте. setf-ать же  можно не его а отдельное поле в нем.
источник