LINUX.ORG.RU
ФорумTalks

Как насчёт такого ЯП?

 ,


0

1

Перепробовав D, Rust и C на одном и том же коде, реализовав один из алгоритмов на Cuda и найдя крайне геморным перенос его на OpenCL, я до сих не чувствую себя удовлетворённым.

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

Помимо этого хотелось бы таких свойств языка:

  1. Имя переменной = её тип. Т.е. если есть переменная image, то это однозначно некоторая структура описывающая изображение, а не скажем имя файла с картинкой.

  2. Имя функции = её входящие и исходящие переменные. Т.е. например вызов scaled_down_image(image) означает что на вход функции подаётся изображение, а на выходе мы получаем уменьшенное изображение в переменной scaled_down_image (если нет присваивания)

  3. Язык является полностью шаблонным и все типы уточняются в отдельном месте программы

  4. Отсутствие как класс в языке такого понятия как «указатель». Компилятор сам решает передать структуру по значению или по указателю. Явно указатели могут быть указаны только в отдельном разделе для связи с другими ЯП.

  5. Автоматическая сериализация данных. Из-за пункта 4 одна и та же структура легко может быть перекомпилирована в структуру без указателей и таким образом сериализована. Если же речь идёт о циклических структурах, то будет использована относительная адресация.

  6. Явное указание в заголовке функции на используемые системные вызовы. Сбалансированные вызовы такие как open/close не указываются. Например если функция считывает файл в переменную, то указывается не open, read, close, а только read. Примерно так:

    file_data(filename; read);

А вопрос мой состоит в том, нет ли этого всего уже где-нибудь?

★★★★★

Не совсем то, совсем не то, но пригодится, наверное: https://halide-lang.org

Halide is a programming language designed to make it easier to write high-performance image and array processing code on modern machines. Halide currently targets:

  • CPU architectures: X86, ARM, MIPS, Hexagon, PowerPC, RISC-V
  • Operating systems: Linux, Windows, macOS, Android, iOS, Qualcomm QuRT
  • GPU Compute APIs: CUDA, OpenCL, OpenGL Compute Shaders, Apple Metal, Microsoft Direct X 12

Rather than being a standalone programming language, Halide is embedded in C++. This means you write C++ code that builds an in-memory representation of a Halide pipeline using Halide’s C++ API. You can then compile this representation to an object file, or JIT-compile it and run it in the same process.

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

Интересная ссылка, спасибо!

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

Mojo ведь компилируемый питон, разве он сумеет скомпилироваться для gpu сохраняя все возможности языка?

unDEFER ★★★★★
() автор топика

Есть библиотека для Python, называется Numba, добавляешь перед функцией @jit и она скомпилирует эту функцию либо нативно для процессора либо для CUDA. Сохранять возможности языка бессмысленно, для видеокарт свои приемы нужны, а для процессора другие.

MOPKOBKA ★★★★★
()

Имя переменной = её тип

А если надо более одной переменной такого типа? дописывать индексы типа image_1, image_2? добавить имена, но с обязательным префиксом типа? Всё равно неудобно выглядит

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

Сохранять возможности языка бессмысленно,

Ну как сказать. Я вот не требую чего-то экзотического. Например я хочу глобальную константу, но сослаться на неё как на обычную переменную. Но на OpenCL так нельзя - видите ли это разные адресные пространства. Я бы скопировал и сослался бы на копию, но там и выделить под это дело пространство нельзя.. В общем выглядит OpenCL довольно ущербно в сравнении с Cuda. Вот мне и захотелось чтобы такие вещи разруливал компилятор.

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

А если надо более одной переменной такого типа? дописывать индексы типа image_1, image_2?

Да как обычно, просто будет локальный alias для этого типа.

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

На ролике похоже на какой-то унылый RAD. Что там под капотом?

унылый RAD :-) Бейсик там. Но под любую платформу, с нативным или web гуи.

MKuznetsov ★★★★★
()

Имя переменной = её тип.

Т.е. переменная image - типа image, а image2 - уже другого типа image2?

