Pull to refresh

Comments 55

Я вот недавно купил вторую книгу по Go. Один из авторов — Брайан Керниган.
И в этой книге есть схема языков, которые повлияли на Go:
ALGOL60->C-Go,
ALGOL60->Pascal->Newsqueak->Alef->Go,
Pascal->Modula-2->Oberon-Oberon-2->Go

Так что идеи Вирта живут и здравствуют. Вместе с идеями Кернигана.
Керниган взял некоторые идеи из Оберона, да, но Go не имеет ровным счётом никакого отношения к тем ценностям, который пропагандирует Вирт. Опять этот жуткий С-подобный синтаксис (пускай и с Обероновской структурой программ) с кучей колокольчиков и сюрпризов на ровном месте. Эдак можно и кивая в сторону Java сказать, что идеи Вирта живут и здравствуют. Идеи Вирта (максимально простой, жёсткий и в то же время достаточный язык программирования) последовательно воплощались лишь в его же линейке (Pascal -> Modula -> Oberon) и, пожалуй, нигде более. Ну разве что Modula-3 сюда же можно отнести с небольшой натяжкой: исключения и обобщённое программирование не делают этот язык максимально простым, но в то же время Oberon, в котором эти средства отсутствуют, не является всегда достаточным. Имеем своего рода компромисс, который, правда, можно оспорить.
Ага, только раньше там была другая фотка.
А почему, кстати, Оберон совсем не прижился в коммерческой разработке?
Потому что Оберон это студенческая поделка, там всё КАПСом, и ещё он только для обучения, и нет корпорации-овнера и ещё рынок не выбрал, а в продукшон нужны фичи, а не академичность, а Вирт вообще теоретик. А ещё в России никому не нужен ещё один язык программирования.
А фичи в библиотеки нельзя вынести? И поделкой является реализация языка а не сам язык (как абстракция) — т. е. этот недостаток устраним.
Простите, но ваш комментарий очень школьный
Сплошные цитаты корифеев ИТ с Хабра и других площадок. Что же вам не нравится? Может что-то оспорить хотите?
у вас детектор сарказма сломался, кажется :)
Потому что инвестиции в другие языки уже были сделаны (с оглядкой на разработки Вирта, естественно — сам профессор вспоминал, как компания Sun, ныне почившая в бозе, изучала исходники его оберон-системы) и инфраструктурная поляна оказалась занятой.

Другими словами, точка бифуркации была пройдена без Оберона. Хотя на Оберонах делались (и делаются) промышленные разработки.
Сложность низкоуровневого программирования, отсутствие поддержки обобщенного программирования (в C это делалось через void *, но делалось).
Расскажите об этом дедушке Вирту и парням из ETHZ, которые на Обероне сделали не одну ОС.
Вирт далеко не студент и способен разработать ОС почти на чем угодно.
Он показал, что Оберон пригоден — и другие проверили его опыт на себе, у всех всё получилось. Если вы изучите матчасть, то и у Вас получится. В этом суть, Вирт показывает всем, что ничего сложного для человека или невозможного для простого ЯП в этом всём нет.
> Целесообразность включения средств параллельного программирования непосредственно в язык подвергается сомнению многими специалистами. Это могло бы решаться на уровне библиотек.

