LINUX.ORG.RU

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

 , ,


6

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

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

Владимир

Трудно оценить ...
А результат то правильный дает?

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

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

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

Не компилится даже. Куски кода еще попробую где-нить приткнуть.

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

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

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

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

Владимир

Думал вам действительно «labview c generator» поможет ...

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

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

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

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

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

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

Владимир

Первое впечатление от «labview c generator» - «Выкрасить и выбросить».

anonymous ()
Ответ на: комментарий от 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 ()
Ответ на: комментарий от VarfolomeyKote4ka

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Какая от них польза в алгоритмах? Показал бы теоретик пример на Лабвью - стало бы понятнее.

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

Вообще-то указатели на функции и на данные в Си не взаимозаменяемые.

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;
}

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

Замыканий в С нету, поэтому так сделать не получиться как в первом примере...

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

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

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

Второй пример понятнее, в метапроге уже реализуемый (если в 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;
}

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

Бэд. Хоть в 10 раз больше и что? Видел мои скрины с лабвью?

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Можешь в графике нарисовать эскиз диаграммы с замыканиями?

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

При желании можно купить (или спиратить) лабвью, пока Метапрог не готов:)

metaprog ()

Holy crap! What the Hell is that? O_o

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

Какое видео? На лабвью тоже можно программировать по-разному. Мало кто его насилует так как я:)

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

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

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

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

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

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

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