Как стать автором
Обновить

Комментарии 75

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

Выдумывать язык под каждую задачу -- это путь в ад. Те, кто программируют на ФП-языках, знают, что в них легко навертеть свой под-язык. Но другим членам команды нужно его учить и дебажить, что сводит на нет начальные преимущества.

Уточню, что сейчас для создания сайта нужно знать:

  • HTML

  • CSS

  • JavaScript

  • SQL

  • regex

  • bash/shell

  • один из языков бекенда

То есть уже многовато, а в каждом языке свои фремворки. Больше языков => раньше наступит комбинаторый взрыв.

...или один lisp и разные интерпретаторы!
/s

чтобля?
начнем с того что для создания сайта (просто сайта) сейчас нужно знать только html+css
и то и то можно за день познать и за месяц осознать полностью

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

SQL вообще не в тему.
если затронули бек, то сейчас все через ORM и для 80% задач хватит базы

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

фреймворки != язык
и сейчас фреймворки можно назвать отдельным языком, потому как временами синтаксический сахар становится синтаксисом

начнем с того что для создания сайта (просто сайта) сейчас нужно знать только html+cssи то и то можно за день познать и за месяц осознать полностью

  1. Тут бы определение, что можно считать "просто сайтом"

  2. А деплоить кто будет?

  3. Невозможно эффективно пользоваться ORM и при этом не знать SQL

  1. 90% "просто сайта" это визитки или/и лендинги

  2. Сейчас все для людей, взять хостинг и залить на него сайт можно одной мышкой и за 10 мин

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

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

Если ORM сделана качественно, то SQL можно вообще не знать.

Зависит от нагрузки. ORM дает удобство, но платить за это приходится скоростью + генератор запросов иногда может упороться и выдать какую-то дичь, так что sql знать нужно.
Ну и полное понимание принципов БД, без тыкания в них палкой при помощи написания всяких селектов и апдейтов, как мне кажется, невозможно.

Вот-вот. И при этом под каждый язык есть свои девелоперы (SQL-разработчик, фронтендер, бэкенд-разработчик). И нас еще часто спрашивали, а зачем мы сделали один язык, на котором можно и в SQL, и в backend и в фронтенд.

SQL, regex, bash/shell

Не обязательны вообще ни разу.

один из языков бекенда

Это может быть тот же JavaScript.

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

Хранилище бывает no sql, сборка одной командой осуществляется, скопировать файлы итоговые можно банальным rsync-ом или вообще руками. А для валидации кучу библиотек понаписали. На любителей регулярочек регулярно натыкаюсь. То они точку в имейле запретят, то ещё что-нибудь учудят.

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

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

так WordPress это и есть по сути такой высокоуровневый "малый ЯП" для создания сайтов !!

Скорее нет, иначе ворд это "высокоуровневый яп для создания документов". Низкоуровневым тогда будет какой-нибудь LaTeX

Любой мало мальский большой проект, представляет собой отдельный язык: набор своих функций и объектов.
Каждый фреймворк-язык приносит с собой головную боль, не устраняя необходимость знания технологий на которых он основан.
Хотя вру ассемблер сейчас знать уже не надо.
Может знания CSS и HTML уйдут в прошлое, что иногда встречаю.
Да и SQL не знают используюя ORM в питоне, а во времена Delphi это было вообще правилом.
Вообщем то самый простой для изучения язык это ASM, и чем выше уровнем язык тем больше функций в языке появляется.

ASM для изучения может быть и прост, но писать на нём ой как не просто ))

Это write-only язык 😆

а примеры этого утверждения есть?

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

Если язык не для алгоритмов, то он не язык программирования. Самый малый язык, который существует - язык машинных кодов =) Чуть больше MASM. Очень лаконичный C. А есть и Erlang.

Будущее языка определяется количеством носителей, документации, практики и количеством постов на SO

Хм. Пример с уравнениями Максвелла и наблой слишком прост. В математике всё хорошо формализовано, и пожалуйста - есть какой-нибудь Maple.
Я б сказал, если мы можем выделить какие-то объкеты/понятия и они важны большому количеству людей - да, можно сразу ваять новый язык программирования.

Ну то есть академики предлагают разделить проект на два: компилятор "малого языка" и собственно код. Тут есть две проблемы:

  1. всё течёт, всё меняется. Со временем, "малый язык" перестанет удовлетворять требованиям и его придётся улучшать. Тут же вылезут проблемы совместимости, криворукости и всего такого. Просто академики пишут код один раз, публикуют статью и до свидания. В промышленности кодовая база должна жить годами и десятилетиями.

  2. оно уже примерно так и работает. Серьёзный проект строит продукт на внутренних и внешних библиотеках, которые как бы и выступают "малым языком", но при этом находятся в той же кодовой базе и написаны на то же языке, что и сам проект. Что, естественно, куда удобнее, управляемее и долговечнее.