Все библиотеки выполняются внутри виртуальной машины. Если эта виртуальная машина не поддерживает многопоточность, то никакая библиотека не поможет. От этого очевидного ограничения сильно страдают ruby, python, javascript, php. И никакие библиотеки не помогают.
UFO just landed and posted this here
Картинка «Сравнение объема синтаксиса языков» заставила меня страдать. Но за статью спасибо. Сам начинал с ТрубоПаскаля.
То, что Java отстой, — это святая правда. Целый год на ней программировал. Это был худший год в моей жизни. Как будто добровольно сделал себе временную лоботомию. Ничего толком нельзя сделать нормально. Для всего уже есть готовые библиотеки, которые более-менее подходят к случаю, и потому приходится их использовать, хотя интегрируются друг с другом они отнюдь не бесшовно. Все время такое ощущение, что закручиваешь крестовые шурупы плоской отверткой.
А в сравнении с до-диезом как? Просто я долгое время считал, что джава это тот же шарп, только появился раньше и в нем отсутствует много полезных фич (вроде полноценной рефлексии), но в целом языки достаточно похожие. Основные идеи совпадают. Например для меня «массив как объект» намного предпочтительнее, чем просто указатель на память и длина секции. Зачастую над массивами нужно производить многие вещи, расширять и т.п., все это решается типичными ООП средствами — интерфейсами, которые однозначно используются полиморфно. Поэтому я так и не понял предъявы по поводу «плохой джавы». Может объясните, что в ней не так? Я близко не общался с ней, только переносил пару классов одно время, немного неприятно, но все же лучше, чем паскаль или делфи.
Да, всё с ней не так. Какой-то бесконечно убогий язык. Крайне ограниченный. Множественного наследования нет. Дженерики, которые претендуют на роль шаблонов, нельзя назвать даже бледной тенью настоящих шаблонов… какая-то пародия. Ленин в своё время очень точно описал шаблоны в Джаве: «Формально правильно, а по сути издевательство». Прямого доступа к памяти нет. Общее ощущение такое, как будто ты ещё недостаточно взрослый, чтобы программировать по-настоящему, и тебя просто запустили в некую песочницу для маленьких программистов с напутствием типа: «Ну, давай, пока здесь поиграй. Попробуй хотя бы сам себе не навредить. Вот тебе совочек, который мы специально затупили так, что он почти не копает, но зато выглядит как настоящий. Главное, не ешь песок, всегда обрабатывай исключения, а любое взаимодействие делай через интерфейсы.»
Ну, от того что в шарпах есть указатели сильно они не распространились, ибо это достаточно серьезный удар по GC, который не может перемещать куски памяти, в которых мы шаримся по абсолютным адресам. Множественное наследование поддерживается интерфейсами, насколько я знаю. Множественное наследование же классов очевидно несет в себе кучу проблем с нулевой пользой. Да, были бы трейты или миксины, было бы лучше, но они во-первых позже распространились, а во-вторых это не множественное наследование.

Лично я указатели в продакшн-коде вообще ни разу не использовал, потому что если они где-то и используются, то либо где-то очень глубоко в библиотеках для всяких некрасивых хаков, либо в интеропе с С/С++, хотя и там оберток Managed-кода вроде ref/out/IntPtr достаточно, чтобы снизить написание unsafe до 0.
В языке D есть и GC и прямой доступ к памяти. Так что теоретически одно другому не мешает. Надо просто явно определить, что адресная арифметика не порождает сильных указателей, которые мешают уборке мусора. Т.е. ты можешь ходить по куску памяти как угодно, порождая сколько угодно указателей в его середину, но все эти указатели будут жить ровно до тех пор, пока жива главная ссылка на этот кусок памяти в целом.

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

В наши дни голые указатели и в С++ нечасто используются. Люди предпочитают оборачивать их в shared/unique_ptr. Хотя лично я считаю, что при программировании на безопасных указателях ощущения не те.
В наши дни голые указатели и в С++ нечасто используются. Люди предпочитают оборачивать их в shared/unique_ptr. Хотя лично я считаю, что при программировании на безопасных указателях ощущения не те.

Если только так.

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

Зачем сначала позволять множественное наследование реализации, а потом ломать себе голову, как ничего не отстрелить? Это детский подход, что шрамы украшают мужчину, а чем сложнее ЯП, тем элитнее на нем писать. Вон, можно посмотреть хаб PVS, там статистика подсказывает, что люди совершают элементарные ошибки в простейших местах, зачем расставлять грабли дополнительно? Какую выразительную силу это несет?

Вот покажите пример, что вот так вот с множественным наследованием реализации сделать изи, а вот с интерфейсным ничего хорошего не выходит.
Когда у тебя множественно наследуются только интерфейсы, тебе приходится делать реализацию руками непосредственно в классе-потомке. Это более безопасно, когда у тебя кривые ручки. Но это менее ООПшно.
Обычно реализацию делают с помощью экстеншн-метода, причем тогда она появляется сразу у всех реализующих интерфейс классов, а не только у «наследованных». И тот же LINQ показывает, что это крайне полезный вариант.

