Pull to refresh

Развитие пользовательских типов данных в программировании

Reading time 16 min
Views 37K
Хотелось бы остановиться и посмотреть на развитие языков программирования с точки зрения развития пользовательских типов данных (ПТД).
Сразу хочу оговориться, под пользователями понимаются программисты, как люди, пишущие код на этих языках. Ну, и те, кто этот код сопровождает или просто читает.

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

Пользователи желают иметь примерно такие типы данных

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

Отсутствие пользовательских типов данных



Когда-то пользовательских типов данных не было. Как-то выкручивались

На заре компьютерной эры языки были не ахти – машинные: или ты подчиняешься их диктату (а диктат там простой: или ты используешь малобитовые числа в двоично-десятичной системе исчисления (ну, или с какой процессор работает) и команды процессора) или нет.
Затрагивать те «тёмные века» мы не будем.
Одно можно сказать – пользовательских типов данных там не было, но программисты как-то выживали и как-то писали программы.

Встроенные типы данных



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

Первым более-менее нормальным языком был Ассемблер (на самом деле их много ассемблеров, мы говорим о костяке языков, который появился в 50х годах). Помимо читабельности, он принёс в себе много нового в плане пользовательских данных.
Самое крупное и неоспоримое достижение – это возможность создания переменных! С тех пор, почти во все языки вставлена такая возможность – возможность создавать переменные.
Второе не менее крупное достижение ассемблера, сделанное из благих побуждений, — попытка вставить в язык все типы данных (из тех, что возможно понадобятся программисту) прямо в язык.
Ну и остальное по мелочи – прежде всего, возможность записывать числа не только в двоичной, но и 16-ричной, восьмеричной, двоично-десятичной системах.
Тогда казалось, ну что ещё пользователю может понадобиться?

Шли годы, а необходимость не только в высокоуровневых абстракциях, но и в пользовательских типов данных всё росла.
И вот грянул 1957й год с Фортраном.
Написанный код на нём выглядел почти как современные языки, хотя его же вариант на перфокартах может подвергнуть в шок людей, которые захотят его читать.
Фортран дал всё что необходимо… для расчёта полёта баллистических ракет – такие данные как целые числа (типа int), с запятой (типа float), и комплексные.
Строки? Кому они нужны на перфокартах? Они в Фортране появятся позже – настоящие строки только через 20 лет, а их имитация – через 10 (вместе с логическим типом данных).
А ещё Фортран дал почти-настоящий пользовательский тип данных как массив (хотя его использование несколько отличается от современного), более детально об этом мы поговорим в главе о Групповых пользовательских данных.

Но пользователям мало — они хотят ещё и ещё пользовательских данных.

И вот появляется он – Алгол, уже в 1958, программы на котором легко читаются и в наши дни.
Вот как раз Алгол принёс основу того, что сейчас есть везде — булевские типы, строковые, разнообразные целочисленные типы и числа с запятой. Немногим позже всё это применит и Фортран, но Алгол был пионером.
Казалось бы — все аппетиты удовлетворены, какие ещё типы необходимы пользователям? Да всё уже реализовано — только бери и пользуйся.

И тут наступая на пятки Алголу с Фортраном, в 1958 появился ещё один, совершенно непохожий на язык язык – Лисп.


Лисп может сделать невообразимые функции. Только как с этим жить?

Он дал ещё один, совершенно новый тип данных, настоящих пользовательских типов данных – функции (вида С-выражений), прочно начавших входить во все современные языки только с начала 21 века (прежде всего, благодаря мультипарадигменным языкам Питон и Руби). Если учесть, что Лисп даёт оперировать макросами – что-то вроде программирование eval-ами (в 58-то) – неудивительно, что мир был к нему не готов.
А вот готов ли сейчас мир к Лиспу? Наверное, нет.
Заострю внимание, почему. Лисп, как и любое другое функциональное программирование, работает с сильно-взаимосвязанными объектами, чем-то напоминает сцепленные шестерёнки механических часов. В отличие от императивных языков, любое вклинивание в шестерёнку – стопорит весь механизм. Из-за этого, требования к языку, в том числе и к пользовательским типам данных значительно строже. Те, проблемы, которые возникли у Лиспа сразу же, у императивных языков они обострились лишь к концу 80х годов.
Лисп даёт возможность построить любые С-выражения. Но он даёт лишь один инструментарий – стандартный и простой инструментарий работы с С-выражениями.
Получается, есть возможность написать любые пользовательские данные, но работать с ними можно лишь как с примитивами. Развитие Лисп-подобных языков показало что пока хороший инструментарий не найден для ненаписанных С-выражений.

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