Я как-то давно высказал мысль за которую схватил кучу минусов ))) - зачем нужны новые языки если есть (например) С++ на котором можно написать всё?
Относительно низкоуровневые языки программирования не содержат ограничений, таким образом можно создавать фреймворки, наращивать функционал и т.п... С другой стороны возникает желание сознательно ограничить возможности пользователя, чтобы он не наделал лишнего. На Хабре была статья, что каждая новая парадигма программирования (ООП, ФП) это новые ограничения.
Я сам являюсь (своего рода) автором языка программирования (некий интерпретируемый язык для перемещения координатного устройства и подачи команд на АЦП), и соответственно у нас есть доступ к коду на С++ куда мы постоянно лазим и расширяем возможности - и без этого было бы очень грустно.

Потому что С++ слишком сложный

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

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


Вообще упрощённый Си с классами это. Java (ну и C#), так как в основном Java и была построена на идеи — возьмем С++ и отрежем все избыточное и вызывающее головную боль (даже ручное управление памятью из этой оперы.

А можно пример устаревших вещей в Си ?

Мне на Си написать какую нибудь CGI-шку для простенького сайта с опросом гораздо проще и быстрее чем разбираться с миллиардами фремворков специального назначения. Полностью согласен с предидущим оратором - чрезмерное богатство языков это злейшее зло!

А можно пример устаревших вещей в Си ?

goto, define макросы, циклы for без foreach и проверки выхода за предела массивов, ручное управление памятью (ну тот спорно, конечно, но оно не нужно для 99% задач).


быстрее чем разбираться с миллиардами фремворков специального назначения… чрезмерное богатство языков это злейшее зло!

Ну и какая связь с фреймворками и самими языками?


Никто вас и не заставляет использовать миллиарды фремворков, на условной java базовый синтаксис (без стандартной библиотеки функций) это несколько десятков конструкций (особенно если не использовать многопоточное программирование) — if, for, switch, while, do while, conts, var, final, return, class, main, public, protected, static, private, enum, interface, try catch finally, throws, import, package, String + 8 примитивных типов и определение массивов. Ну и понимание как определяются класы и функции.


Все остальное опцинальные использование стандартной библиотеки — никто не мешает взять и написать все те же функции самим.

А можно пример устаревших вещей в Си?

goto, define макросы, циклы for без foreach и проверки выхода за предела массивов, ручное управление памятью…

Вы это сами придумали или кто сказал? Си предназначен для написания небольших утилит и библиотек. Из который потом можно компоновать более сложные конструкции (например с помощью bash или python). Но когда надо строить монолит, оказывается что в нём нет namespace и отделять чужие кирпичи от более чужих с одинаковыми именами вызывает страдания. И в отличии от C++ в C всё делается явно. Например вы не можете в C++ выставить наружу интерфейс со строками или лямбдами, даже в виртуальных таблицах классов могут пропадать методы из за оптимизаций. В Си вы все ваши извороты можете описать явно. Например корутины в Cи вы сможете записать состояние в файл и потом загрузить, а вот C++20 корутинах нет, т.к. там всё от вас скрыто. Зато есть десяток мест кастомизации, и одинаково выглядящий код может делать совершенно не то что вы ожидаете. Не говоря уже об аккуратно разложенных UB которые сразу не видно, но со временем они обязательно всплывают.

Так можно и дальше спускаться - к ассемблеру и машинному коду. Еще понятнее, еще низкоуровневее. Только писать дольше.

каждый новый слой требует больше «кирпичей», чем предыдущий

И каждый использует свои кирпичи и еще переходники к чужим кирпичам и переходники к переходникам переходников тоже.

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

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

Мы как бы пишем диалект под игры, программы или сайты.

И уже на нем написано конечное приложение.

Увы, но select функции может иметь сайд-эффеуты

Многие библиотеки питона (pandas, numpy,...) уже можно назвать малыми языками для определённых задач. Но они совместимы с питоном и многие поддерживают элементы друг друга, что лучше, чем отдельные малые языки.

В качестве наглядного примера можно привести ядро Linux, которое в 1992 году состояло из примерно 10 000 строк кода. Спустя двадцать лет, его размер достиг около 30 миллионов строк.

Откуда берется столько кода? Я не думаю, что расширение функциональности может объяснить такой рост его объёма; скорее, это связано с нашим подходом к разработке ПО. Обычно новые функции в программе добавляются поверх уже существующих, как при строительстве пирамиды.

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

На самом деле проблема надумана — язык это 10% сложности программирования, основная часть сложности это фреймворки, библиотеки, инструменты для разработки и сборки и как сделать что полезное. То есть вся экосистема, возникшая поверх языка. Перейти на другой язык не проблема — перейти на другую экосистему сложно.

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

И написаны настолько криво и убого, что например для просто склейки двух бинарников (загрузчик+прошивку) тянут с собой пайтон третий, а для вычисления CRC32 по обоим бинарникам скачивают тикль, а для записи внутрь бинарника CRC32 LUA и тд.
Горшочек не вари! ведь скоро атомов во вселенной может не хватить чтоб ЭТО заработало /sarcazm

Ибо генераторы абстрактных фабрик конфигураторов скриптов сборки нужного тебе проекта порой генерят не саму сборку а скрипт сборки в 40 тыщь раз больше чем сама прошивка.

Ох уж этот дивный мир сборки C, где сначала придумали make чтобы не писать shell-скрипты для сборки, а потом придумали automake чтоб не писать и тем более не шаблонизировать Makefile-ы вручную... В итоге генерируются configure-скрипты на 30 тысяч строк, которые затем (через пару минут работы) превращаются в Makefile на 5 тысяч строк.

>В итоге генерируются configure-скрипты на 30 тысяч строк, которые затем (через пару минут работы) превращаются в Makefile на 5 тысяч строк.


это не так плохо, к сожалению не все ITшники видят всю картину целиком: когда они делают отдельные инклудники для отдельных либ, а этих либ много сотен потому что на каждую разновидность периферии по либе, т.е. ADC1 - одна либа, ADC2 уже другая TIMER1 третья а TIMER2 четвёртая потому что первый таймер трёх фазный а второй трёхфазный с dead интервалами и в итоге сотни либ порождают строку конфигурации gcc в десятки тысяч символов в строке ... но вот в скрипте 5 тысяч таких строк
поэтому и получаем под сотню мегабайт скрипт сборки.
(плюс define дофига, плюс каждый *.a или *.lib файл надо отдельно слинковать и тд и тп)

PS. И эти люди жаловались на SPL от STM32 где ты просто скопировал или слинковал две папки, инклудников и исходников и установил пару define ов. И все работало как чистые функции без глобальных переменных и состояний.

НЛО прилетело и опубликовало эту надпись здесь

Не сделают. Квантовые компьютеры - вообще не про хранение больших объемов, и для написания make-ов они точно не помогут.

Уравнения Максвелла - очень лаконичные и совершенные, но никак не относятся к языкам программирования.

Интересно видеть как снова просыпается интерес к специализированным языкам. Идеи Н. Вирта снова востребованы :-)

