Pull to refresh
16
0
Антон Жуков @Beetle_ru

Программист

Send message
Думаю, что в случае форта нужно исходить из практической задачи, а не пытаться изобрести самый лаконичный, компактный или быстрый компилирующий интерпретатор. Форт предельно прост, гибок, компактен форт это стековая vm + командный интерфейс взаимодействия с пользователем, функциональность определяется набором слов из коробки. При разработке своего форта есть место распутья, можно предоставить набор слов для решения узкого круга задач, некий DSL или постараться сделать что-то универсальное и попытаться реализовать максимум ansi стандартных слов, чтобы затянуть готовые алгоритмы из других реализаций. А можно постараться придумать полностью свой универсальный набор слов как это сделал автор retro, но зачем не совсем понятно, этот путь тернист, нужно многое изобрести и понаступать на грабли. Все тоже самое можно реализовать и на стандартном форте, но для этого его хорошо бы изучить прежде чем начать делать свое решение.)

Кажется, что благодаря своей простоте форт мог бы стать отличным встраиваем скриптовым языком для конфигурации или написания логики в стиле DSL. Для популяризации такого использования не хватает методички по написанию своего форта на ЯП высокого уровня с нуля, чтобы каждый желающий мог бы за n шагов без долгого погружения получить язык готовый для использования, причем с нужным только ему функционалом. Мне для того, чтобы получить свой форт, который я мог бы использовать подходящим мне способом пришлось поковырять не мало литературы и исходников готовых проектов. В итоге имею решение, которое прикручиваю к проектам для конфигурации или для dsl. Но вот чтобы это решение двинуть в сторону стандарта приходится опять копать и переделывать, ломая совместимость со своими предыдущими решениями.

Так что я тоже вынашиваю идею, но не конкретной реализации форта, а пошаговой инструкции по написанию форта, желательно близкого к стандарту.
Вам спасибо, добавил ссылку.
Нет, замыкания не передаются, не вижу практического смысла и сложности реализовать это. Сервер реализует функции, а клиент их вызывает и получает ответ, по типу
(+ 1 2 3) => 6
. Для удобства все это дело завернуто в механику похожую на wcf, на сервере реализуется интерфейс, на клиенте в рантайме компилируется реализация клиента, и сериализаторы из s-exp в dto, доступ к методам сервера осуществляется через общий интерфейс. Но это проще попробовать, чем описать). В репозитории есть пример использования. Кстати, обмен может инициировать сервер.

Вот пример обмена:

