• Что не так с современным преподаванием информатики
    –1
    Да, было бы неплохо учебники переписать с Паскаля на Аду.

    Паскаль
    const n = 100;
    var a: array[0..n - 1] of integer;
    for i := 0 to n - 1 do
      a[i] := 0;

    Пайтон
    n = 100
    a = [0] * n

    Ада
    n : constant := 100;
    a : array (0 .. n - 1) of Integer := (others => 0);


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

    стыдно давать в руки ученикам


    А как на счёт программ, которые стыдно запускать? Вот эти приложения-браузеры, приложения-сценарии? Кто на Perl писал в 2005м, того и разработчиком-то не называли. Так, помощник сисадмина. Сисадмин в основном своё не писал, но если надо, не только чужой патч накатит, но и свой патч сделает, и пересоберёт, а кто не способен даже на это, кто только по скриптам может — вот он помощник.

    Рыночек порешал, что надо строить дома из целебного асбеста и делать еду из канцерогенных нефтепродуктов (aka «пальмовое» масло). Значит ли это, что надо учить этой «настоящей жизни» строительных и пищевых технологов?

    Я за то, чтоб там, докуда не добрался рыночек, в образовании, готовить армию спасения от той пропасти, в которую этот рыночек падает.
  • Языки программирования с однобуквенным названием
    0
    Когда портировали Аду с JVM на дотнет, ей дали название A#.

    В средстве отладки Sun DTrace язык когда-то назывался просто D.
  • Будущее веба: станет ли рендеринг в <canvas> заменой DOM?
    0
    Кто «мы» исключения бросает?

    Да обычные Delphi, Ada, Модулы, Обероны, и на чём ещё люди пишут.

    Всякие языки со сборкой мусора относятся к нативу или нет? Там и упомянутый вами mmap

    Сборка мусора ортогональна загрузке по mmap. Например, AOT ngen.exe делает бинарники, подходящие к проецированию в память, уже с инструкциями в машинных кодах. У Оберонов практически все реализации как раз создают машинный код. Самая известная, Compoment Pascal, скорее, исключение, чем правило. Да и к ней вроде бы приделали уже возможность подключать скомпилированные в машинные коды расширения.

    а в обычном C или Java, без использования ассемблера/интринсиков

    __builtin_sadd_overflow и другие интринсики расползаются по компиляторам, а на случай трудных платформ можно скопипастить реализацию из спойлера
  • Vivaldi 4.0 — Первое приближение
    –1
    Что за бред. А Comodo и WoSign зонды, стало быть, не вставляют, нет? Чисто случайно дырки оставили
  • Vivaldi 4.0 — Первое приближение
    –1
    Да и без корпоративного сектора можно зайти и купить: cainet.ru/content/ssl

    Всем браузерам нужны киллер-фичи для завлечения. Можно удачно обыгрывать то обстоятельство, что основные как-то долго допетривают до ГОСТ TLS. С 2012го года 9 лет прошло, и всё не сделают
  • Будущее веба: станет ли рендеринг в <canvas> заменой DOM?
    +5
    «Непрозрачные» веб-приложения, которые беспокоят пуристов, это — мелочь в сравнении с тем, что обещает нам WebAssembly. Речь идёт о выводе производительности веб-приложений, работающих в браузерной «песочнице», практически на уровень нативных приложений.


    WebAssembly для этого много ещё не умеет.

    Чтобы запустить истинный параллельный поток, нужно создать Wasm.Memory с параметром shared True, но сейчас требуется обязательно указание максимального размера памяти, то есть, заранее обозначен потолок роста.

    Настоящий процессор, когда складывает 2 миллиарда с 2 миллиардами, отмечает в EFLAGS переполнение, и мы сразу идём бросать исключение. В WebAssembly EFLAGS теряется. А как жить-то, как жить без EFLAGS? Приходится изгаляться так:

    AdaMagic/wasm/rtl.wasm/standard.h
    /****************/
    
    /* Unary negation and absolute value overflow only for the most-negative
    number. */
    
    #define s_32_neg_v(result, x) /* result = -x; */ \
      if (((result) = -(x)) == S_FIRST) rts_overflow()
    
    #define s_32_abs_v(result, x) /* result = abs(x); */ \
      do { \
        const int32 _xcopy = (x); \
        if (_xcopy == S_FIRST) rts_overflow(); \
        (result) = abs(_xcopy); \
      } while (0)
    
    /****************/
    
    /* Signed addition and subtraction are implemented in terms of the
    unsigned operations.  Overflow is determined by comparing
    the sign bits of the operands and result, which is done
    using bit-wise xor.  We first calculate the result (lower 32 bits)
    and then check whether it overflowed. */
    
    /* Addition overflows iff x and y have the same sign,
    and the result has a different sign (from x and y). */
    
    #define s_32_plus_v(result, x, y) /* result = x + y; */ \
      do { \
        const int32 _xcopy = (x); \
        const int32 _ycopy = (y); \
        const int32 _same_sign = ~_xcopy ^ _ycopy; \
          /* The sign bit of _same_sign is set iff x and y have \
             the same sign. */ \
        (result) = _xcopy + _ycopy; \
        if ((_same_sign & ((result) ^ _xcopy)) < 0) rts_overflow(); \
        /* The sign bit of "((result) ^ _xcopy)" is set iff result and x have \
           different signs.  Overflow if that and _same_sign both have \
           sign bits set. */ \
      } while (0)
    
    /****************/
    
    /* Subtraction overflows iff x and y have different signs,
    and the result and x have different signs. */
    
    #define s_32_minus_v(result, x, y) /* result = x - y; */ \
      do { \
        const int32 _xcopy = (x); \
        const int32 _ycopy = (y); \
        const int32 _diff_sign = _xcopy ^ _ycopy; \
          /* The sign bit of _diff_sign is set iff x and y have \
             different signs. */ \
        (result) = _xcopy - _ycopy; \
        if ((_diff_sign & ((result) ^ _xcopy)) < 0) rts_overflow(); \
        /* The sign bit of "((result) ^ _xcopy)" is set iff result and x have \
           different signs.  Overflow if that and _same_sign both have \
           sign bits set. */ \
      } while (0)
    
    /****************/
    
    /* For multiplication, we treat the various cases for y separately.  We
    check for overflow by checking whether x is in the right range.  If one
    operand is known at compile time, then the compiler should make that one
    y, so the C compiler can hope to eliminate all but one range check, and
    perform the divides at compile time.  We need to take care to avoid
    dividing by zero, and to avoid dividing the most-negative number by
    minus one. */
    
    #define s_32_times_v(result, x, y) /* result = x * y; */ \
      do { \
        const int32 _xcopy = (x); \
        const int32 _ycopy = (y); \
     \
        if (_ycopy > 0) { \
           rts_range_check(_xcopy, S_FIRST/_ycopy, S_LAST/_ycopy); \
        } else if (_ycopy < -1) { \
           rts_range_check(_xcopy, S_LAST/_ycopy, S_FIRST/_ycopy); \
        } else if (_ycopy != 0) { \
           /* The "-1" special case */ \
           if (_xcopy == S_FIRST) rts_overflow(); \
        } \
        (result) = _xcopy * _ycopy; \
      } while (0)
    
    /****************/
    
    /* Division can only overflow when dividing the most negative number by
       -1. */
    
    #define s_32_div_v(result, x, y) /* result = x / y; */ \
      do { \
        int32 _xcopy = (x); \
        int32 _ycopy = (y); \
        if (_xcopy == S_FIRST && _ycopy == -1) rts_overflow(); \
        (result) = _xcopy/_ycopy; \
      } while (0)
    
    /****************/
    



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

    Ах, да, если обнаружена лажа, нужно бросить исключение. Но в Wasm нет исключений. Родных. Можно зайти в JS, чтоб JS бросил исключение, тогда оно сдерёт весь стек Wasm и вылетит с другой стороны в вызывающий JS. И не сработают финализаторы! Ну такое.

    Если мы хотим писать как на настоящем процессоре, нас такая лажа не устроит, мы хотим ещё и ловить эти исключения, и обрабатывать. И всякие ошибки роста памяти, обычно сдирающие стек Wasm, хотим ловить. И тут начинаются танцы на батуте (Trampolined Style) по типу Continuation Passing C. Так вот ты какой, «практически натив»!

    Что ещё может натив? Может библиотеку загрузить динамически и в синхронном стиле. Существующие трансляторы Wasm это поддерживают довольно плохо. Ну вот что нужно сделать в обычном Wasm, чтоб произвести такую загрузку? Библиотека динамически загружаемая предоставляет какие-то, допустим, COM-подобные объекты. Если там не COM, а glib, погоды не меняет. Для косвенных вызовов в Wasm используются массивы функций с идентичной сигнатурой. Для каждой сигнатуры отдельный массив. Нужно массивы дополнить тем, что предоставляет библиотека. Вызывающих нужно связать с дополненными версиями всех массивов, чтоб они могли косвенно вызывать методы объектов, созданных новой библиотекой. Чтоб сама библиотека могла косвенно вызывать свои методы, ей нужно произвести релокацию: рассказать библиотеке, по каким смещениям в дополненных массивах начинаются добавленные ею методы, а потом в блобе сегмента данных пропатчить таблицы виртуальных методов.

    Под Windows-то уже ASLR отработал, и несмотря на его работу, и достаточно рандомно получилось, и релоцированный слепок закешировался на диске. Ах да, диск. А зачем на диск? А мы же прямо с диска можем mmap сделать! У нас в нативе есть вирутальная память. А на WebAssembly фиг. У нас каждый байт Wasm.Memory стоит как настоящий. В нативе может применяться оптимистичное выделение памяти, почти моментальное, а потом по требованию выделяются настоящие страницы. В нативе библиотеки нередко прямо с диска шлёпаются релоцированные. Под стек место выделяется оптимистично. Почему стеком Wasm крайне сложно пользоваться, написано выше, но если им не пользоваться, то пользуемся сегментированным стеком в Wasm.Memory, где за каждый байт надо честно платить.

    Это всё очень далеко от натива.

    Многие компиляторы, которые я видел, поэтому генерят отнюдь не набор библиотек. Отнюдь! Вот берём мы, допустим, сайт типа ВК и видим, что он сделан на JS, и что JS там грузятся по требованию: для музыки, для альбомов, для вики грузится только когда понадобилось. Библиотеки кешируются и обновляются независимо. Нам втирают, что Wasm вроде как то же самое, но быстрее. Но когда мы берём многие реальные Wasm-трансляторы, они ведут себя совсем не так. Мы хотели такие же отдельные кешируемые независимо обновляемые библиотеки, а получили большой целиком обновляемый блоб, и из-за того, что обновляется он целиком, он ещё и обновляется часто. Минус кеш.
  • Vivaldi 4.0 — Первое приближение
    –1
    ГОСТ TLS поддерживается?
  • Прошло тридцать лет, а QBasic по-прежнему лучший
    0
    но как общий принцип кто не научился жить без трассирующей сборки мусора, тот идёт нафиг из технологического стека


    А какова мотивация у такого принципа?


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

    Трассирующая сборка — это вечный двигатель наоборот. Ему всегда есть, чем заняться, и он этим занимается. Мне бы, пожалуйста, вечный двигатель нормальный, чтоб вырабатывал, а не потреблял. А если такого нет, то пусть не будет никакого. Настрадался.

    Да и foreign export в хаскеле есть и вполне успешно работает.


    Когда я думаю про интероп, у меня в голове образы WinRT, COM, OLE Automation, VirtualBox XPCOM, libobjc и отчасти SOM. С уже формально решёнными вопросами владения, освобождения ресурсов, уведомления об ошибках и наследования.

    А FFI — это только первая ступень лестницы, по ней ещё шагать и шагать к высокоуровневому взаимодействию. Вот, допустим, на макосе есть Oxygene/Toffee, и взять бы написать на гипотетическом избавленном от трассирующей сборки мусора Хаскелле монаду Дейкстры, заполучить её в Oxygene как значение-последовательность (sequence of), и по этому значению походить средствами LINQ. Или в языке Ада, если генератором привязок спроецировать на тип с аспектом Default_Iterator, тоже comprehension можно устроить.
  • Прошло тридцать лет, а QBasic по-прежнему лучший
    0
    В Delphi 10.3 уже добавили, правда, ключевое слово почему-то взяли не declare
  • Прошло тридцать лет, а QBasic по-прежнему лучший
    0
    Моя подпись в письмах гласит: If you want to get to the top, you have to start at the bottom

    Переходил с QBasic на Turbo Pascal, и там дорвался до ассемблерных вставок. Помню, изучал: вот есть mov для чисел, а есть stos и lods, s = «строковые» инструкции. Для чисел и для строк, видимо. Какой же был шок узнать, что процессору как муравью нужно всю строку облазить, чтоб что-то с ней сделать, и эти «строковые» инструкции не для всей строки, а для шажочка по ней.

    Вот эти современности рискуют закамуфлировать ещё больше деталей
  • Прошло тридцать лет, а QBasic по-прежнему лучший
    0
    Я бы подсунул SDLAda
  • Прошло тридцать лет, а QBasic по-прежнему лучший
    0
    Осваивать его не придётся, он часть учебной программы JetBrains, но как общий принцип кто не научился жить без трассирующей сборки мусора, тот идёт нафиг из технологического стека. Как Haskell научится, так библиотеки на нём станет приемлемо использовать из других языков.
  • Прошло тридцать лет, а QBasic по-прежнему лучший
    0
    Но ведь ось Y и вправду много, где направлена вниз, а не вверх, а популярный порядок индексов (строка, столбец) это (-Y, X)
  • OLE, COM, COM+
    +1
    Тут в соседней ветке пишут:

    Я бы добавил, что утечка утечке рознь.

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

    Куда более распространенная в си ситуация связана с «беспорядочной половой жизнью» указателей и спонтанные, неформализованные и нигде не задокументированные контракты владения вида:

    • память освобождает вызывающий
    • память освобождает вызываемый
    • указатель нужно скопировать себе, передавать его как есть (работает как дескриптор)
    • содержимое указателя нужно скопировать себе, передавать копию по значению/указателю
    • память статическая, не копировать, ссылаться напрямую


    и т.д.

    Притом что во всех случаях интерфейс, утрируя, может выглядеть как void foo(void* ptr).

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


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


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

    Может быть, дело не в COM, а в ATL? Я иногда слышу жалобы на COM, и часто при этом всплывает какой-то ATL, наверное, одно с другим как-то коррелирует.

    За что-либо путное надо платить деньги, а бесплатное, как правило, не стоит выеденного яйца.


    Ну и что есть путного за деньги?
  • OLE, COM, COM+
    0
    чужими серверами воспользоваться маловероятно, а свои делать трудоемко


    И что там трудоёмкого? Берём и клепаем интерфейс за интерфейсом
  • Прошло тридцать лет, а QBasic по-прежнему лучший
    0
    Без трассирующей сборки мусора реализацию сделали уже?
  • OLE, COM, COM+
    +1
    Я не знаю ни одного реально практического примера, где была бы полезной технология COM

    У вас часть кода на Аде, часть кода ещё на чём-то. Чем их сопрягать собираетесь?

    Разновидности COM встречаются и под Mac OS. Ну не реестр там, по-другому было. Для Linux я видел и в p7zip автономный COM, и VirtualBox XPCOM с возможностью RPC.
  • OLE, COM, COM+
    0
    можно сразу разобраться в алгоритме приложения

    Да неужели? Все вызовы простого COM — виртуальные, по смещению в таблице виртуальных методов. Таблиц виртуальных методов COM плодит немеряно, плюс, система ещё прокси генерит даже внутри процесса, для разных apartments. Поди разберись, чей седьмой метод хотят вызвать.

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


    Да прям там длительный период. COM 1995, DCOM 1996, вот и все основные события. 2 года, а потом внедрение. Это же не Swift, сменивший 5 ABI. COM+ нигде не видел в действии. Из интересного только OLE Automation и .NET интероп было, и потом надолго стабильность. Подвижки случились только в WinRT.

    Учитывая, насколько плохо программисты осведомлены хотя бы о том, что есть, к каким-то подвижкам я бы и не призывал. Подвижки нужны в том, чтобы COM и VirtualBox XPCOM (под Linux) библиотеки делали почаще.
  • Как я влюбился в Rust и чего мне это стоило
    0
    За ковидный карантин я успел перепробовать множество разных языков, остановившись в итоге на Расте.


    Была ли в этом множестве Ада?
  • “Прыгни со скалы!”: взлеты и падения легендарного геймдизайнера Уоррена Спектора
    +1
    У ремейка первого СС вышла Демо, а если предзаказать выходящую этим летом полную версию, то
    Customers who pre-order this version of System Shock will receive System Shock 2: Enhanced Edition for free when SS2:EE is released.


    Для разработки BioShock 4 нанимали специалистов по открытому миру.

    Интересующиеся этой темой собираются на канале GothenX
  • Microsoft Windows 10X: революции не случилось
    0
    Надеюсь, вы знаете, что можно вернуть старый Пуск за 133 рубля
  • Интернет-магазин «на минималках»
    0
    Думаю, многим пригодится список агентов, которые позволяют вообще НЕ покупать собственную кассу, а пробивать через агентскую:

    pokupo.ru/online-kassa
    arsenalpay.ru/cashbox.html
    robokassa.com/robokassa/robocheck

    Никогда не видел столько агентов в одном месте. Столько перерыл, чтоб найти.

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

    А тем, кто всё же собрался покупать кассу, можно поискать скидки на ОФД тут, тут и тут
  • «Почему Kotlin хуже, чем Java?»
    –3
    Что в 90х джава тормозила, что сейчас. Божатся, клянутся, что вот теперь-то мы точно сборщик мусора не тормозящий сделали. А воз и ныне там. Тормозит как чёрт знает что. Диспетчер задач откроешь, и сразу понятно, где у нас трассирующая сборка мусора.

    image

    В Delphi IDE, угорев по дотнету, добавили дотнетовские компоненты, и оно затормозило. Хорошо, что нашлись умельцы, сделали Delphi Lite, и оно не тормозит, потому что всё, что со сборкой мусора, вырезано. Я сделал вывод: хочешь, чтоб не тормозило — делай без сборки мусора. Только так.

    20 лет кормят завтраками, надоело до чёртиков. Так и хочется сказать: ребятки, давайте вы там где-нибудь отдельно в своей песочнице самоубеждайтесь в быстроте трассирующего сборщика мусора, а мне как пользователю дайте старый добрый счётчик ссылок, раз уж не смогли придумать ничего лучше, чем написать программу на Джаве.

    Кстати, для Java есть Javolution. Он не умеет инлайнить в JIT и прочее, но он быстр. Уж не связано ли это с тем, что там счётчик ссылок вместо трассировок по свопу?

    Но Javolution не поставить так просто вместо java.exe. А было бы здорово, чтоб прямо java.exe ключики в командной строке прописать, и трассирующий сборщик мусора пошёл нафиг.
  • «Почему Kotlin хуже, чем Java?»
    0
  • «Почему Kotlin хуже, чем Java?»
    0
    Неправда. В Java можно использовать и счётчик ссылок тоже. Но статьи, в которых это описывается, сравнивается, относятся к таким древним версиям JVM, что их и не установить-то уже, наверное, 16-битные ДОС реализации, на 64-битную Windows. И не запустить на Apple M1 версию для Motorola 68k Mac OS Classic. А я хочу счётчик ссылок для современной Java.
  • «Почему Kotlin хуже, чем Java?»
  • «Почему Kotlin хуже, чем Java?»
    0
    У .NET синтаксис может быть такой же, как у JVM, если на Oxygene писать
  • «Почему Kotlin хуже, чем Java?»
    0
    Ох уж это паскалефобство
  • «Почему Kotlin хуже, чем Java?»
    0
    Не могу понять, какой из этих GC реализует счётчик ссылок
  • «Почему Kotlin хуже, чем Java?»
    0
    У Mozilla был (есть?) протокол сборки циклов в дополнение к ARC
  • «Почему Kotlin хуже, чем Java?»
    0
    «нелигитимный режим» — это ГДЕ?!

    А как же ВШи?

    Как раз напротив одного из офисов JetBrains расположены, и рядом композиция, изображающая пословицу «хуже дурака только дурак с инициативой»

    image

    Рука поднята, головы нет
  • «Почему Kotlin хуже, чем Java?»
    0
    Посыл был в том, что много областей, где заставляют писать на Java
  • Три письма об увольнении: почему люди уходят с любимой работы
    0
    Удивили переживания по работе в Гугл. В Гугле не пишут на Аде. Чего там переживать-то
  • Как мы верифицированный полетный контроллер для квадрокоптера написали. На Ada
    0
    Вот бы ещё Пользователям объяснить, что адаисты им Служить хотят, чтоб со стороны Пользователей осознанное финансовое давление шло.
  • Как мы верифицированный полетный контроллер для квадрокоптера написали. На Ada
    0
    на шарпе писать хорошо, очень хорошо

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

    И Ада ещё больше, чем Delphi, про Служение Пользователю.

    достаточный объем платформы для Ады под ПиСи


    Не понял. Чего не хватает. Вот есть задачи, которые надо решать. На шарпе будет дико тормозить, особенно, на офисных компах старинных, закупленных сотнями, в которые ещё принудительно антивирус воткнут. На плюсах будет дико глючить. На Аде и Делфи будет работать хорошо.
  • Как мы верифицированный полетный контроллер для квадрокоптера написали. На Ada
    0
    ЧСХ писать на Аде под писюк наверное станет только псих (когда есть элитный шарп)


    Помню, Delphi сначала начали делать под .NET. Настоящее унижение, что моё любимое число 8, в долгожданной версии Delphi 8 стало проклятьем, эта Delphi ничего другого не умела. Потом какая-то муха покусала многих разработчиков, они к мёду нативных программ начали подмешивать дёготь дотнета. И МатКАД, и АвтоКАД, и не обошла беда стороной RAD Studio. Подсказки кода почему-то надо было сделать в дотнетовской части. К счастью, нашлись народные умельцы. В Delphi 10 Lite вырезано всё, что связано с дотнетом.

    Вот так нативной частью программы, без трассирующей сборки мусора, народ с удовольствием пользуется, а дотнетовскую дрянь отпилит первый же риппер. А какую часть хотите писать вы?
  • Как мы верифицированный полетный контроллер для квадрокоптера написали. На Ada
    0
    Применительно к таблице из [EFF], раз уж мы доказали отсутствие исключений, то можно исключать проверки из кода, и тогда скорость повыше. По такому пути шли в проекте CubeSat, попутно решая другую проблему. Родного транслятора Ады для National Instruments нет, взяли AdaMagic.

    Но AdaMagic из коробки для Linux и Windows, а на других надо что-то думать с механизмом исключений, портировать рантайм. Нет исключений — нет рантайма — нет проблем.
  • Как мы верифицированный полетный контроллер для квадрокоптера написали. На Ada
    +3
    Из коробки не может, как и чистая Ада, без SPARK. Но вот тут какие-то инструменты вижу:
    alastairreid.github.io/rust-verification-tools
  • Упавшая звезда. Как выглядела самая первая ОС с графическим оконным интерфейсом
    0
    Язык Mesa по-своему интересен. После того, как Хоар изобрёл мониторы, начались реальные попытки встраивания мониторов в язык программирования. Например, в книге «Операционные системы» Танненбаума используется несуществующий Pidgin Pascal со встроенными в язык мониторами. А из реальных языков это Active Oberon и Ada. И в Pidgin Pascal, и в AO мониторы явные. Отличие от Ады можно увидеть в том, что, например, в AO можно, будучи в мьютексе в глубине защищённой монитором процедуры, атомарно выйти и ждать условную переменную. А в языке Ада все такие ожидания навешиваются только на вход в entry, но никак не в середину, а если надо из середины отпустить мьютекс и чего-то ждать, то для этого можно сделать requeue в другой entry.

    Mesa — ещё один паскалеподобный язык программирования, в котором мониторы были встроенными. Или, наверное, лучше сказать, алголоподобный. Потому что я его смотрел, и после адско-обероновского чистописания Mesa довольно загрязнена спецсимволами. Когда Вирт делал Modula-2, он вдохновлялся Mesa, но, как можно убедиться, виртовские языки сильно почище. Я изучал материалы по Мезе из исторического интереса. Интересно поузнавать немного про отбракованные ветви. Например, сейчас почти нигде не осталось векторных обработчиков исключений. В Common Lisp Condition System тоже была возможность обрабатывать исключительную ситуацию с восстановлением. Казалось бы, почему бы и нет. Оказывается, эта особенность языка причудливо сталкивается с мониторами. Оказывается, векторный обработчик исключения запросто может вешать программу, не в силах войти в мьютекс или дождаться условной переменной. В Мезе этому пытались противостоять, на языковом уровне делая у защищённых процедур что-то типа предбанников, в которых мьютекс не взят, и доступа ко внутренним данным нет. Сейчас в языках программирования как бы надпись «Здесь живут драконы», и только через язык Меза можно на этих драконов посмотреть. Убедиться.

    Другой интересной особенностью Мезы был упор на обильную многозадачность. То есть, Меза тогда — как Go сейчас.
  • Зеркала в Duke Nukem 3D
    0
    А в Shadow Warrior было управление техникой, а не только в охранные камеры смотреть, как в Дюке.