Ну и ты так и не ответил на опрос, зачем наследовать МНОЖЕСТВЕННУЮ реализацию? Ведь можно наследовать как кучу интерфейсов, так и базовый класс. Зачем наследовать разную реализацию? Как раз с ООП множественное наследование плохо сочетается, как правило это все от хреново продуманной иерархии.
Всмысле зачем? Я не понимаю вопрос. Никто же не говорит о том, что надо одновременно наследовать разные виды одного и того же поведения. Типа, когда объект одновременно наследует реализацию «квадрат» и реализацию «круг». Это дебилизм. Одновременно надо наследовать разные виды поведения и реализацию разных аспектов функционала. Например, объект может от одного базового класса унаследовать реализацию своей квадратности, а от другого — реализацию возможности сохраняться в БД. Использование в данном случае наследования интерфейсов вместо естественного наследования непосредственно реализаций неизбежно приводит к необходимости использовать всякие фабрики только для того, чтобы банально создавать объекты.
Зачем делать класс сохранения в БД, если можно сделать интерфейс `IDbEntity`, и затем написать сколько угодно экстеншнов для сохранения в БД этих `IDbEntity`? По факту это то же множественное наследование, за маленьким исключением: мы всегда можем указать своё поведение этой `IDbEntity`, а не зависеть от базового класса. Можем написать свою реализацию, можем использовать экстеншн с поведением по-умолчанию.

Множественное наследование же заставляет нас использовать реализацию, которую придумали разработчики языка.

Ну и да, если у вас одновременно объект — круг, и он еще и умеет в БД сохраняться, то это очевидное нарушение SRP.
Против экстеншен-методов я ничего не имею. Это очень неплохая замена мн. наследованию. И даже маленького исключения нет. При наследовании мы тоже всегда можем переопределить любой метод по-своему.

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


Его нет практически нигде в современных языках высокого уровня. Все почему-то пишут разные FFI. И они теперь все убогие?
Множественного наследования нет


Знаете, во многих языках вообще наследования нет. Например в Lisp-ах, и вообще в большинстве функциональных. Они убогие тоже?

Вам бы стоило понять, что есть языки, которые просто нужны для другого.Совсем для другого.
Lisp — не ООП язык. К нему претензий нет. И вообще, если бы вместо Java столь широко использовался Lisp, то мир был бы другим. Все крутые фичи Lisp'а можно просто добавить в тот список, который я начал с отсутствия прямого доступа к памяти и отсутствия мн. наследования. Сам Lisp не становится убогим из-за отсутствия мн.наследования, а вот Java из-за отсутствия макропрограммирования становится ещё более убогой, чем просто из-за отсутствия мн. наследования. Хотя всегда можно утешиться тем, что «зато на Java могут программировать даже олигофрены». Для многих это считается веским достоинством языка.

А намек на кучу других языков вы проигнорировали, или не уловили? Еще раз — прямого доступа к памяти нет в Haskell, например. И в Python. И в javascript. И что? И ничего. Это смешная придирка при наличии JNI/FFI.


Что до наследования — то оно прекрасно заменяется делегированием. И это всем известно, и никаких проблем не вызывает. Т.е. вообще никаких. А вот само множественное наследование их еще как вызывает.


Можно я спрошу просто — вы много языков-то знаете? Ну, таких на которых работали и работаете?

Ну, Python и Javascript знаю, поскольку регулярно использую. Perl уже почти забыл. Даже Java владею на достаточном уровне, чтобы осознанно ненавидеть. Молодыми языками типа Go не владею вообще и не имею к ним интереса. Функциональными тоже не владею, но лишь потому, что нет возможности их реально где-то применять, а в целом они мне нравятся.

Ну вот при всем при этом, ваши претензии выглядят странно. Про те же библиотеки, скажем… Я не знаю других распространенных систем, где бы подключение сторонних библиотек было настолько же просто, как в языках на базе JVM. Фактически — добавить в проект ссылку на репозиторий — и уже можно работать. В Perl это сложнее. В Python — тоже сложнее, хотя и не сильно. Примерно на таком же уровне это в javascript. Поддержка сторонних компонент в IDE на порядки лучше — во многом благодаря той самой "неполноценной" рефлексии, которая позволяет видеть метаданные по классам без исходников.


А то что библиотеки друг с другом не стыкуются — так какая же это претензия к языку?


Опять же — Java это язык для другого. Скажем, сделать отчет на основе данных из базы, в формате Excel — это плюс одна-три зависимости, и 5 строк кода + шаблон в виде xls файла.