SQL не парюсь вообще

ребята мне проще написать запрос в базу без ОRM

SQL ну оч простой, php и то проще вы что такого не знаете?

Программирование это кухня. Где фрэймворки это мясорубки, блендеры и т.д. Обычные языки это ножи, вилки, ложки. А малые языки это открывалки, штопоры, толкушки и т.д. В принципе приготовить блюдо можно только вилкой, ложкой и ножом. Вопрос в эффективности.

Проблема в том, что, как и в случае с пирамидой, каждый новый слой требует больше «кирпичей», чем предыдущий.

Походу, автор видит пирамиды примерно так 😄

Почитайте про пирамиды Майя, и как у них расположены слои кирпичей.

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

Интересно, forth это мини язык?

Форт - скорее минималистичный универсальный.

awk - миниязык (хотя, кажется, его преднамеренно заморозили), регекспы, спека sed - миниязыки.

Языки 90х - это простые универсальные инструменты. Их библиотеки линейны, в смысле, просто сокращают длинный код до одной функции. Программисты в это время - универсальны.

Но в 1985 уже появляется Borland TurboVision, 1986 - Erlang/OTP, 1996 - JavaBeans. Это были первые ласточки того, что сегодня называется "фреймворками" и всякий суслик в своей жизни должен написать такой же, но новый. По сути - это и есть определения новых языков, но не доведённые до полной абстракции.