<< ((sd3-srv:Commit "b72dfef2338240eebd055edcabe376df" (quote ((Id . "39f5873a9838845a6150ed08ee6002d6") (ComplectId . "39f5873217153076485946b324ebb1ea") (User (Id) (UserLogin) (UserDomain)) (Stage (Id . "wo.handle.crop-passport") (Name . "")) (CreateDate . "02.06.2020 12:42:14.968") (ComplectRouteId . "tcb-short-offer.flow") (Tags ((Id . "39f5873a98678479238f985bfaaa819f") (Key . "skip") (Value . "WO-CROP.HANDLE-WARNING. Для request-id: 39f5873a4eaa78cd8e9528a2960ae8dd данных нет") (CommitId . "39f5873a9838845a6150ed08ee6002d6"))) (AttachCriteriaBindingIds #nil) (TargetStageId)))))         
>> True                             

В текущей версии s-exp передается в бинрном виде, это нужно, например, чтобы передавать файлы без base64, проще передавать строки, не нужно с экранированием заморачиваться, да и быстрее reader работает. Составные объекты, как экземпляры класса(DTO) преобразуются к виду (quote (...)), примитивы передаются как есть в бинарном виде.

Суть в том, что можно разорвать запрос/ответ и полуить нечто похожее на модель акторов, осталось только сделать удобный инструмент для работы с этим из C#. А вот как возвращать ответ, в принципе можно и через коллбеки, но опять же зачем сервер и так знает куда передать ответ?
На Scheme Workshop хочется идти с концептуальным докладом. Эти статьи по большому счету особо нового не несут, всего лишь scheme для .net. За 5 лет по этой теме у меня произошло много интересного, были изучены разные интерпретаторы scheme под .net, даже Microsoft опубликовал свой интерпретаор схемы. Почти сразу после публикации статей я начал разрабатывать свои интерпретаторы схемы, для использования в качестве встраиваемого языка, и что самое интересное в качестве RPC и не только. S-expression как формат доставки сообщений показал себя очень интересно, поскольку может описывать произвольную структуру данных с одной стороны, а с другой очень легко парсится, и к тому же компактен, что уменьшает оверхед при передаче. Даже первая версия проекта Ogam показывала отзывчивость выше, чем у мейнстримных решений SOAP, REST. Кроме этого, на принимающей стороне используется scheme интерпретатор, что позволяет не только вызывать процедуры но и комбинировать их без передачи временных результатов на клиента, например, отфильтровать или конвертировать множество и уже результат вернуть на клиента. Так же экспериментировал с сериализацией .net объектов(таблицы хранения примитивов и лисповский cons для связи) для сохранения в реляционной базе, что очень удобно для хранения произвольных структур, с возможностью select'а по ним. Сейчас, в новой версии я иду к модели акторов + scheme, суть понятна, но сложнее сделать юзабильное и простое в использовании решение под .net. И вот с этим уже можно на Scheme Workshop, но это точно не раньше чем через год.)
А стоит ли теорию формальных языков применять к форт? В языках типа Си, phyton, js и др. грамматика задана и не может быть изменена. В форте грамматика есть, но она не постоянная, что не ложится на теорию формальных языков. По ходу интерпретации программы грамматику можно изменить, поэтому можно сказать что ее нет совсем. Конечно можно придумать автомат описывающий форт, но это и будет реализация форта, разве нет?
Из форт программы доступна вся форт система, соответственно можно написать ридер который анализирует хоть естественный язык и в стихах описать GUI, потом опять вернуться к форту. Причем это будет цельный и монолитный листинг. Понятно, что так вряд ли кто-то будет делать, хотя это технически возможно. Кстати есть проект по реализации AI на форте, называется MindForth, по этой теме можно много интересного материала нагуглить.
Компактность достигается выкидыванием из языка всех конструкций длиннее одной буквы, а понятность достигается структурой языка и форматированием.

В целом дать пользователю какой-нибудь JavaScript и написать для него библиотеки будет много проще, чем возиться с DSL.

Ну смотрите, вы же наверняка использует регулярные выражения, конечно можно ту же логику описать на JavaScript, но так обычно не делают. На SQL web сервер не напишешь, но это мало кого беспокоит. Применение сценарных языков тоже имеет место, от DSL отличается тем, что последние описывают логику в терминах предметной области, за счет чего и достигает компактность и понятность(RegExp, SQL, awk, TeX, lex/yacc).

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

Не знаю что вы имеете ввиду под общим решением. Для целенаправленной разумной деятельности необходимо формирование в сознании модели явления или понимание. Для себя понимание определяю как выявление значимых связей явления и удержания их в сознании. У человека объем внимания ограничен, именно внимание отвечает за активацию смыслов, связей. Когда задача перестает помещаться единомоментно в сознании, тогда и происходит резкое увеличение количества ошибок и падает производительность. Здесь ключевым моментом является компактность представления знания. Чем больше букв, тем сложнее это удержать в сознании, консолидировать и оперировать. По вашей логике не важно на чем писать на ассемблере x86 или на Java, ведь есть общее решение, чтобы это не значило. На деле мы видим зависимость от уровня языка и производительностью разработки на нем. DSL априори более высокоуровневый по сравнению с языком общего назначения, позволяет бизнес логику описывать компактно. И как следствие то, что написано в статье.

Но когда вы пытаетесь понять, а потом исправить, всю ту галиматью, которую нарисовал вам юзер

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

Конечно можно долго рассуждать имеет смысл вводить DSL или нет, но важно помнить, что лучшая проверка любой теории это практика.
Интересная у вас реакция. А это на какую-то конкретную картинку? Фильтры везде разные.
В смысле? Картинки понравились?)
Это да). Форт древний и вездесущий, для .net их тьма реализована. У меня это 5 версия). Суть статьи скорее в популяризации и объяснении принципов утилитарного фортостроения. Тема форта в интернете не раскрыта, много кто этим занимается, а вот с публикациями и пошаговыми мануалами как оно работает и как реализовать с нуля совсем плохо. Достаточно материалов типа: «2 dup *. — вуаля», а вот как строить форты не особо. Лично мне в свое время пришлось собирать по крупицам знание как реализовать форт.
кстати относительно digital subscriber line можно сказать точно так же, на хабре есть публикации с тэгом DSL и описанием domain-specific language
Сам язык конечно же заточен под задачу, но движок универсален. Дефолтный язык движка может быть использован как есть, в качестве универсального инструмента, или для удобства сконфигурирован под конкретный синтаксис с некоторыми ограничениями
Очень интересно, хотелось бы посмотреть. Поделитесь пожалуйста ссылкой если все же решитесь опубликовать.
Оп, извиняюсь, я тут имел ввиду AppMetrics и его аналоги.

Может быть, не могу сказать.
никому кроме вас он не нужен

Не следует говорить за всех)
лучше протестирован и постоянно обновляется/фиксятся баги

Вспоминается цитата):
Есть два способа разработки проекта приложения: сделать его настолько простым, чтобы было очевидно, что в нем нет недостатков, или сделать его таким сложным, чтобы в нем не было очевидных недостатков. Ч. Э. Р. Хоар (C. A. R. Hoare)

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