То, что библиотеки подключать просто, — это вообще ни при чём. От этого зависит только то, сколько библиотек разработчик засунет в свой проект ради одной-двух функций, и насколько болезненным будет его геморрой с разруливанием зависимостей прямых и косвенных. Это я даже по себе знаю. Когда мне нужно было преобразовывать геокоординаты в меркатор и обратно, я вместо того, чтобы написать функцию в пару строк, подключил через JNI нативную библиотеку PROJ.4. А почему бы и нет? Это же так просто…

Библиотеки плохо стыкуются друг с другом ровно потому, что само ядро языка слишком ограничено. Почти для всего нужны библиотеки. В итоге авторов библиотек слишком много. Есть очень много библиотек, тупо повторяющих функционал других библиотек, но с немного другим интерфейсом. И практически никогда не получается выбрать такой набор, в котором бы библиотеки идеально подходили друг к другу. Кто-то возвращает списки объектов как ArrayList, кто-то другой — как SomeObject[], кто-то третий — как IList. Сплошной разброд и шатание. В результате, пользовательский код часто более, чем наполовину, состоит из циклов по перекладыванию из одного контейнера в другой.

Кстати, я согласен с тем, что Java — это новый Visual Basic. Только почему-то эта концепция не соблюдается. Очень часто можно увидеть её на серверах.
То, что библиотеки подключать просто, — это вообще ни при чём.


Да ладно ) То-то я видел тут (небольшую правда) кучку постов, о том что не надо тащить в проект лишние зависимости, потому что это трудно. В том-то и дело, что это реальная польза. У меня в текущем открытом проекте — 83 зависимости, и меня это совершенно не волнует. Не будет никакого геморроя — просто не надо тащить все в один проект, надо разбивать на сравнительно мелкие модули.
Почти для всего нужны библиотеки.
Вы не поверите — но это прекрасно! Главное что они не просто нужны — а они есть.


Что до остального — то опять же, с моей точки зрения это мелкие придирки. Да, можно List, можно массив, сейчас стало можно еще и Stream вернуть. Ну так извините, можно ведь и иначе взглянуть — можно вернуть имя файла (это String), можно Path (это уже немного другое, потому тут уже и структура папок в файловой системе, родитель, дети и.т п), а можно и просто File. И в чем же тут недостаток? Это разные вещи, для разных целей.
В результате, пользовательский код часто более, чем наполовину, состоит из циклов по перекладыванию
Ну это вы загнули… Arrays.asList(массив) — у вас этого половина? )))


Но в каком-то смысле — это правда. Потому что большая часть бизнес-кода — она реально из этого и состоит. Из базы в форму, из формы — обратно в базу.
Так просто редко удаётся сделать. Обычно возвращается список не того типа, объекты которого реально в нём хранятся, а список из базовых интерфейсов. И из-за type-erasure приходится вручную циклом бежать по списку, тупо приводя каждый элемент к нужному типу и добавляя в целевой контейнер. Необходимость постоянно делать такое тупое и бесполезное действие меня просто убивает.
вроде полноценной рефлексии


Что, простите? Это куда же она делась-то?
А что, type erasure уже заменили человеческой реализацией?

Видите ли, если вы с точки зрения скажем .Net смотрите, то да, где-то вы правы. Если с точки зрения других языков, где рефлексии вообще нет — то претензия непонятна. Более полноценная? А где вы ее видели?


И потом — это претензия слегка не по адресу. Она к erasure, а не к рефлексии. Глупо требовать давать доступ к тому, чего нет.


И еще — а можно спросить, зачем это вам? И почему вам не хватает скажем вот этого: https://github.com/google/guava/wiki/ReflectionExplained?

Видите ли, если вы с точки зрения скажем .Net смотрите, то да, где-то вы правы. Если с точки зрения других языков, где рефлексии вообще нет — то претензия непонятна. Более полноценная? А где вы ее видели?

Вы же сами сказали — в .Net-е. Да, мне с этой ТЗ странно смотреть на то, что считается рефлексией в джаве. Да, лучше, чем вообще без нее, но это и без моего высказывания очевидно.

И потом — это претензия слегка не по адресу. Она к erasure, а не к рефлексии. Глупо требовать давать доступ к тому, чего нет.