Кстати, в своё время Lisp был идеальным генератором языков и позволял очень "вкусно" кодить снизу вверх - создавать свой язык описания задачи и на нём её формулировать. Но была загвоздка: (чтобы (помнить (порядок (скобочек, аргументов)))), нужно было иметь очень хорошую память. Сегодня есть подсказки в редакторах, есть docstrings, есть ИИ, чтобы транслировать свежеизобретённый набор алгоритмических сущностей на человечий язык и всё это может заиграть вообще новыми красками.

На Брейнфаке все будем программировать?

Привет всем! Мне как-то тоже приходили мысли о будущем ЯП. Сказать однозначно какой путь правильный, сложно т. к. я не знаю ВСЕ ЯП, фреймворки и т. д.)). Кажется, что на "каком языке разговаривать" определяется при рождении проекта. С ним (набором технологий разработки ПО) проект и живёт свою жизнь. Если кто знает пример перевода на "другие рельсы"... Думаю это будет не малая статья.

Я хотел бы предложить идею о сближении синтаксиса языков (вероятно один родить будет сложно), но вот пример одних и тех же конструкций на разных ЯП:

  • fun, func, function

  • if (a == b) {}, if a==b {}

  • Разница синтаксиса конструкций switch... case

  • for...

  • наличие ; в конце строки

    И. Т. Д.

    Думаю, что такие тенденции, вожможны в будущем.

Вы предлагаете обобщить базовый синтаксис, но он и не является проблемой. Выучить ключевые слова и общие правила расстановки скобок и отступов в новом языке можно за день, а то и вовсе автоматически преобразовать имеющийся код к новым требованиям. Примерно тем же самым, только внутри одного языка, уже занимаются программы для автоформатирования кода. Условному astyle достаточно передать ровно 1 аргумент, чтоб привести код к одному из стандартных стилей. Даже если условные JS и Go требуют разного синтаксиса, то их по большей части можно преобразовать друг в друга, что даже сработает для простых случаев типа школьных заданий по информатике (вроде "Пользователь вводит 2 числа, программа должна вывести большее из них, или же написать что они равны").

Настоящая же сложность в том, что разные языки имеют разные библиотеки ( = разные имена системных констант, функций, классов, модулей, ит.д.), а самое главное - зачастую и разные идеи. В браузерном JS нет тредов, в лучшем случае service worker'ы, значит горутины не получится "просто переименовать". А прямого доступа к TCP/UDP нет вообще, только HTTP(S), WebSocket и RTP DataChannel, значит никакую программу, использующую другие сетевые протоколы вы в принципе не можете портировать без значительных изменений. А ни в JS, ни в Go нет поддержки настоящих, системных тредов, которая есть в Rust (и условный tokio позволяет очень легко запускать и таски = гринтреды = горутины). А паттерн-матчинг из того же Rust (match) чем заменять, switch-case ведь даже близко не подходит - цепочками if-ов?

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

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

А паттерн-матчинг из того же Rust (match) чем заменять, switch-case ведь даже близко не подходит

Почему не подходит? В Java вот так сделали, не вижу, чем оно плохо:


var out = System.out;
switch(shape) {
  case null                -> out.println("Nothing.");
  case Circle c
      when c.area() >= 100 -> out.println("A large circle.");
  case Circle c            -> out.println("A small circle.");
  case Square s            -> out.println("A square.");
  default                  -> out.println("An unrecognized shape.");
}

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

Когда я писал комментарий, я имел в виду switch-case как он есть в C, умеющий только сравнивать одно значение за ветку (то есть не pattern matching а value matching). Но конечно же никто не запрещает оставлять имеющиеся ключевые слова при наращивании возможностей.

В первых подвижках к паттерн-матчингу в Java, кстати, добавили поддержку swich-as-expression и возможность указывать несколько значений как ожидаемые для входа в ветку:


System.out.println(switch(policy) {
  case FORBIDDEN, DENIED -> "You do not have permission to do the thing";

  case ALLOWED -> {
    doTheThing();
    yield "The thing is done!";
  }
});

Там вообще с восьмой версии немало полезных для выразительности плюшек добавили в разных местах. Хотя лямбды сами по себе, конечно, по-прежнему имеют максимальный эффект.
И сейчас уже вышла версия JDK 21(!), так что стимулы обновиться очень хорошие.


Ворчание

Вот обновлялась Java по одной версии за три-пять лет, так люди плевались, что язык безнадёжно устарел, и на нём только старпёры пишут. Сделали более быстрый release cycle — и теперь примерно те же люди сами сидят аж на восьмой версии.

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

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

То же самое с "малыми яп".

Заметил пару спорных моментов на которых базируется вся статья :)

  1. Объем кода