Имя функции = её входящие и исходящие переменные. scaled_down_image(image) … а на выходе мы получаем

Объект типа scaled_down_image. Что это за тип такой? А хз.

Ну и т.д. Грубо говоря, ты хочешь, чтобы был язык, который читает твои мысли.

Явное указание в заголовке функции на используемые системные вызовы.

Представляю длину описания заголовка функции main.

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

Т.е. переменная image - типа image, а image2 - уже другого типа image2?

Нет конечно. Могут быть алиасы по типу.

Объект типа scaled_down_image. Что это за тип такой? А хз.

Тот же что и image.

Ну и т.д. Грубо говоря, ты хочешь, чтобы был язык, который читает твои мысли.

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

Представляю длину описания заголовка функции main.

У вас видимо больше фантазии чем у меня :-)

Я пока не про все системные вызовы думал. lseek какой-нибудь наверное нет особо смысла выносить в заголовок. Но не сбалансированный open/close и read/write хотелось бы видеть.

unDEFER ★★★★★
() автор топика

Т.е. например вызов scaled_down_image(image) означает что на вход функции подаётся изображение, а на выходе мы получаем уменьшенное изображение в переменной scaled_down_image

Как это должно выглядеть? Компилятор из одних только названий должен алгоритм соответствующий сгенерить/подобрать существующий? Насколько scaled_down должен быть результат? В каком он должен быть формате?


Я так понимаю, хочется DSL, идеально заточенный под свои задачи.

yu-boot ★★★★★
()
Ответ на: комментарий от yu-boot

Как это должно выглядеть? Компилятор из одних только названий должен алгоритм соответствующий сгенерить/подобрать существующий? Насколько scaled_down должен быть результат? В каком он должен быть формате?

Нет, это просто mangling подобный D или C++ применяемый чтобы у функции-шаблона могли быть разные параметры или результирующие значения. Просто имени функции нет, вместо него имена аргументов и результатов.

Я так понимаю, хочется DSL, идеально заточенный под свои задачи.

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

unDEFER ★★★★★
() автор топика

из 1 и 2 (имя переменной=её тип, имя функции=имена параметров сиречь переменных) следует что все переменные уникальны, а функции показывают зависимость между ними. Такая структура именуется DAG, массово применяется в моделировании, можете посмотреть/поискать соотв. DSL; ищите - должён быть

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

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

DAG - это как раз то во что такой компилятор должен бы уметь код преобразовывать. Спасибо за термин! На нём хорошо выделяются вычисления, которые возможно исполнять параллельно.

unDEFER ★★★★★
() автор топика
Ответ на: комментарий от yu-boot

Я так понимаю, хочется DSL, идеально заточенный под свои задачи.

Неправильно понимаешь. Чел обжегся на молоке, а теперь в рамках гиперкомпенсации хочет дуть на воду, пока кишки не вылетят. Ему бы нормальный какой ЯП, чтоб отошёл.

t184256 ★★★★★
()

вызов scaled_down_image(image) … на выходе мы получаем уменьшенное изображение в переменной scaled_down_image

Ничё не понял, Lisp-2 с нескучными умолчаниями изобретаешь?

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

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

Но недавно всё начало вырисовываться. Первым делом я понял что графически очень хорошо изображать «трансформации». Например:

Имя файла –read-> изображение -> уменьшенное изображение –write-> имя файла.

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

Зато удобно изобразить например что фильтрация изображения это некая подфункция фильтрующая отдельный пиксель. Каждая подфункция может быть исполнена параллельно.

Затем я понял что циклы можно разделить на:

Итерационные - обычные циклы в которых входы и выходы на каждой итерации одни и те же.

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

Рекурсивные в которых на каждой итерации данные преобразуются в группу таких же данных.

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

Вот такая история этой концепции..

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

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

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

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

Вот как раз хотел вспомнить метапрог. Видимо это самое близкое к тому что я сочинил :-)

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

Чтобы было понятней приведу примерный листинг такой функции:

scaled_down_image(image, scale_down)
{
    sum_pixels = image with channel is float[scaledown, scaledown];
    image => scaled_down_image[out_pixel](scale_down)
    {
        image[out_pixel.x * scaledown .. (out_pixel.x+1) * scaledown,
              out_pixel.y * scaledown .. (out_pixel.y+1) * scaledown][in_pixel] => sum_pixels[sum_pixel]
        {
            in_pixel[in_channel] => sum_pixel[sum_channel]
            {
                sum_channel += in_channel;
            }
        }

        pixels_count = scaledown*scaledown;
        sum_pixel[sum_channel] => out_pixel[out_channel](pixels_count)
        {
            out_channel = sum_channel / pixels_count;
        }
    }
}

Похоже это на Lisp? По мне - не очень.

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

Кто-то пятничным вечером не ограничился.

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

Похоже на беспросветный мрак. Сравни:

scale_down(image, factor):
    scaled_down = array(image.shape[0] / factor, image.shape[1] / factor)
    scaled_down[i][j] => avg(image[i*factor:(i+1)*factor][j*factor:(j+1)*factor], axis=(0,1))
    scaled_down

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

Прописываю больному недельку программирования на всяких numba’х да cupy’ях и все пройдет.

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

Предлагаю добавить тег «хочется ненужного». :)
Но мне кажется, что для большей части пунктов подходит Nim, если стать гуру в его макросах.

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

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

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

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

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

Меняется как минимум подход к импорту.

Я предполагаю возможность импорта не только extern функций, но и импорта реализации.

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

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

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

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

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

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

Думаю решаемо, но что бы нормально ответить, нужно видеть что у тебя получилось.

Метапрог планировался как zoom-приложение, пока что он не такой, но все равно, есть диаграммы (функции), в них другие диаграммы которые можно открыть. Я например видел такое заблуждение, что в метапроге будет паутина от глобальных переменных, но не обязательно проводить все от одного объекта, можно в нужных диаграммах вставлять блоки которые будут представителями глобальной переменной, так же не нужно определять диаграммы на верхнем уровне и все вести от них, проще же сделать возможность вставлять блоки которые указывают на один объект в разных местах.

Часто есть момент, когда данные протекают через какую то функцию, например есть две функции: a(x, y) -> x2, b(x2, y) -> c; Можно провести от переменной Y две линии, к A и к B, а можно ввести возможность проводить Y сквозь A, как если бы она была a(x, y) -> (x2, y)

То что я описал выше полезно для циклов, не нужно делать переменную за телом цилка, и использовать ее внутри, можно сделать что бы блок «начала цикла» излучал переменные, которые в него поступают в начале, а блок «конца цикла» опционально принимал измененные значения для установки + опциональный break:bool.

Если говорить не о метапроге, то можно избавится от проводки линий вручную вообще, если сделать язык стековым, линии будут лишь отображать как текут данные, и это уберет проблему форта, когда людям становится непонятно как значения передаются по стеку, а редактирование останется более привычным, стрелки, backspace, enter для перехода к следующему объекту.

MOPKOBKA ★★★★★
()
Последнее исправление: MOPKOBKA (всего исправлений: 3)
Ответ на: комментарий от unDEFER

Вот например диаграмма факториала на метапроге с использованием цикла.

https://postlmg.cc/bGLZYWQq

Аналог на С:

long fac(long n) {
  long value = 1;
  for (long i = 0; i < n; i++) {
    value = (i+1) * value; 
  }
  return value;
}

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

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

Вот даже страшно представить во что это превратиться для более-менее сложной программы. Читается оно очень тяжело..

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

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

Вот даже страшно представить во что это превратиться для более-менее сложной программы.

+1 !

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

Вот даже страшно представить во что это превратиться для более-менее сложной программы. Читается оно очень тяжело..

Хм. А мне наоборот кажется что намного лучше чем C вариант, элементов сильно меньше, возможно это потому что ты уже привык читать С код, а у меня есть опыт программирования на метапроге, а может и не из за этого.

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