Тут наверно можем долго спорить. Как я понимаю основная идея тредпула это ускорить создание потоков, типа кеширования для потоков. Ресурсы под поток выделяются достаточно долго, что легко проверить например создав 10к потоков в цикле. Тредпул на то и пул что содержит уже готовые потоки, которые переиспользуются для выполнения тех же тасков. Поэтому 10к тасков создаются быстро и достаточно быстро обрабатываются на уже готовых потоках. А если у меня 1 поток на все время жизни приложения, зачем же мне таск, хотя не исключаю что его можно использовать. Кстати с тасками и тредпулами тоже есть нюансы, некоторые потоки используются для числодробилок вычислений их создавать больше чем ядер смысла нет. Другие могут использоваться для ввода вывода и большую часть времени висят в блокировке, таких можно создавать почти неограниченно, цпу для них не основной ресурс. Некоторые типы потоков могут потреблять много памяти их количество нужно регулировать по доступной для процесса памяти. В этих случаях под разные задачи приходится писать кастомные тредпулы. В случае создания треда «руками», во всю эту механику не вмешиваемся.
если бы использовали нормальную очередь

За это спасибо, подумаю над этим, вполне возможно вы правы, стоит попробовать BlockingCollection.

Извиняюсь, что несколько резко высказываюсь, с утра воду отключили.

Понимаю вас, с утра не обнаружить в кране воду это жестко. Казалось бы 21 век, компьютеры, ракеты, а бесперебойную подачу воды реализовать не могут!
Однажды мне попало на поддержку весьма жирное и написанное не по феншую приложение, афтор которого бесследно исчез. Приложение начало сильно тормозить, а оно активно использовалось для решения бизнес задач. И мне пришлось экстремально быстро искать проблему, причем нужно было понять что происходит внутри весьма длинных методов. Тогда буквально за 20 минут и был написан почти этот логер, он помог решить проблему достаточно быстро. Потом я его немного причесал и стал много где использовать, в том числе и вместе с тем же Prometheus. Статью писал исключительно чтобы поделиться идеей, кто-то может столкнуться с похожей задачей, а кто-то может придумать как адаптировать решение для своих целей.
А какие потребности решаются прометеусом? Хранение метрик, да решаются. Здесь я пишу как обложить код измерителями не нарушая его работу, а как хранить вопрос уже другой. На удаленных машинах(подразумевается desctop приложение) может и не быть доступа к серверу прометеуса, а померить что-то нужно, как вариант можно использовать sqlite базу, почему нет.

Неподдерживаемый код — ну что за инфантильные ярлыки? Ну почему же тредов руками? Первое — тред один. Второе — интересно узнать каким место вы создаете треды? Только не надо писать про Task, он нужен когда создается множество тредов через тредпул(под капотом) и с удобным управлением. Вот насчет try..catch, соглашусь не помешал бы, хотя у меня еще не было в этом месте исключений, но в принципе они возможны. Динамика понятно зачем нужна, чтобы отвязаться от типов, иногда это удобно, например, чтобы писать обработчики для уже существующих или произвольных logItem. Злоупотреблять динамикой не стоит, но иногда и чуть-чуть, где это сэкономит время и силы почему же нет?

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

BlockingCollection был бы здесь более подходящим вариантом

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

Интересное наблюдение, спасибо что поделились.

Отлаживался я на принтере HP_M9050, на бою используются 603 и 606, так же проверял на Lexmark MS810.
ну даже не знаю что и ответить)

1. В общем соглашусь, хотя и Configuration отражает суть.
2. В конкретном случае нет и не подразумевается никакой вложенности и других прелестей json и xml, просто список в 3 столбца, который отлично ложится на CSV. Вернее здесь два списка которые разделяются заголовками. В другом месте за setting.Split(';')[1] и сам может кого побил бы, LoadConfig() завернута в try-catch, вызывается в одном месте. Вариантов два, конфиг либо валидный либо нет и неважно почему.
3. А оно нужно?

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

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

Information

Rating
Does not participate
Location
Москва, Москва и Московская обл., Россия
Works in
Date of birth
Registered
Activity