Суть идеи заключается в том, что когда вы начинаете находить закономерности в своем приложении, вы можете закодировать их при помощи малого языка. Этот язык позволит вам выразить эти закономерности более компактно, чем это возможно с помощью других средств абстракции. Что позволит не только противостоять тенденции к постоянному увеличению размера приложений, но и сократить объём кода в процессе разработки!

Объем кода != когнитивная сложность. При добавлении большего числа инструментов мы усложняем поддержку приложения, поэтому очень не всегда это приведет к позитивным эффектам.

И даже если малый язык позволит реализовать тот же функционал используя более простые абстракции, это все еще может не привести к упрощению поддержки, так как она в большей упирается в количество РАЗНЫХ абстракций, а не количество из переиспользований.

  1. Предел выразительности кода

 Я лично убежден, что мы достигли предела выразительности языков общего назначения. Если есть уровень выше, то как он будет выглядеть? Возьмем, к примеру, Python — он настолько высокоуровневый, что практически выглядит как псевдокод.

Не только синтаксис влияет на выразительность языка, а его улучшение не сводится к инкрементальным изменениям. Существуют принципиально различные варианты синтаксиса и написания кода, которые обладают большей выразительностью (LISP vs C-подобные языки, декларативный vs императивный код). И это все может проявляться даже в рамках одного языка.

P.S. Приверы других вещей которые влияют на выразительность помимо синтаксиса: парадигма программирования, фреймворки, набор абстракций используемых в коде, структура файлов проекта, документация (в том числе комментарии), типизация и даже такие вещи как сообщения в коммитах в Git. Все это в совокупности постоянно используется в работе с кодом и у нас впереди еще необъятная возможность к совершенствованию :D

Прочитал статью и вспомнил про недавно прочитанную книгу Кернигана "Время Unix". Он там тоже высоко оценивал роль Yacc и Lex в деле лёгкого создания специализированных языков программирования.

И опять. Пилить дрова удобнее цепной пилой. Нарезать фанеру прямоугольными листами - циркуляркой. Вырезать сложные контуры - лобзиком. Для специальных работ есть специальные пилы (торцовки те же). И почему-то никому в голову не приходит мысль сделать суперуниверсальную вундервафлю которой и деревья валить и нелинейные контуры вырезать было бы одинаково удобно.

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

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

А теперь представьте что у вас задача с одной стороны связана с работой с БД и какими-то коммерческими вычислениями, а с другой, там есть что-то низкоуровневое типа сокетов, пайпов и т.п.

И для ее решения вам предлагают стек, в котором есть как язык, позволяющий работать с системными делами (сокеты), так и некий специализированный язык, нативно поддерживающий embedded sql, всякие типы данных с фиксированной точкой (фактически, нативная поддержка всех sql типов данных - decimal, numeric, date, time, timestamp и т.п.). Т.е. вам не нужно никаких внешних библиотек, никаких зависимостей, не нужно создавать никаких объектов для работы с тем или иным типом. Просто объявляете структуру записи (причем, ее можно объявить просто ссылкой на формат таблицы в БД), читаете туда запись и работаете с ее полями. И все это на уроне языка и поддерживаемых им типов данных и операций с ними.

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

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

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

Новые потребности постоянно добавляются в существующие яп, раздувая их.
Удобство использования достигается с помощью синтаксического сахара, который делает поддержку возможностей нативной. Вопрос только во времени появления таких возможностей. Какой то новый яп может уже включать нативную поддержку их и чтобы не проиграть в конкурентной борьбе, существующие яп тоже добавляют такие возможности.
Проблема здесь в том, что яп разрастается, включая в себя всё что нужно для работы программистов. Эти возможности придётся постоянно изучать(или новый яп, который непонятно ещё как решает другие необходимые задачи). На это уходит много времени.
Думаю, уже есть потребность в некоем стандарте новых технологий(универсальный яп и описание новых технологий применительно к нему), который позволит с помощью ИИ(будет переводить псевдопрограмму с универсального к конкретному, возможно генерируя библиотеки) решать задачи на любом яп.

Это сильно упростит/удешевит разработку, не придётся переучиваться, достаточно будет знать какой то один яп...

Новые потребности постоянно добавляются в существующие яп, раздувая их.

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

Какой то новый яп может уже включать нативную поддержку их

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

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

"Универсальный ЯП" - это что-то типа машины, которая и для Формулы-1 и для Париж-Даккар. Не находите, что несколько странная концепция?

Почему-то во остальных областях деятельности от этого давно уже ушли.

Никому не придет в голову играть в хоккей на беговых коньках. Или пробежать дистанцию на фигурных.

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

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

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