намного лучше чем C вариант, элементов сильно меньше

ЯП считается завершённым когда на нём написаны факториал, числа фибоначчи и «99 bottles of beer»; если претендует на универсальность то ещё «Conway Life»; НОВЫЙ ЯЗЫК ГОТОВ В ПРОДАКШЕН

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

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

MOPKOBKA ★★★★★
()

Изучаю LLVM IR (ассемблер LLVM). Крутая там система типов!

И почему в языки программирования более высокого уровня такую не берут?

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

Хм.. А это проще? Мне сходу показалось они попытались повысить уровень этого промежуточного представления и это как-то всё слишком усложнило…

unDEFER ★★★★★
() автор топика

Помимо этого хотелось бы таких свойств языка:

Вы ходите «вокруг и около», а пункт то прибытия называется «Метаданные».

Forum0888
()
Последнее исправление: Forum0888 (всего исправлений: 2)
Ответ на: комментарий от dataman

Да, страничку пользователей MLIR я видел..

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

Не понимаю о чём вы.

Использование метаданных позволяет избавиться от #include, template, сериализации, ... (это иной подход к разработке проектов.)

Неплохой пример (и не более) использования метаданных - 1С.

Forum0888
()
Последнее исправление: Forum0888 (всего исправлений: 1)

Имя переменной = её тип. Т.е. если есть переменная image, то это однозначно некоторая структура описывающая изображение, а не скажем имя файла с картинкой.

Красота! Есть у тебя переменная, скажем, image_1 типа image, а потом ты подключаешь библиотеку в которой есть тип image_1 и всё пропало (это даже не UB, это какая-то Монте-Карло компиляция). Идея привязывать логику к идентификаторам может прийти в голову только в бреду. Это я молчу про clean code, ну а хуль там, давайте давать имена переменным a1, a2, aN - никогда же такого не было в истории программирования.

Т.е. например вызов scaled_down_image(image) означает что на вход функции подаётся изображение, а на выходе мы получаем уменьшенное изображение в переменной scaled_down_image (если нет присваивания)

ЯННП, а если надо несколько раз функцию вызвать, а если функция рекурсивная, а если она void - как это всё работать должно? A ссылки на функции мы будем хранить? А как назвать переменную типа функция?

Язык является полностью шаблонным и все типы уточняются в отдельном месте программы

Вот тут хотелось бы поподробнее, что это за место такое?

Компилятор сам решает передать структуру по значению или по указателю.

Это как? Я же должен знать на этапе проектирования будут ли у меня сайд-эффекты на переменной или нет

Автоматическая сериализация данных.

будем пароли утекать через сериализацию? Где-то это уже было

Явное указание в заголовке функции на используемые системные вызовы.

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

FishHook
()

Как насчёт такого ЯП?

Вы хотите разработать ЯП, который упрощает разработку обобщенных алгоритмов?

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

Красота! Есть у тебя переменная, скажем, image_1 типа image, а потом ты подключаешь библиотеку в которой есть тип image_1 и всё пропало (это даже не UB, это какая-то Монте-Карло компиляция). Идея привязывать логику к идентификаторам может прийти в голову только в бреду. Это я молчу про clean code, ну а хуль там, давайте давать имена переменным a1, a2, aN - никогда же такого не было в истории программирования.

Для этого есть пространства имён.

ЯННП, а если надо несколько раз функцию вызвать, а если функция рекурсивная, а если она void - как это всё работать должно? A ссылки на функции мы будем хранить? А как назвать переменную типа функция?

Всё решаемо, но в данном топике я более подробно описывать не буду. Как реализую, напишу что получилось.

Вот тут хотелось бы поподробнее, что это за место такое?

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

Это как? Я же должен знать на этапе проектирования будут ли у меня сайд-эффекты на переменной или нет

Тут я не понял, что вы имеете в виду.

будем пароли утекать через сериализацию? Где-то это уже было

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

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

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

unDEFER ★★★★★
() автор топика
Закрыто добавление комментариев для недавно зарегистрированных пользователей (со score < 50)