Имитация от оригинальных типов данных почти не отличается по функциональности. В основном в те времена имитация основывалась на эмуляции функциями (процедурный стиль).
Главное отличие от настоящих пользовательских типов одно – если захочется «немного» изменить тип данных, придётся переписывать весь функционал. Это никому не хотелось делать.
Поэтому и имитировать стали гибче.
Сейчас скажу то, что знают все, однако тут важна не сама описываемая техника имитации, а угол зрения на эту технику.


Иногда надо работать только с теми возможностями, которые есть

Вначале появился конфигурируемый функционал на основе флагов. Это не самый простой метод, зато он очень сильно напоминал ассемблер, а его тогда ещё знали.
Суть передачи флагами проста — передача числа как параметра, число же представляется как двоичный ряд флагов. Несмотря на широкий способ использования, до сих пор в языках нет специальных типов данных вроде ряда флагов. Вместо этого нашли хороший заменитель – именованные константы и битовые операции, выглядящие как логические.
Наиболее простой метод – он до сих пор широко применяется везде – конфигурирование параметрами: чем больше надо конфигурировать, тем больше параметров передаётся. Один только имеет минус – слишком легко запутаться в порядке передачи параметров. Поэтому стараются такими методами передавать до 4-5 аргументов.
Для большего количества аргументов, с развитием настоящих пользовательских данных, прежде всего групповых и композитных, появилась возможность передавать один сложный аргумент – это то же самое конфигурирование только не горизонтально, а вертикально.
Развитием этого метода можно назвать создание встроенных языков (DSL) для конфигурирования функций.
Третий метод гибкости имитаторов — это изобретение манипуляторов (handler-ов), хотя в то время они так не назывались, и зачастую они были суррогатами манипуляторов — представляли собой числа и строки, а не ссылки или указатели.

Заканчивалась эра встроенных типов данных.
Но наступил 1972 год, появился… Си. И эра господства динозавров (встроенных типов данных) продолжилась ещё на одно десятилетие, хотя пользовательские типы данных начали отвоёвывать своё место под солнцем.
В том числе и в самом Си.

Но пока вернёмся к ещё одному встроенному типу данных, ставшим одной из причин роста популярности языка. Си ввёл низкоуровневый тип данных, который был в ассемблере, и начисто был забыт в первых высокоуровневых языках — динамические типы. Прежде всего, это ссылки(reference) и указатели(pointer). К ним добавился обслуживающий нулевой тип данных – null.


Динамические типы данных как отмычки — неказистые, зато в какие только потаённые комнаты нельзя с ними попасть?!

Ссылку можно рассматривать как один из вариантов реализации такого типа пользовательских данных как синоним.
Развитие синонимов можно найти в ПХП и его концепцией переменных переменных, когда можно вернуть значение переменной или функции, имя которой записано в значении вызываемой переменной.
В Си вызов функции можно вызвать фукнцией-вызовом (call), или можно передать функцию обратного вызова — callback.
Вдобавок к этому, динамические типы данных помогают хорошо ускорить выполнение скомпилированного кода.
К этим плюсам у динамических типов данных есть ещё один огромный плюс – с ними достаточно просто можно реализовывать то, что не было заложено в самом языке. Лишь одно сокрушает, к написанному с их использованием можно обращаться только с помощью инструментария работы с динамическими данными. Но технику обхода при имитации данных известна – замкнуть в функциях и возвращать ссылку/указатель на созданное – манипуляторы (handler). Манипуляторы — один из тех типов данных, в разних языках которых он может называться совершенно по-разному.
Например, в ПХП они называются ресурсами, в Эрланге — портами и идентификаторами процессов. В Коболе есть такой тип данных как файл и картинка.