Почему непонятно как решает? Есть ЯП, который предназначен для решения конкретного круга задач. И известно, что он решает их эффективно и с минимальными затратами со стороны разработчика (тому просто достаточно пользоваться возможностями языка, а не изображать "каракоряк враскоряку" с поиском и прикручиванием кучи фреймворков к языку, который к этим задачам не приспособлен. Вот на это действительно уходит много времени.

Это сильно упростит/удешевит разработку, не придётся переучиваться, достаточно будет знать какой то один яп...

Поверьте, если вы действительно разработчик и действительно знаете (и понимаете) какой-то язык, то освоить еще один абсолютно несложно. Ничуть не сложнее чем постоянно осваивать нововведения с привычный вам язык. Это личный опыт.

У нас есть С/С++ для низкоуровневых вещей и специализированный язык для работы с БД и реализации коммерческой бизнес-логики (и в котором, в отличии от того же С++ в принципе нет такого понятия как UB - все детерминировано и предсказуемо). На освоение его с нуля у людей уходит месяц-полтора (это с учетом что параллельно еще идет освоение очень специфической платформы и "въезжание" в предметную область). При этом компиляторы любого языка, поддерживаемого на платформе, дают унифицированный "объектный" код. Т.е. одна функция на одном языке, другая на другом - все это легко вызывается друг из друга и сводися в одну программу без проблем.

На других платформах сейчас в этом направлении движется LLVM.

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

"Универсальный ЯП" - это что-то типа машины, которая и для Формулы-1 и для Париж-Даккар. Не находите, что несколько странная концепция?

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

То, насколько активно вы предлагаете дробить языки по их области применения, выглядит слишком уж радикально. Да, объединять всё в единый СуперЯзык+++ - не очень разумно, но и 100500 очень эффективных, но очень узкоспециализированных языков - это тоже перебор. Нелегко определить границу, когда "много" становится "слишком много", когда чайная ложка №317 - для клубничного мороженого, а ложка №318 - для шоколадного (у них разный состав сплава, что придаёт им чуть разный цвет, поэтому на фотографиях они смотрятся лучше именно так, а не наоборот). Нишевые языки конечно же могут существовать, но для их существования должно быть достаточно причин: востребованность, универсальность в рамках своей ниши (представьте, что, например, jq не умеет работать с JSONами, у которых корень - не объект), наличие ресурсов на поддержку и разработку (либо "замороженная" предметная область, что позволит сделать поистине готовый продукт).

И даже если будет множество ну очень уж хороших нишевых языков, всё равно будут востребованы пусть и менее удобные, но более универсальные. Примерно как если вы пишите программу для работы с медиафайлами, то для поддержки всего одного-двух форматов лучше подключить конкретные библиотеки (например, libflac + liblame), но если вы хотите более универсальный продукт - вы обподключаетесь по одной, намного проще сразу libav взять.

Хотя, универсальный язык существует, JavaScript называется. Скоро на нём перепишут вообще всё /s

освоить еще один абсолютно несложно

Если только вы при этом не прыгаете с одной парадигмы на другую. После многих лет отборного ООП, переход на (первый) функциональный язык будет... не столь быстрым.

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

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

Нелегко определить границу, когда "много" становится "слишком много"

Как раз легко. Пара примеров.

  1. Есть таблица БД в которой есть поля типов date, time, numeric, decimal (последние два типа - с фиксированной точкой, отличаются способом хранения в памяти). И есть два языка. Один нативно не поддерживает все эти типы. Чтобы работать с ними, нужно подтянуть некоторое количество зависимостей (библиотек) для работы с таблицами БД, работы с этими типами данных и т.п., прочитать запись в байтовый буфер, куски это буфера передать в конструкторы соотв. объектов и только потом с ними работать (да, это может быть скрыто внутри библиотеки, но работать будет именно так).
    Второй язык все это поддерживает нативно. В нем вы просто объявляете структуру данных со ссылкой на формат записи этой таблицы (одна строка - специальный спецификатор likerec), читаете запись в эту структуру и дальше уже работаете с полями - обычные переменные, не объекты, без конструкторов. И любая арифметика с этими типами - прибавить ко времени nn минут, вычесть из даты mm месяцев, представить дату в виде строки в любом из мыслимых форматов (eur, iso,...) И все это средствами языка.
    Что проще?

  2. Есть фраза (допустим, опять поле из записи в таблице, тип char или varchar). Вам нужно разбить ее на слова и обработать каждое слово отдельно. В одном языке вам для этого нужно создать объект string (опять конструктор вызывать) который содержит нужные методы.
    Во втором ничего этого не надо - просто пишем цикл типа for-each word in split(phrase) и работаем непосредственно с той фразой, что получили из записи в БД. Без создания лишних сущностей (объектов).

Все это уже есть в наличии. Ничего придумывать не надо. Достаточно просто рационально использовать готовое.

Хотя, универсальный язык существует, JavaScript называется. Скоро на нём перепишут вообще всё

Вообще все? Вот когда-то делал задачку. К компу подключается кассовый аппарат (USB, аппаратов может быть несколько, подключение нового аппарата необходимо отслеживать автоматически), который работает по своему протоколу (спецификация есть, страниц на 50, там двоичный формат обмена, жесткие таймауты, квитирование и т.п.). Вам на вход приходят данные о покупке (покупатель, сумма...) Ваша задача инициализировать сеанс связи с кассовым аппаратом, отправить ему данные, получить ответ (чек), сформировать блок данных для чека и отправить их на сервер ОФД (оператор фискальных данных). На стороне оператора TCP сервер (не http, tcp) - двоичный протокол обмена, страниц на 100 спецификации - как связь устанавливать, какие таймауты, описание двоичного формата данных, формата подтверждения, что делать в случае неудачно связи и т.п.).
Реализуете на JS? Будет работать? Готовых фреймворков нет, только спецификации протоколов.
Я лет 25 подобными делами занимался. Начинал с разработки софта для управления настенными информационными табло. Потом софт для работы с сетью удаленных промконтроллеров (начинали с простых 8080 и RS-485, закончили STM32 и UDP через MOXA 485<->UDP).

