Комментарии 40
Именно поэтому мы планируем создать систему, позволяющую энтузиастам легко интегрировать языки программирования по их выбору. Это критически важно для удобства разработчиков, ведь мы создаём инструмент именно для них. Мы хотим предоставить разработчикам свободу в выборе языка, а не ограничивать их использованием традиционных, “олдскульных” (C++).
И чем "новые" языки принципиально отличаются от "старых"? Вот прямо так чтобы радикально?
Не устаю приводить пример из личного. Есть банк, центральные сервера где все задачи - работа с БД и коммерческая бизнес-логика. И есть (на той платформе, на которой работают сервера) специализированный язык, ориентированный именно на работу с БД и ту самую бизнес-логику.
И да, там нет и половины того, что сейчас модно. Обычный (казалось бы) процедурный язык. Даже без ООП (которая там не сильно нужны т.к. все задачи связаны с формированием потока данных - выборок - и дальнейшей с ним работы).
Что отличает его от "обычных" языков?
Нативная поддержка всех типов данных, что есть в БД - все эти char, varchar, date, time, timestamp, numeric, decimal - все они нативно поддерживаются языков ровно как традиционные (int, float...) типы данных
Встроенные средства работы с БД - хоть напрямую (открыли файл, спозиционировались на запись по ключу, прочитали запись, изменили содержимое, обновили запись и т.п.), хоть посредством SQL - непосредственно в год может быть вставлено практически любой сложности SQL выражение, в том числе с использованием хост-переменных
Что это дает?
Не нужно подтягивать разные зависимости для реализации типов данных. Не нужны никакие "обертки" чтобы работать БД типами данных. Достаточно просто описать структуру (не класс с конструкторами и методами, обычный байтовый буфер где написано "от сих до сих у тебя поле типа decimal, а от сих до сих - varchar"), прочитать туда блок данных (запись) из файла и потом работать с полями структуры как с обычными переменными, а не "объектами какого-то типа"
Не нужны библиотеки для работы с БД. Ни напрямую, ни с использованием SQL. Все что нужно уже есть в языке. И оно эффективно работает. Более того, там можно как "динамический" SQL (строка запроса формируется в рантайме, план строится в рантайме), так и "статический" - строка запроса указывается явно, валидируется компилятором, план запроса формируется на этапе компиляции.
В итоге имеем быстрый, эффективный и удобный язык для решения конкретного класса задач.
Плюс к тому еще есть возможность "мультиязыковой" разработки - все компиляторы на этой платформе генерируют единый промежуточный код (это отдельная тема, весьма обширная) что позволяет написать несколько модулей на разных языках и собрать их в одну программу (главное - правильно описать прототипы функций для межязыковых кросс-вызовов). В частности, из кода на вот этом спецязыке можно вызывать любую функцию из С-шной библиотеки. Достаточно просто корректно описать ее прототипа со ссылкой на соответствующую "внешнюю процедуру".
Таким образом при решении конкретной задачи каждая ее часть может решаться с использованием того инструмента (языка), который подходит наилучшим образом.
Этот подход кажется непривычным и не сразу "заходит", но когда привыкаешь, понимаешь что это действительно удобно и эффективно.
В итоге имеем быстрый, эффективный и удобный язык для решения конкретного класса задач
Ну вот а теперь представьте что вместо этого языка у вас есть выбор использовать C или C++.
Таким образом при решении конкретной задачи каждая ее часть может решаться с использованием того инструмента (языка), который подходит наилучшим образом.
Ну так именно про это и написано в процитированном вами куске.
Ну вот а теперь представьте что вместо этого языка у вас есть выбор использовать C или C++.
Представьте, что такой выбор у нас есть. А теперь расскажите, что мне делать с записью, где содержатся поля varchar, date, numeric, в С, где эти типы не поддерживаются на уровне языка?
Накручивать на них обертку вместо того, чтобы сразу их использовать? Извините, но это лишнее время, которое становится ощутимым когда речь идет о десятках и сотнях миллионов записей...
Смогу я в С/С++ вот такое?
Dcl-DS dsHDARes qualified;
DAT zoned(7:0) inz;
USID char(4);
UNAM char(35);
BRNM char(4);
BRN char(35);
CRD timestamp inz(*loval);
MBN char(2);
MBND char(35);
SQN zoned(3:0) inz;
End-DS;
exec sql select HDA1DAT,
HDAUSID,
HDAUNAM,
HDABRNM,
HDABRN,
HDACRD,
HDAMBN,
cast(coalesce(substr(GPVDSC, 1, 35), '') as char(35)),
HDA1SQN
into :dsHDARes
from HDA1PF
join HDAPF on (HDACUS, HDACLC, HDATYP, HDADAT, HDASQN) =
(HDA1CUS, HDA1CLC, HDA1TYP, HDA1DAT, HDA1SQN)
left join GPVPF on (GPVITM, GPVVLE) = ('DAMBN', HDAMBN)
where (HDA1CUS, HDA1CLC, HDA1TYP) = (:CUS, :CLC, :Typ);
zoned здесь - тип соответствующий numeric в SQL.
Результат запроса сразу кладется в структуру dsHDARes и дальше с ней уже работаем без лишних телодвижений.
Если пытаться делать это на языке общего назначения с привлечением каких-то дополнительных библиотек, это все будет работать медленнее и кода будет больше.
Ну так именно про это и написано в процитированном вами куске.
Да, но там приводятся примерно одинаковые языки общего назначения. А я говорю о специализированных под конкретный класс задач языках, обладающих специфическими для этого класса задач возможностях, принципиально облегчающих решение задачи и дающий максимально эффективный результат.
Мне немало приходилось работать с разными БД на С/С++. Так что есть возможность сравнивать.
Представьте, что такой выбор у нас есть. А теперь расскажите, что мне делать с записью, где содержатся поля varchar, date, numeric, в С, где эти типы не поддерживаются на уровне языка?
Вы по моему всё ещё не понимаете о чём речь. Речь как раз о том что сейчас у большинства программистов нет особого выбора на каком языке писать. И есть только выбор вроде "C или C++" или там "C# или Java".
Да, но там приводятся примерно одинаковые языки общего назначения.
Где? Там как раз речь о том чтобы создать систему, позволяющую интегрировать различные языки.
Насколько я знаю, такая система есть - LLVM называется.
На нашей платформе не она, там свое, но на другие платформы оно не переносимо в силу отсутствия тем ряда ключевых концепция и сущностей.
Но LLVM вполне себе портируема на разные платформы. И это как раз то, что позволяет реализовать мультиязыковый подход к разработке.
Вы по моему всё ещё не понимаете о чём речь.
Возможно. Отчасти потому что там много каких-то частностей, но нет четко сформулированной общей концепции в стиле "этот кусок я пишу на С потому что он тут лучше, а это на Go потому что он тут эффективнее". Потом каждый кусок компилируем своим компилятором а результаты работы компиляторов собираем в один исполняемый файл.
Так это работает у нас (это называется ILE - интегрированная языковая среда), так это работает в LLVM.
Это не "мы для своего движка, который писали на С сделали API для питона" - все это было еще в виндовых dll которые просто имели стандартный ABI позволяющий писать dll на чем угодно и вызывать функции оттуда откуда угодно.
Это совместимость промежуточного (объектного) кода, выдаваемого компиляторами разных языков.
Мне кажется, что это наиболее перспективный путь развития в текущей ситуации.
Наш пример я привел просто потому что он очень "контрастен". И потому что работа с БД достаточно распространенное явление, а реализация через "SQL библиотеки" и классы-обертки SQL типов не самое эффективное решение когда речь заходит о работе с большими объемами данных - хотелось бы что-то узкоспециализированное, но с возможностью стыковки с уже существующими языками, чтобы не городить еще один мегаязык "как С++, но с вистом и профурсетками возможностью прямой работы с SQL в коде и поддержкой SQL типов данных". Чтобы можно было выделить в отдельную часть работу с БД и написать ее на отдельном языке.
По человечески это должно выглядеть как-то так (оставлю только совсем не "человеческие" идентификаторы) на декларативном псевдокоде
def dsHDAResFM : #dbfieldgroup //1
{
HDA1DAT -> DAT
HDAUSID -> USID
HDAUNAM -> UNAM
HDABRNM -> BRNM
HDABRN -> BRN
HDACRD -> CRD
HDAMBN -> MBN
GPVDSC -> MBND = left(it ?? "",35) //2
HDA1SQN -> SQN
}
def HDAFM : #dbfieldgroup
require {CUS,CLC,TYP,DAT,SQN}
def HDA1PFFM : HDAFM
with #dbfieldmap rename =
() -> ("HDA${it}" -> "{it}") //3
def HDAPFFM : HDAFM
with #dbfieldmap rename =
() -> ("HDA1${it}" -> "{it}") //3
def HDA1PFWM : #dbfieldgroup
require {
HDA1CUS -> &dbparameter CUS, //4
HDA1CLC -> &dbparameter CLC,
HDA1TYP -> &dbparameter TYP,
}
#dbsource(path.to.database) //5
{
#dbtablekey(path.to.table.HDAPF) HDAPFFM //6
#dbtablekey(path.to.table.HDA1PF) HDA1PFFM
from HDA1PF<-HDAPF<-GPVPF.where(GPVITM=="DAMBN").on(GPVVLE==HDAMBN) //7
where HDA1PFWM.ToCondition() //8
var dsHDARes = get dsHDAResFM //9
}
(e<-dsHDARes(CUS=1, CLC=2, Typ=2)) //10
-> { // какая-то обработка}
Несколько пояснений по номерам:
#dbfieldgroup - это макрос, который ещё на этапе компиляции (а так же в indesigne) возвращает тип, производный от базового FieldGroup - описывающего группу полей, с возможными псевдонимами, расчётами и т.п.
Псевдоним для поля с формулой (формула транслируется в операторы БД в той части, насколько возможно - остальные вычисления будут выполнены в объектной модели), тут может быть и перевод группы полей в одно поле, если нужно несколько полей для расчёта
#dbfieldmap - это макрос который ещё на этапе компиляции (а так же в indesigne - далее все макросы такие же) производит реструктуризацию списка полей по заданной строковой формуле переименовывая и задавая соответствие псевдонимам
&dbparameter - аннотация - определяющая псевдоним как параметр (запроса) - учитывается в строке с меткой //8
#dbsource - этот макрос определяет источник данных из базы данных - весь код внутри будет "видеть" структуру этого источника, в т.ч. в indesigne. При компиляции может подставляться другой ресурс пути, в т.ч. неопределённый и генерироваться более параметризованный код внутри блока - например, чтобы динамически брать пути таблиц из каких-то настроек
#dbtablekey - это макрос, задающий таблице базы данных метанастройку - ключ соответствия по умолчанию! По переданной группе полей
указание источника данных для начинающейся выборки с настроенными левыми соединениями ("левые" два идут по настроенным ключам групп полей, "правое" идёт с персональным фильтром и персональным ключом соединения.
Кстати GPVPF.where(GPVITM=="DAMBN") можно был бы сократить до GPVPF(GPVITM=="DAMBN"). А <-GPVPF(GPVITM=="DAMBN").on(GPVVLE==HDAMBN) превратить в LEFT(GPVVLE==HDAMBN) GPVPF(GPVITM=="DAMBN")Группа полей напрямую преобразуется условие фильтра - здесь преобразование простое - такое же как при соответствии - но псевдонимы становятся параметрами вызова запроса, согласно данной им аннотации.
Непосредственно получение в переменной источника данных - потока, из котором потом можно получать элементы данных согласно переданной группы полей
Обращение к источнику данных с передачей параметров как аргументов функции - открывается выборка - поток - коллекция и тут же начинает поэлементно перебираться
Все фактически не найденные в группах поля без пометки "require" игнорируются!
Многие макросы предполагается выполнять единожды где-то в общем коде, а не всё время по месту использования.
Вот такое у меня виденье как это должно быть оформлено на более продвинутом ЯП - причём тут даже AI не нужен - это достаточно конкретный псевдокод, а с AI его формирование было бы ещё более простым!
Прошу строго не судить - писал "на лету" и "на коленке" - всё-таки это просто очень предварительная концепция.
Будь идентификаторы полей более "удобными", а вся метачасть вынесена в отдельный блок и максимально обезличена от конкретных идентификаторов (бОльшая должно браться из ресурсов настроек или каких-то других источников, а не прописываться жёстко в коде - и тут метапрограммирование и JIT компиляция должны свести все абстракции в итоге в конечные оптимизированные константные цепочки инструкций) - то сам алгоритм вообще выглядел бы смехотворно коротким, с максимальным уровнем абстрагирования от имён полей и таблиц
А теперь скажите - как вы будет работать с полями типа zoned или timestamp? Потребуется для них какие-то преобразования в рантайме прежде чем вы сможете написать, скажем,
a = dsHDA1Data.DAT + dsHDA1Data.SQN
или
ts = dsHDA1Data.CRD - %days(30)
В нашем случае не потребуется ничего. Вот просто прочитали запись и работаем с нее. Типы zoned, timestamp и т.п. - точно такие же нативные типы в языке как int, float и т.п. Т.е. не требуют оберток, преобразований и прочего, что требует времени в рантайме.
А теперь скажите - как вы будет работать с полями типа zoned или timestamp?
Как уже написал - первым делом кодогенгератор должен стараться вынести все эти преобразования в API на стороне СУБД
Там где это не удастся - т.е. в выражении будут вызываться функции, не доступные в СУБД (и которые не удаётся туда импортировать, без заметной потери производительности или когда они чёрный ящик или завязаны на какие-то внешние API) - то выражение должно перестраиваться так - чтобы постараться всё что можно оставить для выполнения в СУБД, а в объектной модели выполнить остальное - кстати тут хорошо иметь клиент-серверный модуль на стороне СУБД - в рамках которого и будут выполнены такие преобразования
Если на придётся работать на стороне объектной модели с какими-то специфическими типами - то выход только один - иметь, условно плагин/расширение, поддерживающее эти типы на бинарном уровне - т.е. из СУБД придётся вернуть бинарные данные, но для ряда случаев может быть и какая-то конверсия на стороне СУБД в более удобоваримый тип (если точность не теряется) - это определяется настройкой правил трансляции. Но тут уже особый случай - это программист сам должен понимать (а анализатор кода ему об этом сообщить) о тонкостях такого подхода - и либо смериться, либо пересмотреть своё выражение - чтобы проблемная часть сместилась на сторону СУБД.
ВНИМАНИЕ! ТРЕБУЕТСЯ ПОНИМАНИЕ ТОГО, ЧТО: Мой код - это не инструкции выполнения в объектной модели - это декларация намерений - и весь этот код может быть перестроен в рамках различных контекстов (взаимодействующих друг с другом) при конкретной трансляции в конкретных условиях! За это отвечает транслятор и его правила! Программист несколько ограничено может влиять на принятие решений особыми хинтами - маркерами специфических требований для транслятора!
Даже вот это "var dsHDARes = get dsHDAResFM" никак не гарантирует, что тут будет обязательная выгрузка в объектную модель - таблица может остаться на сервере СУБД - Таблица даже может быть разделена на части - где часть останется на стороне СУБД, часть в объектной модели - и даже несколько раз они могут туда-сюда перегоняться разделяться и соединяться (но это уже профилировщик сам должен решить как лучше поступить - в случае просадки производительности - сообщить о проблемных местах алгоритма программисту).
Кстати, объектная модель может тоже подключаться прямо в контекст СУБД (как это умеют MS SQL Server, Oracle, отчасти PostrgreSQL, и некоторые NoSQL СУБД) - но безусловно с некоторой просадкой производительности, в сравнении с наивным ЯП самих СУБД).
Поэтому весь код далее может продолжить своё выполнение на стороне СУБД (если там есть доступный API для трансляции) - а тут СУБД буду дальше ещё продолжать эволюционировать, расширяя свой внутренний API - но опять же тут дело за профилировщиком - ему оценивать и решать где лучше продолжить выполнение кода - даже в динамике - в зависимости от балансировки нагрузки в текущий момент времени! Человек так никогда не сможет сделать!
Да, безусловно, в большинстве случаев будут некоторые потери в производительности - но навряд ли сильно большие - когда в итоге данные так или иначе нужны будут в объектной модели (или должны быть переданы на другой сервер или просто другому микросервиса виртуальной среды), а не останутся в той же БД той же СУБД.
Для особо критичных алгоритмов буду писать прямые реализации алгоритмов - но это будут доли процента в общей массе!
И ещё, надо понимать что такой подход больше ориентирован на абстрактное составление алгоритмов - даже вот эта строка
from HDA1PF<-HDAPF<-GPVPF.where(GPVITM=="DAMBN").on(GPVVLE==HDAMBN) //7
where HDA1PFWM.ToCondition()
var dsHDARes = get dsHDAResFM
не совсем абстрактна - в идеале должно быть так
var datares = from HDA1PF<-HDAPF<-GPVPF_DAMBN where FILTER get FIELDS
где все идентификаторы в верхнем регистре (они так для наглядности) определяются где-то в другом месте (наряду с метанастройкой соединения таблиц) - и текущий код о них ничего не знает (но может что-то проверять, требовать, приводить к каким-то другим интерфейсам и типам). Состав полей и условий тут не известен и не фиксирован - они могут собираться из разных частей отдельных модулей и настроек, меняться со временем - а этот код останется неизменным, пока вороне не изменится логика или архитектура. Это настоящее абстрактное программирование! На самом деле даже этот код не идеален а идеал он где-то здесь
var datares = from SOURCE where FILTER get FIELDS
Тут источник данных SOURCE тоже абстрактен и его структура тоже определяется где-то в другом месте (и даже не ясно где фактически расположены данные, они даже на момент данного выражения ещё могут и не быть вычисленными) - согласно заложенной какими-то иными декларациями и настройками архитектуры хранения данных!
ДЕКЛАРИРОВАНИЕ, АБТРАГИРОВАНИЕ И ПОВТОРНОЕ ИСПОЛЬЗОВАНИЕ - вот ключевые аспекты нового ЯП (не забывая про ООП, АОП, функциональное и императивное программирование)
Что мешает на уровне драйвера маппить прочитанные данные га заранее определенные структуры с нулевой стоимостью? Это вообще не вопрос языка. Вы так пишите как будто у вас в памяти эвм реально существуют раздельные int и char
Не очень удачно написал выражение " GPVDSC -> MBND = left(it ?? "",35) //2"
вот так на ООП выглядит лeчше (во многом позаимствовано у C# и немного из Kotlin):
GPVDSC -> MBND = it?.Left(35) ?? "" //2
По сути здесь много синтаксического сахара - это описание соответствия образующего тип KeyValueTriple в виде кортежа
(Field : "GPVDSC", Alias : "MBND", Eval : ${it?.Left(35) ?? ""})
где ${ } - это описание выражения (его раскроет макрос)
it - это автопеременная - в макросе будет макроцикл по коллекции слева - имена полей - здесь будут эти имена - ну а остальное - это просто обработка NULL значений -
if (it != null)
it.Left(35)
else
""
затем с большой долей вероятности это выражение уже будет отранслировано в реализацию конкретной СУБД (если источник данных приложения этоой группы полей будет таблицу расположенная в СУБД на момент вызова)
substr(coalesce(GPVDSC, ''), 1, 35)) as MBND
впрочем, оптимизатор может ещё как-то это оптимизировать под конкретную СУБД и конкретную таблицу и конкретное описание поля в этой таблице
Ну вот а теперь представьте что вместо этого языка у вас есть выбор использовать C или C++.
Со скрипом в душе (т.к. я не рьяный адепт ООП), но я бы выбрал Си, а не С++ - уж больно долбанутый ЯП этот плюсанутый - черт голову в нём сломит. Но это если сравнивать современные редакции. На момент выхода С++ он действительно имел ряд неоспоримых преимуществ (особенно для адептов ООП), хотя и имел ряд жутких проблем - хотя бы в части жутко реализованной идеи шаблонов!
Но сейчас выбирая между ним и более современным C# (хотя, увы, тоже перенявшим туеву кучу неудачных, на мой взгляд, концепций от своих прямых прародителей. и и за свои 20 лет обросший некоторыми своими неудачными решениями) - я однозначно выбираю C# (тем более, что его производительность на прикладном уровне уже не так уж далека от C++ - и есть большой простор для глубокой ручной оптимизации; и теперь уже с широким акцентом на кросс-платформенность, в т.ч. для WEB приложений). Но, вот, Kotlin всё же покрасивее будет. С другой стороны - платформа .NET (без учёта ЯП), с технической стороны, куда интереснее и шире в применении, чем JVM (трансляция Kotlin в JavaScript - это уже другая тема) - но это дело поправимое, хоть JetBrains пока отреклись от разработки компилятора для .NET - это не так уж сложно - и у меня уже есть свой проект Kotlin.NET. Ну а оригинальный Kotlin Native multiplatform - тоже отличная концепция, но пока ещё не выстрелившая и по сути ещё находящаяся в разработке!
Что до Python (или уж лучше тогда более современный, но пока не вышедший в релиз ЯП Mojo) - язык неплохой, но несколько ложек дёгтя в нём уж больно сильно для меня отравляют данную бочку мёда (хотя в мире полно любителей химического привкуса).
Что до Rust - неплохой и перспективный ЯП, но, всё-таки далёкий от идеала - любопытно посмотреть про появление конкурентов в данной концепции!
Но сейчас выбирая между ним и более современным C#
Не-не-не. Вы не поняли: C или C++. И всё. Если вообще. И так сейчас живёт куча айтишников. То есть ЯП или даже фреймворк выбрать нельзя и пиши на чём дают.
И на этом фоне системы с возможностью интеграции различных ЯП выглядят заметно приятнее. Хотя конечно даже в них тебе не дадут разводить зоопарки из 100500 различных ЯП.
Со скрипом в душе (т.к. я не рьяный адепт ООП), но я бы выбрал Си, а не С++ - уж больно долбанутый ЯП этот плюсанутый - черт голову в нём сломит. Но это если сравнивать современные редакции. На момент выхода С++ он действительно имел ряд неоспоримых преимуществ (особенно для адептов ООП), хотя и имел ряд жутких проблем - хотя бы в части жутко реализованной идеи шаблонов!
Очень понимаю :-)
Я начинал с С, потом появился С++, который был "С с классами". Тогда это было хорошо.
В целом, на С/С++ писал более 25-ти лет пока не попал в банк и основным не стал вот этот вот специальный язык. Хотя низкоуровневое, близкое к системному (а оно попадается и тут), до сих пор пишу на С/С++.
Не могу сказать что нравится куда идет современный С++... По мне, так туда просто пытаются тащить все на свете что в других языках увидели. Не уверен что это хорошо. Но раз он до сих пор популярен - значит кому-то это нужно.
Будущее за ещё более новыми языками программирования, которые ещё даже не появились на свет. Позволяющими эффективно разрабатывать логику "условно" бизнес-приложений (но этом могут быть и игры и какие-то медиа приложения или управляющие железом - в т.ч. роботами) с активным применением интегрированных AI технологий (это не означает, разработку систем машинного обучения, а просто интеграция AI-помощников как в сферу разработки программы, так и в сферу их дальнейшего применения), с минимальным уровнем прямого кодирования инструкций, с всё большим уровнем декларативного кодирования. Ни один из ныне популярных ЯП на эту роль не годится - все они заточены на куда более примитивный низкий уровень кодирования - но эти ЯП могут стать промежуточным слоем для кодогенерации со сторон AI, что уже происходит сейчас.
Так же частично нынешние ЯП буду ещё долго востребованы для системного программирования, но всё больше ужимаясь до драйверов и низкоуровневой аппаратной работы, ну или каких-то высокопроизводительных библиотек.
Прикладное программирование будет смещаться в сторону очень высокоуровневых API - максимально удаляющихся от технической аппаратной базы. А всю чёрную работу, генерацию паттернов и оптимизацию будут выполнять AI-помощники. От программиста будет требоваться только боле-менее чётко формулировать описания для этих AI-помощников - всё-таки пока я считаю требования к описаниям должны быть достаточно строгими (условно - математически строгими) - чётко декларирующими требования - чтобы в итоге получаемый код сразу интегрировался целевую систему (без доработок). А затем AI мог бы его ещё и динамически профилировать и при необходимости самостоятельно перестраиваться (ну или на первых порах информировать о своих предложениях программиста, давая статистически подкреплённые обоснования, и свои новые предложения). Да и сами итоговый код может существовать сразу в нескольких вариантах - и динамически переключаться между ними, быстро подстраиваясь под меняющиеся обстоятельства. Так же AI будет постоянно накапливать свою базу знаний - и при пересмотре ранее сгенерированных алгоритмов черпать и новые знания из такой базы знаний - заменяя устаревшие паттерны новыми - более эффективными - и всё под его же непрекращающимся контролем автоестирования и автопрофилирования - можно сказать вообще без вмешательства программиста - хотя человек всё тоже может контролировать (всю статистику ему AI преподнесёт на блюде), и сможет даже вмешиваться - внося специальные хинты в исходные программные декларации - специально направляя AI в заданное русло. Но рядовые программисты навряд ли этим будут активно заниматься - не их уровень! Это уже надо будет устраивать периодический (но не часто) аудит таких решений со стороны, чаще всего, аутсорсинговых компаний - где команда программистов будет заточена именно под анализ автогенерируемого кода, а не на тонкости логики, эффективность UX или красоту выходных форм (хотя тут свои специалисты тоже найдутся - для совершенствования и в данных аспектах)
Но, пожалуй, такой подход - это всё-таки пока ещё будущее. Оно не настанет "завтра" - таких ЯП ещё нет - но, думаю, эпоха начала их появления это дело 10-20 лет.
А пока рулить будут актуальные ЯП и вряд ли в ближайшие годы тут что-то принципиально изменится
От программиста будет требоваться только боле-менее чётко формулировать описания для этих AI-помощников - всё-таки пока я считаю требования к описаниям должны быть достаточно строгими (условно - математически строгими) - чётко декларирующими требования...
... и в качестве такого чёткого описания требований отлично подойдёт код на C#, ну или на Kotlin.
Не совсем. Всё-таки описание должно быть более декларативным. Но отчасти да - даже в декларативном описании всегда найдутся блоки с более ярко выраженными инструкциями в императивном или функциональном стиле - а тут синтаксис данных ЯП очень неплох, но.... всё-таки на мой взгляд через 20 лет устареет - оба этих ЯП не самые всё-таки не идеальны для лёгкого абстрактного и многопоточного распределённого программирования - хотя в них и заложены некоторые правильные идеи - но это всё надо ещё доводить до ума!
И синтаксис Kotlin и C# сейчас несколько громоздок - нужно что-то ещё более синтаксически простое - но при этом ещё более выразительное и позволяющее писать ещё меньше кода - получая затем (после обработки AI) ещё больше выгоды.
Но C# и Kotlin - это отличные высокоуровневые промежуточные ЯП для AI кодогенерации - а она должна сначала идти в такие вот выскоуровневый ЯП - AI не должен сильно заморачиваться насчёт кросс-платформенности - его цель именно генерировать эффективный алгоритм, а не оптимизация под конкретное железо - впрочем этим на следующем этапе займётся уже AI-оптимизатор (формируя низкоуровневый промежуточный код под определённую железную архитектуру и ОС) и AI-JIT-компилятор на финальной стадии машинной оптимизации в runtime.
Ну и когда надо будет проанализировать что там AI нагенерировал - то тут тоже удобнее иметь хорошо аннотированный и комментированный высокоуровневый код
В ближайшие лет 20-40 обычные ЯП никуда не денутся. Как минимум, ИИ будут их использовать как генерируемый"байт код" на выходе, чтобы можно было его скармливать компилятору. Не умеют они сразу машинный код генерировать, по той простой причине, что любителей писать прямо на нулях и единицах или том же LLVM IR ну скажем так мало, а обучать смарт унитазы на чем то нужно. А когда наступит пора сильного само обучаемого ИИ, необходимость писать, что-то отпадет впринципе, ведь зачем, если оно само будет принимать решения и заниматься их реализацией.
И синтаксис Kotlin и C# сейчас несколько громоздок
Ну не знаю, короче этого только натуральный язык или простонародье промпт. Написал "сделай, чтобы было хорошо" и радуешься.
В ближайшие лет 20-40 обычные ЯП никуда не денутся. Как минимум
Разве кто-то говорил обратное. Обычные ЯП и через 100 лет скорее останутся (не знаю какие из нынешних доживут до середины XXII века, но какие-то точно доживут, ну а так же буду появляться ещё и условно классические новые ЯП. Потребность в них никто не отменял. Но вот доля их прямого применения будет во второй половине XXI века постепенно сокращаться.
Как минимум, ИИ будут их использовать как генерируемый"байт код" на выходе, чтобы можно было его скармливать компилятору.
Я же напрямую об этом говорю - но это не стоит считать прямым применением программистами - это уже косвенное использование - хотя его доля как раз будет расти, так что такие ЯП ещё долго буду в ходу.
Ну не знаю, короче этого только натуральный язык или простонародье промпт. Написал "сделай, чтобы было хорошо" и радуешься.
Всегда есть что упростить у C# большое наследие от Си и от ранних версий - которые в нынешних реалиях уже не так актуальны. У Kotlin с этим получше - но всё-равно и тут найдётся что хотя бы формально подсократить.
Например, лично я считаю что у обои ЯП (особенно у C#) очень сильно раздута база ключевых слов. В этом плане, скажем Nemerle был куда сдержаннее (хотя Kotlin тоже старается) - но тем не менее - многое можно было бы перевести на макрофункции, функуии-расширения, функции-операторы и аннотации, или вовсе пустить под нож. Но это всё формальщина - по сути токены для изучения то никуда не делись бы, просто сменили форму, но синтаксически языки стали бы проще как и проще стал бы их синтаксический разбор.
С другой стороны - параллельное/асинхронное программирование, со всеми своими прибамбасами, всё ещё желает иметь ещё большее упрощение без потери надёжности.
Что до "натурального языка" - мне такой подход не нравится - ранее уже пытались (но не особо глубоко) Objective-C и SAP ABAP (были и ещё более глубокие представители - но уже канули в лету) - хреново получается. Такой подход хорош для работы, условно, через ChatGPT - который на выходе уже будет давать более формализованный код
Прекрасные мысли и комментарий, особенно подписываюсь под первой его половиной
Важна база, а выбор конкретного языка, как высказались многие эксперты сегодня, не столь важен
Лицемерие на публику. Ряд этих экспертов почему-то в свои команды требуют опыт на конкретном языке от N-лет. и если этого нет, ты даже на собес не попадешь. А если попадешь, то будешь общаться на тему этого языка и съехать, что ты писал на чем-то другом будет крайне сложно. Раньше тот же ozon допускал такое, сейчас практически нет - извольте 1.5 года именно на Go писать иначе не пройдете даже hr'a.
Без конетекста как-то смысл меняется, там по-моему не совсем об этом. Речь о том, что если у вас хорошо работает голова, то вы можете много зарабатывать и на Go, и на Java, и на JS. Конечно, компания, которой нужно делать бэк на Go отдадут предпочтение человеку с релевантным опытом, который прям завтра сядет и начнет приносить пользу. Но если на рынке нет таких специалистов, то действительно достаточно убедиться что вы нормально соображаете и потом ждать какое-то время, пока вы набьете руку в конкретном языке (что видимо раньше и было в Ozon) и только потом начнете создавать что-то полезное для бизнеса. Когда на рынке полно уже готовых специалистов, конечно компания скорее выберет готового, чем того, в которого надо еще инвестировать.
Другая сторона этого вопроса, например, разработчик пирносил пользу компании и проявляет себя как толковый специалист, но технологии устарели, не востребованы. Совершенно не обязательно его скидывать со скалы и искать свежего на замену. Вполне может оказаться взаимовыгодным решением переобучить.
делать бэк на Go отдадут предпочтение человеку с релевантным опытом
Отдать предпочтение навыку, который со слов "экспертов" не так важен при условии наличия опыта на другом языке? Кажется кто-то здесь лукавит...
"Отдать предпочтение" и "не рассматривают в принципе без N-лет на этом языке" немного разные вещи?
Я не спорю, что лучше нанять человека с уже готовым навыком. Но зачем так лицемерить в статье?
Лицемерие на публику. Ряд этих экспертов почему-то в свои команды требуют опыт на конкретном языке от N-лет. и если этого нет, ты даже на собес не попадешь.
Я попрошу заметить, что кроме этого вас ещё хорошенько прогонят по базе. Так что тут придется вывернуться наизнанку, чтобы пройти этих экспертов. Причем даже поработав в озоне, ты придёшь в какой-нибудь xsolla, и там все будет тоже самое. Эксперты такие эксперты, что даже друг другу не доверяют.
Будущее за 1С. А не вот это вот всё...
Множество компаний различного масштаба переходят на новые Python, Go, Kotlin, а в сфере мобильной разработки - на Swift. Языки C++, C, PHP, Java можно отнести к предыдущему поколению.
Python появился в 1991, Java в 1995
А PHP в 1994. Так себе эксперт, если не в курсе, что Python - относительно старый язык, с тяжелым наследием, которое из него уже никогда не уйдёт.
Go концептуально тоже старый, даже ближе к языкам поколения C.
Новые: Kotlin, Swift, Elixir, Rust, Julia.
У Python уже был очень сложный переход от 2-ой к 3-ей версии без обратной совместимости, но, думаю, наврядли на такое пойдут снова - уж очень болезненным и трудным был переход, а и до сих пор есть много активных проектов, так и оставшихся на 2-ой версии.
Наверное через несколько лет надо будет говорить о ЯП Mojo - как более современной версии языка Python, но без сильного желания быть очень совместимым, но... всё-таки и тут такое желание есть - так что по сути Mojo (по крайней мере в нынешнем его воплощении, ещё далёком до релиз 1.0) - это лишь немногим больше, чем условный Python 4.0 (вернее тут лучше сравнивать более конкретно с CPython компилятором). Так что да - не совсем удачного наследия и в Mojo хватает. Но всё же - именно Mojo тут более современный ЯП, чем старый Python
Если им яиц хватит сделать действительно новый язык, это будет интересно. Но есть большая вероятность, что они просто повторят судьбу Perl и Raku (aka Perl 6).
Updated: Загуглил Mojo. Он же от других разработчиков. С таким же успехом можно и Nim сюда приплести.
Да, это другая команда, поэтому это и не Python 4.0 - но ЯП Mojo основан на диалекте Python.
И да, судьба Mojo пока не определена, но так как это не абсолютно новый ЯП, а с некоторой совместимостью, и обещают ещё и поддержку ключевых питоновских библиотек, а разработчики весьма опытные в деле компиляции - то может и получится что-то, вполне конкурентное с питоном, а питоном нынче вроде бы на первое место вышел по популярности (по некоторым исследованиям) - так что есть за что побороться. Но тут нужно время - и до 1.0 релиза, и даже до 2.0 надо будет подождать, ну а потом ещё лет 10 уйдёт на "завоевание" аудитории, и, попытку, войти хотя бы в 3-5-ку самых популярных ЯП (ну это если к тому моменту уже удастся войти хотя бы в 10-ку или даже хотя бы в 20-ку чтобы быть в шортлисте популярных ЯП)
Популярность языка нынче не стоит ничего. Она сейчас говорит только о двух вещах: либо язык всё ещё преподают в ВУЗах, либо его пиарят на курсах для тех, кто самостоятельно не может программирование освоить. И в том и в том случае будет много запросов в поисковики и мусорных/учебных репозиториев.
А по поводу Mojo, в чём его киллер-фичи по сравнению с Nim? Который уже аж до 2.0 дошёл.
Я не адепт ни Python, ни Nim, ни Mojo (который ещё и в финальный релиз не вышел). Поэтому полноценно Вам ответить не могут. Предполагаю, что в двух вещах - для Mojo: большей синтаксической свободе и приверженности классическому синтаксису питона (Python и Mojo синтаксически простые ЯП, NIM - нет), и заметно большей производительности. И статическая типизация, как ни странно, даёт много удобства и надёжности при разработке, ограниченный специфичный ООП - но это я больше с Python сравниваю, т.к. с NIM не особо знаком, но знаю, что Mojo уже сравнивали с NIM, и считают, что Mojo его превзойдёт, а вот что важно для NIM в сравнении с Mojo - так это кросс-платформенность - и вот тут у NIM не всё гладко (он транслируется в C++ а там такая чехарда с компиляторами и типами данных - да и NIM в итоге легко сгенерирует код, который потом С++ компилятором не компильнётся с классической для него кучей широченных и непонятных ошибок); конечно он может ещё и в JavaScipt - это хорошо - но достаточно узкоспециализировано - хотя JS сейчас активно соперничает с Python за первое место по популярности) Но, наверное это два прямых конкурента, хотя Mojo более питоно-ориентированный чем NIM. И, вероятно, Mojo буду более активно продвигать и багфиксить - так там очень именитые дядьки его разрабатывают! И что там у NIM с надёжностью и удобством многопоточности вообще не совсем ясно, доки хромают!
Лично для меня NIM - это жалкая поделка даже в сравнении с Python (причём перенявшая от него всё самое неудачное), который мне тоже не особо нравится, но хотя бы питон прост и боле-менее лаконичен.
Но вообще я адепт из другого лагеря (и, как можно прочесть тут выше в моих комментариях, вообще пропагандирую рождение концептуально совсем иных ЯП в недалёком будущем)
Ну, мне тоже эта Python-семейка не сильно интересна. Просто кажется слегка странным, что они не могут объединить усилия.
Мне лично сейчас больше всего нравится связка Elixir + Rust.
Elixir отлично подходит для разработки параллельных процессов, а Rust можно использовать точечно там, где важна максимально быстрая производительность в CPU-intensive задачах (что в веб-разработке встречается гораздо реже, чем хотелось бы)
"За ним следует Python, который благодаря своим многочисленным фреймворкам постепенно уступает место Go."
Вот оно оказывается в чем дело! Нужно уменьшать кол-во фреймворков, иначе совсем продадет python.
Так какие прогнозы по искуственому интеллекту то?)
Кажется, тут смешали теплое с мягким и получили енота)
Языки из категории main stream(java, python, C#, JavaScript, C, C++ и т.д) никуда не уходят. Пока не один из новых языков не даёт достаточно ощутимые преимущества, чтобы переход с условного старичка на новичка имел практический смысл. Пример : переход с python на go , условно у нас тут высокая нагрузка питон нужно выкинуть.
Итог : Будущее , фулстеки будут уходить, всё больше людей будет требоваться конкретных спецализаций .Main stream языки свой рынок не отдадут, но активно будут перенимать фишки новичков
В бэкенде я люблю Go и рекомендовал бы его, но сначала стоит посмотреть, что используют крупные компании (банки, VK, OZON, Вита).
Хм, последний пример - имелось в виду Авито?
Будущее программирования: языки, зарплата и перспективы в 2024 году