Однако динамические типы данных – не только одни плюсы. Минусы тоже есть, порой очень большие.
Чем больше свободы в использовании динамических типов данных даётся языком, тем:
1) увеличиваются возможности по созданию того, чего не было заложено в языке (и не обязательно это позитивные возможности)
2) компилятор всё меньше вмешивается в действия пользователя, и вся ответственность за действия ложится на программиста
2) резко увеличивается небезопасность кода
3) резко увеличивается возможность инъекций в пространство имён и значений
4) сборщик мусора всё меньше вмешивается, и вся ответственность ложится на пользователя
Дальнейшая история показала, что создатели последующих языков (или при добавлении к уже существующим языкам) при добавлении динамических данных балансировали межу безопасностью и возможностями.

Близился конец 70х, и эти базовые встроенные типы данных стали уходить в периферию, в рутину, уступая место настоящим пользовательским данным.

Однако реальность преподносит иногда удивительные сюрпризы.
Кто знает, сколько ещё можно найти в старых-добрых и давно понятных типах данных?!


Иногда надо просто увидеть новое там, где всё давно известно. Как, например, эта сортировка М&Мs

Тогда, в конце 70х появился скриптовый язык AWK (использовавший разработки утилиты grep), а, десятилетием позже на его основе, в 1987 появился такой язык как Перл. И среди прочего у него был (до сих пор есть) такой экзотический встроенный тип данных, как регулярные выражения.
Перл помог взглянуть на такой старый тип данных как строки с новой стороны. Инструментарий по работе с ним в ранних языках можно было рассматривать как упрощённые парсеры.
Языки регулярных выражений оказались очень гибким и супер-мощным инструментарием для работы с символьными типами данных.

Групповые типы данных


Некоторые группы большие. Хочется с ними быстро работать

По сути, групповые типы данных – это много чего-то того, что есть в языке, как правило мономорфная группировка. Зачастую эти типы данных не пользовательские, а встроенные, однако они порой столь гибкие, что этого бывает достаточно.
Уже Фортран поддерживал групповые типы данных – это массивы (array), хотя они выглядели немного не так, как сейчас. Массивы, очень похожие на современные были уже в Алголе. В Паскале были множества (set)
В Лиспе были списки (list).
Потом появились хеш-таблицы, ассоциированные массивы, вектора, кучи, очереди, стеки, деревья…
Что-то встраивалось, что-то имитировалось или создавалось с помощью пользовательских типов данных.
Дальнейшее развитие групповых типов данных привело к 2 различным веткам развития
1) необходимость использования своего функционала с каждым групповым типом данных было не самое удовлетворительное, хотелось работать с ними единообразно. Основным инструментарием для этого в императивных языках являются коллекции и итераторы. В основном были добавлены в ранние 2000е.
2) В 80е годы с развитием роста данных, необходимость в расширении инструментария работы с групповыми типами данных росла как на дрожжах. Появились базы данных, а с ними и запросы и языки запросов (query language). В середине 80х Стуктурированный язык запросов (SQL) становится доминирующим. Как и парсеры для строк, язык запросов дал понять, что инструментарий, который использовался для групповых типов данных можно рассматривать как примитивный язык запросов. Базы данных, как правило, вынесены из языка, а в языке существуют лишь методы работы с ними, поэтому их нельзя считать полноценными пользовательскими типами данных. Хотя из-за их гибкости, это несущественно.

Настоящие пользовательские типы данных


В эру встроенных типов данных в разных языках можно найти поддержку весьма экзотических встроенных типов данных.
Например, в Си таким типом данных было перечисление (enum). Его до Си, впервые вводит Паскаль (1970), хотя и называл скаляром.


Что такое перечисление легко объяснить даже детям на пальцах

Перечисление — самый настоящий пользовательский тип данных! Казалось бы, надо Си поставить памятник за это. Нет, разве что надгробный.
Дело в том, что пользователи имеют возможность построить любые перечисления. Только вот для работы с ними в Си нет ничего (в Паскале был базовый набор). Вообще ничего. Создавать перечисления можно, а работать с ними — нельзя.
Поскольку Си был в мейнстриме, мало кто хотел добавлять этот тип данных в другие языки. Только в Си++11 появился хоть какой-то инструментарий по работе с перечислениями.
Этот пример, как и развитие Лиспа, показал, насколько важно иметь не только пользовательские типы данных, но и инструментарий работы с ними.

Композитные типы данных


