LINUX.ORG.RU

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

 , , ,


7

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

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

Владимир

Пришлось переводить программу на Delphi 7 в 1С /исходников не было/.
Так вот в resource exe было сотни две dfm /Delphi не использую/.

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

А, ну в экзешник-то они, конечно, попадают в скомпилированном виде (и оно, да, скорее всего, осталось в историческом формате).

Я про исходное представление говорил. Которое обычно в VCS кладётся.

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

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

А ты задумывался, что версионирование распространяется не только на код программы, но зачастую и те же конфиги и настройки?

Вместо файлов конфигов у тебя тоже картинки будут?

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

В Метапроге графическое представление структур данных выглядит так:

https://postimg.cc/QFYsN9D1

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

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

Владимир

А на LabVIEW?
Или в MetaProg будет свой графический дизайн?

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

Владимир

Добавилась поддержка новых типов данных.

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

Владимир

Меню должно выглядеть как меню, а не набор ромбиков, ...

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

Заметьте: никаких int i и прочего бреда. Соединил блоки - и работает, черт побери!

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

Владимир

Немножко помолчу, а то не прилично много моих комментов ...

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

Владимир

Sorry.
А как выглядит сгенерированный код на C?

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

Лабвью этого не умеет, компилит сразу бинарники через LLVM, насколько я читал. Есть платный модуль Labview C generator, но во-первых он платный и даже пиратку достать нереально, во-вторых - все равно низкоуровщину и вызов сишных функций там вряд ли реализуешь.

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

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

Слишком неудобно сделано в лавбвью, проще и быстрее набрать будет.

#perl
sub fac($n) { $n ?? $n*fac($n-1) !! 1 }
// c
int fac(int n) { 
         return n ? n*fac(n-1) : 1 
}

VarfolomeyKote4ka ()

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

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

Владимир

То были абстрактные примеры, а здесь реальные алгоритмы.
Если код еще не генерируется, то вручную его наберите.

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

Черт, это ж знать-то надо как его набирать. В выражении «n ? n*fac(n-1) : 1» что означает "?" и ":"? Про перл я вообще молчу, взрыв мозга.

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

Лучше автоматом сгенерирую, когда освою циклы и условное ветвление.

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

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

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

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

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

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

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

Владимир

В поисковой строке google вводите «labview c generator download» и можно скачать trial.

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

Ну так и в схемах лавбью разбираться надо, а перл выучил за недельку (многое) и пиши компактный код

Выучить при желании можно хоть китайский, но что-то сложнее хеллоуворлда в текстовых языках мне дается очень тяжело. Лабвью сделало меня программистом:)

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

Владимир

Самый компактный язык был у Эллочки - 30 слов!

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

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

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

Владимир

А как «Война и Мир» представить графически?

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

Войну и мир? Просчитать биохимические реакции в организмах персонажей, если там была любовь и другие чувства, теоретически возможно. Сам не читал, не знаю.

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

Владимир

В некоторых случаях графика приемлема, в других речь.
Категоричность - вредна.

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

Метапрог - это школьная театральная постановка в сельском театре на тему программирования. И не надо Линуса сюда приплетать. Он точно не тупой и не ленивый.

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

Вставить видео как блок)) Вообще это надо мысленно передавать, но технологии пока еще не дошли.

VarfolomeyKote4ka ()

tl;dr

Посмотрел на примеры графического программирования, посмотрел на те же примеры в C...и C мне показался понятнее, программировать практически не умею если что.

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

Получилось. Может серьезно облегчить работу над метапрогом!

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

Владимир

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

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

Владимир

Шутка.

Товарищи учёные, доценты с кандидатами!
Замучились вы с иксами, запутались в нулях,
Сидите там, разлагаете молекулы на атомы,
Забыв, что разлагается картофель на полях.

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

Ну так можно сделать один единственный блок «код на c», в концепцию кубиков укладывается.

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

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

С лямбда-исчислением? Без понятия. Разжуйте в двух словах это понятие из царства сверической науки в вакууме.

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

Картофель на полях — это еще нормально. Это о хлебе насущном, а вот metaprog — это попытка очередной революции («мы наш мы новый мир построим») или построения вавилона от студента-недоучки или просто невежды. Ничем хорошим не заканчивается.

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

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

Сходи уже на базовый курс по информатике.

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

Владимир

Преамбула.
«Так как меня бандерлоги называли ...?»

Эпилог.
Так как код выше приведенных алгоритмов в LabVIEW выглядит в C?

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

Нереально запутанно. Испугаешься. Сам пытаюсь разобраться. Может на днях что-нибудь да скину. Но в Метапроге код генерируется куда поятнее.

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

Владимир

Народ желает видеть истинное лицо LabVIEW.

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

Владимир

Настаивать не буду ... /чтоб кошмаров не было/.
Правильно понял?

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

«Зачем?» не тебе, а на совет пойти на курсы информатики.

Впадайте в трепет, простые смертные. Вот оно, истинное лицо LabVIEW (схема с факториалом):