Сейчас банк (центральные сервера, hi-load, mission critical, мозгодробительная бизнес-логика и все дела). И поначалу казалось, что все можно на С/С++ сделать (тем более, что некоторые расширения тут есть для бизнес-логики). Но достаточно быстро понял, что на специализированном языке бизнес-логику писать проще и быстрее. И, что характерно, в общем случае оно еще и работает быстрее в итоге (а тут это критично). А С/С++ можно и нужно использовать там, где требуется какая-то низкоуровневая работа с системными API - вот там это действительно проще. И эффективнее (можно все на одном языке написать, но низкоуровневые вещи на нем сложнее и не так красиво получается).

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

Один нативно не поддерживает все эти типы. Чтобы работать с ними, нужно подтянуть некоторое количество зависимостей (библиотек).
...
Второй язык все это поддерживает нативно

Если второму языку не нужно даже библиотек для подключения к БД (то есть всё нужное есть либо в стандартной библиотеке самого языка, либо предоставлено специальным рантаймом) - значит он специально для взаимодействия с БД разрабатывался, так? А как у него обстоят дела с поддержкой всех других смежных областей, для которых требуется взаимодействие с БД? То есть, если, например, у меня есть вебсайт, работающий с БД - второй язык определённо удобнее с этой стороны, а что у него с поддержкой HTTP(S)? А другому пользователю нужно проводить аналитику по данным из БД - как дела со статистикой в этом втором БД-языке? А третьему пользователю... А четвёртому... То есть либо в итоге второй язык превращается в тот самый комбайн, от которых вы предлагаете избавляться, либо он хорош для одной-двух задач (например, конвертация данных из БД в один из текстовых форматов типа XML/JSON/YAML), а остальным всё равно придётся использовать нечто другое, вместо или вместе с этим БД-языком.

В одном языке вам для этого нужно создать объект string (опять конструктор вызывать) который содержит нужные методы.

Во втором ничего этого не надо - просто пишем цикл типа for-each word in split(phrase) и работаем непосредственно с той фразой, что получили из записи в БД. Без создания лишних сущностей (объектов).

То есть вы описываете примерно такую ситуацию, верно?

// Язык 1
var a = String("abcde");
a.split().forEach(process_segment);

// Язык 2.1
var a = "abcde";
forEach(split(a), process_segment);


// Язык 2.2
var a = "abcde";
split(a).forEach(process_segment);

Но ведь разница - исключительно синтаксическая, в момент создания. Более того, в вашем примере вы уже имеете сущность записи из БД, которая почти наверняка будет представлена как массив структур-строк с полями-колонками, кто же вам мешает обращаться к полям этих самых структур напрямую, без явного копирования в новые переменные?

Реализуете на JS? Будет работать?