Записи такие разнообразные. Ещё бы научится как ими пользоваться

Зато в Си был другой настоящий пользовательский тип данных. Хотя его придумали значительно раньше – ещё в Коболе, вышедший в ранние 60е (сам язык создан в 1959).
Это запись (record), в Си называется структурой (struct).
Запись – не что иное, как группа разнородных типов данных.
К записям прилагается инструментарий с работой с записями. Например, Си не в полном объёме даёт стандартный ныне минимум работы с записями (например, лишь однобокая инициализация).
С записями легко уже не сымитировать, а создать настоящие списки и деревья.
Неужели, снова всё есть в языке?
Нет, и ещё раз нет.
Уже мало иметь просто пользовательские типы данных. Мало иметь инструментарий работы с ПТД как с ПТД. На первый план выходит другое.
Никто не даёт никакого инструментария для несозданных типов данных!
Теперь уже языки с поддержкой записей попались в похожую ловушку на ту, в какую попал Лисп – свои данные создавать можно, а работать с ними – только базовый набор.
Только у Лиспа ситуация хуже: в этом языке всё является С-выражениями, а в Си, Коболе, и других, запись – самостоятельный тип, к тому же у него есть свой, хоть и небольшой, инструментарий.
Благо, решение этого тупика был давно известен — имитация работы с пользовательскими типами данных с помощью функций.

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

А ответ был. Как ни удивительно звучит, но был ещё за пару лет до создания Си, он был в Европе, и назывался Симула (1967). И тогда, когда Си начал задыхаться в нехватке инструментария пользовательских типов данных, Си++ (в 1983) перенял всё лучшее у Симулы и применил к Си синтаксису.

Объекты


Объекты могут всё делать. Сами и над самими собою

Объекты(object) – ещё один тип пользовательских данных. Он обладает значительно большими возможностями, чем было у записи.
Это дало ему возможность завоевать просто бешеную популярность.
По иронии доли, как и Симула, вышедшая за пару лет до С, в котором не было объектов, так и за пару лет до Си++ Смолтолк в 1980 объявил парадигму «всё объекты».
Но Смолтолк не завоевал большой популярности, ему пришлось ждать, пока Си++ дойдёт до уровня стагнации, и только после этого, Ява в 1995 вновь смогла поднять парадигму «всё объекты» гордо над головой.
Чем же так хороши объекты, ведь они не так уж сильно отличаются от записей. По сути – те же записи с добавлением методов.
Во-первых, инструментарий по работе с самими объектами значительно богаче и сильней, чем инструментарий по работе со структурой.
А во-вторых, инструментария по работе с ещё не созданными объектами… тоже не было.
Стоп, спрашивается, где же тут «во-вторых», если и у объектов нет никакого инструментария с несозданными типами данных, и у записей нет. И, тем не менее, во-вторых! Для записей необходимо было имитировать этот инструментарий, в то время как у объектов можно просто реализовать этот инструментарий внутри самого объекта!
А если вдруг надо было немного изменить пользовательский тип данных, удобно было с помощью инструментария объектов — наследованием создать потомка, и в нём исправить поведение.
Бум и тотальное использование объектов привело ныне к стагнации.
Что же сейчас мешает объектам и дальше развиваться?
Как мы помним, реализация инструментария нового объекта полностью лежит в ответственности у программиста, а не на языке, поэтому уровень переиспользования кода не такой большой, как мог бы быть.
Не менее важна и всё большая закрытость. Объект сам всё будет делать, хотя и делать всего от него почти никогда не нужно. И наоборот, обладая возможностью всё делать самому, другим этот объект ничего делать не будет. Может, но не будет.
Частично проблему помогает решать введение интерфейсов (interface) и примисей (mixins, traits).
Интерфейсы впервые вводят Делфи (в 1986 ещё как Объектный Паскаль), позже Ява и Си#. И это понятно – они были лидерами в объектных языках.
А вот что удивительно, примести/трейты появились при попытке присоединить объекты к Лиспу (Flavors, CLOS) (CLOS — часть Коммон Лиспа), позже добавлены в разные языки.
Однако даже такие абстрактные помощники, как интерфейсы и примеси не всегда помогают, например, к старому объекту с меткой «финализированный» (final). Частично можно решить проблему гибридизации на основе прототипного наследования (открытого языком Селф(диалектом того самого Смолтолка) в середине 1980х и получившего популярность благодаря, прежде всего, ЯваСкрипту десятилетием позже), однако у этого метода есть свои минусы относительно классового наследования.
Интересна поддержка метаклассов (metaclass), которые были заложены в Смолтолк ещё в 1980 и ныне поддерживаются некоторыми языками, например, Питоном. Метаклассы работают с классами как объектами (такой себе рекурсивный подход). Это сильно улучшает инструментарий работы с объектами как объектами.
Ныне на первое место приходит не создание нового объекта, а грамотный подход к проектированию системы с использованием шаблонов(паттернов) проектирования.
Что будет дальше? Вопрос риторический.
Есть ли альтернативы столь мощным пользовательским типам данных, как объекты, структуры? Есть, и даже лучше, чем объекты! Стоит взглянуть на них получше, что бы понять, как могут в дальнейшем развиваться объекты.

