Comments 255
var i32 x=0;
или
i32 x=0;
var i32 x= 0, y= 1, z= 2;
В вашем примере потребовалось бы для каждой переменной указывать тип, ну или не указывать и выводить тип из инициализатора, но тогда пострадает читаемость.
Ключевое слово необходимо для упрощения синтаксического разбора.
Одна из самых больших ошибок при разработке ПО, когда делают упущения ради простоты реализации. Как мне кажется, новый ЯП должен не только покрывать недостающий в других ЯП функционал, но и упрощать синтаксис, уменьшать уровень входа для разработчиков.
Я бы пошел по пути groovy / dart / etc, сделав указание типа опциональным и добавив автовыведение типов, т.е.
int[] num1 = [ 123 ];
var num2 = [ 123, 456 ]; // int[]
Названия типов я бы взял из java, да кому-то нравятся сокращения, но неужели f64 более понятен, чем double?
Для часто используемых конструкций добавил бы литералы – массивы/коллекции [], множества {}, хэш-таблицы {:},
Из новых операторов я бы добавил null-safe оператор obj?.attr, может быть cascade оператор… как в dart'е, elvis-оператор ?:.
Систему типов взял бы из java – все методы виртуальные, т.к. в большинстве случаев это и ожидается в ООП, а для статичных методов, пожалуйста, static. Так же добавил бы в систему типов trait'ы.
На уровне класса оперировал понятиями свойств (как c#, groovy, dart) – доступ к значению поля через автогенерируемые getter / setter, но с возможностью переопределить эти методы.
Возможно, стоило бы добавить функции как объекты первого порядка. Возможно использовать понятие замыканий и указывать замыкаемые перемненые через use(..) как в php.
Для синхронизации потоков стоит или на уровне ЯП определить конструкции типа synchronized блоков / volatile, либо добавить в sdk семафоры / мютексы / атомики, которые бы обеспечивали корректную модель памяти.
В конечном счете, чем больше ЯП вы проанализируете, тем более точное представление о проблемах получите. В текущем виде ваш ЯП больше поход на среднее между rust/c++, думаю, вы не этого изначально добивались.
упущения ради простоты реализацииДанное упрощение ещё и читаемость кода упрощает, глаз сразу видит, где объявление переменной, а где что-то другое.
добавил бы литералыМожно, но это пока не в приоритете.
null-safe операторЕсть встроенный макрос if_var(){}, который достаёт из опционального значения объект, если он там есть, и выполняет содержимое блока для него. Возможно, это не так изящно, но суть примерно та-же.
Систему типов взял бы из java – все методы виртуальныеВсе фунцкии виртуальнуе — это ущерб производительности, это противоречит заявленным целям.
ля синхронизации потоков стоит или на уровне ЯП определить конструкциив язык такое, без должной необходимости, лучше не тащить. Но вот в стандартной библиотеке такое можно.
Одна из самых больших ошибок при разработке ПО, когда делают упущения ради простоты реализации.
Следствием этого обычно являются хорошие сообщения об ошибке, а не "вы пропустили точку с запятой" когда на самом деле закрывающая скобка не там.
Я бы пошел по пути groovy / dart / etc, сделав указание типа опциональным и добавив автовыведение типов, т.е.
Опять неоднозначная грамматика, на месте типа может быть как тип, так и ключевое слово var
. Глазу парсить опять же труднее.
Названия типов я бы взял из java, да кому-то нравятся сокращения, но неужели f64 более понятен, чем double?
Конечно. Или вот в расте сделали тип i128, какое для него будет очевидное название? i32 — это int, long или DWORD?
Для часто используемых конструкций добавил бы литералы – массивы/коллекции [], множества {}, хэш-таблицы {:},
В том же расте сейчас хэшмапу меняют на мапу из сторонней библиотеки, потому что она перфоманснее. Хардкодинг конкретных типов в язык не позволит легко делать такие изменения.
Хотел продолжить разбор комментария, но обратил внимание на некоторые высказывания
Названия типов я бы взял из java
Систему типов взял бы из java
Для синхронизации потоков стоит или на уровне ЯП определить конструкции типа synchronized блоков
Вы в свою очередь предлагаете сделать еще одну джаву.
Вы в свою очередь предлагаете сделать еще одну джаву
Причем а том числе в местах, где в Java очевидно плохо (например virtual по умолчанию)
Бывают даже protected методы, по своей природе не предназначенные для перекрытия. А уж среди public методов таких большинство. Но из-за того, что такие методы виртуальные, у программиста, пишущего наследника, имеется возможность ошибочно их перекрыть и получить конструкцию, неработоспособную в edge cases, но на первый взгляд вполне корректную.
Вы в свою очередь предлагаете сделать еще одну джаву.
В своем комментарии я приводил примеры из java, groovy, dart, php, c#, js, но вы увидели только первое.
Скажите, какой цели вы добивались, создавая пост: получить замечания и критику, указания на недочеты и неудобство? или чтобы потешить свое самолюбие, глядите какой я молодец, сделал еще один c/rust?
Вы немного промахнулись веткой :)
Ваш ответ частично корректен, но я все же считаю, что указанные пункты "как в джаве" это скорее плохо, чем хорошо.
Например, rust очень даже ничего так справляется
fn Foo( i32 x ) : i32
{
if( x < 10 ) { return 0; }
else if( x > 100 ) { return 1; }
// Ошибка, функция не всегда возвращает значение
}
P.S. Моё знакомство с Rust ограничено 8 часов работы с tutorial. Но и после этого совершенно непонятно зачем нужен Ü при живом Rust
При работе с WinAPI, файлами, сетью можно (отчасти) обойтись ссылками. Там где обойтись ссылками будет нельзя, придётся писать свои биндинги.
Вообще, взаимодействие с кодом на других языках это отдельная тема, которую я раскрою позже.
это логотип языка?
MONSIEUR JOURDAIN: U, u. Il n'y a rien de plus véritable: u.
MAÎTRE DE PHILOSOPHIE: Vos deux lèvres s'allongent comme si vous faisiez la moue: d'où vient que si vous la voulez faire à quelqu'un, et vous moquer de lui, vous ne sauriez lui dire que: u.
(«У» в русском переводе не совсем точно передаёт гримасу:
Учитель философии. Чтобы произнести звук У, нужно приблизить верхние зубы к нижним, не стискивая их, однако ж, а губы вытянуть и тоже сблизить, но так, чтобы они не были плотно)
сжаты: У.
Г-н Журден. У, У. Совершенно справедливо! У.
Учитель философии. Ваши губы при этом вытягиваются, как будто вы гримасничаете. Вот почему, если вы пожелаете в насмешку над кем-либо состроить рожу, вам стоит только сказать: У.
Видео как произносить название языка: Kung Pow — Wii-U
Под ваши нужды могли бы подойти: Crystal, Nim, Zig. Они, конечно, не такие популярные, как Си \ Rust \ Go, но все же живые, и человекочасов в них вложено на порядок больше, чем вы в одиночку сможете вложить в свой проект. Поэтому ваша аргументация с недостатками существующих языков неубедительна — скажите честно, что одолела жажда велосипедостроения. Это нормально :)
На счёт перечисленных вами языков: о Nim я немного читал, обнаружил в нём сборщик мусора. Это противоречит моим представлениям об идеальном языке. С Crystal и Zig не знаком, обращу на них внимание.
Подробности тут:
forum.nim-lang.org/t/3801
Немного холивара по поводу исключений. То, что вы называете "проблемами", на самом деле является сутью самого подхода.
Потенциальная возможность возникновения исключения в каждой строчке программы.Это нормально. К счастью, вам не нужно ловить исключение на каждой же строчке.
Из-за этого сложнее сохранять консистентность данныхПруфы, пожалуйста. Не забываем, что программа без исключений также может упасть в любой момент по собственной вине (
halt
), по вине операционки или просто выключения питания.Нарушение уровней абстракции.Никакого нарушения тут нет. Наоборот, исключения можно обрабатывать на том уровне, где это осмысленно, не замусоривая остальной код рутинными проверками с возвратом.
Неоднозначность трактовки понятия исключения.Это глобальная проблема семантики и наличие
Result
вместо исключений ее не решает — например, можно вернуть Some(null)
.Проблема обработки исключения при обработке исключения.Это следствие из первого пункта. В крайне редком случае, когда возникло исключение при обработке исключения и его никто не поймал выше, будет ровно то же, что у вас происходит в любой ситуации с
halt
.вам не нужно ловить исключение на каждой же строчке.Не нужно ловить там, где после каждой строчки состояние будет валидным. Если же переход из валидного состояния A в валидное состояние B требует выполнения операций i, j, k, и во время выполнения операции j возникло исключение, то возникнет невалидное состояние. Чтобы такого не было в среде с исключениями, надо ловить исключения каждой промежуточной операции и откатывать состояние до валидного.
исключения можно обрабатывать на том уровне, где это осмысленноЯ бы даже сказал не просто можно, а нужно. У нужный уровень это тот, на котором происходит вызов. Получается, исключения, которые пролетают несколько уровней стека вызовов, не нужны.
можно вернуть Some(null)Вот именно, «вернуть». На счёт выбора механизма уже нету сомнений. Есть сомнения в типе, но так и с исключениями есть такие сомнения.
Не нужно ловить там, где после каждой строчки состояние будет валидным.Если у вас нет глобального состояния, то после любого исключения будет уничтожен текущий scope (читай — часть стека) и состояние останется валидным. Если глобальное состояние есть (например, внешняя БД) — то в обоих случаях придется писать дополнительную логику (например, отката транзакций). Таким образом, ваш подход с явным возвратом ситуацию никак не улучшает.
У нужный уровень это тот, на котором происходит вызов.Нужный уровень — это тот, на котором есть достаточно данных для принятия решения (сделать retry, залогировать, пробросить выше, показать ошибку и т.д.). На промежуточных уровнях проверки — это лишний boilerplate, из-за которых код распухает и становится менее понятным и поддерживаемым.
будет уничтожен текущий scopeЭто не отменяет изменений в изменяемых переменных. Чтобы отменяло, надо сильно заморочиться.
Нужный уровень — это тот, на котором есть достаточно данных для принятия решенияБольше всего данных для принятия решения по месту возникновения ситуации. Выше по стеку вызовов данных становится всё меньше.
Это не отменяет изменений в изменяемых переменных.Локальное состояние (переменные на стеке) отменится, глобальное внутреннее состояние (глобальные переменные) — признак говнокода, глобальное внешнее состояние (базы, API, прочее) — при исключениях обработать можно, при глобальном halt'е будет «ой».
Выше по стеку вызовов данных становится всё меньше.Окей, элементарный пример: представьте клиент для мессенджера. Пользователь отправляет сообщение, а если оно не отправилось — нужно показать ошибку и предложить попробовать еще раз. Запрос на отправку проходит через три слоя: UI, менеджер сообщений и обертку над API конкретной библиотеки, и падает в самой глубине из-за недоступности сети. На каком из слоев, по-вашему, должна быть логика показа сообщения и выполнения повтора?
Пользователь отправляет сообщение, а если оно не отправилось — нужно показать ошибку и предложить попробовать еще раз.
Не нужно.
Если не отправилось — автоматически повторяем попытки, пока не отправится. У пользователя при этом будет меняться статус сообщения («отправляется» — «падажжи, бяка какая-то» — «отправилось» — «прочитано» — «с той стороны стучат по кнопкам, набирая ответ»).
На каком из слоев, по-вашему, должна быть логика показа сообщения и выполнения повтора?
Показ — в УИ, перепосылка и смена статусов сообщения — в слое менеджера сообщений.
Если же переход из валидного состояния A в валидное состояние B требует выполнения операций i, j, k, и во время выполнения операции j возникло исключение, то возникнет невалидное состояние. Чтобы такого не было в среде с исключениями, надо ловить исключения каждой промежуточной операции и откатывать состояние до валидного.
А как отсутствие исключений решит эту проблему?
Потому что когда вы видите строчку var a = Foo()
вы не знаете, хотел ли автор этого кода прокинуть ошибку наверх или он просто забыл написать try catch. Если у вас раньше была функция, возвращающая результат, а теперь она бросает эксепшн, вы не знаете, какие флоу у вас от этого сломались. Исключения в многопоточной среде тоже привносят свои приколы. Ну и так далее.
Нет, а вот проблему "у нас было изменение состояния в i и j, но потом злобный k бросил исключение, надо теперь обратить i и j" — как решит отсутствие исключений?
Разве отсутствующие исключения не позволят таких ситуаций создавать? Да вроде нет, для этого всего-то надо мутабельное состояние, и в языке оно есть — более того, в языке есть вообще бич любых попыток что-то откатить — переприсваивание значений локальных переменных, переданных по ссылке внутрь j, когда вы уже и не знаете даже, менялось там хоть что-то или нет (мы ведь о чёрных ящиках рассуждаем, раз уж я не могу заглянуть в Foo
, или проследить, какие потоки вызовов ведут ко мне извне).
Если у вас раньше была функция, возвращающая результат, а теперь она бросает эксепшн
Вот прямо вдруг бросает? Хорошо, а если я так же вдруг поменяю тип возвращаемого значения на Either<a, b>
, но в коде не обработан случай с b
(ну, написано там Foo().left
, ну так вот) — это разве такой же проблемы не вызовет?
Нет, а вот проблему "у нас было изменение состояния в i и j, k бросил исключение, надо теперь обратить состояния i и j" — как решит отсутствие исключений?
Я буду видеть, что j всегда завершается успешно, а k завершается с ошибкой. Если вдруг после рефакторинга k станет тоже всегда успешным то весь код-обработчик ошибочной ситуации можно будет обрать.
Разве отсутствующие исключения не позволят таких ситуаций создавать?
Во всех местах мне будет подсказывать компилятор. Любой рефакторинг — и вам либо надо добавить обработку ошибки, либо убрать ту, которая никогда не вызовется, чтобы не замусоривать код. По сути это ровно то же самое, что null vs Option, в одном случае вы всегда знаете, что у вас может быть или не быть значение, а в другом вы в рандомных местах проверяете на null и наедетесь, что не проверяете, где не надо, и проверяете где надо.
Ну и да, мой вопрос остается. Если человек написал var a = Foo()
а функция Foo кидает эксепшн, вы никогда не узнаете, ошибся он и забыл обработчик написать, или надо тут эксепшн обрабатывать. Причем как я уже говорил, сегодня Foo не кидает ошибку, а завтра кидает. А правильно обработать весь коллстек до main без поддержки компилятора не такая уж простая задача. Спросите любого, кто пробовал изменить синхронный метод на асинхронный где-нибудь внизу дерева вызовов.
j всегда завершается успешно
Простите, но это — фантастика в языке с командой "а теперь, детишки, падаем в корку" (i.e. halt
). В конце концов, f может попытаться выделить память, которой ему не дали — и что, будем везде иметь как возвращаемое значение гигатип Result
, одним из вариантов которого будет Result::OOM
? И возвращаемое значение конструктора типа T
канонически запишем как
Either<T, Result::OOM>
?
Если человек написал var a = Foo() а функция Foo кидает эксепшн, вы никогда не узнаете, ошибся он и забыл обработчик написать, или надо тут эксепшн обрабатывать
Мне, на самом деле, не интересно, что думал человек, когда не поймал исключение. Как и то, что он думал, когда поймал что-то, что не следовало. Мне больше интересно, что про это исключение говорит внешний контур его модуля, что вообще за тип исключения у меня на руках, и что об этом всём думает архитектор.
Некоторые такие исключения, кстати, вполне можно показать пользователю, потому что ошибка легальная, и нашими силами не исправляется (максимум, что можно сделать — локализацию сообщения). Некоторые — бессмысленно, так как это банальный баг, и надо просто починить код.
Простите, но это — фантастика в языке с командой "а теперь, детишки, падаем в корку" (i.e. halt)
"Завершается с ошибкой" и "не завершается" это разные вещи, потому что во втором случае обработчик неуспешного завершения писать не нужно, потому что выполнение до него не дойдет.
Я по-прежнему думал, что мы там обсуждаем проблему консистентности данных, старый я дурак, а не синтаксические конструкции, которые заставят разработчика обработать исключительные ситуации (а пустой Option это такое же исключение, только вы ещё и не знаете, почему так произошло, пока код не запустите на точно тех же самых данных). Потому что так-то в языках с исключительными ситуациями тоже можно заставить разработчика обработать ваше исключение — и он иногда даже сделает настоящую обработку, основываясь на данных, которые возможно получить из "формы" объекта исключения. То есть, всё то же самое, что и с различными return-кодами, типа Option, Try, и проч.
Так вот, исходя из проблемы консистентности данных любая форма такого Halt это куда хуже так нелюбимых нынче исключений.
Я говорил исключительно про то, что процитировал. Если f попытается выделить память, а при нехватке будет вызываться halt, то Result::OOM возвращать и обрабатывать не надо.
Я думаю, многие программы всё же вполне могут обработать OOM собственными силами, (хоть и не на уровне условного f
, можно ведь и какой-нибудь LRU-кэш почистить где-нибудь в соседнем модуле). Потому, как раз не надо делать halt если память закончилась, а если и делать, то давать программе возможность это действие обратить и "попытаться снова", и вообще очень много подобных оговорок. Но я не уверен, что такое получится применить в языке без механизма исключений. Разве что не иметь исключений в safe-коде, но иметь его или его аналог в unsafe.
требует выполнения операций i, j, k, и во время выполнения операции j возникло исключение, то возникнет невалидное состояние
Да, в таком случае вам надо оборачивать каждую операцию. Но на практике, если i, j и k так сильно меняют состояние, то это скорее всего будут семантически отдельные операции, например, обособленные процедурами. Или же состояние системы (на каком она шаге) можно точно выяснить в ходе обработки единого блока исключения и откатить куда надо.
Как гуглить? Копипастить букву Ü с голландских сайтов?
Ещё способ с включенной Compose Key: Compose,",U.
üÜ
Название данного языка — «Ü».
Помнится, в книжке некого т-ща Кларка «Talk to the Snail» есть пассаж, удивительно подходящий к ситуации. Цитирую по памяти, так что могу ошибаться:
«Собственно, само название языка — Français — с этим их крючком под буквой ç — намекает нам на причину, по которой французский никогда не станет языком мирового общения».
Ӥ кстӓтӥ, кӓкӧё рӓсшӥрёнӥё бӱдёт ӱ ӥсхӧднӹх фӓйлӧв? :)
А когда (и если) язык станет хоть немного извесным, я убеждён, что можно будет каким-то способом эту проблему побороть.
Ӥ кстӓтӥ, кӓкӧё рӓсшӥрёнӥё бӱдёт ӱ ӥсхӧднӹх фӓйлӧв?Сейчас используется "*.u". Но завязки на расширение в компиляторе нету, можно как угодно файлы именовать, компилятор их в любом случае попытается скомпилировать.
Расширение по идее должно быть .ue
. Это вроде стандартный способ портирования этого звука в английский. Например: Überauth — https://github.com/ueberauth/ueberauth
Сравним с C++ => .cpp
Ӥ кстӓтӥ, кӓкӧё рӓсшӥрёнӥё бӱдёт ӱ ӥсхӧднӹх фӓйлӧв?
Тут просто напрашивается вариант *.uuml
.
Причём непонятно, почему в этом случае они используются:
fn virtual pure Foo(this);
А в этом нет:
fn virtual Bar(this){}
почему нужно это дублирование конца строк? Неужели недостаточно символов CrLF, которые вставляет любой редактор по нажатию на Enter?
Отдельный оператор‐разделитель инструкций в этом случае уберёт мусор в конце каждой строки.
В Scala; нужно ставить только если вы хотите несколько выражений написать в пределах одной строки, а в остальном хватает просто переноса.
в js в некоторых случаях концом будет перенос строки.
несколько странно, как и многое другое в js
Не поэтому. Типизированность языка никак не влияет на использование разделители) Нужно только понимать, является ли следующая строка выражением, продолжающее выражение в текущей.
Опыт показывает, что неоднознасности больше порождает плохая структура решения, чем код без ;
В js есть несколько правил, определяющий будет ли выражение перенесено на след строку в отсутствии ;. Учатся за полчаса.
— инструкции
— возможность писать несколько инструкций в одной строке
мир прекрасен и удивителен
p.s. на всякий случай поясню: я считаю, что: 1. инструкций быть не должно, это лишнее, если есть выражения и функции; 2. запись несколько *инструкций* в одной строке ухудшает читаемость и понимаемость исходника. Но я тут мимо проходил, у меня уже есть свой «идеал языка программирования», а даже не один ;)))
Функциональное программирование — штука интересная, но на практике, императивное программирование до сих пор доминирует.
Я сам противник писать несколько инструкций в одной строке. Лично меня больше заботит возможность переноса длинных строк.
Процедура или «инструкция» отличаются от функции или выражения только тем, что автор не хочет никуда явно сохранить результат.
То, что сейчас принято называть «функциональным программированием», к этому этот факту имеет мало отношения — будет у вас последовательность «инструкций» или «функций» — не принципиально. Зато, вместо нескольких разных элементов языка, по сути остается один — на длинной дистанции дает выгоду — меньше ограничений, проще развитие.
На счет «переноса длинных строк», уж простите за моё старпёрство, но если у вас выражение больше 72 символов (да-да, очень стар по нынешним меркам, и на самом деле у меня во всяких линтерах правая граница строки 120 символов), то нет никаких проблем записать это выражение в виде двух, трёх, десяти. Сделать несколько функций, подумать еще пол часа, и «вообще не делать так длинно».
Задача компилятора сделать так, что бы во время выполнения, то, что написано работало эффективно. Кажется, уже несколько десятков лет, как известны и реализованы методы оптимизации, когда и функции инлайнят, и циклы разворачивают, и переменные размещают в регистрах а не на стеке. Вообще, внутри процессора всё совсем не так, как в исходнике, по итогам.
В результате всего этого, в «идеальном языке» (для меня ) важнее именно то, насколько просто и выразительно записан алгоритм, насколько легко мой коллега поймет, что тут происходит, и где я накосячил. Или наоборот, насколько легко убедится, что реализация точно соответствует спецификации и удовлетворяет исходным требованиям задачи.
Выражения которые в одно лицо занимают несколько строк, с меньше долей вероятности помогают этому, чем три-четыре отдельных выражения, которые каждое вычисляет что-то разумное в контексте задачи или предметной области, «сохраняет» промежуточный результат в локальной «переменной», а потом где-то итоговое выражение вычисляет уже то, что требовалось.
а! еще, кстати, есть люди которым нравятся пошаговые отладчики, для них тоже несколько строк и выражений удобнее, чем одно записанное в несколько строк с переносами.
Учитывая ваш богатый опыт, было бы странным предположить, что вы не видели функций, принимающих несколько аргументов. Имена этих функций могут быть достаточно длинными. Аргументов может быть больше, чем 3 и вообще эти функции могут оказаться частью API сторонней библиотеки. Да, вы правы, часто можно записать все в несколько отдельных строк. Но с моим неидеальным и многословным C++, не все удается вместить в 80-90 символов и перенос на следующую строку бывает неплохим компромиссом.
Мне в js нравится писать без ;
К, сожалению, редко встречаешь людей кому это тоже нравится. Поэтому в команде пишу; и не жужу.
Но это опциональность языка. Хочешь учи правила переноса и не ставь точкусзапятой. Хочешь не учи и не парься и так и так работает
Второй случай — функция с пустым телом.
И, возможно, убрать auto, потому что чтобы понять программу, ее компилируешь в голове, и в этом известность результирующего типа нередко помогает.
Имхо ваш язык отличный кандидат чтобы занят пустую нишу языка мощного (компилируемого в нативный код, без GC), простого (доступного новичкам и старичкам), поддерживающего ООП. С++ ушел из этой ниши и не так важно куда он идет, как занять то святое место, которое он оставил пустым. Именно на таком языке должны бы быть написаны и десктопные приложения типа офиса или CAD, именно на таком надо бы писать тем, кого государство могло бы нанимать для написания нужных ему программ, вовлекая в этот процесс широкие круги, примерно как в open source, но за зарплату и хостя самостоятельно.
Предложу убрать ust::Надо подумать, нет ли очевидных минусов у данного решения.
убрать autoСовсем убрать нельзя, в шаблонах без него тяжело будет. Злоупотребление auto пока что останется на совести автора кода.
С++ ушел из этой ниши и не так важно куда он идет, как занять то святое место, которое он оставил пустымТакого хотелось бы конечно, буду работать над этим.
Совсем убрать нельзя, в шаблонах без него тяжело будет. Злоупотребление auto пока что останется на совести автора кода.
Вы заставляете пользователя вашего языка использовать его так как задумано, прямым путем, и одновременно ограждаете его ошибок где можете, одна система учета ссылок чего стоит. И это концептуально правильно, массовый язык должен защищать от ошибок. Имея это в виду, посмотрите что творится в шаблонах С++, как выглядит код ATL, насколько он удобен в использовании (не говоря о модификации развитии) не сильно искушенному в шаблонах программисту. Мало удобен, надеюсь, Вы знаете это. А многие идеи Александреску, прекрасно зашедшие в С++, и породившие использование системы типов для решения разных задач, но не создания экземпляров порожденных шаблонных типов в привычном для «С с классами» смысле. Не ищите такого использования шаблонов, массовый пользователь ЯП и метапрограммирование — вещи противолежащие. Простота ЯП, быстрота понимания его программ, это и защищенность от ошибок и эффективность работы на нем.
в Ü есть проверка верности потока управления. При обнаружении недостижимого кода порождается ошибка
Почему не предупреждение? Иногда в процессе отладки хотелось быстро влепить return в свежий метод, но Java отказывалась запускать код и приходилось городить «if (true) return;»
Почему реализация на C++? Есть же более надежные языки, тот же Rust для компилятора подходит лучше.
Почему Ü? Потому, что хотелось однобуквенного названия, а все буквы из набора A-Z уже заняты.
Может я плохо гуглил, но I, Y, P, G и др. не нашел.
C — слишком низкоуровневый и небезопасный
А почему это он небезопасный?
Panzerschrek, язык у вас назван немецкой буквой, ваш никнейм тоже на немецкий манер, подумал вы увлекаетесь немецким языком. Зашел в репозиторий на гитхаб а там в коммитах везде транслитом русские слова. Почему так?
UPD даже не латиницей(пример: Podderžka kortežej v parametrah signatury šablonov klassov i v parame…)
там в коммитах везде транслитом русские словаИспользую такое для личных целей. Нужно это затем, чтобы не переключать часто раскладку клавиатуры. Символы с диакритикой есть в моей раскладке клавиатуры, отчасти поэтому у меня не вызывает проблем напечатать название языка.
Спасибо за статью, но все же немного неубедительна аргументация и некоторые решения.
(субъективно) опасность подхода, когда всё есть выражение и возвращает результат
А в чем собственно опасность? Я вот 100 лет ждал возможность написать код в стиле
let result = if condition { DoExpensiveStuff(); 10 } else { 0 };
Ну и возвращать результат из того бесконечного цикла явным образом тоже отлично.
наличие явного указания соответствия протоколу
Это что за зверь?
отсутствие наследования
Мне казалось, даже гиганты от ООП вроде фаулера говорили "используйте композицию, а не наследование". От наследования реализации обычно больше проблем нежели достоинств.
Что касается вашего языка, то во-первых отсутствие ссылок немного смущает, немного смахивает на го, где в генерики можно только авторам языка, а остальным нельзя, а во-вторых странный выбор синтаксиса:
fn Foo( i32 x ) : i32
Тип то слева, то справа. Сравните с той же скалой:
def Foo(x: i32): i32
Намного чище и логичнее
Я вот 100 лет ждал возможность написать код в стилеЧитать такое бывает сложно.
Это что за зверь?Ну это когда надо писать impl SomeTrait for SomeStruct{}. Мне больше нравится подход из C++ шаблонов — соответствие требованиям к типу определяются по необходимости, скажем, если вызвали std::sort, то будет использован operator<, и не обязательно наследовать тип от какого-нибудь Ordered.
От наследования реализации обычно больше проблем нежели достоинствДействительно, можно перемудрить с наследованием. Но мне кажется, достоинства от наличия наследования всё же перекрывают недостатки от возможности его неправильно использовать.
отсутствие ссылок немного смущаетСсылки есть. Нету ссылочных типов.
странный выбор синтаксисаВ начале разработки так и было, тип аргумента функции указывался после двоеточия. Но потом я пришёл к выводу, что двоиточие тут лишнее и не несёт особой смысловой нагрузки, а если двоеточие убрать, то логичнее будет указывать на первом месте тип аргумента, а имя на втором.
если вызвали std::sort, то будет использован operator<вот так просто будет взят и использован, без задней мысли? Отсортирует как-нибудь, как ему вздумается, а ты потом думай, почему так странно получается.
В остальном, вы пытаетесь сделать ещё один раст с кажущимися вам необходимыми фичами — уже проще форкнуть то, что есть. Также обратите внимание на /rfc/ и /issues/ раста — многое из того, что вам кажется очевидно-необходимым там так или иначе было отсеяно (очень многое было перед этим реализовано в nightly) как раз из-за возможной неоднозначности/небезопасности.
Читать такое бывает сложно.
Так альтернативы (если условное выражение не expression) заведомо сложнее.
Зачем, кстати, темплейты? Мы же в 2019 живем, а не в 80-х, уже давно все умеют нормальный параметрический полиморфизм.
То есть в мире уже существует язык U?)
Спасибо, рванул гуглить)
Test na ctenije kompilätorom putej s Junikodom.
(Нужен бы опрос, но и отметиться неплохо)
GUI, чтобы было удобнее смотретьМожете показать?
module Hello.World;
this()
{
}
alias void *HANDLE;
alias HANDLE HWND;
alias char CHAR;
alias const(CHAR)* LPCCH, LPCSTR, PCCH, PCSTR;
alias uint UINT;
alias ushort WORD;
version (Windows) {
extern (Windows) {
nothrow {
@nogc
{
int MessageBoxA(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType);
}
}}}
struct Soo {
int x, y;
};
int foo(int x, int y)
{
return x+y;
}
int main()
{
int i = 12Lu;
Soo s;
if(i>10) {
int j = i;
s.x = foo(50,50);
}
MessageBoxA(cast(void*)0, "test", "hello world", 0);
return 0;
}
маленький кусок дерева выглядит вот так
![](https://habrastorage.org/webt/tt/f6/oy/ttf6oyze-w5behqgodnxmzx2y9u.png)
На самом деле ничего особенного, просто я навесил самодельную рефлексию на все структуры синтаксического дерева, чтобы их можно было как-то смотреть в удобном виде.
Изучаю VHDL, так что делаю свой процессор…
А я этот язык когда-то учил (наткнулся на интерпретатор на какой-то файлопомойке), это был мой первый си-подобный язык (си я тогда не осилил). Перестал заниматься, потому что проект мне показался заброшенным.
С точки зрения ФП любая программа это свой язык + абстрактный интерпретатор :)
C++ — по наследству получил много недостатков низкоуровневости, появились новые способы выстрелить себе в ногу, отсутствие рефлексииВот бы жаловаться на язык, на котором написано почти всё, что в нем чего то не хватает для решения задач =) Появились новые способы, зато убралось гораздо больше старых…
D — сборщик мусора, отдельные ссылочные типыМожно жить и без сборщика, но бедненько. Можно и без ссылочных типов (классов).
Rust — необходимость явного взятия ссылок и явного их разыменования, (субъективно) опасность подхода, когда всё есть выражение и возвращает результат, наличие явного указания соответствия протоколу, отсутствие наследованияЭто совсем не главные проблемы Раста, и кстати разыменование ссылок там неявное
Go — сборщик мусора, отсутствие шаблоновШаблоны там и не нужны (м.б.нужны дженерики, ждем 2.0). Специально так сделано: простой язык — простые решения для энтерпрайза
P.S. Чтобы понять, чего стоит язык, нужно сначала попробовать написать что-либо практическое, хотя бы после набора юниттестов стандартной библиотеки. На этом многие ломаются.
Фундаментальные (и некоторые другие) типы требуют обязательной инициализации:
var i32 x= 22, y(12345);
А давайте провозгласим, что фундаментальные типы всегда инициализированы, но если мы просто пишем
var i32 x, y;
то переменные будут проинициализированы строго определенным значением по умолчанию (которое 0 для целых, false для булевских, пустая строка для строк и т.д). Удобнее же будет — инициализация каким-то конкретным значением нужна заметно реже чем нулем.
На счёт удобства — спорно. ак подсказывает мой опыт, чаще всего переменные объявляются сразу с инициализатором, где инициализатор это не просто какое-то число (вроде нуля) а значение сложного выражения, результат вызова функции и т. д. Случаи, когда мы объявляем переменную и только потом в неё что-то записываем редки, в основном это случай с аккумулятором для цикла.
var a: i32;
Сейчас в вашем языке всё вразнобой: объявления переменных начинается с типа, как в С, а тип возвращаемого значение функции указывается после, через двоеточие, как в Pascal.
Имена числовых типов зачем-то сделали трудночитаемыми — одна буква, намекающая на тип, и разрядность после. Чем вам не угодили простые и понятные char (byte), short, int, long, вместо i8, i16, i32, i64? Не понимаю этой тяги к минимизации и сокращению ключевых слов, в ущерб читаемости исходного текста.
А объявления переменных кстати в таком формате («КлючевоеСлово Тип СписокОбъектов») лучше всего смотрятся. К тому же, в С++ есть например «const int x = 100», это ведь никого не смущает.
Имена числовых типов — наверное так однозначнее; ведь Си знаменит тем, что там int и char могут быть разных размеров для разных платформ. Хотя олдскульные имена типов тоже неплохи, если жестко задать им размерность в байтах.
А объявления переменных кстати в таком формате («КлючевоеСлово Тип СписокОбъектов») лучше всего смотрятся.А объявление функций при этом в совершенно другом формате… Здесь так, а там этак. Язык не смотрится целостным.
Си знаменит тем, что там int и char могут быть разных размеров для разных платформДля Си это наследие прошлого. А вот к примеру в D типы (u)byte, (u)short, (u)int, и (u)long одинаковы для всех платформ, и читаются не в пример лучше чем что-то вроде «i16».
Тип возвращаемого значения после описания аргументов функции, как мне кажется, более логичен.
имена фундаментальных типов специально включают разрядность, для наглядности, чтобы не вспоминать, сколько там байт в каких-нибудь shot, long.
В nim можно объявить несколько переменных одного типа как
var a, b, c: int
Основное преимущества написания типа "в конце" — возможность опустить его вообще, когда происходит вывод типов.
Можно конечно пойти по пути C/C++/C#/Java и просто принять, что если есть два идентификатора, разделенные пробелами — то первый это всегда тип, второй — объект. Но в этом случае нужно очень аккуратно подходить к синтаксису, чтобы не нагородить неоднозначностей.
там обычно тип все равно в начале
Go — в конце, Rust — в конце, Pascal — в конце. Где именно "обычно" тип в начале?
Здесь есть некий конфликт с объявлением параметров функций и полей структур — там обычно тип все равно в начале.
Тип в конце у всех языков, которые решили не идти по пути вникуда за си и сделать иначе. Почитайте интервью с тимлидом команды разработки C#, он там этот вопрос тоже поднимает. Следование правилу спирали одно из самых глупых подражаний которое можно было придумать.
И да, один из самых мейнстрим языков с нотацией "в конце" — это тайпскрипт. И конечно же структуры там объявляются точно так же:
class Greeter {
greeting: string;
constructor(message: string) {
this.greeting = message;
}
greet() {
return "Hello, " + this.greeting;
}
}
Можно конечно пойти по пути C/C++/C#/Java и просто принять, что если есть два идентификатора, разделенные пробелами — то первый это всегда тип, второй — объект.
В C/C++ всё далеко не так просто:
a * b;
— это операция умножения, или объявление переменной-указателя?На этапе синтаксического разбора это определить невозможно.
В приведенных вами "простых и понятных" типах char
(byte
) — знаковый или беззнаковый? А какую разрядность имеет long
? Мне всегда казалось, что различные системы типов решают различные задачи.
Например, при реализации низкоуровневых примитивов очень важно, чтобы некоторые переменные были именно беззнаковыми 32-разрядными (uint32_t
), другие, например, беззнаковыми 64-разрядными (uint64_t
), а третьи — тоже беззнаковыми, но неопределенной разрядности (size_t
). Код, который эти переменные использует, может, например, рассчитывать на конкретное поведение в случае переполнения (wrapping underflow/overflow).
А при реализации высокоуровневых примитивов разрядность переменных может уже не иметь значения, и там вполне достаточно char
и int
, а в некоторых случаях можно вообще обойтись без примитивных типов.
Поэтому, опять же, на мой взгляд, в удобном и при этом универсальном языке программирования окажутся и те, и другие типы. При этом я совсем не против забирать определения более специфичных типов из отдельных заголовочных файлов (модулей, пакетов, etc.), но совсем выкидывать их из языка мне кажется неправильным.
N — натуральные (без знаковые)
Z — знаковые
Q — с плавающей запятой
N16bit, Z32bit… Но программисты не любят в алгебру…
И почему так мало языков вводят возможность определять числа большие чем 256 bit? Q64Kbit
Q — рациональные числа, IEEE 754 ассоциировать с каким-то алгебраическим множеством неразумно.
И почему так мало языков вводят возможность определять числа большие чем 256 bit? Q64Kbit
Это достаточно узкоспециализированная вещь, обычно для этого существуют специальные библиотеки.
Чем V не подошел?
"Java — сборщик мусора, все композитные типы ссылочные, сильная завязанность на виртуальную машину. Многое и этого применимо и к языках на основе JVM."
Здесь перечислены достоинства, а не недостатки
Ключевое слово halt — настоящая пушка крупного калибра для гарантированного отстрела ног. Представляю себе восторг инженеров, когда какой-нибудь сервис в проде просто молча выйдет в окно, из-за того, что одна из множества используемых либ так решила
С исключениями в C++ проблема схожая тоже присутствует, все вызовы к сторонним библиотекам в try-catch мало кто заворачивает, а значит, если оттуда прилетит исключение, его могут и не поймать, что закончится std::abot.
Здесь один из примеров скрытых особенностей языка, которые по-хорошему должен знать каждый программист — пользователь языка, но мало в какой книжке по языку о подобном пишут, и обычно из таких особенностей получаются грабли, которые рано или поздно проявляются. И сам факт наличия таких граблей говорит о плохой реализации языка. В плюсах таких моментов слишком много. И других языков, с усложнениями всех видов, много, поэтому актуальна потребность в простом языке, но эффективном.
И вообще неправильно это, создавать скрытую особенность языка, замаскированные грабли, потому что не удается сделать нормальную реализацию. Надо добиваться нормальной реализации сразу, и всячески избегать замаскированных граблей. Чтобы программист при переносе объектной модели в язык программирования не получал мин замедленного действия, на которых подорвутся пользователи.
Подробности и ссылка на скачивание здесь. Это всего лишь прототип, но он должен быть интересен тем, кого интересует новый этап развития языков программирования.
- В чём заключается «предел развития» текстовых языков?
- Чем «новый этап развития» отличается от заявленной ещё в 70-е годы концепции «языков программирования четвёртого поколения», давшей нам Matlab/Simulink и LabView, но не заменившей текстовых языков?
- Функция трансляции схемы в код на C издавна была в Simulink. Чем отличается ваш подход?
- Где вообще спецификация вашего языка? Или языка и вовсе нет, а есть только трансляция в C один к одному?
Автор назвал язык в честь самого себя — как по мне, это уже достаточная характеристика для языка :)
В чём заключается «предел развития» текстовых языков?Низкоуровневые сложны (как Си), а высокоуровневые тоже непростые в обучении и требут толстых рантаймов. Мое разочарование в софте. Софте, написанном на текстовых языках.
Чем «новый этап развития» отличается от заявленной ещё в 70-е годы концепции «языков программирования четвёртого поколения», давшей нам Matlab/Simulink и LabView, но не заменившей текстовых языков?Тем, что код не пишешь, а собираешь из боков и соединяешь проводками. По этой теме уже есть LabVIEW, но область его применения очень ограниченная, не говоря уже о том, что оно пропиетарное, с закрытым кодом и дорогой лицензией. Метапрог будет опенсорсным и, самое главное, он претендует на универсальность. Он может все, что может Си. Кстати, прототип уже опенорсный, правда пока что требует Лабвью для запуска и просмотра кода (но это временно).
Функция трансляции схемы в код на C издавна была в Функция трансляции схемы в код на C издавна была в Simulink. Чем отличается ваш подход?.. Чем отличается ваш подход?Тем, что Метапрог универсальный. Можно делать низкоуровщину сишного уровня, используя функции Си и вставки сишного кода, оперировать указателями. В графике, а не тексте. И Метапрог опенсорсный, в отличие от Simulink.
Где вообще спецификация вашего языка?Метапрог пока существует только в виде LabVIEW-прототипа и еще не устаканен окончательно. И это не обычный текстовый язык, который можно запросто описать текстовыми спецификациями. Основная часть работы с Метапрогом — в графическом интерфейсе, как в компьютерной игре. Где вы выдели игры с отдельно лежащими интсрукциями/спецификациями? Я могу вспомнить только Герои 3, в большей части игр есть встроенная обучалка. И в прототип Метапрога я тоже встроил интерактивную обучалку и справочную систему, а если этого мало — можно консультироваться со мной в личке или «Метапрог онлайн».
- Совершенно непонятно, чем ваш язык должен быть проще, если в нём должны быть как минимум те же возможности, что и в текстовых языках. Программу вычисления факториала на Питоне или Паскале поймёт даже тот, кто почти не программировал. Вашу программу я не понимаю.
- В Simulink схема точно так же рисуется, как и у вас. Если речь о деньгах, то аналогичный редактор схем есть в бесплатном SciLab. Про возможности LabView судить не возьмусь.
- Язык программирования — это не игра, и публикация почти любого нового языка — это публикация его спецификации. Без неё я не понимаю даже того, существует ли вообще некий ваш язык, или есть только трансляция схемы в C. Мне всё больше кажется, что нам просто предлагается «C в картинках».
Программу вычисления факториала на Питоне или Паскале поймёт даже тот, кто почти не программировал. Вашу программу я не понимаюДаже не знающий слово «for»? Есть входы и выходы цикла и жесткие последовательности. Пожалуй, кое в чем вы правы: когда напишу пост о Метапроге, наделаю скринов с описаниями базовых элементов диаграмм.
аналогичный редактор схем есть в бесплатном SciLabОн не текстовый?
Мне всё больше кажется, что нам просто предлагается «C в картинках».Си с графическими плюшками.
Даже не знающий слово «for»?Сейчас трудно оставаться таким отшельником, чтобы совсем не видеть английского языка (кстати, слово for было чуть ли не первым английским словом, которое я узнал). А вот разноцветные квадратики с редкими подписями по-украински мне мало что объясняют.
Он не текстовый?Редактор схем — разумеется, графический. Он задумывался как бесплатная альтернатива Simulink.
А вообще, посмотрите Википедию. Там обширнейший список визуальных языков программирования. Если соберётесь писать пост, вам придётся объяснять, чем ваш проект отличается от всех перечисленных. И конечно, советую воздержаться от громких слов о «пределе развития» и «новом этапе».
А вообще, посмотрите Википедию. Там обширнейший список визуальных языков программирования.
Есть ли из них хоть один, на котором можно, скажем, делать и декстопный софт, и мобильный софт, и ядра ОС под х86 и ARM, и прошивки на микроконтроллеры (любые, а не только фирменные)? Википедия меня встретила скрином со Scratch — это все равно, что если б в статье со списком текстовых языков программирования первым примером показать Brainfuck.
Лучшее из того что я знаю — это LabVIEW. Оно, опять же, весьма ограниченное по возможностям и сфере применения, но все же позволило мне сделать прототип Метапрога, не обращаясь к текстовым языкам. Все что вы видите на видео (интерфейс, работа с диаграммами, сетевой функционал) сделано исключительно из графических схем. Си там — только сущность, которой оперирует транслятор, на самом Си я почти ничего не писал.
разноцветные квадратики с редкими подписями по-украински мне мало что объясняют.Примерно так же не-программист (особенно не знающий английский) видит текстовый код. Когда напишу пост про Метапрог — постараюсь сделать понятные скрины с базовыми элементами. А насчет украинского — так есть русская локализация, даже на видео видно.
«Есть ли языки с поддержкой трансляции схем в C?». Есть. Simulink — точно, насчёт остальных предоставляю выяснять вамИ импорт сишных функций, и работа с указателями тоже? Насколько я знаю, ничего лучше Лабвью нет.
генерация кода под разные платформы — это в любом случае не ваша заслуга, а создателей компилятора CТак кто же спорит? Или у вас стоит цель потешить собственное ЧСВ, принизив мои заслуги? Моя заслуга в том, что я выбрал Си, как наиболее кроссплатформенный и при этом низкоуровневый язык, имеющий кучу готовых библиотек. И сделал реально работающий прототип Метапрога на Лабвью. И даже выложил его код для всех желающих ознакомиться с ним. Если хотите — могу попробовать и в ехешник скомпилировать (правда стабильность не гарантирую, прототип как-никак:)).
Про умерить оптимизм — я вот именно попытался охладить пыл, что там еще нечего сравнивать со зрелыми продуктами, это именно прототип и относиться надо соответствующе.
Даже не знающий слово «for»?
А блок-схему алгоритма поймет человек, не знающий значка «цикл со счетчиком»? Нет, это общее место.
ПМСМ, единственное место, где программирование блок-схемами (в широком смысле, речь не просто о диаграммах алгоритмов, это могут быть блок-схемы процессов) нагляднее традиционного текстового — это там, где мы можем при помощи блок-схем показать потоки данных.
Но это преимущество уже давно нивелировано введением stream-синтаксиса библиотек, где мы так же можем указать, что вот этот поток данных проходит через вот такие-то блоки:
something.get_data.filter_this_way(a,b,c).compress.filter_again.save
mapron
Если вам так хочется почитать мотивацию автора, можете ознакомиться с его постами на ЛОРе и комментами там же) Боюсь, вы слишком оптимистичны.
Посмотрел — как это развидеть? Ужас. Как бы там что с автором ни было, но это (ЛОР. Не в целом, а эти темы) настолько токсичная помойка, что не представляю, как там в таком стиле вообще можно общаться.
Private Process GetAllRecords(count As Long)
Var i As Long
For i := 0 To count - 1
Avaya1.GetRecordInfo(i)
End For
End Process
А запускается это просто:
StartProcess GetAllRecords(rcount)
дальнейший код выполняется параллельно.
Возможности развития текстовых языков приближаются к своему пределу.
Очень интересное заявление. А можно узнать ваш опыт в разработке на текстовых языках, какие языки применяли, в насколько больших проектах участвовали, какими были команды по количеству участников?
Однако вскоре выяснилось, что на нем можно далеко не все. Метапрог я делаю с прицелом на универсальность. Для того, чтобы можно было делать любой софт любой сложности, вообще не обращаясь к текстовым языкам.
я пытался писать
то есть опыта нет и мнение
Возможности развития текстовых языков приближаются к своему пределу.
основано на ничем, верно?
И тут я познакомился с LabVIEW
я когда практику на fennovoima проходил, тоже этого касался. И не разделяю восторга. Да хороший инструмент для своих задач, не более. И значит ли это, что я могу утверждать, что
Возможности развития графических языков кончились уже в 90х?
Лабвью в обучении оказалось куда проще и нет никаких причин чтобы не расширить область его применения, сделав из него универсальную среду. Но так как Лабвью закрытое и пропиетарное, то приходится с нуля делать Метапрог. Хорошо хоть есть на чем сделать прототип, не прибегая к текстовым языкам:)
А много ли вы переделывали лабвьюшных схем за третьими лицами? Ну или хотя бы что-то добавлять приходилось довольно существенное? Вот ни в свои схемы, а в те, кто уже когда-то сделал? Рекомендую.
Если учиться текстовым языкам сложно, а в итоге мы получаем раздутый и полный багов софт, значит текстовые языки практически исчерпали свои возможности для развития.
Нет не значит. Есть еще один вариант, о котором вы в силу недостатка опыта не подумали. Если учиться текстовым языкам сложно, а в итоге мы получаем раздутый и полный багов софт, значит это сама по себе сложная задача, и замена инструмента эту сложность не уберет.
Если учиться текстовым языкам сложно, а в итоге мы получаем раздутый и полный багов софт, значит это сама по себе сложная задача, и замена инструмента эту сложность не уберет.О чём тогда думали создатели языков? Чего им не сиделось на ассемблере или вообще на тумблерах-перфокартах? И почему чуть ли не у каждого текстового программиста возникает мысль написать свой язык? Почему блюпринты стремительно набирают популярность? Вопросов получилось много, можете и не отвечать, если не хотите.
Ну, во-первых, создатели языков вряд ли думают, что учиться текстовым языкам так уж сложно, иначе бы не создавали свои, и вряд ли они разделяют представления автора комментария о масштабах багов в софте. Во-вторых, есть техническая сложность задачи и логическая. Техническую сложность можно уменьшить подходящими инструментами, но логическая как была так и останется. Если надо реализовать N взаимозависимых требований, значит их надо реализовать. И раз специально придуманные текстовые языки не уменьшают сложность разработки софта, значит осталась в основном логическая сложность.
У графических программистов, судя по данному обсуждению и количеству таких языков, тоже возникает мысль написать свой язык. Значит графика в языках принципиально ничего не меняет. Текст это вообще говоря тоже графические символы, и нет принципиальной разницы, писать "y = sin(x)" или рисовать что-то вроде "y <------- sin <------- x", особенно если там должен быть косинус.
Не знаю, может где-то блюпринты и набирают популярность, но на hh.ru вакансий с этим словом всего 90 штук, а по обычным текстовым языкам по несколько тысяч.
Я говорил про конкретное высказывание "Почему блюпринты стремительно набирают популярность?"
Тем не менее, вы не в такой же ситуации. Графические языки уже есть. Только мало кто ими пользуется, потому что у них куча недостатков и ни одного преимущества. Серьезно, в чем вы видите разницу для вычисления синуса? Как может предотвратить ошибку графический язык, если по требованиям нужен косинус?
Графические языки уже естьИз серьезных — только Лабвью и то оно такое себе, иначе я б не делал Метапрог ему на замену.
в чем вы видите разницу для вычисления синуса?В том, что не прописываешь, а вытягиваешь в виде блока из меню. Ладно, синус прописывать недолго, пропиши-ка, например, bufferevent_read(struct bufferevent *bufev, void *data, size_t size);, не допустив ни одной ошибки, помня все названия нужных типов, не забыв ни одной запятой и скобки — и это только заголовок!
В Метапроге (даже прототипе) вытащил блок функции — и типы прописывать не надо, какими сложными они б ни были. Вытягиваешь константы, входы или выходы нужного типа по клику на подсказку, соединяешь все проводками. Не нужно задавать и помнить имена локальных переменных, все в проводках.
В том, что не прописываешь, а вытягиваешь в виде блока из меню.
Эм, те недостатки, которые вы приводите для текстовых языков — сложно изучать, большой размер и наличие багов — не исчезают из-за смены способа ввода.
пропиши-ка, например, bufferevent_read(struct bufferevent bufev, void data, size_t size);, не допустив ни одной ошибки, помня все названия нужных типов, не забыв ни одной запятой и скобки
Если вы забудете запятую или скобку, у вас программа не скомпилируется. Баги в софте возникают не из-за этого, а большой размер тем более.
В Метапроге (даже прототипе) вытащил блок функции — и типы прописывать не надо, какими сложными они б ни были.
А откуда же они возьмутся в меню-то?) Вот скажем нам надо сделать функцию, которая делает HTTP-запрос:
RequestResult request(string method, string uri, array parameters, array files)
Метапрог по волшебству узнает, что нам нужна такая функция с такими типами аргументов, и сам добавит ее в меню?
Кроме того, имея 3 заранее объявленных типа, их можно скомбинировать в сотни функций. Вы предлагаете все возможые комбинации заранее в меню добавлять?
и типы прописывать не надо, какими сложными они б ни были. Вытягиваешь константы, входы или выходы нужного типа по клику на подсказку, соединяешь все проводками. Не нужно задавать и помнить имена локальных переменных, все в проводках.
Вот это вот всё не является тем, что создает сложность в программировании. Это делают даже школьники на уроке информатики. Как же вы собираетесь решить проблемы сложности разработки, если не понимаете, чем она вызвана.
Эм, те недостатки, которые вы приводите для текстовых языков — сложно изучать, большой размер и наличие багов — не исчезают из-за смены способа ввода.По крайней мере, изучение Лабвью для меня оказалось проще, чем текстовых языков. И особенно изучение функционала библиотек на Лабвью. Мне вообще не приходится читать мануалы к ним, просто посмотреть контекстную справку и диагарммы функций. Да и мануалы к лабвьюшным функциям нужны намного реже, чем к текстовым. Хочу сделать Метапрог еще более удобным.
А откуда же они возьмутся в меню-то?) Вот скажем нам надо сделать функцию, которая делает HTTP-запрос:Берутся функции из меню для ТСР и работы со строками и из них собирается соответствующая функция. Для удобства дальнейшего использования функция HTTP-запроса вписывается в новое меню в HTTP.
RequestResult request(string method, string uri, array parameters, array files)
Метапрог по волшебству узнает, что нам нужна такая функция с такими типами аргументов, и сам добавит ее в меню?Функции (в виде диаграм) и меню из них создают пользователи.
Если вы забудете запятую или скобку, у вас программа не скомпилируется. Баги в софте возникают не из-за этого, а большой размер тем более.Иногда не там поставленная скобка создает трудноуловимый баг. Но отсутствие необходимости ставить скобки — вопрос даже не столько багов, сколько элементарного удоства.
Мне вообще не приходится читать мануалы к ним, просто посмотреть контекстную справку и диагарммы функций. Да и мануалы к лабвьюшным функциям нужны намного реже, чем к текстовым.
Нужны намного реже вам.
Чем к текстовым на языке C, и только к тем, с которыми вы работали.
Вы почему-то обобщаете свой опыт на всех и делаете слишком общие утверждения.
Я на графических языках не пишу, но мне тоже обычно не надо читать мануалы к библиотекам, достаточно контекстной справки.
Берутся функции из меню для ТСР и работы со строками и из них собирается соответствующая функция. Для удобства дальнейшего использования функция HTTP-запроса вписывается в новое меню в HTTP.
Функции (в виде диаграм) и меню из них создают пользователи.
Ну так значит надо прописывать типы аргументов. А вы говорили, что не надо.
Меню на десятки тысяч элементов это сомнительное удобство.
По крайней мере, изучение Лабвью для меня оказалось проще, чем текстовых языков.
Но отсутствие необходимости ставить скобки — вопрос даже не столько багов, сколько элементарного удоства.
Ага, то есть уже не "возможности развития текстовых языков приближаются к своему пределу", а лично вам неудобно ставить скобки.
Ну так значит надо прописывать типы аргументов. А вы говорили, что не надо.Не надо ничего прописывать. Достаточно мышью вытащить вход нужного типа из подфункции (ведь большинство функций — это вызов других функций).
Меню на десятки тысяч элементов это сомнительное удобство.Сколько функций для работы с TCP? Десятки тысяч? Едва ли. Рекомендую ознакомиться с Лабвью и Метапрогом.
лично вам неудобно ставить скобкиДа, мне неудобно ставить всякие там скобки, запятые, точки с запятыми. А читать чужой код так еще хуже.
Достаточно мышью вытащить вход нужного типа из подфункции
А какая разница-то? Прописывать, протыкивать, все равно задавать тем или иным образом. От Ctrl+C/Ctrl+V названия типа это ничем не отличается, его в большинстве редакторов даже мышью можно делать с зажатым Ctrl.
Сколько функций для работы с TCP? Десятки тысяч?
Причем тут TCP? Размер среднего приложения на текстовом языке — от 100000 строк и выше. Например 400000 строк, по 10-100 строк на функцию, получаем 4000-40000 функций. Да, все они что-то делают и где-то вызываются, иначе бы их не писали.
Да, мне неудобно ставить всякие там скобки, запятые, точки с запятыми. А читать чужой код так еще хуже.
Ну а при чем тут тогда возможности текстовых языков?
От Ctrl+C/Ctrl+V названия типа это ничем не отличаетсяБольшая часть современого прогрммирования на текстовых языках — это и есть Ctrl+C/Ctrl+V.
4000-40000 функцийЕсть множество способов отображения и сортировки этих функций. По названию, по типам входов, выходов итд итп.
Потому что в графике этого делать не надо. Ну в питоне вроде тоже не надо точки с запятыми ставить, но зато надо следить за табами и пробелами — что тоже ужас.Да, мне неудобно ставить всякие там скобки, запятые, точки с запятыми. А читать чужой код так еще хуже.
Ну а при чем тут тогда возможности текстовых языков?
Но все это теория. Советую перейти к практике: потыкать Лабвью и прототип Метапрога. Прототип пока что глючный и тормозной, но в принципе работает и как демонстратор сойдет. Со следующей версии прототипа на нем можно будет начать делать и Метапрог «сам на себе».
Да, мне неудобно ставить всякие там скобки, запятые, точки с запятыми. А читать чужой код так еще хуже
Это проблема набора текста в «блокноте».
IDE с которой я работаю, а ей уже 15 лет, простите, имея плагины, делает и автодополнение, и скобки подставляет, и сигнатуры функций подсказывает, и управляющие структуры автоматически дописывает. И подсветку делает — хоть совпадающих идентификаторов, хоть парных скобок, хоть отчерчивает блоки (блочные операторы) разноцветными линиями.
И это — древняя IDE.
IDEА, так вот что сдерживает развитие визуального программирования! Однако все же лучше именно визуальное программирование, чем просто облегчение текстовой писанины.
Развитие сдерживают огромная сложность создания чего‐то для редактирования визуальных языков, сопоставимого по удобству хотя бы с *vim, а также отсутствие каких‐либо внятных преимуществ, кроме «некоторым людям читать диаграммы легче». Кривая обучения в качестве преимущества не подойдёт — работа над уменьшением сложности обучения дальше определённого предела полезна, только если вы создаёте язык не для программистов (а LabVIEW, вообще‐то, делается для инженеров), при обучении разработке ПО вы всё равно больше потратите на паттерны проектирования, техники разработки, алгоритмы; а также знакомство со стандартной библиотекой, характерными для конкретного языка шаблонами, чем на собственно синтаксис.
Ни первую, более общую группу, ни вторую, применимую к языку, графическое программирование не удаляет, и вряд ли сокращает что‐либо, кроме знакомства с библиотекой. К тому же, менюшки (сокращающие время на знакомство со стандартной библиотекой), из которых можно вытащить функции, не являются чем‐то таким, что нельзя реализовать для текстового языка. Я вроде это даже видел в какой‐то IDE для VHDL. Просто в том же LabVIEW функций мало, но у них есть иконки (доставать что‐то из меню без иконок будет сложновато) — а в текстовом языке вы, скорее всего, напишете гораздо больше функций — в том числе и из‐за того, что придумать только название функции в любом случае гораздо быстрее, чем и название, и иконку.
И ещё, не забывайте про проблему «курицы и яйца», которая всё усугубляет дальше: к языку должна прилагаться хорошая экосистема, но для её создания и поддержания язык должен быть достаточно популярным, для чего нужна хорошая экосистема. Проблему можно обойти, если у вас есть спонсоры, которые помогут её создать, но их ещё надо как‐то убедить.
Кстати, про курицу и яйцо: изучение одного текстового языка делает изучение другого намного легче, особенно если они схожи. Изучение графического языка… Если не считать небольшой пачки DSL вроде графических HDL для FPGA, то там есть LabVIEW, что‐то для обучения и на этом примерно всё. При нужде работу сменить будет сложнее.
Я тут подумал ещё об одной сложности: я одним освоенным Vim могу редактировать программы на куче разных языков. Кто другой программы на тех же языках может редактировать в Sublime Text. Программы на языке G можно редактировать только в LabVIEW, программы на metaprog наверняка можно редактировать только в вашей среде, у других графических языков тоже у каждого своя единственная среда. Так что если мне что‐то не нравится в редакторе графического языка, то я могу либо молча терпеть, либо попытаться изменить код редактора (что сложнее, чем попытаться перейти на другой, практически невозможно, если язык ещё и проприетарный), либо уйти с языка. И я не могу перейти на другой графический язык, сохранив редактор и связанные с ним привычки.
не забывайте про проблему «курицы и яйца», которая всё усугубляет дальше: к языку должна прилагаться хорошая экосистемаЯ взял Си за основу, с кучей готовых библиотек.
в текстовом языке вы, скорее всего, напишете гораздо больше функций — в том числе и из‐за того, что придумать только название функции в любом случае гораздо быстрее, чем и название, и иконкуИконки рисовать не обязательно, в Лабвью-схемах Метапрога я их почти не рисовал (правда изначально я и не думал открывать код лабвьюшного прототипа).
Программы на языке G можно редактировать только в LabVIEW, программы на metaprog наверняка можно редактировать только в вашей средеМетапрог, в отличие от Лабвью, претендует на универсальность. Вам не понадобится учить другие языки, зная Метапрог, когда он обрастет библиотеками на все случаи жизни.
если мне что‐то не нравится в редакторе графического языка, то я могу либо молча терпеть, либо попытаться изменить код редактораВ Лабвью мне много чего не хватает, поэтому я и задумал Метапрог.
Я взял Си за основу, с кучей готовых библиотек.
Что добавило необходимость знать C, когда в этих библиотеках обнаружится ошибка. Или когда в метапрог протечёт какая‐та абстракция. Ну и при использовании библиотек на C в более безопасных языках кому‐то придётся писать безопасные binding’и — или программисты будут «радостно» ловить SEGV.
Если вы действительно претендуете на универсальность, то напомню ещё про такие вещи, как Web и FPGA. Со вторым, кстати, LabVIEW, неплохо справляется. Но библиотек на C ни там, ни там, вы не получите (с Web ещё есть шансы из‐за emscripten, с FPGA — никаких).
Иконки рисовать не обязательно, в Лабвью-схемах Метапрога я их почти не рисовал (правда изначально я и не думал открывать код лабвьюшного прототипа).
Тогда у вас меню с кучей похожих иконок. По моему мнению, когда иконки слишком похожи, вытащить VI из окна проекта проще, чем из меню. По крайней мере, там нужно сканировать список только в одном направлении.
Программы на языке G можно редактировать только в LabVIEW, программы на metaprog наверняка можно редактировать только в вашей среде
Метапрог, в отличие от Лабвью, претендует на универсальность. Вам не понадобится учить другие языки, зная Метапрог, когда он обрастет библиотеками на все случаи жизни.
Вы уверены, что ответили на правильный абзац здесь?
В любом случае, у меня там объяснение, что мешает графическим языкам стать популярными. Если вы отвечали на
Кстати, про курицу и яйцо: изучение одного текстового языка делает изучение другого намного легче, особенно если они схожи. Изучение графического языка… Если не считать небольшой пачки DSL вроде графических HDL для FPGA, то там есть LabVIEW, что‐то для обучения и на этом примерно всё. При нужде работу сменить будет сложнее.
, то «универсальность» тут не ответ от слова «совсем». Во‐первых, даже если у вас удастся создать универсальный язык (ни у кого пока не получилось), абзац о том, что многие его не будут выбирать, так как с него сложно уйти. Это не проблема, если есть много компаний с вакансиями на метапрог, но их нет. И эта проблема делает вероятность убеждения кого‐либо ещё ниже.
Во‐вторых, если у меня есть какой‐нибудь Altium и я хочу написать к нему дополнение, то как мне поможет метапрог? Программа закрытая, а дополнения на pascal. Открытые программы также ещё долго не будут добавлять возможность написания дополнений на другом языке, если будут вообще — мало где сейчас есть возможность писать дополнения на нескольких языках.
В Лабвью мне много чего не хватает, поэтому я и задумал Метапрог.
Это не ответ. В вашем редакторе будет то, чего не хватает вам. Но все остальные программисты — не вы. У текстовых языков есть выбор, про графические с альтернативными редакторами я не слышал.
Что добавило необходимость знать C, когда в этих библиотеках обнаружится ошибка. Или когда в метапрог протечёт какая‐та абстракция. Ну и при использовании библиотек на C в более безопасных языках кому‐то придётся писать безопасные binding’и — или программисты будут «радостно» ловить SEGV.Совершенно верно. Но если сделать базовые блоки из сишных функций — проблем быть не должно.
Если вы действительно претендуете на универсальность, то напомню ещё про такие вещи, как Web и FPGA. Со вторым, кстати, LabVIEW, неплохо справляется. Но библиотек на C ни там, ни там, вы не получите (с Web ещё есть шансы из‐за emscripten, с FPGA — никаких).Микроконтроллеры вроде на Си программируют, а на чем программируют FPGA? К тому же, Си — всего лишь одна из целевых платформ, можно для разных платформ, не совместимых с Си, сделать свои трансляторы.
Тогда у вас меню с кучей похожих иконок. По моему мнению, когда иконки слишком похожи, вытащить VI из окна проекта проще, чем из меню.Я так и делаю. В Метапроге тоже ничто не помешает сделать меню из списка названий функций.
В вашем редакторе будет то, чего не хватает вам. Но все остальные программисты — не вы. У текстовых языков есть выбор, про графические с альтернативными редакторами я не слышал.Метапрог с открытым кодом, даже начиная с прототипа. Можно добавлять нужные конкретно вам фичи и слать патчи в главный проект. Так, собственно, и работает опенсорс.
Микроконтроллеры вроде на Си программируют, а на чем программируют FPGA? К тому же, Си — всего лишь одна из целевых платформ, можно для разных платформ, не совместимых с Си, сделать свои трансляторы.
То, на чём программируют FPGA, коллективно называется HDL (Hardware Description Language). Наиболее известные — VHDL и VeriLog. G компилируется в VHDL (потому что ПЛИС и компиляторы для них делает не National Instruments). Насколько я помню, LabVIEW позволяет вставлять код на VHDL при разработке для FPGA.
Метапрог с открытым кодом, даже начиная с прототипа. Можно добавлять нужные конкретно вам фичи и слать патчи в главный проект. Так, собственно, и работает опенсорс.
Добавить/изменить код, даже без принятия в upstream — гораздо сложнее, чем просто поменять редактор на более соответствующий нуждам. И, как я сказал, графические редакторы сложнее текстовых.
HDLИспользовании Си в Метапроге не является догмой в последней инстанции и другие языки тоже можно будет добавлять как бекенд.
Добавить/изменить код, даже без принятия в upstream — гораздо сложнее, чем просто поменять редактор на более соответствующий нуждамБыли времена когда даже текстовые редакторы (ed, vi, Emacs) казались чудом (после набивания перфокарт), но при этом были ужасно сложны в использовании (в сравении с современным блокнотом) и требовали постоянной доработки. К тому же, современные IDE для текстовых языков тоже простыми не назовешь.
графические редакторы сложнее текстовыхЭтого не отнять, но если они могут работать со своим же кодом — то эта сложность компенсируется графикой.
Ладно, синус прописывать недолго, пропиши-ка, например, bufferevent_read(struct bufferevent *bufev, void *data, size_t size);, не допустив ни одной ошибки, помня все названия нужных типов, не забыв ни одной запятой и скобки — и это только заголовок!
В этом нет нужды — современные инструментальные среды — они сложнее, чем «блокнот» и подобные вещи делаются в виде автоподсказок.
Не нужно задавать и помнить имена локальных переменных, все в проводках.
Не уверен, что это плюс. То, что переменные поименованы — позволяет легче понимать алгоритм, это мнемоническая подсказка.
Да, вы не ответили на комментарий ниже:
Здорово. А вы не приведет просто-напросто скриншот, прямо здесь, с примером такого diff'а. Ну, чтобы можно было оценить преимущества, наглядность графического diff'а по сравнению с текстовым.
Спасибо.
В том, что не прописываешь, а вытягиваешь в виде блока из меню. Ладно, синус прописывать недолго, пропиши-ка, например, bufferevent_read(struct bufferevent bufev, void data, size_t size);, не допустив ни одной ошибки, помня все названия нужных типов, не забыв ни одной запятой и скобки — и это только заголовок!
Для этого есть автодополнение. Подсказывать идентификаторы, которые уже встречались в тексте умеет практически любой редактор, что сложнее блокнота. Куча редакторов ещё и подтянут тип идентификатора и покажут его в подсказке (а для функций тип содержит и возвращаемое значение, и аргументы). Для часто встречающихся конструкций можно создавать snippet’ы — целые блоки кода, вставляющиеся по одной команде (в LabVIEW, кстати, такое тоже можно). Если вы пишете вызов функции, то в хорошее автодополнение вполне себе умеет и показывать название и тип того аргумента, который вы сейчас пишете, и дополнять только совместимые типы. IDE по слухам могут ещё больше, но я предпочитаю использовать *vim.
Кроме того, я замечу, что заголовок нужно написать один раз. Имени функции в автодополнении, конечно, не будет, но типы будут. И имена переменных могут быть тоже, особенно если вы не создаёте функцию, которая имеет дело с совсем новой сущностью.
В Метапроге (даже прототипе) вытащил блок функции — и типы прописывать не надо, какими сложными они б ни были. Вытягиваешь константы, входы или выходы нужного типа по клику на подсказку, соединяешь все проводками. Не нужно задавать и помнить имена локальных переменных, все в проводках.
При вызове функций типы ни в одном современном текстовом языке прописывать в бо́льшинстве случаев не надо. Меньшинство — это когда вывод типов не сработал.
Про имена локальных переменных: если у вас есть хотя бы три провода одного типа, идущих в параллель, то без подписывания, что это такое, понять схему становится намного сложнее. Когда я пишу на LabVIEW, то я всегда держу контекстную помощь включённой, а она показывает вещи вида «это массив array, состоящий из элементов value типа f64». Как не сложно догадаться, если в подсказке идентификаторы будут именно «array» и «value», то толку с неё будет не очень. Поэтому в моём коде вы можете увидеть, к примеру, что есть case structure, в котором в одном случае пришедший по очереди variant превращается в массив булев, и в соседнем случае он делает то же самое. А при наведении курсора на эти массивы вы увидите, что в одном случае это массив «oes» из элементов «oe», а в другом — массив «clk_enables» из «clk_enable» (на диаграмме не видно, поскольку это трата места и всё понятно и так из названия case, если нет — то я включаю отображение метки константы с типом верхнего уровня (т.е. самого массива), но всё ещё скрываю название элемента). И в результате протянутые по циклу провода называются нормально, хотя без контекстной подсказки выполненной работы не видно вообще.
И это весьма раздражает: в текстовом языке мне нужно придумать имя переменной и написать его примерно один раз, если оно большое (потом автодополнение). В LabVIEW мне нужно придумать имя переменной (не только потому что подсказки, но ещё и потому, что терминалы SubVI должны иметь нормальное название) и писать его на порядок чаще — потому что нет автодополнения и потому что в текстовом языке мне не нужно называть элементы массива. Иногда спасает копирование — вставка.
А, и насколько я знаю, обычно в LabVIEW принято не полагаться на подсказку, а подписывать провода с помощью label на диаграмме, если они длинные и/или их много в параллель. Но в этом случае не только опять нет автодополнения, но ещё и вы даже не можете получить название провода автоматически из названия терминала, который является для него источником — одна из причин использовать именно подсказку заключается в том, что если я подпишу все терминалы и все константы, то она будет автоматически показывать что‐то адекватное в бо́льшинстве случаев и мне не нужно будет думать, насколько оправдана трата времени на создание label у провода (и я их всё равно иногда подписываю, просто реже).
Когда я пишу на LabVIEW, то я всегда держу контекстную помощь включённой, а она показывает вещи вида «это массив array, состоящий из элементов value типа f64».
насколько я знаю, обычно в LabVIEW принято не полагаться на подсказку, а подписывать провода с помощью label на диаграмме, если они длинные и/или их много в параллельДля меня все очевидно именно через контекстную справку.
вы не ответили на комментарий ниже:Я не могу отвечать на все комментарии из-за 5-минутного ограничения из-за низкой кармы. А по поводу diff — пока что он не настолько красивый как мог бы быть, так что пока что скринов не будет. Есть желание — качай прототип Метапрога и тестируй его, заходи в Метапрог онлайн и входи в процесс разработки Метапрога.Здорово. А вы не приведет просто-напросто скриншот, прямо здесь, с примером такого diff'а. Ну, чтобы можно было оценить преимущества, наглядность графического diff'а по сравнению с текстовым.
А по поводу diff — пока что он не настолько красивый как мог бы быть, так что пока что скринов не будет. Есть желание — качай прототип Метапрога и тестируй его
Я просто пытаюсь подсказать вам, как вы можете улучшить свои позиции.
Сложности с diff'ом — один из краеугольных камней в аргументации противников графического метода.
Что касается «раздутого и полного багов» софта — то тут как раз всё не в пользу LabVIEW — словить исключение в рантайме на сложном проекте как нефиг делать — ну и, как говорится, флаг в руки. Напороться на баги в майкрософтовской студии и в компиляторе можно, но не так просто, ибо среда разработки широко используется, достаточно хорошо оттестирована, и т.д., а в LabVIEW, которая не так распространена — они сплошь и рядом. Понятно, что сложность графической среды несколько выше текстовой, но тем не менее. Я начал работать с LabVIEW начиная с пятой версии почти двадцать лет назад, так вот версию 6.0i я до сих пор вспоминаю с дрожью.
понятие библиотек, соглашений о вызовах, понимание потокобезопасности, состояний гонки, очереди, семафоры рандевуМногое из этого я понял из Лабвью.
алгоритмическое мышление, паттерны проектирования, понимание взаимодействия с операционной системой и т.д. никто не отменял и в графическом программированииРечь не об этом, а о том, что представлять все это можно и нужно в графике, а не тексте.
Что касается «раздутого и полного багов» софта — то тут как раз всё не в пользу LabVIEWЭто недостатки конкретно Лабвью, а не графического программирования как такового. И все же самый главный недостаток Лабвью — закрытость и пропиетарность, что и сдерживает его распространение. Поэтому я и делаю Метапрог ему на замену.
Речь не об этом, а о том, что представлять все это можно и нужно в графике, а не тексте.
Возможно это и так, но то как это делает LabVIEW — точно не тот подход.
Как ужe писали — для нано-проектов работает нормально, но абсолютно не масштабируется. И «зум мышкой» тут не поможет, в принципе концепция не та.
Свое мнение о текстовых языках я составил по этой статье
Но эта статья — не о текстовых языках. Она о проблемах более высокого, нежели синтаксис/метод задания операций уровня.
Если учиться текстовым языкам сложно
Текстовым языкам учиться не сложно — синтаксис осваивается (если мы не говорим о, скажем, понимании последних плюсов во всех мелочах) дай бог за месяц. Проблема с дальнейшими абстракциями, и графический язык тут ничего не улучшит — он заменит синтаксис, но все эти проблемы останутся — они лежат в иной плоскости.
Посмотри на код прототипа Метапрога. Я редко делаю тесты как отдельные сущности, дебажу прямо на диаграммах пробами и брейкпоинтами на проводках.
Простите, но вот это вот — Данинг-Крюгер в чистом виде. Человек спросил вас о тестах (это industry standard в принципе) не просто так — чтобы показать, что это не так просто сделать «в графике», а вы просто ответили «я руками тестирую».
В прототипе Метапрога уже реализовано слияние, даже сравнение диаграмм (старой и новой версии
Здорово. А вы не приведет просто-напросто скриншот, прямо здесь, с примером такого diff'а. Ну, чтобы можно было оценить преимущества, наглядность графического diff'а по сравнению с текстовым.
В Лабвью при ошибке жмешь на «разбитую стрелочку» и оно тебе «пальцем тыкает» где что не так.
В обычной текстовой IDE так же.
По поводу опыта: можете ответить, как часто вам приходилось заниматься рефакторингом кода в текстовых языках и в LabVIEW? У вас есть опыт реализации тестов в текстовых языках и в LabVIEW? А рефакторинга тестов вслед за кодом? Этот «секс с ошибками в синтаксисе» вполне себе оправдан и гораздо лучше того, что вы в LabVIEW можете взять и не указать индекс при получении элемента из массива и LabVIEW это сожрёт, посчитав, что вы решили взять первый элемент (изначально это даже удобно, а вот при рефакторинге куча подобных нюансов заставляет желать бо́льшей строгости).
Мне приходится писать на LabVIEW и приходится заниматься рефакторингом. И процесс рефакторинга в LabVIEW мне совершенно не нравится, даже несмотря на то, что специфика работы предполагает, что я работаю над проектом один. По моему мнению, при разработке ПО вам никак не избежать рефакторинга, а конкретно у LabVIEW с этим всё плохо.
Ещё при разработке больших проектов вам не избежать совместной разработки и тут, по моему мнению, у графических языков (уже не «конкретно у LabVIEW») всё будет ещё хуже: понятный diff сам по себе сделать нелегко, а ещё вам нужно как‐то сделать процедуру слияния, которая не будет ни постоянно превращать код в нечитаемое месиво, ни переставлять абсолютно все элементы схемы при малейших изменениях. Ни то, ни другое, мне не кажется совсем невозможным, но это намного сложнее реализовать для графических языков.
У вас есть опыт реализации тестов в текстовых языках и в LabVIEW?Посмотри на код прототипа Метапрога. Я редко делаю тесты как отдельные сущности, дебажу прямо на диаграммах пробами и брейкпоинтами на проводках.
Этот «секс с ошибками в синтаксисе» вполне себе оправданВ Лабвью при ошибке жмешь на «разбитую стрелочку» и оно тебе «пальцем тыкает» где что не так.
вы в LabVIEW можете взять и не указать индекс при получении элемента из массива и LabVIEW это сожрёт, посчитав, что вы решили взять первый элемент (изначально это даже удобно, а вот при рефакторинге куча подобных нюансов заставляет желать бо́льшей строгости).По-хорошему этот терминал должен быть обязательным. Или «условно-обязательным», чтоб при дебаггинге можно было просматривать подключены ли такие-то терминалы такой-то функции. Но так как Лабвью с закрытым кодом, изменить это нельзя. Приходится пилить Метапрог.
Кстати, почти всегда я делаю все входы своих функций обязательными для подключения. То же самое в самом Метапроге, но уже по-умолчанию.
Ещё при разработке больших проектов вам не избежать совместной разработкиУ Лабвью с этим, конечно, хреново, но в Метапроге я планирую даже делать возможность одновременной онлайн-разработки.
понятный diff сам по себе сделать нелегко, а ещё вам нужно как‐то сделать процедуру слиянияВ прототипе Метапрога уже реализовано слияние, даже сравнение диаграмм (старой и новой версии). Есть даже репозиторий и система контроля версий (Метапрог онлайн). Есть Лабвью — попробуй потыкать.
Посмотри на код прототипа Метапрога. Я редко делаю тесты как отдельные сущности, дебажу прямо на диаграммах пробами и брейкпоинтами на проводках.
Тесты — они как бы не для отладки, они для того, чтобы показать наличие ошибок. Откуда вы узнаёте, что надо «дебажить»?
В Лабвью при ошибке жмешь на «разбитую стрелочку» и оно тебе «пальцем тыкает» где что не так.
А в текстовых языках не так? Тот же Rust не только покажет, где ошибка (с точностью до символа), но зачастую ещё и исправление предложит. Но обычно во всех достаточно развитых языках есть указание на символ с ошибкой, а также IDE, которые умеют как минимум туда прыгать (если не вообще показывать ошибки во время набора). А почти во всех текстовых языках есть указание на ошибку с точностью до строки.
В прототипе Метапрога уже реализовано слияние, даже сравнение диаграмм (старой и новой версии). Есть даже репозиторий и система контроля версий (Метапрог онлайн). Есть Лабвью — попробуй потыкать.
Вопрос в первую очередь про понятный diff. Замечу, что diff
применяется к проекту, не к одной диаграмме. Это особенно актуально, если вы используете ту же идею «один файл — одна функция».
Со слиянием примерно то же — какое‐то слияние сделать не так уж сложно. А вот чтобы после слияния диаграмма выглядела не сильно хуже, чем до…
Кстати, увидел в аннотации «Открывать и запускать! метапрог.vi и! метапрог онлайн.vi». Напомню, что для получения хоть какой‐то популярности вам придётся использовать английский, и лучше начинать это делать сразу. Ну и при использовании английского нужно использовать исключительно ASCII: LabVIEW даже в 2019 году не умеет в Unicode. Впрочем, судя по требованию «с кириллической локализацией», вы об этом знаете.
Тесты — они как бы не для отладки, они для того, чтобы показать наличие ошибок. Откуда вы узнаёте, что надо «дебажить»?Тест — это что? Вызвать функцию, подать параметры и сравнить результат с ождаемым? С графическими блоками диаграмма теста будет напоминать испытательный стенд для физических микросхем.
какое‐то слияние сделать не так уж сложно. А вот чтобы после слияния диаграмма выглядела не сильно хуже, чем до…Слияние и diff пока что в зачаточном состоянии. Уже есть, но еще нет того удобства и наглядности, которая будет в готовом виде.
для получения хоть какой‐то популярности вам придётся использовать английский, и лучше начинать это делать сразуМетапрог, так же как и Метапрог-проекты и диагарммы, будет мультиязычным. Ведь логика здесь не прописывается (за исключением сишных вставок), а собирается из блоков и тут английский будет использовать необязательно. Но, чтобы англичане понимали, можно делать и английскую локализацию названий.
Тест — это что? Вызвать функцию, подать параметры и сравнить результат с ождаемым? С графическими блоками диаграмма теста будет напоминать испытательный стенд для физических микросхем.
Плохой вид тестов — это минус графических языков, а никак не тестов. Я, правда, ничего такого плохого в тестах данного вида не замечал, за исключением проблем с их рефакторингом.
Метапрог, так же как и Метапрог-проекты и диагарммы, будет мультиязычным. Ведь логика здесь не прописывается (за исключением сишных вставок), а собирается из блоков и тут английский будет использовать необязательно. Но, чтобы англичане понимали, можно делать и английскую локализацию названий.
Английский использовать необязательно для разработциков на метапроге. Разработчику метапрога его использовать обязательно, иначе сам метапрог будут использовать только те, кто говорит на языке автора. А локализация… вам очень нужно делать двойную работу? Особенно если вы будете принимать исправления.
при разработке больших проектов вам не избежать совместной разработки и тут, по моему мнению, у графических языков (уже не «конкретно у LabVIEW») всё будет ещё хуже: понятный diff сам по себе сделать нелегко, а ещё вам нужно как‐то сделать процедуру слияния
Мы работаем командой, но всячески избегаем diff/merge, и этого достигаем за счёт очень высокой «гранулярности» проекта. Иными словами, он разбит на небольшие модули (вплоть до интерфейса, который тоже собирается через вставку панелей) и в результате в каждый момент времени над одним модулем работает один разраб. Опять же небольшой размер и унификация позволяет легко перебрасывать модули между членами команды (скажем, в отпуск кто ушёл или заболел). Ну и диаграммы стараемся держать в размер экрана (ну, правда 30 дюймов экрана, но всё же) и в основном рефакторинг на три четверти — это упрощения разросшихся диаграмм путём организации подприборов. Ну а на небольших диаграммах и автоматический Clean Up более-менее вменяемо работает. Вот сейчас посмотрел — 6К+ VI/Ctl раскидано по 300+ модулям, больше десяти лет уже в продакшене, полёт нормальный. Впрочем пора с оффтопиком завязывать — всё-таки тут Ü обсуждается.
Merge так избежать можно — я сам бью VI на довольное мелкие, потому что мне нужно таскать изменения из ветки в ветку (проект разрабатывается так, что у меня есть ветка с «шаблоном» проекта и есть по ветке на каждое конкретное испытываемое изделие). Diff — нет, он для того, чтобы посмотреть, что реально изменилось.
я сам бью VI на довольное мелкие, потому что мне нужно таскать изменения из ветки в веткуСлишком мелко разбитые VI создают оверхед, если не инлайнить. А если инлайнить — усложняется дебаггинг. Все жа Лабвью не идеал (однако при этом лучшая среда разработки из существующих).
В моей практике он не особо усложняется — достаточно отладить один раз и включить встраивание потом. Кроме того, есть два особых случая:
- Если цель — FPGA, то встраивается всё и всегда. И в качестве отладки вам доступны только что‐то вроде «отладочного printf» (в гораздо менее удобной форме, чем если бы это действительно был отладочный printf) и попытки понять, что не так, потыкав осциллографом. И ещё тесты на хосте для SubVI, если SubVI не используют чего‐то, специфичного для FPGA. (Ну и метод «пристального взгляда», куда же без него.)
- LabVIEW’шный вариант дженериков (они же mallable VI) можно иметь только если эта самая VI настроена на встраивание.
Чего я не могу понять при этом всём встраивании — почему авторы LabVIEW не позволяют настроить два варианта запуска — один используется, когда вы открыли VI и запустили сами, другой — когда VI — это SubVI. Весьма неудобно.
Кстати, насколько я знаю, не выключение отладки всегда создаёт overhead.
На Хабре нас,
А можно узнать, как будет выглядеть работа с VCS на этом языке? История изменений в большом проекте, сравнение двух версий одного проекта, аннотации те же (какое изменение каким пользователем было сделано)?
![image](https://habrastorage.org/getpro/habr/comment_images/03c/1da/e38/03c1dae38435d9971ca7c08a49059ea0.png)
Опять же, это всего лишь прототип.
сделайте свой пост «metaprog» и резвитесь наздоровье, зачем же здесь флудить?..
Язык программирования Ü. Введение, мотивация к созданию, цели