Хотелось бы остановиться и посмотреть на развитие языков программирования с точки зрения разработки пользовательских типов данных (UCD).
Сразу хочу оговориться: под пользователями мы подразумеваем программистов, как людей, которые пишут код на этих языках.
Ну и те, кто сопровождает этот код или просто его читает. Пользовательские типы данных — это типы данных, которые могут быть созданы пользователем на основе того, что доступно в языке.
Пользователям нужны такие типы данных:
Пользователи хотели иметь возможность компоновать данные так, как им хотелось.
Хотели, хотят и, наверное, захотят. Все больше, разнообразнее и сильнее.
Вот почему полезно следить за развитием пользовательских типов данных в программах и языках программирования.
Нет пользовательских типов данных
Когда-то не было пользовательских типов данных.
Каким-то образом мы выбрались На заре компьютерной эпохи языки были не ахти - машинные: либо ты подчиняешься их диктату (а диктат там простой: либо ты используешь малоразрядные числа в двоично-десятичной системе счисления (ну, или независимо от того, с каким процессором работает процессор) и команды процессора) или нет. Мы не будем касаться тех «темных веков».
Можно сказать одно — пользовательских типов данных не было, но программисты как-то выживали и как-то писали программы.
Встроенные типы данных
Встроенные типы — это так удобно! При условии, что вы используете их так, как задумано разработчиками.
Первым более-менее нормальным языком был Ассемблер (на самом деле ассемблеров много, речь идет о ядре языков, появившихся в 50-е годы).
Помимо читабельности, он привнес много нового в плане пользовательских данных.
Самое большое и неоспоримое достижение — это возможность создавать переменные! С тех пор почти все языки включили такую возможность — возможность создания переменных.
Второе не менее важное достижение ассемблера, сделанное с благими намерениями, — это попытка вставить в язык все типы данных (из тех, которые могут понадобиться программисту) непосредственно в язык.
Ну а остальное мелочь - прежде всего, умение записывать числа не только в двоичной, но и в шестнадцатеричной, восьмеричной, двоично-десятичной системах.
Тогда казалось, а что еще может понадобиться пользователю? Шли годы, росла потребность не только в абстракциях высокого уровня, но и в пользовательских типах данных.
А потом наступил 1957 год и появился Фортран.
Написанный на нем код выглядел почти как современные языки, хотя его вариант на перфокартах может шокировать людей, желающих его прочитать.
Фортран предоставил все необходимое.
для расчета полета баллистических ракет - такие данные как целые числа (тип int), с запятыми (тип float) и комплексные.
Линии? Кому они нужны на перфокартах? В Фортране они появятся позже — настоящие строки только через 20 лет, а их имитация — через 10 (вместе с логическим типом данных).
Фортран также предоставил почти реальный тип пользовательских данных в виде массива (хотя его использование несколько отличается от современного), об этом мы поговорим подробнее в главе о групповых пользовательских данных.
Но пользователям этого недостаточно — они хотят все больше и больше пользовательских данных.
И тут появляется — Алгол, уже 1958 года, программы на котором легко читаются и сегодня.
Именно Алгол принес основу того, что сейчас повсюду — булевы типы, строки, различные целочисленные типы и числа с точкой с запятой.
Чуть позже все это применил Фортран, но Алгол был пионером.
Казалось бы, все аппетиты удовлетворены, какие еще типы нужны пользователям? Да всё уже реализовано — просто бери и пользуйся.
А затем, по горячим следам Алгола и Фортрана, в 1958 году появился еще один совершенно другой язык — Лисп.
Лисп может делать невообразимые вещи.
Но как с этим жить? Он дал другой, совершенно новый тип данных, настоящие пользовательские типы данных — функции (типа C-выражения), которые прочно стали включаться во все современные языки лишь с начала XXI века (прежде всего благодаря мульти- парадигмальные языки Python и Ruby).
Учитывая, что Лисп позволяет оперировать макросами — что-то вроде eval-программирования (в 58-й версии) — неудивительно, что мир оказался к этому не готов.
Но готов ли мир к Lisp сейчас? Возможно нет. Позвольте мне сосредоточиться на том, почему.
Лисп, как и любое другое функциональное программирование, работает с сильно взаимосвязанными объектами, чем-то напоминающими взаимосвязанные шестерни механических часов.
В отличие от императивных языков, любое заклинивание в шестерне останавливает весь механизм.
Из-за этого требования к языку, в том числе и к пользовательским типам данных, значительно ужесточаются.
Те проблемы, которые возникли в Лиспе сразу, в императивных языках обострились лишь к концу 80-х.
Лисп позволяет создавать любые C-выражения.
Но он предоставляет только один инструментарий — стандартный и простой инструментарий для работы с C-выражениями.
Получается, что можно записывать любые пользовательские данные, но работать с ними можно только как с примитивами.
Развитие Lisp-подобных языков показало, что для неписаных C-выражений пока не найдено хороших инструментов.
Некоторое время все были счастливы.
Развитие пользовательских данных замедлилось почти на десятилетие.
Если им чего-то хотелось, они добавляли эти типы данных прямо в язык.
Но в те времена языки развивались и обновлялись не так быстро, как сейчас, поэтому в основном имитировали создание пользовательских типов данных.
Имитация по функциональности практически идентична исходным типам данных.
Большая часть моделирования в те дни была основана на эмуляции функций (процедурный стиль).
Основное отличие от реальных кастомных типов в одном — если вы захотите «слегка» изменить тип данных, вам придется переписать весь функционал.
Никто не хотел этого делать.
Поэтому они стали более гибкими в подражании.
Сейчас я скажу то, что всем известно, но здесь важна не описываемая техника имитации, а угол зрения на эту технику.
Иногда приходится работать только с теми возможностями, которые существуют
Во-первых, появился настраиваемый функционал на основе флагов.
Это не самый простой способ, но он очень напоминал ассемблер и был тогда ещё известен.
Суть передачи флагов проста — передача числа в качестве параметра, причем число представляется в виде двоичной последовательности флагов.
Несмотря на широкое распространение, языки до сих пор не имеют специальных типов данных, таких как ряд флагов.
Вместо этого они нашли хорошую замену — именованные константы и битовые операции, похожие на логические.
Самый простой метод - он до сих пор широко используется везде - это настройка по параметрам: чем больше нужно настроить, тем больше параметров передается.
Минус только один — слишком легко запутаться в порядке передачи параметров.
Поэтому этими методами стараются передать до 4-5 аргументов.
Для большего количества аргументов, с развитием реальных пользовательских данных, в первую очередь групповых и составных, появилась возможность передавать один сложный аргумент — это та же самая конфигурация, только не по горизонтали, а по вертикали.
Расширением этого метода является создание встроенных языков (DSL) для настройки функций.
Третий способ сделать симуляторы гибкими — это изобретение обработчиков, хотя в то время они так не назывались и часто служили суррогатами манипуляторов — чисел и строк, а не ссылок или указателей.
Эпоха встроенных типов данных заканчивалась.
Но наступил 1972 год, и появился.
С.
И эра доминирования динозавров (встроенных типов данных) продолжалась еще десятилетие, хотя определяемые пользователем типы данных начали завоевывать свое место под солнцем.
В том числе и в самом C. А пока вернемся к другому встроенному типу данных, который стал одной из причин растущей популярности языка.
C представил низкоуровневый тип данных, который был в ассемблере и был полностью забыт в первых языках высокого уровня, — динамические типы.
Прежде всего, это ссылки и указатели.
Они дополнены обслуживающим нулевым типом данных – null.
Динамические типы данных подобны отмычкам — некрасиво, но в какие потайные комнаты с ними не проникнешь?!
Ссылку можно считать одним из вариантов реализации этого типа пользовательских данных в качестве синонима.
Развитие синонимов можно найти в PHP и его концепции переменных переменных, где вы можете вернуть значение переменной или функции, имя которой записано в значении вызываемой переменной.
В C вызов функции может быть вызван функцией вызова или вы можете передать функцию обратного вызова.
В дополнение к этому динамические типы данных помогают ускорить выполнение скомпилированного кода.
Помимо этих преимуществ, у динамических типов данных есть еще одно огромное преимущество — с их помощью можно довольно просто реализовать то, что не было включено в сам язык.
Смущает только одно: все, что написано с их использованием, доступно только с помощью инструментов для работы с динамическими данными.
Но известен прием обхода при моделировании данных — закрытие их в функциях и возврат ссылки/указателя на то, что было создано — манипуляторов (обработчиков).
Манипуляторы — один из тех типов данных, которые на разных языках могут называться совершенно по-разному.
Например, в PHP они называются ресурсами, в rlang — портами и идентификаторами процессов.
В Коболе есть такой тип данных как файл и картинка.
Однако динамические типы данных — не единственные преимущества.
Есть и недостатки, иногда очень большие.
Чем больше свободы язык дает в использовании динамических типов данных, тем: 1) увеличиваются возможности создания того, что не было включено в язык (и это не обязательно положительные возможности) 2) компилятор все меньше вмешивается в действия пользователя и вся ответственность за действия ложится на программиста 2) резко возрастает небезопасность кода 3) резко возрастает возможность инъекций в именно-ценностное пространство 4) сборщик мусора вмешивается всё меньше и вся ответственность ложится на пользователя Последующая история показала, что создатели последующих языков (или тех, которые добавлялись к существующим языкам) балансировали безопасность и возможности при добавлении динамических данных.
По мере приближения конца 70-х эти базовые встроенные типы данных начали отходить на периферию, в рутину, уступая место реальным пользовательским данным.
Однако реальность иногда преподносит неожиданные сюрпризы.
Кто знает, сколько еще можно найти в старых добрых и давно понятных типах данных?!
Иногда просто необходимо увидеть что-то новое там, где все уже давно известно.
Например, вот такие M&Ms. Затем, в конце 70-х, появился скриптовый язык AWK (с использованием разработки утилиты grep), а десятилетие спустя на его основе, в 1987 году, появился такой язык, как Perl. И, кроме всего прочего, у него был (есть) такой экзотический встроенный тип данных, как регулярные выражения.
Perl помог взглянуть на такой старый тип данных, как строки, с новой точки зрения.
Инструменты для работы с ним в ранних языках можно было рассматривать как упрощенные парсеры.
Языки регулярных выражений зарекомендовали себя как очень гибкие и сверхмощные инструменты для работы с символьными типами данных.
Групповые типы данных
Некоторые группы большие.
Я хочу работать с ними быстро По сути, групповые типы данных — это множество элементов языка, обычно мономорфные группы.
Часто эти типы данных не пользовательские, а встроенные, но иногда они настолько гибкие, что этого достаточно.
Фортран уже поддерживал групповые типы данных — массивы, хотя выглядели они немного иначе, чем сейчас.
В Алголе уже были массивы, очень похожие на современные.
Были наборы на Паскале В Лиспе были списки.
Потом были хеш-таблицы, ассоциированные массивы, векторы, кучи, очереди, стеки, деревья.
Некоторые из них были встроены, некоторые были имитированы или созданы с использованием пользовательских типов данных.
Дальнейшее развитие групповых типов данных привело к двум различным ветвям развития.
1) необходимость использовать свой функционал с каждым групповым типом данных оказалась не самой удовлетворительной; Я хотел работать с ними единообразно.
Основными инструментами для этого в императивных языках являются коллекции и итераторы.
В основном добавлено в начале 2000-х годов.
2) В 80-е годы с развитием роста данных потребность в расширении инструментов работы с групповыми типами данных росла как на дрожжах.
Появились базы данных, а вместе с ними запросы и языки запросов.
В середине 1980-х годов доминирующим стал язык структурированных запросов (SQL).
Подобно анализаторам строк, язык запросов ясно давал понять, что инструментарий, используемый для групповых типов данных, можно считать примитивным языком запросов.
Базы данных, как правило, вынесены за пределы языка, а в языке есть только методы работы с ними, поэтому их нельзя считать полноценными пользовательскими типами данных.
Хотя ввиду их гибкости это не принципиально.
Реальные пользовательские типы данных
В эпоху встроенных типов данных можно встретить поддержку довольно экзотических встроенных типов данных в разных языках.Например, в C этот тип данных был перечислением.
Впервые он был представлен до C Паскалем (1970), хотя он называл его скаляром.
Что такое перечисление, легко объяснить даже детям на пальцах.
Перечисление — это настоящий пользовательский тип данных! Казалось бы, Си должен поставить за это памятник.
Нет, кроме, может быть, надгробия.
Дело в том, что пользователи имеют возможность строить любые перечисления.
Только на С с ними работать нечего (у Паскаля был базовый набор).
Ничего вообще.
Вы можете создавать перечисления, но не можете с ними работать.
Поскольку язык C был широко распространен, мало кто хотел добавлять этот тип данных в другие языки.
Лишь в C++11 появились хоть какие-то инструменты для работы с перечислениями.
Этот пример, как и разработка Lisp, показал, насколько важно иметь не только собственные типы данных, но и инструменты для работы с ними.
Составные типы данных
Записи очень разнообразны.
Я бы хотел научиться ими пользоваться Но в C был еще один настоящий пользовательский тип данных.
Хотя он был изобретен гораздо раньше – еще в Коболе, выпущенном в начале 60-х годов (сам язык создан в 1959 году).
Это запись, называемая структурой в C. Запись — это не что иное, как группа разнородных типов данных.
К записям прилагается инструментарий для работы с записями.
Например, C не полностью обеспечивает стандартный теперь минимум работы с записями (например, только одностороннюю инициализацию).
С записями легко не имитировать, а создавать настоящие списки и деревья.
Неужели все снова в языке? Нет и еще раз нет. Уже недостаточно просто иметь собственные типы данных.
Недостаточно иметь инструменты для работы с PDD как с PDD. На первый план выходит нечто другое.
Никто не предоставляет никаких инструментов для не созданных типов данных! Сейчас языки, поддерживающие записи, попали в ловушку, аналогичную той, в которую попал Лисп — создавать свои данные можно, но работать с ними можно только в базовом наборе.
Только в Лиспе ситуация хуже: в этом языке всё — C-выражения, а в C, Cobol и других запись — самостоятельный тип, к тому же у него есть свой, пусть и небольшой, инструментарий.
К счастью, выход из этого тупика давно известен — имитация работы с пользовательскими типами данных с помощью функций.
Именно благодаря записям/структурам (в том числе на C) программисты осознали важность пользовательских типов данных.
При этом явно обозначился острый дефицит инструментов для работы с еще не созданными типами данных.
И был ответ. Как бы удивительно это ни звучало, но до создания C оставалось пару лет, он был в Европе и назывался Simula (1967).
А затем, когда C начал задыхаться от нехватки инструментов для пользовательских типов данных, C++ (в 1983 году) взял все самое лучшее от Simula и применил это к синтаксису C.
Объекты
Объекты могут все.
Сами собой и над собой Объекты — это еще один тип пользовательских данных.
Он имеет значительно большие возможности, чем имела запись.
Это дало ему возможность обрести бешеную популярность.
По иронии судьбы, точно так же, как и Simula, выпущенная за пару лет до C, в которой не было объектов, так и за пару лет до C++, Smalltalk объявил о парадигме «всех объектов» в 1980 году.
Но Smalltalk не снискал особой популярности, ему пришлось ждать, пока C++ выйдет на уровень стагнации, и только после этого Java в 1995 году снова смогла гордо поднять над головой парадигму «все объекты».
Что такого замечательного в объектах, так это то, что они мало чем отличаются от записей.
По сути те же записи с добавлением методов.
Во-первых, инструменты для работы с самими объектами гораздо богаче и мощнее, чем инструменты для работы со структурой.
А во-вторых, инструментов для работы с еще не созданными объектами не было.
тоже.
Стоп, возникает вопрос, а где тут «второе», если объекты не имеют никакого инструментирования с несозданными типами данных, а записи — нет. И, тем не менее, во-вторых! Для записей нужно было имитировать эту инструментацию, а для объектов можно просто реализовать эту инструментацию внутри самого объекта! А если вдруг нужно было немного изменить тип пользовательских данных, удобно было воспользоваться набором инструментов объекта, чтобы создать потомка с помощью наследования и скорректировать поведение в нем.
Бум и тотальное использование объектов в настоящее время привели к стагнации.
Что сейчас мешает объектам развиваться дальше? Как мы помним, реализация инструментирования нового объекта полностью лежит на программисте, а не на языке, поэтому уровень повторного использования кода не так высок, как мог бы быть.
Не менее важным является повышение секретности.
Объект сам сделает все, хотя от него почти никогда не требуется делать все.
И наоборот, имея возможность делать все сам, этот объект не будет ничего делать другим.
Возможно, но это не так.
Частично решить проблему помогает внедрение интерфейсов и миксинов, трейтов.
Интерфейсы были впервые представлены Delphi (в 1986 году как Object Pascal), а затем Java и C#.
И это понятно — они были лидерами в объектных языках.
Но что удивительно, так это то, что аппроксимации/трейты появились при попытке присоединения объектов к Lisp (Flavors, CLOS) (CLOS — часть Common Lisp), а позже были добавлены в разные языки.
Однако даже такие абстрактные помощники, как интерфейсы и миксины, не всегда помогают, например, со старым объектом с меткой «final».
Частично проблему гибридизации можно решить на основе прототипного наследования (открытого языком Self (диалект того же Smalltalk) в середине 1980-х годов и получившего популярность в первую очередь благодаря JavaScript десятилетие спустя), но этот метод имеет свои Недостатки, связанные с наследованием классов.
Интерес представляет поддержка метаклассов, которые были введены в Smalltalk еще в 1980 году и сейчас поддерживаются некоторыми языками, например Python. Метаклассы работают с классами как с объектами (разновидность рекурсивного подхода).
Это значительно улучшает инструментарий для работы с объектами как с объектами.
Сегодня на первое место выходит не создание нового объекта, а грамотный подход к проектированию системы с использованием шаблонов дизайна.
Что будет дальше? Вопрос риторический.
Существуют ли альтернативы таким мощным пользовательским типам данных, как объекты и структуры? Да, и даже лучше, чем предметы! Стоит к ним присмотреться, чтобы понять, как объекты могут развиваться в будущем.
В поисках альтернативы
Христос и Кришна вместе.
Императивность и функциональность могут идти вместе Где искать альтернативу? Декларативные языки (например, HTML) и логические языки (например, Пролог) в настоящее время не содержат альтернатив.
Они основаны на том, что вместо программиста работает компилятор/интерпретатор.
И здесь нужно либо 1) просто отказаться от попыток добавления собственных типов данных и войти в симбиоз с другим языком (например HTML+JavaScript) 2) подключить другие парадигмы программирования.
Кстати, по поводу связи других парадигм, казалось бы, почему хорошо иметь мультипарадигмальные языки? Python (1991) и Ruby (1994) так не считали.
И они оказались правы.
Там, где Лисп сделал все легко — удобно использовать парадигму функционального программирования, где нужна простота — есть процедурный стиль, для остальных случаев — хорошо справляются объекты.
Казалось бы, никаких новых пользовательских данных не добавлялось, а эффективность написания кода сильно возросла.
А в 2011 году даже в C++ появились лямбда-функции из Lisp. The Rock вырос из Java в 2003 году, приняв предпосылку, что объекты также являются функциями.
Метапрограммирование — это хорошо.
Но, как правило, он позволяет либо расширить (сделать более гибкими) встроенные типы данных, либо сгенерировать новый код, либо просто иметь возможность создавать обобщения, он работает со встроенными типами данных.
Пока только со встроенными.
Но даже без пользовательских типов данных метапрограммирование — это будущее (и во многих отношениях настоящее) с точки зрения избавления от рутинного программирования.
Алгебраические типы данных
АТД настолько красивы, что их хочется оформить в рамку и повесить.
А иногда оставь это там и больше не трогай.
Ух, как угрожающе это звучит! В Standard ML впервые были представлены алгебраические типы данных (ADT) в 1990 году.
Алгебраические типы данных — одни из самых мощных пользовательских типов данных.
Они были открыты математиками Хиндли и Милнером в лямбда-исчислении.
ADT — это «все в одном» — унитарные типы данных (тип null), перечисление (тип enum, bool), защищенные базовые типы (например, ресурс, а не ссылка), типы переключателей (что-то вроде объединения в C), структуры, подобные спискам.
, древовидные структуры, функции, кортежи, записи, объектноподобные структуры (но не объекты).
И любая комбинация всего этого.
Это намного лучше, чем удобства! По крайней мере, с точки зрения создания самих разнообразных пользовательских типов данных — да, лучше, конечно.
Только с других точек зрения такого рода данных, как в Стандарте ML, так и в позднейшей ОКамле, очень и очень скудно.
Инструменты для работы с АТД как с АТД — это не намного больше, чем работа с записями, и гораздо меньше, чем работа с объектами.
Во-вторых, нет инструментов для работы с еще не созданными типами данных.
И, в отличие от предметов, самописные инструменты некуда спрятать.
Просто подражайте.
Камл, как потомок Стандартного ML, недолго думая, добавил к себе объекты и стал OKaml (к 1996 году).
А параллельно OKaml начал разрабатывать альтернативное, более функциональное решение, где скрыть реализацию инструментов работы с пользовательскими данными — в параметрических модулях.
И за 15 лет Окамл построил достойную функциональную замену объектам.
Здесь тоже есть интересный подход - как мы помним, параметрические модули-функции начали вводить для того, чтобы избавиться от проблемы нехватки инструментов для неписаных данных АТД, но сами параметрические модули теперь почти ничем не отличаются от АТД.
, а это значит, что сейчас нет инструментария для ещё не написанных.
модулей.
Прям рекурсия! И за эти 15 лет Окамл нашел другое решение проблемы нехватки инструментов для несозданных типов данных, он их так назвал — вариант. Это другой тип данных, чем ADT, хотя он выглядит похоже.
Это переключаемый тип данных, при этом их можно разделять в любых пропорциях, включая смешивание (ATData не может делиться в пропорциях и не смешивается).
Хорошо, что можно делиться пропорционально (с объектами этого можно добиться только с помощью интерфейсов или трейтов, да и то не полностью), смешивание часто заманчиво (с объектами так нельзя), плохо то, что в любых пропорциях .
Есть еще над чем работать.
Этот тип данных недостаточно развит. Один из самых простых путей развития — добавить к скудным до сих пор инструментам работы с опциями инструменты множеств.
Алгебраические типы данных в сочетании с классами типов
ADT и классы типов выглядят примитивно, но могут многое сделать.
В начале 90-х на основе Standard ML, а также нескольких академических языков был разработан еще один язык, впервые стандартизированный только в 1998 году.
Это был Haskell. Он имел те же алгебраические типы данных, что и Standard ML и OKaml. И тот же скудный набор инструментов для работы с ADT, что и с ADT. Но В Haskell было (и есть) то, чего раньше не было ни в одном другом типе пользовательских данных.
В Haskell есть инструменты для еще не написанных пользовательских типов данных.
– это классы типов (class).
Классы типов сами по себе являются чем-то вроде интерфейсов или примесей, наиболее похожих на роли в Perl, только введение классов отличается от введения интерфейсов/особенностей.
Интерфейсы для классов простых типов, миксины для более сложных.
Более того, для сложных занятий аналогия с примесью уже не подойдет. Для сложных классов нет необходимости подключать все данные; достаточно присоединиться в точках входа или в одной из нескольких точек входа, если это разрешено.
Более того, используя реализацию класса (экземпляра), вы можете совместно использовать инструменты не только с кодом, написанным после создания класса, но и для данных, созданных ранее (как если бы к финализированным объектам можно было добавить поведение).
Если брать аналогию в объектных языках, то это достигается, прежде всего, за счет присоединения к объектам не интерфейсов и миксинов, а, наоборот, объектов к миксинам и интерфейсам (частично роли в Perl уже это имеют).
Но Haskell даже на этом не остановился.
Он реализовал автоматическое наследование классов для различных типов данных.
Это определенно гораздо более возможно с точки зрения возможностей пользовательских типов данных, чем присуще объектам.
Haskell быстро развивается.
Алгебраические типы данных уже являются частью чего-то большего.
В настоящее время вполне возможно создание семейств данных, обобщенных алгебраических типов данных (GADT), экзистенциальных, многоранговых.
Типовые классы тоже не стоят на месте.
Уже возможно использовать многопараметрические, функционально-зависимые и многотипные классы.
Расширяются инструменты работы с АТД как с АТД в контексте метапрограммирования.
Большая часть этого нового существует в виде расширений языка и в 2014 году может стать языковым стандартом.
Заключение
История ясно показала острую необходимость в пользовательских типах данных.Пользовательские типы данных требуются все больше и больше.
Все разнообразнее.
С глубокой поддержкой инструментов, которые могут работать как с общим типом пользовательских данных, так и с тем, что будет создано только программистами.
Как только удалось скрыть самописные инструменты в самих пользовательских данных, начался стремительный рост пользовательских данных.
Однако, как показала история, иногда языку недостаточно освоить передовые технологии, чтобы стать популярным.
Изобретение объектов в Simula до появления C (в котором даже объектов не было) не стало прорывом для самой Simula. История показала, что найти под ногами то, чего никто не видит, тоже полезно.
Объединение нескольких парадигм и достижение большего, чем по отдельности (Ruby, Python, .
), открытие низкоуровневых динамических типов данных (C), обобщение работы со строками — например, работа с парсерами (Pearl) — очень помогли обоим этим языкам.
и программирование в целом.
Найдут ли Lisp-подобные языки свои инструменты для еще не созданных типов данных? Объекты перестанут развиваться? Если нет, то куда они пойдут — по пути языка Scala? Рубин? Перл? Когда наступит золотой век алгебраических типов данных? Есть ли шанс на появление варианта типа данных? Будут ли классы Haskell приняты другими языками? Куда пойдет Хаскель? Время покажет и ответит на вопросы.
Теги: #программирование #fortran #Lisp #C++ #C++ #perl #OCaml #haskell #программирование #ООП #Функциональное программирование
-
Как Динозавры Появляются В Новостях О Марсе
19 Oct, 24 -
Чистка Матрицы Ноутбука От Следов Жидкости
19 Oct, 24 -
Отложить: От Перехода К Php
19 Oct, 24 -
Флеш-Накопитель Usb И Esata
19 Oct, 24 -
Издатель Позаимствовал Текст Из Википедии.
19 Oct, 24 -
Техники Персонализации Контента
19 Oct, 24