Поиск альтернативы


Христос и Кришна вместе. Императивность и Функциональность могут быть вместе

Куда бы посмотреть в поисках альтернативы?
Декларативные (типа HTML) и логические языки (типа Пролога) на сегодня альтернативы не содержат. Они основаны на том, что вместо программиста работает компилятор/интерпретатор.
И тут надо либо
1) просто бросить попытки добавить пользовательские типы данных и войти в симбиоз с другим языком (например HTML + ЯваСкрипт)
2) подключить другие парадигмы программирования.

Кстати, на счёт подключения других парадигм, казалось бы, чем хорошо иметь мультипарадигменные языки? Питон (1991) и Руби (1994) так не думали.
И, оказались правы. Там, где легко уделывал всех Лисп – удобно применять парадигму функционального программирования, где нужна простота — там процедурный стиль, на остальные случаи — хорошо справляются объекты.
Казалось бы, никаких новых пользовательских данных не добавилось, а эффективность написания кода сильно возросла.
И вот когда на дворе 2011, даже в Си++ пришли лямбда-функции из Лиспа.
Из Явы выросла Скала с 2003, приняв посылку, что объекты — это ещё и функции.

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

Алгебраические Типы Данных


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

Ух ты, как грозно звучит!
Стандартный МЛ в 1990 впервые вводит Алгебраические Типы Данных (АТД).
Алгебраические типы данных – это один из самых мощных пользовательских типов данных. Найдены они были математиками Хиндли и Милнером в лямбда-исчислении.
АТД — это «всё в одном» — унитарные типы данных (типа null), перечисление (типа enum, bool), защищённые базовые типы (типа как resource в противовес ссылке), переключательные типы (что-то вроде в Си — union), спископодобные структуры, древовидные структуры, функции, кортежи, записи, объекто-подобные структуры (но не объекты). И любые комбинации всего этого.
Это значительно лучше объектов! По крайней мере, с точки зрения создания разнообразных самих пользовательских типов данных – да, лучше, безусловно.
Только с других точек зрения этот тип данных как в Стандартном МЛе, так и в более позднем ОКамле – весьма и весьма скуден.
Инструментарий для работы с АТД как с АТД не сильно больше, чем работой с записями, и значительно меньше, чем с объектами.
Во-вторых, инструментария для работы с ещё несозданными типами данных нет. И, в отличие от объектов, прятать самописный инструментарий некуда. Только имитировать.
Камль, как потомок Стандартного МЛ, недолго думая, добавил к себе объекты и стал ОКамлем (к 1996му). И параллельно ОКамль начал развивать альтернативное, более функциональное решение, куда спрятать реализацию инструментария по работе с пользовательскими данными – в параметрические модули. И, за лет 15 ОКамль построил достойную функциональную замену объектам. Тут ещё интересен подход – как мы помним, параметрические модули-функции стали вводить для того, что бы избавиться от проблемы отсутствия инструментария для ненаписанных данных АТД, только вот сами параметрические модули ныне почти не отличаются от АТД, а значит, сейчас нет инструментария для ещё не написанных… модулей. Прямо рекурсия!
А за эти 15 лет ОКамль находит ещё один вариант решения проблемы отсутствия инструментария по несозданным типам данных, он их так и называл — вариант (variant). Это иной, не АТД тип данных, хотя внешне похож. Это переключательный тип данных, заодно им можно делиться в любых пропорциях, включая смешивание (АТДанными делиться в пропорциях нельзя, равно как и смешивать). Хорошо, что можно пропорционально делиться (с объектами можно добиться лишь с помощью интерфейсов или трейтов, да и то – не полностью), зачастую заманчиво смешивание (такое с объектами не сотворишь), плохо, что в любых пропорциях. Тут есть ещё над чем работать. Этот тип данных недоразвит. Из простых путей развития – добавить в доселе скудный инструментарий работы с вариантами инструментарий множеств.