#define LV_MAIN
#include "LVCGenIncludes.h"
#include "A__________Lib.h"
#if CGEN_VERSION != 13000
#error CGenerator version mismatch
#endif
/* VI heap data */
struct _A___________heap { 
	int32 l_Multiply_x_y_SR;
	int32 l______;
	int32 l_______1;
	int32 l_For_Loop_N;
	int32 l_Multiply_x_y_SR_1;
	int32 l_For_Loop_i_1;
	int32 l_Increment_x_1;
	int32 l_Multiply_x_y;
	int32 l_______SR;
} _DATA_SECTION __A___________heap; /* heap */

static struct _A___________heap _DATA_SECTION *heap = &__A___________heap; /* heap */



/****** Clean Up Uninitialized Left Shift Registers before program exits to prevent memory leaks **********/


void _TEXT_SECTION A___________CleanupLSRs(void);
void _TEXT_SECTION A___________CleanupLSRs(void) {
}


/****** Add Sub VI Instance Data to global list **********/


void _TEXT_SECTION A___________AddSubVIInstanceData(void);
void _TEXT_SECTION A___________AddSubVIInstanceData(void) {
}


/****** Allocate VI Constants  **********/


void _TEXT_SECTION A___________AddVIGlobalConstants(void);
void _TEXT_SECTION A___________AddVIGlobalConstants(void) {
}


/****** VI Constant Initialization function **********/


void _TEXT_SECTION A___________InitVIConstantList(void);
void _TEXT_SECTION A___________InitVIConstantList(void) {
}


/****** Block diagram code **********/


int32 A___________in_0_A_______62 = 0 ;
static DataType dtA___________in_0_A_______62 = int32DataType;
int32 A___________out_0_A___________132_init_ = 0 ;
static int32* A___________out_0_A___________132 = &A___________out_0_A___________132_init_;
static DataType dtA___________out_0_A___________132 = int32DataType;
extern eRunStatus A___________Run(	)
{
	Boolean bRunToFinish = true;
	int32 nReady = 1;
	A___________InitVIConstantList();
	{
		heap->l______ = 1;
		heap->l_______1 = A___________in_0_A_______62;
		heap->l_Multiply_x_y_SR_1 = 1;
		for (heap->l_For_Loop_i_1 = 0;(heap->l_For_Loop_i_1 < heap->l_______1) && !gAppStop && !gLastError; (heap->l_For_Loop_i_1)++) {
			{
				heap->l_______SR = heap->l_Multiply_x_y_SR_1;
				/**/
				/* Increment */
				/**/
				heap->l_Increment_x_1 = (int32)(heap->l_For_Loop_i_1 + 1);
				/**/
				/* Multiply */
				/**/
				heap->l_Multiply_x_y =  (heap->l_______SR * heap->l_Increment_x_1);
				heap->l_Multiply_x_y_SR_1 = heap->l_Multiply_x_y;
			}
		} /* end for */
		heap->l_Multiply_x_y_SR = heap->l_Multiply_x_y_SR_1;
		*A___________out_0_A___________132 = heap->l_Multiply_x_y_SR;
		return eFinished;
	}
}
/****** Main Entry Point for VI **********/

TextPtr A___________VIName = "\364\340\352\362\356\360\263\340\353.vi";

eRunStatus A___________Start(subVIInstanceDataPtr viInstanceData, Boolean bShowFrontPanel, Boolean bRunToFinish, ArgList* argsIn, ArgList* argsOut, Boolean *pause);
eRunStatus A___________Start(subVIInstanceDataPtr viInstanceData, Boolean bShowFrontPanel, Boolean bRunToFinish, ArgList* argsIn, ArgList* argsOut, Boolean *pause){
	A___________AddSubVIInstanceData();
	return A___________Run();
}


/****** Library interface **********/


void fac()
{
	int32 i;
	LVCGenRTInit();

	/* Init globals */
	for (i=0;i<sizeof(globTable)/sizeof(InitFPTermsFunc);i++) {
		(*(globTable[i]))(NULL, false);
	}

	/* Init VI Constants */
	for (i=0;i<sizeof(globConstInitTable)/sizeof(VoidFn);i++) {
		(*(globConstInitTable[i]))();
	}

	A___________AddSubVIInstanceData();
	A___________InitVIConstantList();

	/* Call top level VI main function */
	A___________Run();

	/* Cleanup VI Constants */
	for (i=0;i<sizeof(globConstCleanupTable)/sizeof(VoidFn);i++) {
		(*(globConstCleanupTable[i]))();
	}

	/* Cleanup globals */
	for (i=0;i<sizeof(globCleanupTable)/sizeof(VoidFn);i++) {
		(*(globCleanupTable[i]))(false);
	}

	for (i=0;i<sizeof(lsrCleanupTable)/sizeof(VoidFn);i++) {
		(*(lsrCleanupTable[i]))();
	}

	LVCGenRTEnd();
	return;
}



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