Ну так, собственно тезис можно свести к «без real-time дженериков полноценной рефлексии не получится». Хотя бы потому, что List&ltint> и List&ltstring> это разные типы.

И еще — а можно спросить, зачем это вам? И почему вам не хватает скажем вот этого: https://github.com/google/guava/wiki/ReflectionExplained?

«А почему ви собственно спrашиваете?». Так диалог строить нехорошо :)
Тут налицо парадокс блаба. Зачем — ну тут много вещей, зачем. Например я использовал рефлексию для динамическоо построения наследника IComparer&ltT>, чтобы вручную постоянно не писать. Когда нужно сравнить 4-5 полей приходится писать кучу бойлерплейт-кода для этого. А так — просто перечислил поля для сравнения, вызвал метод GetComparer(), он динамически чик-чик, все типы проинспектировал, проверил что у них есть нужные методы (всё в рантайме, естественно), после этого сгенерировал код нужного класса, проистанцировал его и вернул в качестве результата. Т.к. класс после всего этого дела кэшируется то не считая первого вызова разницы в скорости никакой нет, а вот удобство использования повышается на порядок.

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

То, что такого нет в Java — это просто позор. При наличии интерпретирующей JVM сам бог велел предусмотреть хоть что-то для генерации байт-кода в рантайме.

Хоть что-то? Да их навалом, этих инструментов. На любой вкус, вы о чем? На этом построены кучка ORM, и еще кучка JavaEE.

Ну, тогда предъява снимается. Я просто был не в курсе…
Не, ну я же вполне конкретно спросил — почему вам не хватает TypeToken? У меня это основной язык, и я в редчайших случаях сталкиваюсь с тем, что рефлексии мне почему-то не хватило.
для динамическоо построения наследника IComparer,
Ну это да, имеете право, хороший пример. Просто я обычно такие вещи пытаюсь решить на этапе компиляции, именно там где дженерики имеются в наличии (а еще есть аннотации).
Я не использовал TypeToken и не могу сказать, что меня в нем не устраивает :)

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

Я был бы рад, если бы подобные вещи можно было бы решить на этапе компиляции (я несколько завидую тем же constexpr из плюсов, в шарпах все рантаймово делается, даже если по идее компилятор может все это сам провернуть), но я лично не представляю, как именно. В данном случае пользователь может просто взять мою dll и использовать, для него лично ничего не поменяется — не надо использовать сторонние либы, (создавать токен на свои типы и передавать), не надо на этапе компиляции ничем заниматься — он может вообще, получить описание типа по сети (WCF), сгенерировать новый тип в рантайме, затем создать коллекцию этих типов и типобезопасно туда их складывать. И если внезапно придет объект другого типа на тот же эндпойнт, при попытке запихнуть его в коллекцию возникнет typemismatch. Это очень очень полезная фишка.

У меня это основной язык, и я в редчайших случаях сталкиваюсь с тем, что рефлексии мне почему-то не хватило.
В этом и суть :) Вы не сталкивались, потому что у вас это основной язык, мне даже ничего добавлять не надо — это типичная зона комфорта. Мое личное мнение, что это плохо, т.к. развитие останавливается — экстенсивно оно идет, новые фреймворки/классы и т.п., но интенсив пропадает. В этом весь парадокс блаба:
Программисты старше определенного возраста редко меняют язык по своей воле. Они будут считать достаточно хорошим тот язык, к которому привыкли.

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

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

Когда наш гипотетический Блаб-программист смотрит вниз на континуум мощности языков, он знает, что смотрит вниз. Менее мощные, чем Блаб, языки явно менее мощны, так как в них нет некой особенности, к которой привык программист. Но когда он смотрит в другом направлении, вверх, он не осознает, что смотрит вверх. То, что он видит, — это просто «странные» языки. Возможно, он считает их одинаковыми с Блабом по мощности, но со всяческими сложными штучками. Блаба для нашего программиста вполне достаточно, так как он думает на Блабе.

Когда мы поменяем точку обзора программиста, используя любой язык программирования выше по континууму мощности, мы обнаружим, что теперь программист смотрит на Блаб сверху вниз. «Как же можно что-то сделать, используя Блаб? В нем отсутствует даже конструкция Y!»