Алгебраические Типы Данных в паре с Классами типов


АТД вместе с классами типов выглядят грубо, но способны на многое

В начале 90х на основе Стандартного МЛ, а так же нескольких академических языков, был разработан ещё один язык, впервые стандартизированный лишь в 1998. Им был Хаскель.
У него были те же Алгебраические типы данных, что у Стандартного МЛ и ОКамля. И такой же скудный набор по работе с АТД как с АТД. Но у Хаскеля было (и до сих пор есть) то, чем не обладал доселе ни один тип пользовательских данных. У Хаскеля есть инструментарий для ещё ненаписанных пользовательских типов данных – это классы типов (class).
Сами классы типов представляют собой что-то вроде интерфейсов или примесей, наиболее близко к ролям (roles) в Перле, только введение классов отличается от введения интерфейсов/трейтов.
Интерфейсы для простых классов типов, примеси – для усложнённых.
Причём для сложных классов аналогия с примесью уже не будет подходить. К сложным классам нет необходимости подключать полностью данные, достаточно присоединиться в точках входа, или в одной из нескольких точек входа, если это разрешено.
Причём с помощью реализации класса (instance) можно делиться инструментарием, причём не только с кодом, написанным позже создания класса, но и для данных, созданных ранее (как если можно было добавить поведение финализированным объектам). Если брать аналогию в объектных языках, это достигается, прежде всего, путём присоединения не интерфейсов и примесей к объектам, а наоборот, объектов к примесям и интерфейсам (частично это уже есть у ролей в Перле).
Но Хаскель не остановился даже на этом. Он реализовал автоматическое выведение (deriving) классов для различных типов данных.

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

Хаскель бурно развивается. Уже сейчас Алгебраические Типы Данных – лишь часть большего.
Ныне вполне можно создать семьи данных, Обобщённые Алгебраические Типы Данных (GADTs), экзистенциальные, многоранговые.
Классы типов тоже не стоят на месте. Уже сейчас можно использовать многопараметрические, функционально-зависимые, разновидовые классы.
Расширяется инструментарий работы с АТД как с АТД в контексте метапрограммирования.
Многое из этого нового существует как расширения языка, а в 2014 году это может войти в стандарт языка.

Заключение


История открыто показала острую необходимость в пользовательских типов данных.
Пользовательские типы данных нужны всё больше. Всё разнообразней. С глубокой поддержкой инструментария, способного работать как с обобщённым типом пользовательских данных, так и с тем, что только будет создано программистами.
Как только удалось спрятать самописный инструментарий в сами пользовательские данные — начался бурный рост пользовательских данных.
Однако, как показала история, иногда недостаточно языку владеть прогрессивными технологиями, для того, что бы стать популярным. Изобретение объектов в Симуле до появления Си (в котором даже не было объектов) не сделало прорыва для самой Симулы.
История показала, что находить под ногами то, что никто не видит — тоже полезно. Объединение нескольких парадигм и достижением этим большего, чем по отдельности (Руби, Питон, ..), открытие низкоуровневых динамических типов данных(Си), обобщение работы со строками — как работой парсерами (Перл) — очень помогло как этим самим языкам, так и программированию в целом.
Найдут ли Лисп-подобные языки свой инструментарий для ещё не созданных типов данных?
Остановятся ли объекты в развитии? Если нет, то куда пойдут — по пути языка Скала? Руби? Перл?
Когда наступит золотой век Алгебраических типов данных? Есть ли шансы развиться у вариантного типа данных?
Будут ли заимствованы хаскелевские классы другими языками? Куда пойдёт Хаскель?
Время покажет и ответит на вопросы.
Tags:
Hubs:
+51
Comments 51
Comments Comments 51

Articles