LINUX.ORG.RU

Stodin DSL

 , ,


0

3

Здравствуйте!

В данной теме представляю для обсуждения язык программирования, созданный с использованием принципов разработки предметно-ориентированных языков (по книге Мартина Фаулера). Ссылка на проект языка: https://github.com/kupriyanov-sn/StodinDSL

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

В данный момент это работающий прототип. Библиотека языка пока на начальной стадии разработки. Но уже есть 3 небольших приложения-примера, написанных на Stodin (в examples).

Возможно, у кого-нибудь будут идеи, советы, пожелания как по библиотеке, так и по синтаксису.



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

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

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

А полиморфизм решается через структуру с контейнерами разных типов.

Раз пятьдесят в постах говорил, что проблема C++ в том что язык «гвоздями прибит» к class.
И …

Как о стенку горохом.

В коде C/C++ использую иную объектную модель.

Владимир

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

В C++ я бы через умные указатели работал. Но у моего языка их нет.

Задача, о которой Вы говорите, актуальна в документообороте, например. Но там можно c# просто взять и не мучиться. У моего языка задачи другие - мотором управлять, картинку обрабатывать и т.д.

Kogrom
() автор топика

Надеюсь, что наша дискуссия была полезной и много лучшей от той,
где вас бы просто «дурачили».
А таких «дискуссий» - МНОГО.

Владимир

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

Дискуссия интересная. Она иллюстрирует ситуацию в IT.

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

И в этих областях дают для работы ассемблер, си, а по праздникам с++. И сами ребята из embedded не могут представить, что есть другие языки, кроме си, и разработчикам языков они не интересны. Им интересны ФП, многопоточность, интроспекция и метаданные. А потом происходит переполнение целого числа и робот выдаёт брак. И хорошо, если это робот, а не самолёт.

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

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

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

Зря с вами дискуссию вел.
«Век живи - век учись».

Владимир

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

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

Вы так ничего и не поняли из того, что вам говорил.
Документооборот …

Владимир

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

Я на словах не понимаю, только на примерах. Взять, например, инициализацию структуры json-строкой.

Для C++ я нашёл такой пример: https://github.com/nlohmann/json

Делают так:

namespace ns {
    // a simple struct to model a person
    struct person {
        std::string name;
        std::string address;
        int age;
    };
}
auto p2 = j.get<ns::person>();

Вроде бы красиво. Но чтобы оно работало, необходимо реализовать функции:

namespace ns {
    void to_json(json& j, const person& p) {
        j = json{{"name", p.name}, {"address", p.address}, {"age", p.age}};
    }

    void from_json(const json& j, person& p) {
        j.at("name").get_to(p.name);
        j.at("address").get_to(p.address);
        j.at("age").get_to(p.age);
    }
} // namespace ns

Магии нет. У меня же транслятор знает имена и типы всех полей и я бы мог автоматически генерировать такие функции. Но это надо жёстко заложить в транслятор.

Аналогичный проект на Rust: https://github.com/serde-rs/json Там аналогичную инициализацию структуры делают без ручного создания функций, через атрибуты, которые, вероятно, какие-нибудь макросы подключают, которые интроспекцию используют. Возможно, это то, что Вы предлагали.

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

Вы уже несколько раз иронизировали, …
В дискуссии с моей стороны ничего такого не было.
Зачем мне такая дискуссия?

Владимир

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

Аналогичный проект на Rust: https://github.com/serde-rs/json Там аналогичную инициализацию структуры делают без ручного создания функций, через атрибуты, которые, вероятно, какие-нибудь макросы подключают, которые интроспекцию используют. Возможно, это то, что Вы предлагали.

Там процедурные макросы. Такой макрос получает на вход список токенов и возвращает уже модернизированный список токенов, интроспекция при этом не нужна.

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

Такой макрос получает на вход список токенов и возвращает уже модернизированный список токенов, интроспекция при этом не нужна.

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

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

Kogrom
() автор топика
Ответ на: комментарий от byko3y

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

Сейчас в голову пришёл пример области, где это не будет избыточно:

image1; image2 @erode params1 @delate params2 @blur params3
@show image1 x1 y; image2 x2 y  

Примерно оно же на питоне:

for img in (image1, image2):
    erode(img, params1)
    delate(img, params2)
    blur(img, params3)
show(image1, x1, y)
show(image2, x2, y)

Python без учёта отступов: 133 символа. Stodin: 91 символ.

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

Тебе же уже сообщили, что методичка кривая. Нет ты продолжаешь.


erode(img, params1)
    delate(img, params2)
    blur(img, params3)

Что это за говно? img.erode(params1).delate(params2).blur(params)

Не уровень крестов, конечно, но лучше твоего синтаксического мусора.

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