Вы упустили (судя по вашему ответу и даже по цитате) два очень важных символа в моём предыдущем сообщении: /s. Это обозначение сарказма в текущем предложении (иногда в целом абзаце).
Но я не удивлюсь, если на npmjs.com найдутся пакеты для взаимодействия со многими +- распространёнными железками. Например, raspi-sensors (устаревший) или i2c-bus - раньше с железками на ASM/C взаимодействовали, потом пришла Arduino со своим C++ с библиотеками, более известном как Wiring (он был и до Arduino, но не так известен), а теперь вот можно и из JS битиками в провода пулять.

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

А никак. Суть этого подхода в том, что из этого языка можно вызывать то, что написано, например, на Java. Или на С/С++

С джавой не пробовал, с С/С++ регулярно так делаем.

Обратно - у нас есть вебсервисы, которые вызываются извне, а сами при этом вызывают что-то, написанное на этом языке. Возврат идет или через возвращаемое значение или через один или несколько result set (sql).

всё равно придётся использовать нечто другое, вместо или вместе с этим БД-языком

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

Но ведь разница - исключительно синтаксическая, в момент создания. Более того, в вашем примере вы уже имеете сущность записи из БД, которая почти наверняка будет представлена как массив структур-строк с полями-колонками, кто же вам мешает обращаться к полям этих самых структур напрямую, без явного копирования в новые переменные?

Разница вот в чем. Из БД на физическом уровне запись читается в байтовый буфер в котором каждое поле - набор байт по соответствующему смещению и соответствующей длины. Та же "строка" - это просто 100 (например) байт с (например) 50-го по 150-й. Чтобы использовать так, как Вы написали, нужно для этого куска буфера создать объект. А это значит, вызвать конструктор, который внутри себя выделит память и скопирует туда кусок буфера, а по окончанию работы вызвать деструктор (он может вызываться автоматически, но он вызовется), который освободит память.

В результате, если посмотреть PEX статистику (Performance EXplorer - инструмент используемый у нас для исследования эффективности в процессе нагрузочного тестирования), то для задачи, обрабатывающей, скажем, 20млн записей (что для нас дело, в общем-то, обычное) Вы увидите там 20млн вызовов конструктора, 20млн выделений памяти, 20млн операций копирования, 20млн вызовов деструктора и 20млн освобождений памяти. И это не считая собственно логики. И все это в рантайме.

Здесь все проще. Описываем переменную

dcl-ds dsYAR  likerec(YAR12LF.YARPFR: *all);

Это структура (DS - Data Structure в этой терминологии) которая повторяет структуру записи YARPFR логического файла YAR12LF. *all - включать все поля (можно *key, тогда будут включены только ключевые поля индекса). Имена полей в ней будут соответствовать именам полей записи.

Переменная будет создана в compile time.

Дальше читаем (не важно как - можно SQL запросом, можно прямым обращением) в эту структуру запись из БД и дальше напрямую работаем с полями. Без создания дополнительных объектов, лишнего выделения/освобождения памяти, вызовов конструкторов/деструкторов, лишних копирований.

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

Поэтому каждая часть каждой задачи решается при мощи того инструмента, который дает наилучший результат. Если в рамках задачи требуется работа с какими-то низкоуровневыми системными вещами (сокеты, пайпы, например) - она будет написана на С/С++. Потому что это проще и эффективнее. Та же работа с регулярными выражениями на С делается проще. В принципе, из нашего языка я могу вызывать любую функцию С-шного рантайма просто описав ее прототипа на нашем языке со ссылкой на "внешнюю процедуру".

Ну вот как пример. Нет у нас в языке генератора ПСЧ. зато он есть в С:

int rand(void);

Если мне вдруг потребуется, делаю просто

dcl-pr Random int(10) extproc(*cwiden: 'rand');
end-pr;

Все. Теперь у меня есть функция Random, которая возвращает int32.

Но при этом тут много всякого сахара, особенно в описании структур - неименованные поля (вместо всяких tmp, dummy, reserved в С), частично или полностью перекрывающиеся поля в структуре, задание дефолтных значений полей структуры при описании ее шаблона (шаблон - это типа typedef) при котором любая созданная по этому шаблону структура сразу будет проинициализирована дефолтными значениями (на этапе компиляции, не в рантайме!) Ну и еще много всякого, чего порой не хватает в тех же С/С++.

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

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

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

"Проблема в том, что, как и в случае с пирамидой, каждый новый слой требует больше «кирпичей», чем предыдущий"

Я думаю всё же в разработке как и в строительстве пирамид всё наоборот

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

будем ждать DOOM на CSS

Зарегистрируйтесь на Хабре, чтобы оставить комментарий