Используя метод индукции, приходишь к выводу, что только те программисты, которые понимают самый мощный язык, в состоянии осознать полную картину разницы в мощности между различными языками (видимо, именно это имел ввиду Эрик Реймонд, когда говорил о том, что Lisp сделает вас лучше как программиста). Следуя парадоксу Блаба, нельзя доверять мнению других: другие программисты довольны тем языком, который используют, потому что этот язык определяет способ их программистского мышления.

Ну вы же его (TypeToken) только что просили? :)


Называется, угадайте с трех раз, для чего вот это нужно:


TypeToken<List> stringListTok = new TypeToken<List>() {};

Что до генерации на этапе компиляции, то можно просто погуглить проект lombok, и поглядеть на живых примерах. Это конечно не сам компилятор генерирует, а annotation processors, но в данном случае это пофиг.


Что до остального, то я сказал основной язык, а не единственный ))) Мне например вполне комфортно на лиспе, без всяких преувеличений. И на Python тоже. И на многих других.

Да, вроде бы TypeToken то, что нужно. Правда чуть беднее и синтаксис убивает, но зато работает.
TypeToken<List> stringListTok = new TypeToken<List>() {};

даже не знаю, что бы это могло быть. Если судить по примеру, тут должно быть TypeToken&ltList&lt?>>.

Лисп кстати тоже бывает разный. Common например так себе, а вот диалекты вроде схемы уже съедобное. Хотя в любом случае сознание расширяет неплохо и классика :)
Утверждение, что «Знаменитая операционная система OS/400 для IBM AS/400 была реализована на Modula-2» не совсем правда.
Вот что по этому поводу пишет Франк Солтис, создатель AS/400:

"… Язык программирования VLIC, называвшийся PL/MP и использовавшийся со времен разработки оригинальной System/38, был основан на языке PL/I. MP в его названии расшифровывается как Machine Product — имя, которое часто использовалось для обозначения аппаратных средств и обоих слоев микрокода. Компилятор PL/MP, как и ассемблер IMPI, генерировал двоичные машинные команды IMPI.
… В течение ряда лет мы пытались использовать другие языки при разработке компонентов VLIC. Например, один из наших новейших трансляторов был написан на Modula-2, применялся также язык С. Однако, мы чувствовали, что ни один из них не подходит для проекта, основанного на объектно-ориентированной технологии. Выбор напрашивался сам собой — язык C++. Нам нужно было разрабатывать код ОС очень низкого уровня. Иногда, для достижения оптимальной производительности приходилось прибегать к ассемблеру, и С+ + легче позволял это. Ведь, фактически, язык С++ и есть современный вариант ассемблера…
Технология ООП не подвела: производительность программистов при разработке SLIC повысилась почти в четыре раза по сравнению с традиционной методикой. В период с июля 1992 года, было создано более миллиона строк кода на С+ + и более 7 000 классов.… "
Ф. Солтис, «Основы AS/400».
О, чувствуется стиль оберонкорщиков (oberoncore.ru)! «Вирт был в основе всех современных языков и технологий. Неблагодарные плагиаторы его даже вскользь не упоминают!» Херня всё это. Вирт остался на задворках технического прогресса, благодаря своему узкому мышлению и тяге к примитивизму. До сих пор его лучшие достижения — это Паскаль и книга «Алгоритмы + структуры данных». По сути, с 1970 года он ничего более существенного не добился. Ему можно было на пенсию уходить ещё 40 лет назад.
Ну Ваш то стиль ничем не лучше, если не хуже. Даже если Вам Оберон не нравится, то Модула — однозначно «более лучшее» достижение, чем Паскаль. А это уже конец 70-х. Модульность в большинстве императивных языков есть пошла именно от Модулы, что таки очень даже существенно. А книги… Ну мне вот АиСД вообще не по душе, но вообще Вирт — это в первую очередь разработчик языка Оберон, одноимённого компилятора и ОС, а уже только потом я бы стал обсуждать его книги. Не очень люблю аргумент «сперва добейся», но, ей богу, Вы много знаете людей, которые спроектировали ЯП, реализовали для него компилятор и написали с его использованием ОС? Вот с конца 70-х Вирт этим и занимался. Как-как Вы там сказали: «ничего существенного не добился»?! Ну-ну.
Григорий, большое спасибо за отличную статью!
Sign up to leave a comment.

Articles