Вроде бы красиво. Но чтобы оно работало, необходимо реализовать функции:

Колхоз бездарный и птушный. Это так сделано лишь потому, что колхозники не могут в кресты.

Я беру и пишу: https://godbolt.org/z/nwW4wL , есть реализации и на макросах https://godbolt.org/z/x27_4c

У меня же транслятор знает имена и типы всех полей и я бы мог автоматически генерировать такие функции.

И? Компилятор тоже мог бы генерировать эти функции, только вот это никому не нужно. Это говно. Берёшь шланг и пишешь эту генерацию за пол часа.

К тому же объектная модель крестов - это не объектная модель говнораста, которой там нет.

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

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

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

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

img.erode(params1).delate(params2).blur(params)

Имена этих переменных и функций имеют смысл. И в соответствии с этим смыслом я даже подыграл питону. На практике оно выглядит так:

https://docs.opencv.org/2.4/modules/imgproc/doc/filtering.html?highlight=erode#erode

То есть dst = cv2.erode(src, kernel ...) потому что все функции обработки пихать в один класс - дурная архитектура. Даже Страуструп в своей книге советует выносить из класса во внешние функции всё что можно. Можно было бы предположить такой вариант:

dst = blur(delate(erode(dst)))

Но, во-первых, это упадёт (потому как там внутри C++, который не перенесёт того, что источник и цель совпадают), а во-вторых тут меняется порядок вычисления операторов, что снижает читаемость.

Но даже если бы они реализовали чейнинг, то было бы такое:

for img in (image1, image2):
    img.erode(params1).delate(params2).blur(params)
image1.show(x1, y)
image2.show(x2, y)

117 символов без отступа против 91.

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

Я беру и пишу: https://godbolt.org/z/nwW4wL

Мощно. Хотя гугление пока не помогло мне понять, meta::data_member_range может ли возвратить имена полей вложенных структур. Тут вроде рекурсия нужна или какой-нибудь хитрый цикл.

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

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

Имена этих переменных и функций имеют смысл. И в соответствии с этим смыслом я даже подыграл питону. На практике оно выглядит так:

Ещё раз, тебе уже сообщали - это херня. Когда ты реализуешь у тебя это api с теми же свойствами - тогда и будешь рассказывать. А кукарекать, что в твоих фантазиях круто, а других нет - это чушь.

Но, во-первых, это упадёт (потому как там внутри C++, который не перенесёт того, что источник и цель совпадают), а во-вторых тут меняется порядок вычисления операторов, что снижает читаемость.

Разупорись - ты несёшь херню. Упадёт у него что-то, нет.

Но даже если бы они реализовали чейнинг, то было бы такое:

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

К тому же - это пистон убогий, который сливает в хлам крестам в выразительности.

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

Мощно. Хотя гугление пока не помогло мне понять, meta::data_member_range может ли возвратить имена полей вложенных структур. Тут вроде рекурсия нужна или какой-нибудь хитрый цикл.

Ты ничего не знаешь о С++. Ничего из того о чём ты рассказываешь - там не нужно.

В тесте (main) все структуры одинаковые, только имена у них разные.

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

Вложенных структур нет, контейнеров нет.

Ещё раз, изучи букварь.

Кто его знает, осилит ли эта конструкция сложную структуру с вложенными структурами и контейнерами.

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

А во-вторых, изучи то, о чём пытаешься рассуждать.

И ещё. Не уверен, но это вроде бы сериализация, а не на десериализация.

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

С++ сам может сериализовывать что угодно и как угодно. Ему не нужны для этого какие-либо генераторы - он сам генератор.

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

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

Упадёт у него что-то, нет.

Этим функциям нужен отдельный источник и отдельный приёмник, потому что они по источнику проходят несколько раз и его нельзя затирать. Поэтому нормально реализованная такая функция, чтобы не выдать мусор на выходе, должна в случае совпадения источника и приёмника выдать исключение. Единственно что, дело тут не в особенностях C++.

Для чейнинга надо внутри делать клон изображения.

Во-первых здесь говноцикл, а у тебя его нет.

Так цикл тут чтобы уменьшить количество символов.

Во-вторых - это специально подобранный пример и ты даже на нём не выиграл.

Да, это так. Об этом написано над примером. В общем случае питон, естественно, будет впереди.

Когда ты реализуешь у тебя это api с теми же свойствами - тогда и будешь рассказывать.

Это отдельная тема. Речь же в примере о том, что бывают случаи, когда одни и те же данные подряд надо в несколько функций передать.

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

https://godbolt.org/z/QumUqT - сила земли.

Думаю понятно как реализовать что угодно. У тебя у любой структуры данных есть некие базовые типы - числа/строки. Допустим в том же жсоне. Вот для них ты пишешь сериализаторы.

