LINUX.ORG.RU

Metaprog: универсальная графическая среда программирования [в разработке]

 , , ,


10

7

Почему, несмотря на обилие «чудесных» ООП-языков, Си, разработанный в 1973 году, до сих пор не умер? Потому что не выхдящие за рамки текстового программирования попытки «улучшить» или заменить Си давали и дают проблем больше, чем решали.

Какой из ныне существующих языков программирования позволяет программировать мышкой, а не клавиатурой? На чем можно программировать графически, а не в тексте? Пока что это позволяет на приличном уровне только пропиетарное LabVIEW. Трудно поверить, но это единственная полностью графическая среда программирования серьезного уровня в 2019 году! Но даже в LabVIEW есть куча недостатков (которые невозможно самостоятельно устранить из-за пропиетарности).

Графическое программирование намного проще и понятнее. Если в качестве бэкенда брать Си и манипулировать функциями из сишной стандартной библиотеки, это не будет создавать никаких лишних абстракций, зато серьезно упростит жизнь программистам и особенно людям, имеющим дело с чужим кодом. Код любого уровня и любой сложности, представленный в виде графических блоков, станет открытым не только для узких специалистов, но и вообще любому продвинутому пользователю. Простота программирования и эффективность, не меньшая, чем у Си, убьет C++, Python, Java, Javascript и прочую ерунду с раздутыми и полными багов абстракциями (которые Линус не раз крыл матом).

Я уже делаю некое подобие LabVIEW на самом LabVIEW, назовем его Metaprog. Так же, как в 1991 Линус Торвальдс делал линукс, пользуясь пропиетарным Minix. И так же жаловался на кучу недостатков в Minix, желая устранить их в своей системе.

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

Примеры

Примеры с кодом на Си генерируются автоматически. Они тут же скармливаются компилятору и не предназначены для чтения эстетами, не любящими «абракадабру». Здесь они приведены лишь как пример работы транслятора и для возможности самостоятельно скомпилировать графические диаграммы со скринов. Так сказать, приобщиться к прекрасному.

Самое простое - Hello World. Скомпилируйте (gcc -o ./test ./code.c).

https://i.postimg.cc/YCywWbSh/fwrite.png

#include <stdio.h>

int main(){
char metaprog_array_pointer_10156130170823954432[] = {72,101,108,108,111,32,87,111,114,108,100};
unsigned long int metaprog_variable_13830126042312755200 = 1;
unsigned long int metaprog_array_size_10156130170823954432 = 11;
fwrite(metaprog_array_pointer_10156130170823954432,metaprog_variable_13830126042312755200,metaprog_array_size_10156130170823954432,stdout);

}

Я подписываю терминалы на украинском (сам оттуда), с таким же успехом их можно подписывать на русском, а не только на английском. Можно будет перевести все, кроме, разве что, вызываемых сишных функций, а gcc этого и не заметит (посмотрите код). При работе международной командой можно к каждой подписи/надписи прилагать словарь с нужными языками. Игры ж локализируют, чем визуальное программирование хуже?

Массив декларируется не как строка в кавычках, а как последовательность байтов, а байт - это цифра. Строки редактируются отдельным редактором (пока что средствами LabVIEW, но это временно). Больше никаких проблем и глюков с управляющими символами, кавычками итп (очень серьезная проблема при программировании на Си, Shell scripting и вообще всех текстовых языках).

Константа-массив имеет отдельные терминалы для указателя на массив и длины массива (известной редактору кода). Если терминал длины подключен - декларируется отдельная переменная. Не подключен - незачем и декларировать.

Пример посложнее: запись и в stdout, и в файл ./fwrite-test.txt

https://i.postimg.cc/v8KvKKmQ/fwrite2.png

#include <stdio.h>