Далее тебе нужно сериализовать объект. Ты создаёшь специализацию для объектов. Пишешь какой-либо предикат(ты можешь узнать сколько там полей, pod структура или нет и прочее), оборачиваешь в концепт.

Ну и всё, далее для каждого поля вызываешь условный proсcess - он сам поймёт куда ему идти.

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

Этим функциям нужен отдельный источник и отдельный приёмник, потому что они по источнику проходят несколько раз и его нельзя затирать. Поэтому нормально реализованная такая функция, чтобы не выдать мусор на выходе, должна в случае совпадения источника и приёмника выдать исключение. Единственно что, дело тут не в особенностях C++.

api-проблемы, которые будут и у тебя.

Для чейнинга надо внутри делать клон изображения.

Зачем?

Так цикл тут чтобы уменьшить количество символов.

Опять же - пистонопроблемы. В крестах это ты можешь определить каждую операцию и для range и для item и всё будет работать. imgs | op(args) | op1(args)...

Так же можно сделать и auto pipe = op(args) | op1(args)...; img0 | pipe | show(args); img0 | pipe| shaow(args) - это та причина почему пайпы лучше чейнинга.

Так же можно реализовать какой-то оператор aka zip_call, | zc(show(args), show(args))

Причём это решает все твои проблемы. Потому api явно асинхронное, потому что пистон дерьмо. А ranges ленивые, что идеально ложиться на данную модель.

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

Правда, опять же, в крестах нахрен не нужно это мусорное дерьмо для дошколят. Текст, сериализация - всё это для бездарной скриптухи.

Поэтому в крестах всё это используется для более фундаментальный вещей, нежели убогая сериализация дерьма.

Я не занимаюсь этим говном с жсоном и прочим мусором, но когда я писал про api парсеров. В общем код я куда-то просрал, но скрипн остался в пасте про стиль дерьма. Вот.

Соответственно, тут ты можешь видеть как это работает.

Я могу просто пройтись форичом по структуре, далее я пишу руками простенький сериалазтор для базовых типов. А далее его запускают от second(x) - это значение поля, соответственно second(x) - его имя.

В этом смысл всего. С++ позволяет работать с обобщёнными структурами данных. И самый просто способ работать со структорой(которая struct) - это превратить её в тапл tuple{tuple{key, value}, ...} - а далее с нею можно делать что угодно.

Так же понятно как реализовать десериализатор, который тут так же написан руками. Просто реализуешь сериализатор для variant<T…> - это не сложно.

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

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

Документооборот и web традиционно привлекают максимум ресурсов.

Вы это серьезно?! Конечно веб-браузеры память жрут как не в себя, но че то я не слышал про создание суперкомпьютеров для документооборота… или о каких ресурсах Вы говорите?

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

AntonI ★★★★★
()

Если вместо того дог-шоу, которое ты там развел, юзать chaining, то все остальные плюсы твоего языка уже есть в Cython.

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

Мощно.

Учти что царь тут везде носится с нестандартным экспериментальным расширением clang, для стандартного C++ это все недоступно, а когда будет доступно и в каком виде пока неизвестно.

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

Эти сектанты поехавшие. Они никогда не вылечатся.

Пацан предлагает вообще какой-то левый язык, приводит в пример говнораст. Ни у того ни у другого нету никакого стандарта и все они - нестандартные расширения.

Но тут этот поехавший приходит и говорит «у царя не стандартный С++» - да ты чё, неужели? Ты откуда того гения откапали?

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

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

У царя может быть все что угодно, тем более у царя хеловордов, это совершенно неважно, просто нужно предупредить человека чтобы не наступил на какашку подумав что в C++ это уже доступно.

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

Ты совсем поехавший? Как это не доступно, если оно доступно? Я что показываю, клоун? Вас там совсем всех таких одарённых отбирают?

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

Как это не доступно, если оно доступно?

В случае C++ доступно это принято в стандарт и реализовано в нескольких самых массовых компиляторах. Все остальное это на уровне поделки уважаемого топикстартера.

anonymous
()

Последние дни на ЛОР

Кислые щи.

Владимир

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

Я говорил о деньгах. Возможно, термин «Документооборот» не очень удачно я там применил. Можно было бы сказать Enterprise.

Чтобы не создавать три сообщения отвечу и на другие вопросы тут. Мне было интересно, насколько шаблон на шаблоне в новом C++ может эффективно парсить json. Поэтому все сообщения царя тут по теме. Понятно, что рискованно применять методики не проверенные временем. Ну так и я в процессе разработки.

Cython хорош как инструмент дополняющий питон. Он имеет определённую нишу. Но чтобы на нём писать, надо знать и питон, и си. Надо знать, например, как работают указатели, надо знать, что строки в си заканчиваются нулём и т.д.

Nim более интересен, но сложен, изменчив и нишу не имеет. Поэтому скорее всего последует за Boo. Проблема в том, что если постоянно менять синтаксис, то для разработки и поддержания библиотек потребуются большие ресурсы (человеческие и временные). Их нет у разработчиков Nim, не было у разработчика Boo (у того хотя бы доступ к .Net был).

Я же хочу сделать примитивную обёртку над C++, которая будет максимально стабильна. Это высвободит ресурсы для разработки «батареек». Возможно, такой подход будет оправдан в небольшой нише.

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

Я же хочу сделать примитивную обёртку над C++, которая будет максимально стабильна.

Что бы это взлетело (и было полезно) придется очень тщательно вылизать идеологию и синтаксис.

Удачи!

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

Мне было интересно, насколько шаблон на шаблоне в новом C++ может эффективно парсить json. Поэтому все сообщения царя тут по теме. Понятно, что рискованно применять методики не проверенные временем. Ну так и я в процессе разработки.

Это не просто рискованно, это еще хуже, скорее всего именно этот механизм никогда ни будет принят в стандартном C++, возможно примут что-то по мотивам, но точно не в ближайшие три, а скорее и даже шесть лет (по срокам релизов стандарта).

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

Что бы это взлетело (и было полезно) придется очень тщательно вылизать идеологию и синтаксис.

Такое кстати уже есть https://felix-lang.github.io/felix/ правда функциональщина, зато генерирует C++ код и может наоборот и прозрачно встраивать куски C++ кода.

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

Да, у felix-lang батареек много. Странно, что за многие годы разработки (10 лет примерно, насколько я понял) у них не возникло искушение переписать компилятор с окамла на феликс.

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

В случае C++

Какое отношение блеяние какого-то анонимного дошколёнка относится к С++? И почему именно к С++?

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

Побежал, клоун, показывать стандарт, массовых и несколько компиляторов в расте, поделке автора темы. А так же в целом обосновывать своё нелепое блеяние.

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

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

Судя по http://freshmeat.sourceforge.net/projects/flx/releases языку уже 16 лет. А зачем переписывать если все и так работает, тем более OCaml очень хорош как язык для реализации компиляторов.

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

Безусловно, авторы имеют право выбирать подходящие им инструменты. Но сточки зрения уменьшения зависимостей, стоит переписать. У них зависимости такие:

  • Python 3 (???)
  • Ocaml 4.06.1 (only for source build)
  • C++ compiler: g++, clang++, or msvc

Мой опыт говорит, что они не просто так указывают версию 4.06.1. Скорее всего, с 4.02 или 4.10 не соберётся. Поэтому для Windows они таскают с собой бинарики: https://github.com/felix-lang/win64ocaml . Для Linux же в каждом дистрибутиве своя версия OCaml: https://ocaml.org/docs/install.html , соответственно, могут быть небольшие сложности.

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

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

Мой опыт говорит, что они не просто так указывают версию 4.06.1. Скорее всего, с 4.02 или 4.10 не соберётся. Поэтому для Windows они таскают с собой бинарики: https://github.com/felix-lang/win64ocaml . Для Linux же в каждом дистрибутиве своя версия OCaml: https://ocaml.org/docs/install.html , соответственно, могут быть небольшие сложности.

У OCaml есть такая полезная штука как https://opam.ocaml.org/ которая позволяет легко переключаться между версиями компилятора, версия 4.06.1 там есть https://opam.ocaml.org/packages/ocaml/ocaml.4.06.1/

anonymous
()
19 июня 2021 г.

Возможно, у кого-нибудь будут идеи, советы, пожелания как по библиотеке, так и по синтаксису.

Интересные у вас задачи, но на форумах из обсуждать с «ненужниками» - НЕ НУЖНО …
К сожалению на форумах «ненужников» и иной … - большинство.

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

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

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

Если вернуться к деревьям, то наряду с массивами и словарями можно было бы заложить дерево в стандартную библиотеку, но синтаксис создания такого дерева был бы чудовищный, если в языке нет возможностей использования динамической типизации. Если же все ветки - object, которые мы преобразуем к нужному классу во время выполнения программы, то мы получим гибкость в обмен на бесконечную отладку, ибо сложно предсказать как будет расти дерево. И это я ещё не говорю о случаях, когда между листьями разных веток есть какие-то связи. В данном случае надо звать aist1 с Memoria или Владимира с его метаданными.

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

В данном случае надо звать aist1 с Memoria или Владимира с его метаданными.

А чего его звать то?
Он здесь, и пост от него был …

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