int main(){
char metaprog_array_pointer_10156130170823954432[] = {72,101,108,108,111,32,87,111,114,108,100};
unsigned long int metaprog_variable_13830126042312755200 = 1;
unsigned long int metaprog_array_size_10156130170823954432 = 11;
fwrite(metaprog_array_pointer_10156130170823954432,metaprog_variable_13830126042312755200,metaprog_array_size_10156130170823954432,stdout);
char metaprog_array_pointer_12385851444566411264[] = {46,47,102,119,114,105,116,101,45,116,101,115,116,46,116,120,116,0};
char metaprog_array_pointer_16510743873862514688[] = {119,43,0};
fwrite(metaprog_array_pointer_10156130170823954432,metaprog_variable_13830126042312755200,metaprog_array_size_10156130170823954432,fopen(metaprog_array_pointer_12385851444566411264,metaprog_array_pointer_16510743873862514688));

}

В данном примере используется функция fwrite, а не printf. То есть, символ «0» не влияет на запись массива в файл или stdout. Сколько символов писать функция и так знает из длины массива.

Заявки

Принимаю заявки на новые фичи. Пишите в комментариях. Уже приняты заявки:

1. Пример с простым HTTP-сервером.

2. Пример с сортировкой Хоара (quicksort).

3. Простой в пользовании функционал работы со строками (больная тема для Си и С++).

4. Полностью графический функционал работы с регулярными выражениями, без вовлечения PCRE.

Сейчас нужно научить Metaprog «компилировать» блок-схемы прямо в Си и скармливать этот код gcc, получая бинарники. После чего перенести сам Metaprog на Си, чтоб перестать нуждаться в пропиетарном LabVIEW и выложить результаты в опенсорс. И получить за это донат, хотя желательно уже сейчас (для ускорения работы). Bitcoin:1AYoK2TScSpD5bhf67mv9AxHDJ2RidRvjD



Последнее исправление: CYB3R (всего исправлений: 9)
Ответ на: комментарий от metaprog

Это _пока_ для Вас сферическая наука. Рано или поздно Вам придется с этим столкнуться. В двух словах: это представление вычислений виде функций, которые могут принимать на вход функции, применять функции и возвращать другие функции. Само по себе, оно может быть и выглядит как теоретическая модель, однако ее реализация (поддержка функционального программирования) в том или ином виде присутствует во многих языках и позволяет упрощать многие конструкции, предлагая удобные абстракции.

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

Теперь понятнее. Это как в Си указатель на функцию? В Лабвью возможно через VI reference, Invoke node, Property node. Вызывать функции, задавая им параметры.

В Метапроге указатели на функции бут, сейчас как раз работаю над ними.

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

лямбда-исчислением

Нинужно. Но реализовать можно будет.

Ну, в принципе, да. С-шники как-то обходятся же.

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

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

А чому? Так проще и работать будет быстрее.

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

Это как в Си указатель на функцию?

Нет, в Си нет аналога.

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

Допустим, что ваша функция сравнения, помимо пары зависит еще от некоторых параметров, например my_cmp(a, b, order_by, reverse) которые становятся известны только в процессе других вычислений, которые вам надо как-то этой функции передать до того, как отдать ее qsort.

В идиоматике функционального подхода вы просто «на лету» создаете lambda-функцию с двумя параметрами, которая вызывает ваш «обобщенный» my_cmp с известными order_by и reverse:

my_sort(array, order_by, reverse): qsort(array, array.size, array.elemsize, lambda x,y: my_cmp(x, y, order_by, reverse))

где конструкция lambda <params>: <body> — конструирует нужную функцию. В этом случае, qsort принимает на вход уже замыкание (функцию, которая в своем определении содержит состояние создавшей ее ф-ии).

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

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

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

С расширениями GNU реализовать можно.

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

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

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

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

Подтверждаю это и с точки зрения практики. Ни Event-структур, ни рекурсивных функций, ни даже чтения из бинарного файла оно не поддерживает!!! Зато денег требует (если вы честный законопослушный пользователь, а не пират).

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

Понапридумывают сферические теоретики в вакууме всякой чуши, а потом парси ее да дебажь. Те же расширения GNU усложняют Си, а это плохо.

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

Без расширений С ядро не скомпилируется.) Они упрощают имхо.

Понапридумывают сферические теоретики в вакууме всякой чуши

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

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

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

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

Да указатели и указатели, чем они отличаются от других?) Хранят адрес функции, по ним можно вызвать эту функцию...

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

Не больше чем функции и данные. Или нет?

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

my_sort(array, order_by, reverse): qsort(array, array.size, array.elemsize, lambda x,y: my_cmp(x, y, order_by, reverse))

Это что, эсперанто от программирования?

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

Дорогу, конечно, только идущий осилит. Но если Вы уже на данном этапе, замахнувшись на язык общего назначения, не изучили (и не желаете) существующие подходы, говоря патентным языком, state of art, скорее всего, результаты Вашего труда также будут преданы забвению (и оплеванию). Будет очередная игрушка, которой Вы поиграетесь и бросите. Дай Бог, чтобы запала энтузиазма хватило, чтобы Вы при столкновениями с трудностями начали обращаться к опыту поколений или хотя бы уважительно к нему относиться.

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

С замыканиями:

int main(void) {
	Window *win = NewWin("Example");
	Button *btn = NewBtn(win, "Click Me!");
	int i = input_from_console();
	
	connect_signal(btn, void () {
		printf("Hello World! Input = %d\n", i);
	});
	return 0;
}

и без

void signal_fn(Window *win, Button *btn, void *data) {
	printf("Hello World! Input = %d\n", *data);
}

int main(void) {
	Window *win = NewWin("Example");
	Button *btn = NewBtn(win, "Click Me!");
	int i = input_from_console();
	
	connect_signal(btn, signal_fn, &i);
	return 0;
}

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

Ваще разные вещи. Посмотри, в первом примере я передал переменную «i» без аргументов сразу в функцию для сигнала, а во втором мне пришлось это делать через аргумент. То есть «i» попал сразу в функцию в первом примере... Удобно, а вот во втором случае не очень, а если еще и аргументов много? Придется заводить структуру для них.

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

Второй пример понятнее, в метапроге уже реализуемый (если в include будут нужные функции).

А что плохого в том. что много аргументов? Да будь их хоть сто или даже тысяча - что такого? У меня в лабвью встречаются функции с больше 10 аргументов, а 6 аргументов - так вообще норма.

С чего вообще повелось, что количество связей надо уменьшать? Что плохого в большом количестве связей?

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

П. С.: пока не реалезуемый, бо не докрутил указатели на функцию, но будет.

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

Добавляем еще переменную, и смотрим как меняются программы... И так, первый пример с замыканиями...

int main(void) {
	Window *win = NewWin("Example");
	Button *btn = NewBtn(win, "Click Me!");
	int i = input_from_console();
	int b = input_from_console();
	
	connect_signal(btn, void () {
		printf("Hello World! Input = %d, %b\n", i, b);
	});
	return 0;
}
И второй, единственный реализуемый на С.
struct args_for_signal_fn {
	int a;
	int b;
};

void signal_fn(Window *win, Button *btn, void *data) {
	struct args_for_signal_fn *dat = data;
	printf("Hello World! Input = %d, %d\n", dat->a, dat->b);
}

int main(void) {
	Window *win = NewWin("Example");
	Button *btn = NewBtn(win, "Click Me!");
	int i = input_from_console();
	int b = input_from_console();
	
	struct args_for_signal_fn args;
	args.a = i;
	args.b = b;
	
	connect_signal(btn, signal_fn, &args);
	return 0;
}

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

Для меня довольно обычно передавать по 10 аргументов через 10 слоев вызова функций только потому что функции снизу «просят». Лабвью мне наглядно показывает какая функция какой тип аргумента просит, чего не хватает. Я делаю - и все работает!

Как бы ты замыкания в графике делал?

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

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

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

Кстати, в Лабвью у функций может быть не один, а много выходов. В метапроге тоже так будет возможно (крому вызываемых сишных функций).

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

Мне спокойнее когда все видно явно.

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

Когда никаких подводных камней нигде нет.

А их и не может возникнуть.

Deleted
()

Holy crap! What the Hell is that? O_o

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

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

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

Программировать на нем получается медленнее чем на С для меня, тем он мне и не понравился.

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

Посмотрим что будет с Метапрогом. Участвовать в проекте будешь? Хотя что уж там - ты уже фактически участвуешь...

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