Когда я впервые вернулся к старому коду на Pascal, меня поразило, насколько спокойным и уверенным был этот язык. Без магии, без догадок, без самоуверенности динамической типизации. Pascal не прощал халтуру — и именно поэтому программы на нём жили десятилетиями. Эта статья — не ностальгия, а попытка разобраться, почему мы потеряли культуру типобезопасности и почему сейчас снова к ней возвращаемся.

Когда компилятор был союзником

Если вы писали на Pascal, вы наверняка помните его как строгого, но справедливого учителя. Он не позволял вам совершить «глупую» ошибку, даже если вы очень этого хотели. Тогда это раздражало. Сейчас — вызывает уважение.

Pascal заставлял думать не о том, как заставить программу работать, а о том, почему она должна работать именно так. Каждая переменная, каждый тип — это обещание, данное компилятору. И если вы нарушали договор, он вас останавливал.

Я как-то открывал старый проект, написанный ещё в конце 90-х. Free Pascal спокойно его собрал. Ни одной ошибки, ни одного ворнинга. И этот момент был почти шокирующим. В мире, где проект на Node.js ломается после обновления одного пакета, Pascal казался островом предсказуемости.

Типобезопасность как часть инженерной этики

Многие разработчики воспринимают типобезопасность как формальность — мол, это просто синтаксические ограничения. Но на самом деле типы — это способ мышления. Это инженерная этика в действии.

var
  a: string;
  b: integer;
begin
  a := '42';
  b := 10;
  writeln(a + b); // Ошибка компиляции
end.

Pascal не позволял «проскочить» такие вещи. Он не давал шанса притвориться, что строка и число могут быть одним и тем же. Он требовал осознанности.

В современных языках вроде Python или JavaScript мы привыкли к свободе:

a = "42"
b = 10
print(a + b)  # Ошибка в рантайме

Проблема не в том, что код упадёт, а в том, что мы это узнаем слишком поздно. Pascal выявлял проблему ещё до запуска — как строгий ревьюер, который не пропустит «авось пронесёт».

Свобода без ответственности

Когда я перешёл на динамические языки, всё казалось прекрасным: писать можно быстро, без лишнего шаблонного кода, без ограничений. Но через пару лет выяснилось, что ошибки типов — это не просто мелочи, а источник хаоса.

Pascal был «медленным» только внешне. В реальности он экономил время, которое мы теперь тратим на тестирование, дебаг и CI/CD-фиксы.

В одном из моих экспериментов я переписал сервис авторизации с Python на Free Pascal. Код вырос с 600 строк до 950. Но из тестов ушло почти 40 проверок — просто потому, что они стали не нужны. Компилятор уже сделал свою работу.

Компилятор как ментор

Когда Pascal выдавал ошибку «Type mismatch», это звучало почти назидательно. Но если присмотреться, он ведь не ругал, а объяснял: “ты хочешь присвоить одно другому — но их смысл разный”.

type
  TPoint = record
    x, y: integer;
  end;

var
  p: TPoint;
  z: integer;
begin
  z := p; // Ошибка: несовместимость типов
end.

Современные языки, наоборот, часто позволяют ошибку сделать — а потом уже вылавливают последствия в рантайме. Pascal не ждал, пока вы ошибётесь. Он не доверял «авось», и это делало программы прочнее.

Каждая ошибка компиляции в Pascal — это предупреждение из будущего. “Если я позволю тебе это сейчас, завтра ты получишь сегфолт”.

Типы как живой дизайн

Pascal не нуждался в Swagger, JSON Schema или аннотациях. Его типы уже были документацией.

type
  TUser = record
    id: integer;
    name: string;
    age: byte;
  end;

Когда я открываю старый код на Pascal, мне не нужно лезть в комментарии. Всё видно сразу. Типы объясняют намерения автора.

В современных проектах мы снова изобретаем то же самое — только сложнее. TypeScript пытается навесить типы поверх JavaScript, Python получает типовые аннотации, Go изобрёл строгие интерфейсы, Rust буквально превратил типобезопасность в философию языка.

Но Pascal уже всё это сделал. Просто мы тогда не поняли, что теряем.

Исторический контекст: от Pascal к Rust

Pascal стал логическим продолжением идей Алгола и Wirth-овского стремления к ясности. Позже появился Modula-2, где типовая система стала модульной и предсказуемой. А потом случился C — гибкий, быстрый, но безжалостный к типам.

С тех пор история типобезопасности — это история маятника:

  • C дал скорость, но убил безопасность;

  • Java вернула строгие типы, но утопила их в шаблонах;

  • Python дал свободу, но вместе с ней — непредсказуемость;

  • Rust попытался собрать лучшее из обоих миров.

Если посмотреть на Rust, видно: он идейно ближе к Pascal, чем к C.
Rust говорит то же самое, что говорил компилятор Turbo Pascal в 90-е: “ты не можешь так писать, потому что это небезопасно”. Разница лишь в том, что теперь это снова считается достоинством.

Pascal и Rust: один и тот же принцип, только разная эпоха

Для примера возьмём простую задачу — поиск минимума в массиве.
Один и тот же алгоритм на Pascal и Rust показывает, насколько схожи философии этих языков — строгие типы, гарантии безопасности, отсутствие неявных преобразований.

Pascal:

program MinExample;
var
  i, min, n: integer;
  data: array[1..5] of integer = (4, 7, 1, 9, 3);
begin
  min := data[1];
  for i := 2 to 5 do
    if data[i] < min then
      min := data[i];
  writeln('Минимум: ', min);
end.

Rust:

fn main() {
    let data = [4, 7, 1, 9, 3];
    let mut min = data[0];
    for &x in &data[1..] {
        if x < min {
            min = x;
        }
    }
    println!("Минимум: {}", min);
}

В обоих случаях — ни одного неявного преобразования, ни одной возможности случайно записать не тот тип.
Оба языка следят за владением памятью (в Pascal — статически, в Rust — через систему ownership).
И оба заставляют программиста думать на этапе компиляции, а не отлавливать глюки на проде.

Разные эпохи — одинаковые принципы. Просто Rust снова делает популярным то, что Pascal когда-то считал нормой.

Возвращение уважения к типам

Pascal научил меня относиться к типам не как к ограничению.

Сегодня мы снова приходим к этому — через Rust, Swift, TypeScript. Мы возвращаем уважение к типам, потому что устали от хаоса. Ирония в том, что ответ на этот хаос был у нас с самого начала — в старом, строгом, занудном Pascal.

Комментарии (164)


  1. inv2004
    20.10.2025 11:15

    Можно найти кусочек паскаля в nim-lang


  1. wataru
    20.10.2025 11:15

    При чем тут именно паскаль, если все аргументы каксаются исключительно статической типизации. Можно было бы в статье заменить паскаль на С/C++/Java/C# и никакие аргументы бы не поменялись.


    1. ildarz
      20.10.2025 11:15

      Цитата:

      ни одного неявного преобразования, ни одной возможности случайно записать не тот тип

      C и производные, говорите?


      1. wataru
        20.10.2025 11:15

        А тут очередная ошибка автора статьи. Неявные преобразования есть и в паскале: https://wiki.freepascal.org/Typecast:

        implicit typecasting

        Да, С чуть повальяжнее тут, но не принципиально.


        1. HemulGM
          20.10.2025 11:15

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

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


          1. wataru
            20.10.2025 11:15

            Вдобавок ко всему, сложение двух строк, с числами внутри, никогда не даст в результате число, а не строку.

            Вы C с javascript не путаете? В си строки не преобразуются в числа. Там есть арифметика указателей, но складывать 2 строки так не получиться.


            1. HemulGM
              20.10.2025 11:15

              Я говорил немного в отрыве от Си. Я говорил в целом о неявном преобразовании


              1. wataru
                20.10.2025 11:15

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


                1. tyomitch
                  20.10.2025 11:15

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


                  1. wataru
                    20.10.2025 11:15

                    Автор выше путает "неявные" и "свободные".


            1. Hlad
              20.10.2025 11:15

              Насколько помню, в Си можно сделать Char++. В Паскале напрямую так сделать нельзя.


              1. wataru
                20.10.2025 11:15

                В паскале нет ++. Там есть inc. И оно отлично работает. Вот этот код выведет b:

                program Hello;
                var
                c: char;
                begin
                  c := 'a';
                  inc(c);
                  writeln (c);
                end.

                Вот складывать целые и char нельзя. И вообще сложение символов дает строку в паскале.

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


                1. vadimr
                  20.10.2025 11:15

                  Автор пишет, что его напрягает динамическая типизация, но в пример приводит выражение '42'+10, которое к динамической типизации не имеет никакого отношения (это пример нестрогой типизации, которая может сочетаться как с динамической, так и со статической).


                  1. wataru
                    20.10.2025 11:15

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


                    1. vadimr
                      20.10.2025 11:15

                      PL/I, Cobol. Наверное и RPG.


                      1. wataru
                        20.10.2025 11:15

                        Ладно, признаю свою неправоту конкретно в этом вопросе. Все еще считаю, что статья не о явном/неявном преобразовании, а о статических/динамических типах.


            1. sdramare
              20.10.2025 11:15

              В си нет строк, так что конечно нельзя складывать то, чего нет.


              1. wataru
                20.10.2025 11:15

                А что тогда "bla-bla-bla" и char *s;? Да, они странные, нуль-терменированные и по сути являются указателями. Но их везде называют c-style strings.


                1. sdramare
                  20.10.2025 11:15

                  Первое это массив символов, второе это указатель на символ. Тип "строка" в си не существует.


        1. ildarz
          20.10.2025 11:15

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

          int i=1;

          char a='A';

          i=a;

          воспроизведите на Паскале.


          1. CitizenOfDreams
            20.10.2025 11:15

            int i=1;

            char a='A';

            i=a;

            воспроизведите на Паскале.

            А в чем проблема? i=ord(a);

            И сразу видно намерение программиста: он хочет присвоить i значение ASCII-кода символа, хранящегося в a. Здесь, конечно, тоже есть неявное преобразование типов (longint в int), но по крайней мере и компилятору, и человеку понятно, что программист хотел сделать именно это, а не ошибся с типом или именем переменной.


            1. ildarz
              20.10.2025 11:15

              Именно эту разницу я и хотел показать примером - там, где C использует неявное преобразование, в Паскале нужно либо явное, либо вообще используются совершенно другие конструкции (ord ведь вообще не преобразование типов). Одинакового конечного результата можно добиться и там, и там. Но в Паскале это именно что явно выраженное намерение программиста, а в C то ли так и надо, то ли человек ошибся/опечатался. С одной стороны, где-то удобнее, с другой - более широкое поле для ошибок.


    1. ShaltaiBoltai
      20.10.2025 11:15

      Ну, помилуйте, батенька, не требуйте от малыша сразу слишком многого. Вот малыш вчера узнал про Pascal. Глядишь, завтра ему кто-нибудь расскажет про существование C. Он и так находится в культурном шоке: оказывается, кроме JavaScript в мире существуют и другие языки программирования! Дайте уму время переварить эту информацию, а там, глядишь, он дозреет и до получения новой информации.


    1. Warperus
      20.10.2025 11:15

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

      На C++ аналогично и расширенно перегрузками. И да, можно писать по-новому, но стрелять себе в ногу никто не мешает.

      Впрочем, в паскале через mem тоже никто не мешает в ногу стрелять. А через union и указатели в борланд-разновидностях можно переписывать память типов другими типами, и компилятор тоже не заругается.


  1. wataru
    20.10.2025 11:15

    Оба языка следят за владением памятью

    Только для локальных переменных. В паскале, точно так же как в C, можно выделять данные в куче и работать с указателями. Там точно так же можно 2 раза удалить что-то или работать с данными после удаления. Паскаль гарантирует не больше чем C.

    Rust к паскалю настолько же близок, как и к С++.

    Вот Java - да - со своим сборщиком мусара сам следит за памятью. Но в паскале сборщика мусора не было.


    1. tyomitch
      20.10.2025 11:15

      Иронично, что в свои следующие языки (Modula-2+/3 и Oberon-2) Вирт добавил сборку мусора, но за 30+ последовавших лет её не стали бэкпортить ни в одну реализацию Паскаля


    1. pae174
      20.10.2025 11:15

      Паскаль гарантирует не больше чем C.

      В отличии от С в Паскале нет неопределенного поведения.


      1. viordash
        20.10.2025 11:15

        В отличии от С в Паскале нет неопределенного поведения.

        Разве в паскале нельзя использовать неинициализированную переменную? Или нельзя прочитать\записать в освобожденую память?


        1. HemulGM
          20.10.2025 11:15

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


          1. viordash
            20.10.2025 11:15

            Хм, запрошенные мною две ситуации, это же классическое UB, https://en.cppreference.com/w/cpp/language/ub.html + https://en.cppreference.com/w/c/memory/free.html


            1. RichardMerlock
              20.10.2025 11:15

              На этапе компиляции у переменной появляется адрес в памяти, место резервируется, а без инициализации там просто будут какие-то левые данные. Тут вообще никакого УБ! Запись в освобожденную память тоже норм, т.к. физически она по освобожденным адресам осталась на месте - пиши/читай, пока ОС не видит криминала.


              1. viordash
                20.10.2025 11:15

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


                1. vadimr
                  20.10.2025 11:15

                  Цитата, на которую вы ссылаетесь, начинается так:

                  В языке Си ...

                  * * *

                  Я в реальной жизни встречал программу, которая работает много десятков лет, сначала на Фортране, потом на Паскале, используя значение переменной до инициализации (там потом в итоге получается, что это значение никуда не идёт). Современный компилятор C/C++ такую программу запросто бы порушил.

                  С точки зрения семантики Фортрана и Паскаля, переменная – это просто именованная ячейка памяти, которая всегда имеет какое-то значение.


                1. mihaild
                  20.10.2025 11:15

                  В паскале это не UB в терминах C. В C чтение неинициализированной переменной имеет полное право отформатировать диск. Этого на практике, конечно, обычно не происходит, но вот

                  int a;
                  if (g()) a = 0;
                  if (a == 0) printf("%d", a);

                  Вполне может вывести что-то, отличное от нуля - компилятор видит, что "если в aвообще что-то записали, то туда точно записали 0, так что проверку условия можно выкинуть", при этом в printf передать реальный адрес. Т.е. получится поведение, которое нельзя обеспечить никаким значением переменной.

                  В паскале такое невозможно - там у переменной всегда на самом деле есть какое-то значение. И аналог третьей строчки либо не выведет ничего, либо выведет 0.


                1. RichardMerlock
                  20.10.2025 11:15

                  Компилятор решает, будет УБ или нет. Если компилятор видит объявление переменной, но при обращении к ней без инициализации считает нужным пропустить резервирование памяти под переменную и выкинуть код обращения, то программист утирается и довольствуется отмазкой - ну это же УБ, вот почему у меня последовательность выполнения протекла. Вот такие нынче понятия, жрите кактус с утроенной силой!


                  1. HemulGM
                    20.10.2025 11:15

                    Объявленная переменная в Pascal уже зарезервировала память. Там есть адрес, там есть выделенная область, просто данные там не затерты нулями, а содержится то, что там было ранее. Следовательно чтение и запись туда никак не сможет вызвать UB в понимании Си.

                    Ну и если читать где-то такую переменную, то анализатор покажет WARNING.


              1. At1ass
                20.10.2025 11:15

                Если я правильно перевел, то в ISO 7185:1990 для Pascal написано, что вы неправы
                Если я правильно перевел, то в ISO 7185:1990 для Pascal написано, что вы неправы


        1. vanderPon
          20.10.2025 11:15

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

          Но те задачи, за которые взялся Rust в Паскале не были решены и не могли быть решены в то время


      1. wataru
        20.10.2025 11:15

        Ну какая вам разница, написано ли в стандарте, что программа будет работать "непонятно как" при некорректном коде, или что программа будет работать неправильно. Паскаль точно так же не ловит use-after-free при компиляции.


    1. AbitLogic
      20.10.2025 11:15

      В паскале таки есть сборщик мусора, не полноценный, но лучше , чем ничего - конкретно строки, динамические массивы и объекты интерфейсов уничтожаются сами


      1. vanderPon
        20.10.2025 11:15

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


  1. pewpew
    20.10.2025 11:15

    Вы снова открываете холивар "строгая типизация против не строгой".
    Мне кажется, тут надо понимать, как использовать преимущества выбранного языка, а не указывать на недостатки. Кто-то отметит, что отсутствие автоматического кастования - это слабость языка. В Паскале вообще нельзя перегрузить оператор "+", чтобы такое реализовать.
    А вот взять к примеру Lua - не строгая типизация в нём - заранее продуманная фича. И вообще вся философия языка на этом построена, что всё что угодно - в первую очередь таблица, а уж потом данные каких-то типов.
    Или, например то, что в PHP выражение "1abc" + 2 будет равно 3, это тоже фича. Кому надо типизацию построже - отключит нотисы или укажет явно типы данных.
    А Паскаль попросту устарел. Да и на свои программы на нём конца 90-х - начала 2000-х не могу смотреть без боли, хотя в своё время много чего успел на нём написать, в т.ч. околосистемного. Режет глаза в основном кодстайл тех времён.
    Так что даже сейчас я бы не хотел советовать его новичкам, тот же python для основ программирования куда лучше, хотя бы по тому что учит писать сразу красивый код.


    1. mantiscorp
      20.10.2025 11:15

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

      так это он сейчас красивым кажется, как и код на Pascal из 2000-х. а лет через 20 будете джуниорам рассказывать, как нашли свой исходник на python из 2025 и ужаснулись...


      1. WASD1
        20.10.2025 11:15

        Ну мне код на Pascal сразу же (как только я познакомился с C) казался некрасивым чисто визуально.

        Зашумление ключевыми словами, когда за begin ... end логики не видно (не смотря на то, что долгое время на Pascal) продолжал писать.
        Так что код на Pascal - из-за его синтаксиса - действительно не образец изящества.


        1. tyomitch
          20.10.2025 11:15

          Судить о красоте кода по фигурным скобкам и begin .. end -- всё равно что судить о красоте поэмы по цвету её обложки


          1. WASD1
            20.10.2025 11:15

            А для вас визуальная зашумлённость/незашумлённость синтаксиса - по важности эквивалентна цвету обложки поэмы?

            Я ваше "экспертное мнение" правильно понял?


            1. HemulGM
              20.10.2025 11:15

              А в чем захламленность? Чем это отличается от того, если там будут "{}"? При том что для try/catch вы вынуждены ставить ещё одни операторные скобки, а в Pascal - нет. Для указания выражения в условиях и циклах - всегда требуется указать "()", а в Pascal - нет.


              1. WASD1
                20.10.2025 11:15

                > зашумлённость
                ...а в чём захламлённость
                ... определите что синтаксис критически зашумлён (другой собеседник)
                ... не зашумлёнными у них считается -2%{2+.2/@*\/10.3??2*+ (третий собеседник)

                В чём смысл перевирать мои слова? Это форма демонстрации социальной righteousness через "посмотрите какой он плохой", и не важно, он такого не говорил и вы пытаетесь пинать соломенное чучело, или в этом есть другой смысл?


                > в чём зашумлённость / чем плох стиль?
                Сам стиль мне не нравится.
                Причём не просто "вкусовщина" - а за длинными именами и двойными вместо четверных пробелами поток управления не схватывается "на лету". TListBoxChatList / TListBoxItemChat - визуально трудноотличимы. И уже если вы эти первоочередные проблемы зашумлённости подчистите - излишне громоздкие и отвелекающие внимание begin / end начнут бросаться в глаза.

                То есть тут в целом должно быть вдвое меньше символов.

                Все плюсы (быстро напрогать POC и возможно MVP) и минусы (программа после некоторого количества десятков тысяч строк становится труднорасширяемой) - программирования в окошках Дельйей оставим вне контекста рассуждения.
                Но в целом - так и хочется JSONChats сгенерировать отдельной ф-ией.


                1. HemulGM
                  20.10.2025 11:15

                  Для меня, если в коде используются везде сокращения: вместо ListBox - lb, вместо ListItem - li, вместо Json - js, и прочее - это говнокод. Откровенный говнокод.

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


                  1. WASD1
                    20.10.2025 11:15

                    "если вы в innermost loop итератор называете не li, а ListItem - это значит, что за свою жизнь вы написали мало циклов".

                    ListItem - li, вместо Json - js

                    li - выглядит отлично
                    js - не знаю, мне не видится это общепринятым обозначением (но это очень далеко от области моих интересов и профессии - я системный программист).

                    Вообще почти идеальным для меня выглядит библиотечный код Хаскеля:
                    1. Ввести хорошо устоявшиеся короткие обозначения (имеющие довольно очевидные базовые истоки в предметной области)
                    2. Использовать их - за счёт минимума лексической зашумлённости - при взгляде на код сразу видно важное: структура кода (а не JSONListBoxItem (и думай что тут лексический шум, а что нужно)), что очень экономит время.


                    1. HemulGM
                      20.10.2025 11:15

                      Я всегда и везде пишу полные имена. А на моем счету десятки огромных и сотни больших (до 500к строк) проектов


                      1. WASD1
                        20.10.2025 11:15

                        Я всегда и везде пишу полные имена. А на моем счету десятки огромных и сотни больших (до 500к строк) проектов

                        Написано так, будто вы это самолично написали (иначе девочка технический писатель может засчитать себе сотни проектов к которым она только документацию по ГОСТ оформляла).
                        Давайте подсчитаем:

                        500к строк * 200 (минимум от "сотни") = 100_000_000 строк кода.

                        100_000_000 / 30(лет стажа) / 365(дней в году) = 9500 строк кода каждый божий день.


                        Э... надо осетра урезать. Или быть существенно аккуратнее в формулировках.


                      1. HemulGM
                        20.10.2025 11:15

                        Во-первых, ДО 500к - это проекты 50к, 100к и т.д.

                        А стажа у меня всего 12 лет.

                        Кода я очень много написал за это время. Мой репозиторий легко это подтвердит.


                      1. WASD1
                        20.10.2025 11:15

                        больших (до 500к строк) проектов
                        Во-первых, ДО 500к - это проекты 50к, 100к и т.д.

                        "Скидка до 90%".
                        Но вещь подорожала в 2 раза!
                        "но -100% скидки это до 90%, так что технически мы не соврали".

                        Вести диалог с человеком, который "технически не соврал", но разброс его цифр сходу разнится в 10 раз - пустая трата времени.

                        За сим прощаюсь.


                      1. HemulGM
                        20.10.2025 11:15

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


              1. Siemargl
                20.10.2025 11:15

                Сам Вирт в последующих языках убрал избыточные begin в половине конструкций


                1. vadimr
                  20.10.2025 11:15

                  Правильно сделал. Однако в Си в соответствующих местах стоят избыточные фигурные скобки.


            1. omxela
              20.10.2025 11:15

              А вы бы сначала определили понятие "зашумлённый синтаксис" и то, как определить, что синтаксис как-то критически зашумлён, или не зашумлён вообще.


              1. AbitLogic
                20.10.2025 11:15

                Наверное не зашумленым у них считается всякие гольф на perl/ruby, типа -2%{2+.2/@*\/10.3??2*+

                Каждая закорючка что-то да делает, а про читаемость кода никто не думает, на мой взгляд любой код на Pascal, тем более Rust на порядок более читабелен, чем типичный код C/C++

                Но давайте напишите на C/C++/Java например объявление функции

                Procedure Foo(const a,b,c,d,e:Word),

                Хочу сравнить зашумленность, сколько раз встречу const unsigned int вместо одного const Word?


                1. Kripiron
                  20.10.2025 11:15

                  Ну вместо unaigned int можно написать просто unsigned, но да, вы правы.


        1. ShaltaiBoltai
          20.10.2025 11:15

          Обожаю я рунет. Везде, где движок общалки (форум, соцсеть) дает возможность обосрать пишущего, его обязательно обосрут.

          Вирт делал свой язык специально для студиков. И не современных, а тех, кому сейчас уже за 70. Поэтому его язык такой многословный. Надо ему сказать спасибо, что в его языке не надо писать clauses вида:

          Please, be so kind prepare to follow these instructions. Are you ready? So, begin with ..., then do ..., after that do ..., and in the end, please do .. . Thank you.

          C же делали суровые мужики, которые с помощью ЯП хотели деньги зарабатывать, а не показывать, насколько виртуозно они владеют языком Шекспира. Поэтому в C нет таких длинных слов, он обходится скобочками.


          1. HemulGM
            20.10.2025 11:15

            Язык не создавался "для студиков" это заблуждение. Pascal создавался не "для кого-то", а с целью создать язык, который легко изучить и писать на нём. Это уже впоследствии язык стали применить именно для обучения программированию, потому что это было намного удобнее


            1. ShaltaiBoltai
              20.10.2025 11:15

              Да, вы правы, специально "для студиков" он не создавался. Но это заблуждение, как вы справедливо выразились, у нас в ходу.

              Вообще, Pascal по своим keywords сильно напоминает BASIC. С оглядкой на него, видимо, и делался. Не знаю, может, на персоналки 1970-х годов тогда C не завезли, поэтому американских студентов учили на BASIC и на Pascal.

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

              А вот в России 1990-х Pascal стал почему-то особенно популярен именно в вузах. Видимо, нашим не рассказали, что кроме него есть еще другие языки.


      1. aamonster
        20.10.2025 11:15

        Я помню переход с бейсика и ассемблера на паскаль 35 лет назад. Было ощущение, что пишешь кучу бойлерплейт-кода. Но потом программы стали больше – и строгая типизация начала реально помогать.

        Сейчас, кстати, со строгой типизацией ещё лучше: есть вывод типов, о котором тогда и не мечталось.


    1. HemulGM
      20.10.2025 11:15

      В старом Паскале нельзя, в новом - можно


      1. pewpew
        20.10.2025 11:15

        В новом - да. Но это уже не классический паскаль. Это его развитие. Покажите мне код перегрузки операторов, который скомпилируется в Borland Turbo Pascal 7.1 (вроде бы это последняя версия того самого классического паскаля), я полностью с вами соглашусь. Дальнейшее развитие - это уже Delphi а также Free Pascal и Lazarus или даже Pascal ABC где все пошли своим путём, это уже диалекты. Причём не факт что совместимые друг с другом.


        1. HemulGM
          20.10.2025 11:15

          Так ведь Borland Turbo Pascal не закончился когда-то, а просто сменил название и до сих пор развивается. Брать одну старую какую-то версию не совсем честно. Delphi ничего не изменил или потерял от своих старых версий, а лишь расширил. Всё, что можно сказать о старом Турбо Паскале, можно сказать и о Delphi


    1. HemulGM
      20.10.2025 11:15

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


  1. Cheater
    20.10.2025 11:15

    Оба языка следят за владением памятью (в Pascal — статически, в Rust — через систему ownership).

    Очень странная формулировка. Система владения в Rust - тоже статическая. Также там есть и динамическая, через типы с ref-count (Rc) и т.д. Статической системы владения в Pascal нет, и вообще я не знаю ЯП кроме раста где она бы существовала. В паскале есть динамическая система владения, через типы с ref-counting как и в расте. Статическая типизация здесь ни при чём. Также в обоих ЯП есть освобождение локальных переменных, видимо это и имелось в виду под "статическим владением" в паскале.

    ПС: классический пример когда человек пишет на Rust как на паскале :( Из проблем, например, что переменная min в такой реализации должна быть мутабельной. А почему собственно? Это же неизменяемый минимум неизменяемого массива.

        let min = [4, 7, 1, 9, 3].iter().min().expect("bad array");
        assert!(min == &1);
    


    1. HemulGM
      20.10.2025 11:15

      Так ведь min в коде поста вычисляется вручную и значение меняется по ходу перечисления массива


      1. Cheater
        20.10.2025 11:15

        Да, но после этого никак не объявляется, что значение min после вычислений зафиксировано и менять его нельзя. Точнее это можно сделать, используя такую фичу Rust как ре-декларация переменных, но это некрасивый хак:

        let mut min = some_value;
        let min = min;
        


        1. HemulGM
          20.10.2025 11:15

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


          1. Cheater
            20.10.2025 11:15

            Её семантически нельзя менять

            Семантически-то нельзя, но компилятор этому не помешает, в отличие от иммутабельного min:

            let mut min = data[0];
            // вычисляем минимум как раньше
            assert!(min == &1);
            // 1000 строк
            min = &2; // ну мало ли захотели другой какой-то минимум посчитать
            // ещё 1000 строк
            println!("Минимум массива [4 7 1 9 3]: {}", min); // ой забыли что min менялся
            

            И лучше бы её вообще не отдавать наружу функции min как мутабельную, если мы уж пишем min руками:

            let min = data.iter().reduce(|min_internal, x| cmp::min(min_internal, x))
                                 .expect("bad array");
            


  1. smt_one
    20.10.2025 11:15

    Хуже то, что вместе с введением статики мы получаем негибкость и хрупкость программ, а также теряем удобную разработку через образ как в Lisp и Smalltalk. Поэтому подход Python, подсмотренный у Newspeak и такого человека как Gilad Bracha, выглядит нормальным компромиссом. Пусть будут pluggable types, только не надо, чтоб они влияли на рантайм.


    1. pecheny
      20.10.2025 11:15

      Хуже то, что вместе с введением статики мы получаем негибкость и хрупкость программ

      Ну негибкость-то понятно. Но хрупкость? В лучшем случае, мы получим приложение, которое работает "непонятно как" вместо того, чтобы упасть. Мне кажется, что в подавляющем большинстве случаев, мы хотим второе.

      теряем удобную разработку через образ как в Lisp и Smalltalk

      Подход, конечно, классный. Но был ли он когда-нибудь хоть сколько-то распространен, чтобы говорить о "потере"? Вероятно, сколько его было в той нише, столько и осталось.
      Что из этого есть в современном питоне?

      Вообще, мне кажется, современные динамические языки скорее взяли худшие черты, профукав преимущества. Поэтому популярнейшие из них типа питона и js скорее смещаются в сторону статики.

      Динамизм ли определяет мощь лиспа? В некоторой степени, но без гомоиконичности магии не будет.

      Пусть будут pluggable types, только не надо, чтоб они влияли на рантайм.

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

      А более динамические юзкейсы, мне кажется, уползают в сторону каких-нибудь Jupyter (и org-babel для тех кто знает толк).


      1. smt_one
        20.10.2025 11:15

        Динамические типы не дают пенальти по производительности при разогретом JIT, что было доказано командой языка Self на практике. Они сделали JIT, когда ещё термина такого не было.


        1. pecheny
          20.10.2025 11:15

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

          только не надо, чтоб они влияли на рантайм


      1. TimurZhoraev
        20.10.2025 11:15

        Наверное имеется в виду что в Питоне может быть условная статика вроде type hints, вплоть до пометок в комментариях а-ля Doxygen, которые позволяет некоему внешнему мета-инструменту производить моделирование и согласование типов. Поэтому сам язык выступает как кристалл с динамикой который может быть вставлен в оправу со статикой или её эквивалентом. Важен именно сам подход, а далее под него уже отдельный инструмент либо сам компилятор либо IDE либо рантайм (как раз на случай падения, привет assert-ам проверкам int overflow и границам итераторов из мира статики).


        1. pecheny
          20.10.2025 11:15

          Ну, тайпхинты и внешний верификатор типов сейчас много где появляются. Поскольку были упомянуты Newspeak и разработка через образ – я подумал, что речь именно об этом.
          Правда, про Newspeak я особо ничего не знаю, но при упоминании рядом с лиспом и смоллтолком, я подумал именно про образ.
          В какой-то момент мне нужно было поиграться с данными, и я решил попробовать что-то похожее, начал искать какие-нибудь REPL-alike тулы и подходы. Но все что находил, было похоже либо на игрушку, либо было для clojure, то есть опять-таки сводилость к лиспу.
          В сторону питона я не особо копал, скорее искал что-то вокруг js – подумал сейчас, вдруг пропустил там что-то важное.
          А в тот раз, потыкавшись, я вернулся к понятному окружению emacs, поиграл с данными через org-babel и успокоился до следующего раза.
          Может быть, кода в следующий раз вопрос встанет, снова попробую копнуть, уже в сторону clojure или внимательнее поищу какие-нибудь пайплайны вокруг elisp.


    1. HemulGM
      20.10.2025 11:15

      А можно узнать, в чем "негибкость" проявляется?


      1. smt_one
        20.10.2025 11:15

        Наверное, на примере C# лучше всего видно, что его дженерики несколько ограничены. Конечно, Haskell в этом плане поинтереснее, но даже этот язык не предел выразительности в плане типов (привет Idris и зависимые типы). И вот поэтому мне нравится подход с несколькими разными "подключаемыми" системами типов.


        1. HemulGM
          20.10.2025 11:15

          Мне всё ещё не совсем понятно. Можно как-то конкретнее?


          1. smt_one
            20.10.2025 11:15

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


            1. Quintanar
              20.10.2025 11:15

              Типы давно уже достигли оптимума в соотношении польза-удобство. Зависимые типы уже могут сделать написание типа сложнее, чем решение самой задачи, поэтому за 30 (если не 40) лет разговоров они дальше специализированных языков не ушли и никогда не уйдут.


              1. TimurZhoraev
                20.10.2025 11:15

                Достигли дна, но снизу уже постучали. Нейросети - это отдельный тип данных, ещё более динамический. Добавить ещё определения вроде |int,float> соответствующие кубиту, который говорит, что переменная вроде бы int но ещё и не float, об этом знает только кот Шрёдингера. Ну а если по существу - то компромисс между моделированием, моделью и встраиваемыми явными и неявными элементами. Статика также содержит проверки как и динамика, вопрос куда тянуть этот канат это дело скорости разработки умноженной на эффективность кода нежели уже языка или библиотеки.


  1. Kelbon
    20.10.2025 11:15

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


  1. goldexer
    20.10.2025 11:15

    А так же обёртки, типа .NET Framework, сборщики мусора, разбросанные в памяти данные, простейшие типы, обернутые в классы, миллион операций для простейших действий с данными и ещё миллион под капотом, тысячекратная потеря производительности при использовании всего этого хлама. Люди перебросили всю ответственность на рантаймы, не желая контролировать свои данные и ход выполнения. Это да, это - современные реалии. Для исполнения сотни строчек кода нужен обвес вокруг исполняемого файла в виде манифестов, библиотек, кучи мусора, без которого, на самом деле, всё способно отлично работать


    1. vb2005
      20.10.2025 11:15

      А нужно ли это тысячекратное ускорение в прикладных задачах? Современные процессоры вполне переваривают все эти обвязки, вызванные особеностями высокоуровевых ЯП. А если требуется добиться максимальной скорости в узких местах, тот же .NET позволяет переложить выполнение кода в unsafe-область при помощи CLR, либо же P/Invoke. А там, пожалуйста, и SSE, и AVX-512 и прочие прелести...


      1. d_nine
        20.10.2025 11:15

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


      1. select26
        20.10.2025 11:15

        А нужно ли это тысячекратное ускорение .. ?

        Просто нужно помнить, что вместо 10 000 серверов, можно было бы обойтись 10.
        Вот и всё.


  1. maisvendoo
    20.10.2025 11:15

    Почему же ностальгия. А как же FreePascal?


  1. WASD1
    20.10.2025 11:15

    Если уж речь пошла про Rust и типобезопасность - то не использовать Option в функции возвращающей минимум - осквернение типизации.

    В целом - Pascal прекрасный учебный язык, но его время ушло (Python уже обзавёлся типизацией), закопайте уже стюардессу.


  1. GBR-613
    20.10.2025 11:15

    На Паскале , благодаря его продуманности, программы очень быстро компилировались. В старые добрые времена (конец 80-х, начало 90-х) это преимущество было важнее многих других, заметно увеличивая скорость разработки (примерно как Питон впоследствии). А программы, на нем написанные, работали, увы, медленнее.


    1. HemulGM
      20.10.2025 11:15

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


      1. mantiscorp
        20.10.2025 11:15

        Скоростью чего? Компиляции?

        Так Pascal был "однопроходной", поэтому и скорость выше


        1. HemulGM
          20.10.2025 11:15

          Нет, скоростью работы конечного кода


          1. TimurZhoraev
            20.10.2025 11:15

            вообще говоря сейчас вряд ли кто то из команды Pascal/Delphi занимается объёмом работы по оптимизации компилятора особенно под новые SSE/AVX, не говоря уже про GPU-расширения и др. Это задача уже либо монстров GCC (откуда скорее всего и заимствовано ядро оптимизации инструкций) или наборов компиляторов Intel, но для C/C++/Fortran или Microsoft для C/C#/VB. Скорее всё максимум застряло на MMX в 90-х на пике Borland. Сейчас же Pascal это скорее обёртка над сгенерированным C вплоть до файла в памяти и нативной прямой оптимизацией языка под процессор никто не занимается.


            1. HemulGM
              20.10.2025 11:15

              Но это не так.
              SIMD / SSE + SSE2 + SSE3, AMD-SSE4A - поддерживаются с XE4 (2013)
              SSE4.1 и SSE4.2, AMD 3DNow - c XE5
              AVX2 и AVX-512 - с D10+ (2015)
              Под кроссплатформу вообще используется LLVM и его преимущества
              А всё остальное вообще вами откуда-то выдумано


              1. TimurZhoraev
                20.10.2025 11:15

                Это просто предположение, хорошо если так. Просто оптимизатор под процессор очень не тривиальная штуковина, особенно с учётом особенностей кеша, порядка команд, векторных расширений, и отдельной командой для языка, не входящего в Топ-10 его явно невозможно мейнтейнить (собственный компилятор). Скорее всего там взят GCC на уровне Generic/Gimple, который уже сам на выходе поддерживает указанное с фронтендом на bison/flex.


                1. HemulGM
                  20.10.2025 11:15

                  Нет там никакой связи с gcc. Там собственный компилятор.


            1. ShaltaiBoltai
              20.10.2025 11:15

              Вы не правы. Delphi - это древний продукт, написанный в свое время с нуля. Никакой "оберткой над C" она никогда не была. У них есть отдельный C++Builder - вот его-то с какой-то натяжкой можно назвать "оберткой над Delphi". У них в их C++ даже расширения специальные есть, например

              __property

              чтобы поддерживать фичи из Delphi.


            1. Siemargl
              20.10.2025 11:15

              какое прямо восхитительное невежество =)


              1. TimurZhoraev
                20.10.2025 11:15

                Просто исходя из этого, там предстоит довольно большой объём работ и в комментарии указан один из вариантов решения проблемы =)


    1. WASD1
      20.10.2025 11:15

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

      Ну С++ знатно обделались с "синтаксическими шаблонами" и их инстанцированием (есил что - C-define работает на лексическом уровен, С++ template на синтаксическом, Interface / rust Trait / haskell typeclass - на семантическом).
      Собственно это один из важных факторов появления Go.

      А программы, на нем написанные, работали, увы, медленнее.

      Просто Borland написали довольно слабый компилятор, в сравнении с icc / gcc / MSVC.


      1. TimurZhoraev
        20.10.2025 11:15

        Ну так это началось довольно давно. Изначально как интерпретатор (стр. 128/248). Та самая P-машина (взятая за основу под Go). Вообщем если бы Pascal ещё в то время свернул по пути Python, как некий Бэйсик с классами, может быть сейчас он и был в топе. Но решили все усилия похоже пустить на эффективность, а это очень затратно хоть и занятно.


  1. T700
    20.10.2025 11:15

    Проблема серьезная. Языков программирования, много, но ошибки все теже. Какое-то топтание на месте. Либо яп, более менее читаемый (JS) но нет обязательной типизации, либо есть, но очень плохо читаемый (rust), либо она не обязательна но везде $ (php 8 испортили уже), либо в языке бесконечное множество стандартов и он не читаемый (c++), либо бесконечное количество проверок на err (go). Нет одновремено стабильности, читаемости, производительности, гениальной простоты с гибкостью, с zero trust подходом. И null, полезная вроде явление, но сколько в этом проблем.

    Я не доволен и думаю что когда нибудь, будет новый яп, в котором учтут проблемы и опыт прошлых лет.


    1. tyomitch
      20.10.2025 11:15

      Что не так с Котлином, например? или с C#?


      1. T700
        20.10.2025 11:15

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


        1. CrashLogger
          20.10.2025 11:15

          Избыточен и переусложнен - это С++) А Kotlin осваивается за пару дней, если до этого уже был опыт с Java.


      1. sdramare
        20.10.2025 11:15

        в C# сейчас нет алгебраческих типов и контроля мутельности переменных. Ну и рантайм с GC, что ограничивает применение в системном программировании.


      1. Siemargl
        20.10.2025 11:15

        что и со Свифтом. языки фактически прибитые к платформе


    1. grammidin4eg
      20.10.2025 11:15

      Кстати, в процессе чтения этой статьи поймал себя на мысли, что Pascal намного понятней синтаксически. Там почти нет магии, можно читать буквально что написано.


      1. T700
        20.10.2025 11:15

        В том то и дело, что чтение кода, и соответственно понимание и соответственно его поддержка, это основное что бывает и поэтому неоходим легко читаемый яп.


  1. Alex_Builder
    20.10.2025 11:15


    JS рождался как срипт на коленке для придания динамичности статичному HTML.
    Кто тогда в Netscape думал, что это скриптовое простенькое Ховно (на момент создания) будет когда-то всерьёз использоваться для серьёзной разработки интерфейсов или тем более на серверах?!
    Но беда в том, что в погоне за дешевыми кодерами (даже без профильного образования) и веб-кросплатформенностью т.н. "эффективные мЭЭнеджеры" сделали ставку на веб-мординг - ну и понеслась.

    С другой стороны чистый Pascal язык сугубо академический. На нём почти ничего массово не писали.
    Тот Pascal которым до сих пор пользуются - это Object Pascal (Delphi / Lazarus).
    А в ObjectPascal как раз испокон веков для удобства хранения любых типов есть динамический тип данных Variant .Этот тип по реализации несколько отличается от dynamic в C# или Dart, и по скорости работы конечного кода чуть более эффективен.
    НО при его использовании тоже запросто словить ошибку времени выполнения.

    var
    V1, V2, V3: Variant;
    begin
    V1 := 'aaa';
    V2 := 1;
    V3 := V1 + V2; // Здесь будет EVariantError во время исполнения

    ...

    Другое дело, что в таких языках как ObjectPascal объявляя переменную как Variant вы как бы понимаете зачем вы это делаете, а значит и осознаёте свою ответственность.
    Тогда как в скриптовых и изначально динамических убожествах типа JS у вас просто нет выбора.

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

    Кстати, хорошо хоть Google сейчас активно пытается исправить часть бед динамических скрипто-убожеств, активно продвигая такие языки и opensource библиотеки со строгой статической типизацией как Go или Dart (Flutter).


    1. AndrewT2
      20.10.2025 11:15

      Js стал ассемблером web. Дикий шаг назад.

      Человек предполагает, а Бог располагает.

      Лучше бы готовый object pascal использовали )


    1. TimurZhoraev
      20.10.2025 11:15

      Проблема статики - это изначально непоколебимый, единственный выбор руководящей и направляющей линии партии архитектуры. Это годно для нечто того, чей лайфтайм будет отсчитываться по количеству трудовых договоров прошедших через одну рабочую станцию и сопроводителя этого дела, включая их внуков. Что-то вроде Oracle-SQL, POSIX-OS, AWS и прочая статическая мелюзга для обработки динамики. А когда нужно в продакшн выпустить миллион экземпляров кликалок, с заменой пиктограммок по вайбу из тик-тока, то исходя из входного билета, требований к этому работнику получается что скриптоубожества становятся незаменимым инструментом для руководителя, и как ни парадоксально, конечного юзера бабы Клавы, даже если приходится набирать 8-800 с вопросом "у меня зависло куда нажать".


      1. HemulGM
        20.10.2025 11:15

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


        1. TimurZhoraev
          20.10.2025 11:15

          Зато мешает руководителю выбирать время, требуемое на разработку и квалификацию участников. Чтобы слово руководитель не раздражало, его можно заменить на систему управления и моделирования (тестирования) проекта. Статика вообще говоря не нужна для разработки при условии, что имеется разработчик с идеальной памятью и предсказуемым поведением функций с заданными ограничениями, он полностью знает как пройдёт Var от запуска до последнего деструктора. В ином случае она превращается в синтаксический сахар, не имеющий отношения к выполняемым функциям. Количество информации, требуемой для надёжной работы не изменяется при статике и динамике. В первом случае указывается явно, наряду с assertion и флажками, во втором - прячется в механизмы реализации и исключения. Быстродействие же не является определяющим, но желаемым, относительно скорости разработки и внедрения.


          1. HemulGM
            20.10.2025 11:15

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

            Во-первых, такого разработчика быть не может. Во-вторых, помимо одного "всезнающего" разработчика будут и другие, которые будут читать код. В-третьих, если взять случайный участок кода, то без подробного анализа с самого начала не будет понятно, какого типа эта переменная и как с ней работать.

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

            А скорость написания кода вообще не зависит от того, есть статика, или нет


            1. TimurZhoraev
              20.10.2025 11:15

              Разработчик такой может быть, у которого есть соответствующий инструмент, анализирующий этот код и производящий его моделирование. Инструмент анализирует, показывая, что любой объект не выходит за пределы области аллокации, не имеет висячих ссылок или Null-pointer-ов на действующий объект а также что по завершению стек вновь как новый. А далее там что угодно. Явный пример - это union. Очень часто используется для экономии памяти с использованием приведения типов и размещения объектов с шагом 2^N, например, когда имеется пара входных матриц 640 на 480 основная и буфер, далее осуществляется всяческое преобразование этих пикселей. Так вот эти буферы размером Nx\cdot Ny попарно используется простым приведением для всего остального в процессе обработки, вплоть до того что туда вполне можно гвоздями (static/reinterpret cast) прибить хоть std::list<std::pair<int, int>> МоиXY по результатам вычислений. Та же ситуация с числодробилками-численными методами и прочими нейросетями. Всё. Больше для статики места нет нигде, int-float-double. Тот же Fortran элегантнейшим образом спрашивает про тип данных не как что это, а сколько для этого нужно.

              Статика в необходимой мере сама не знает сколько у неё памяти до встречи с линкёром и размещением согласно map, задаваемой тоже внешним источником, который также надо проверять. Чтобы не ошибиться, выбрали (впаяли) чип с номером 6 или 8, 32 там флеша кБ или 64. Забыл про sizeof() и захардкодил константой? Это не проблемы компилятора.


              Вот в этом очень грубо и есть основная беда таких типов данных, что им даётся malloc/free этикетка с мелькающим всюду параметром Length за которой надо вручную следить, особенно если это выскакивает любым боком по указателю изнутри какой-нибудь функции. В любом ином случае (вплоть до искусственных глобальных макро, анализирующих первичную аллокацию внутри процедур из разряда #define malloc MyMalloc) это превращается... в самописный "динамический код" на базе статического. В подавляющем большинстве случаев это изобретение велосипеда, который давным давно встроен, апробирован, содержит все заплатки во всех динамических языках. Более того, масштабируемость. Ну вот забыл поменять int16 на int32 и в самый удобный момент положительные становятся отрицательными. Аллокация объектов прилетающих по последовательным портам для неизвестных типов данных - туда же. Слоты, обёртки, перегрузка, проверка типа, изменение объекта во времени выполнения без лишних копипастов по памяти - это существенно сокращает время. Включая гипотетический компилятор (включая ИИ) который может динамику превратить в статику глобально или локально для ускорения, застолбив длину объекта его строгим типом.


  1. NeoCode
    20.10.2025 11:15

    Динамическая типизация (когда прямо числа со строками можно складывать) мне не нравится (а еще больше не нравится отсутствие явного объявления переменных, когда просто пишут в коде vairable=10 и неизвестно новая это переменная или старая, или вообще опечатка как у меня).

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

    Предпочитаю золотую середину. Что-то близкое к С/С++, возможно построже чем C, но однозначно слабее чем Rust. В частности, удобно когда числа разных типов преобразуются друг в друга неявно; также довольно удобно когда 0==false а неноль==true. В остальном же пожалуй лучше явные преобразования типов.


    1. TimurZhoraev
      20.10.2025 11:15

      Если сюда ещё добавить прямой и обратный код, то получим что +0 это false а -0 это true, так что в строгой типизации надо ещё и этот атрибут указывать чтобы для полного ощущения так сказать помимо дополнительного кода. Туда же floating point с нулевой мантиссой и не нулевой экспонентой.


    1. theonevolodya
      20.10.2025 11:15

      Почему что у вас, что в статье путается динамическая и строгая типизация?
      Давайте поясним. Есть три деления типизаций:
      1. динамическая и статическая
      2. строгая и нестрогая
      3. явная и неявная
      Динамичекая, если упрашать, - это программист может записать в переменную строкового типа число.
      Нестрогая - программа автоматически приведёт переменную к ожидаемому типу. Если функция принимает число, а в неё передали строку, то строка преобразуется в число.
      Явная - при объявлении переменной необходимо указать тип
      Динамическая типизация - это не противоложность строгой. Так у python - строгая динамическая типизация


      1. vadimr
        20.10.2025 11:15

        Всё верно. А в PL/I – нестрогая статическая.

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


      1. NeoCode
        20.10.2025 11:15

        Согласен с вами, я хотя и знаю эту теорию, но написал неверно (хотя там главной мыслью было просто выразить свое предпочтение умеренно-строгой статической типизации). Наверное потому что с питоном дела практически не имел, а на "чисто-бытовом" уровне это воспринимается так - вот есть "скриптовые" языки, там можно с переменными делать (почти) все что угодно, а вот "компилируемые" где все статическое, строгое и компилятор ругается. Но конечно на самом деле есть и строгая динамическая, и нестрогая статическая, и к интерпретации/компиляции это отношения не имеет.


  1. AndrewT2
    20.10.2025 11:15

    TrueScript от создателя Turbo Pascal )


    1. NeoCode
      20.10.2025 11:15

      Для создателей новых языков, на выбор: TurboScript, PascalScript, TurboPascalScript :)


  1. alan008
    20.10.2025 11:15

    Не грех вспомнить эту полезную статью:

    https://habr.com/ru/articles/161205/


  1. Alexey2005
    20.10.2025 11:15

    На самом деле код на Pascal/Delphi читается настолько легко вовсе не из-за типизации, а потому, что там явно видно, в каком порядке этот код выполняются. Весь поток выполнения представлен в явном виде, его никто не прячет, и алгоритмы сразу как на ладони: сперва выполняется это, потом выполнение переходит сюда, потом вот в эту функцию...

    Тогда как на C# или JS мы получаем стейт-машину худшего свойства. Программа нарезана на крошечные фрагменты, которые вызываются через события. То есть выполнился кусок кода, и... И управление ушло в никуда, в среду (фреймворк), который потом его вернёт... куда-нибудь. Чтобы разобраться, куда именно, придётся приложить существенно больше умственных усилий, нежели при изучении Pascal-кода.

    А когда всё это сверху заполировано промисами, да ещё динамическим связыванием, так что из кода вообще ни хрена непонятно, что именно лежит в данной переменной и куда уйдёт управление при вызове метода some_method этой переменной - это ад. А в C# с его LINQ получаем ад вдвойне, потому что даже сами вызовы части методов заметены под ковёр - их неявно осуществляет сам фреймворк, и нет простого способа сообразить, что же тут вызвалось.

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


    1. Sirion
      20.10.2025 11:15

      В своём дипломе на делфи я написал настолько лютый колбек хелл с логикой, раскиданной по обработчикам нажатий кнопок, что до сих пор вспоминать страшно. На жс я такого уровня лютости так и не достиг)


      1. HemulGM
        20.10.2025 11:15

        Вы только увеличили длину пути, но путь всё равно пройти можно


      1. ALexKud
        20.10.2025 11:15

        Ну это от незнания как правильно было делать на делфи.
        Зато все работало наверно без проблем?


        1. Sirion
          20.10.2025 11:15

          Баг на баге) еле защитился


    1. ALexKud
      20.10.2025 11:15

      Все верно. Еще лучше будет читаться код PASCAL\DELPHI когда логика не раскидана по обработчикам событий и упорядочена в виде процедур, функций и т п.


    1. kmatveev
      20.10.2025 11:15

      Забавно, что вы противопоставляете JS и Delphi. Типичные Delphi-приложения очень похожи на single page web app, со стейтом и обработчиками событий, с вёрсткой отдельно от поведенческого кода.


      1. Alexey2005
        20.10.2025 11:15

        Вот только в Delphi обработчики события являются лишь точкой входа. После того, как событие случилось, весь дальнейший алгоритм прослеживается легко. Потому что у Delphi есть два важных архитектурных преимущества перед браузерной платформой.

        Первое - он позволяет читать внешнее состояние, не выходя из функции. Тогда как JS не позволяет выполнить что-то вроде getMouseState() или isLeftButtonClicked() - для этого сперва надо выйти из функции, а потом зайти уже в другое событие. В итоге на ровном месте имеем тонны входов-выходов "в никуда" только чтобы считать состояние того или иного внешнего объекта.

        Второе - Delphi позволяет обработать накопившуюся очередь событий, также не выходя из функции, просто банальным запуском ProcessMessages(). В итоге для долгого расчёта можно сделать, к примеру, индикатор прогресса с кнопкой "отмена" без существенного усложнения алгоритма и тонн мелких функций, распиханных по обработчикам событий.

        Собственно, JS'овские "лапша из коллбэков", потом (по мере развития языка) "лапша из промисов", а потом те же промисы, но перекрашенные в async/await - это как раз и есть кривая попытка закрыть данные архитектурные изъяны.


        1. aamonster
          20.10.2025 11:15

          Второе - Delphi позволяет обработать накопившуюся очередь событий, также не выходя из функции, просто банальным запуском ProcessMessages().

          Это проблема. То же самое есть в Objective C – и приводит к сложно обнаружимым багам вроде не срабатывающих таймеров и дедлоков.

          По возможности следует избегать использования этого инструмента.


    1. monco83
      20.10.2025 11:15

      Те, кто действительно пишет на C#, не замечают большей части описанных вами страданий. Бывает, конечно, что люди стреляют себе в ногу, не понимая, как работают итераторы или IQueryable. Но выстрелить себе в ногу и в других языках есть много срособов.


      1. Alexey2005
        20.10.2025 11:15

        кто действительно пишет на C#, не замечают большей части описанных вами страданий

        Их замечает тот, кто потом читает написанное. C# - один из худших языков, если требуется разобраться в логике работы чужого проекта, скачанного с GitHub. Хуже, кажется, только Perl.


        1. monco83
          20.10.2025 11:15

          Это просто какие-то фантазии. Тем более что упомянутые выше итераторы и Linq совсем не на каждом шагу в проектах встречаются. Да и с ними проблем у шарписта нет, если это не джун, который только читая чей то код открыл для себя, что Count на IQueryable имеет своим эффектом обращение в базу.


  1. ShaltaiBoltai
    20.10.2025 11:15

    Завидую я молодым.

    Чел родился в 2000 каком-то году. С 3-х лет стал интересоваться компьютерами. Ну, то есть, они просто были частью его повседневной жизни: он спал с телефоном в обнимку, под каждой подушкой, на каждом столе лежал планшет, а по квартире он ходил, спотыкаясь о батины старые компы. С 5 лет он узнал, что компы можно программировать! Ты пишешь ему текст, а он по этому тексту что-то делает, как по инструкции! Ахренеть! Но текст надо писать не на русском мате, а на особом мате, называемом javascript. И вот на 20-м году жизни он узнал, что кроме javascript, оказывается, существуют другой мат, на котором компу можно писать инструкции! Шок! Сенсация! И в этом мате есть такая удивительная хрень, как типы! Но это не те типы, которые в подворотне дают тебе в морду и отбирают твой телефон, а это особые типы: они обозначают, что за данные можно хранить в переменной. Переменная может быть Integer, String, Float - это всё не одно и то же! И такой трюк позволяет отловить некоторые ошибки еще до запуска программы! Шок! Сенсация! А в javascript никаких типов нет.

    Так вот. Я этому челу щас подвезу еще одну шок-сенсацию. Таких матов, где есть типы, придумано не один, а несколько. Кроме того, они на выходе позволяют получить отдельный exe, и им не нужен для работы ни Chrome, ни NodeJS! Шок! Сенсация! Кроме Pascal есть еще C++, C#, Visual Basic и даже Java! И у всех у них есть типы!

    Эх, завидую я молодым. Сколько у них еще открытий впереди...


  1. Pusk1
    20.10.2025 11:15

    Поставил + за сравнение RUST с паскалем. Хотя меня он подкупил управлением памятью, но подсознательно с паскалем как первым языком матчится и с PL/SQL от Oracle, который копия Ada. Согласен про сравнение с С. На все остальные языки я бы обобщал аккуратнее. С библиотеками в паскале тоже приключений хватало. У меня в школьном проекте они динамически автономных компилятором компилировались, например. Но это уже не про паскаль от Вирта.


  1. CrashLogger
    20.10.2025 11:15

    Не понимаю восторгов. Абсолютно то же самое будет и в C++, и в Java. Pascal тут вообще не уникален.


  1. pocheketa
    20.10.2025 11:15

    Паскаль уже тем хорош, что он ум в порядок приводит!
    А ещё это ламповые воспоминания из детства, когда компы были без винчестеров, ты приходил в школе в дискаб, загружал ДОС и Волков-коммандер с дискетки... И ваял :)


  1. SabMakc
    20.10.2025 11:15

    Помнится, в Turbo Pascal (Borland Pascal) была интересная "фича" - неинициализованные переменные хранят мусор. Но в debug-режиме неинициализованные переменные обнуляются.

    В итоге у тебя прекрасно работает все в дебаггере, но при релизной сборке вдруг ломается... И дебагер, опять же, не поможет - в нем все прекрасно работает.

    Но зато и плюс некоторый есть - убитый вечер (или несколько) и куча нервов жестко научили тщательно следить за инициализацией переменных.

    Но в целом, Pascal мало чем отличается от всех других языков со строгой статической типизацией.


    1. aamonster
      20.10.2025 11:15

      Забавно, для меня этот прикол (код работает в дебаге, но не работает в релизе – проверяй инициализацию переменных) ассоциируется с C++, в Паскале я с этим почему-то вообще не сталкивался (хотя использовал паскаль и дельфи достаточно много).


      1. SabMakc
        20.10.2025 11:15

        В C/C++, на сколько помню, неинициализованные переменные не обнулялись в дебаге (если говорить про Turbo C/Turbo C++/Borland C++) - так что если не работало, то не работало сразу. Хотя и бывало, что в дебаге работало, а в релизе нет из-за различий в режимах компиляции - в переменные попадал разный "мусор".

        С Delphi тоже не помню подобных приколов (хотя не скажу, что много с ним работал - предпочитал C++ Builder), но на сколько знаю, там подобное поведение тоже было.


        1. aamonster
          20.10.2025 11:15

          Visual C++ – кажется, 6.0. Локальные переменные в дебаге обнулялись, в релизе нет. В итоге приобрёл привычку всегда инициализировать переменную в момент объявления.

          Почему я не сталкивался с таким ни в Паскале (Турбо паскаль, потом Борланд 7.0), ни в Дельфи (кажется, до 3 или 5 пользовался) – не знаю.


          1. SabMakc
            20.10.2025 11:15

            В продуктовой разработке бывает, что все на дебаг-версиях и работает. Просто потому что релиз падает непонятно почему, а рабочая версия нужна еще вчера. А потом "исторически так сложилось" и "работает - не трогай" - и дебаг-сборка становится основной...


            1. aamonster
              20.10.2025 11:15

              Технический долг, начало начал

              Ты в жизни моей надёжный причал

              Технический долг, дебагинга свет

              Горит в твоих окнах много лет


  1. domix32
    20.10.2025 11:15

    Не знаю какую там типобезопасность вы теряли, но долгое время холивар был между Паскалем и C++ и С++ в ней победил, когда появились типобезопасные библиотеки на шаблонах. Ну и с имплементацией ISO стандартов Паскаля проблемы. Деривативы а ля Object Pascal/Delphi спеки по сей день не имеют насколько мне известно.

    Ошибки в паскале были не сказать чтобы прям сильно полезным, а уж если что-то падает, то даже stacktrace было проблемно получить. А там в нулевых по нескольку ядер на процессор и широкие регистры завезли - стартанула эпоха параллелизма, за которой Паскали не сказать чтобы поспевают, если конечно не писать ручками asm вставки.

    А вообще, помимо C++ многие использовали Ada для типобезопасности и там ограничений по типам есть побольше и повкуснее. Очень рекомендую хотя бы посмотреть на него.

    А сравнивать паскаль с динамическими языками а ля JS/Python/Lua это странно как минимум - разные ниши, разное назначение, разная история развития.


  1. abrca
    20.10.2025 11:15

    У вас на КДПВ ошибка, в коде на мониторе - использование неинициализированной переменной, в строке

    min := data[i];

    Про "код" на бумажке вообще молчу )

    На экране ноутбука вроде "0", но остальное плохо видно


    1. HemulGM
      20.10.2025 11:15

      Она нейронкой сгенерирована же


      1. abrca
        20.10.2025 11:15

        это понятно, но всё равно небрежность, особенно для темы статьи ))


  1. Yami-no-Ryuu
    20.10.2025 11:15

    Если автор не читал, то люто рекомендую классический MIT Structure and Interpretation of Computer Programs (SICP) https://mitp-content-server.mit.edu/books/content/sectbyfn/books_pres_0/6515/sicp.zip/full-text/book/book.html Schema - язык строго типизированный и красивый. Ну и книга прекрасно прочищает мозги. И с ООП и с DSL.

    Ну и современный Ocaml, как хороший компромисс между строгостью и практичностью https://ocaml.org/manual/5.4/index.html


  1. Alex_Builder
    20.10.2025 11:15

    Сегодня мы снова приходим к этому — через Rust, Swift, TypeScript. Мы возвращаем уважение к типам, потому что устали от хаоса.
    Ирония в том, что ответ на этот хаос был у нас с самого начала — в старом, строгом, занудном Pascal.

    Это якобы "типовое занудство" было испокон создания языков программирования.
    Тупо потому, что на базовом уровне железа процессор как минимум только примитивными типами - машинно-разрядными integer, double (а в древние времена и без double) и ещё машинно разрядными указателями и оперирует.
    А когда вы добавляете любую динамику, то она тут же тянет за собой необходимость отдельного сохранения доп. данных, их проверки и косвенного вызова некоторых лишних процедур для понимания с чем собственно мы имеем сейчас дело - а это всё лишнее время, время, время, которое суммируется в достаточно большие задержки.

    Вообще, IMHO сейчас, к большому сожалению, народилось уже целое взрослое поколение т.н. "программистов", которые вообще крайне слабо себе представляют как именно работает конечный машинный код на процессорах (причём не важно на какой архитектуре - на x86/64 ли, на ARM ли, на другой ли).
    В основном это самоучки со стороны, без профильного образования, въехавшие каким-то боком в профессию на волне IT-бума тупо за деньгой. И львиная доля из них как раз и есть мамкины скрипто-кодеры на JS или Питоне, но так же и часть Жабистов, C-Шарпистов и т.п.
    Иногда из общения с такими "профессионалами" просто диву даёшься, какую чушь они несут на собеседованиях или пишут в свои блогах.

    Это похоже на такой же ужас, как если бы ваш лечаший врач никогда не изучал основы органической химии, биологии, анатомии, и не проходил интернатуру, а так по быстрому нахватался бы знаний из пары книг и советов от друзей, и приступил бы к вашему лечению )))
    Может быть на сотом пациенте он бы чего-то бы и понял, почитал бы и глубже поучил бы, но первые минимум сто (включая вас) точно бы лежали уже в деревянных ящиках.

    Ребята из университетов хотя бы сначала базовую школу булевой алгебры, алгоритмов, архитектур, ассемблеров, C/C++, операционок, синтаксически анализаторов и т.п. так или иначе проходят, а уже потом пересаживаются на тот же JS при насущной необходимости.

    А вот причина стремительного взлёта полно-динамического скриптинга типа JS только одна - это идея быстрого кроссплатформенного ВЕБ-мордошлёпства, а вовсе не удобства сплошной динамики без статики.
    Эта идея, во-первых, очень понравилась т.н. "эффективным менеджерам" на рубеже 2000-х,
    а во-вторых, надо признать, что на рубеже 2000-х и последующие лет ~15 хороших альтернатив-то почти и не было.

    • С++Qt был достаточно сложен, и долгое время покрывал только десктоп. Да и сам современный С++ слишком заковырист и опасен для большинства описанных выше "мамкиных кодеров" без хорошего образования и большого опыта разработки.
      QML же деятели из Qt запустили уже существенно позже.

    • Многочисленные Java фреймворки тормозили нещадно и особой красотой не обладали. А JavaFX тоже уже позже стартанул, но как-то до сих пор особо и не взлетел.

    • C# был долгое время без кроссплатформы, а десктоповый GUI у них и до сих пор без кроссплатформы без сторонних решений. Ну а с Вебом у MS вечная чехорда, то чистый ASP.NET, то Razor, то Blazor, завтра ещё что-нибудь.

    • Borland Kylix забросил по причине убытков. Embarcadero со своим мега-глючным FMX тоже делала все как будто нехотя и медленно, хотя кто-то сейчас мобилки уже и на этом пишет. И между прочим, вроде бы древний и замшелый Delphi/Object Pascal сейчас на 10-м месте в рейтинге TIOBE.

    А в это время и на этом фоне с начала 2000-х "мамкины кодеры" очень быстро могли осваивать ВЕБ и JS и это было относительно безопасно для производственного процесса и очень выгодно для т.н. эффективных мЭ-Э-Энеджеров.

    Сейчас есть надежда, что, например, благодаря денежным вливаниям серьёзно взлетит такой фреймворк(язык) как Flutter(Dart) для красивого, современного, безопасного, кроссплатформенного и производительного мордошлёпства (включая и идентичную отрисовку в Веб поверх Canvas).
    А может появится что-то ещё лучше этого. Короче, "будем посмотреть" (tm)...
    НО если проект Flutter+Dart стараниями Google взлетит, то тогда велика вероятность, что HTML+JS погонят SSаными тряпками из кросплатформенного мордошлёпства и тем более с серверов туда, где ему изначально самое место - на поддержку динамики ВЕБ-сайтов.
    Но пока здесь ключевое слово - #если ))

    На Qt с их QML надежды не много. Да, там очень хорошее конечное быстродействие и очень объёмная библиотека, но как ни крути без знания C++ всё равно соваться не желательно, что как бы уже повышает порог вхождения.
    Ну а Delphi/Lazarus (Object Pascal) при всём моём глубочайшем уважении, какой там фреймворк уже не прикрути, уже вряд ли снова станет майнстримом.
    Слишком уж архаичен синтаксис. Много чисто исторических затычек из разряда "так уж повелось" и т.п.

    ХОТЯ В НЕКОТОРЫХ НИШАХ ОН ПО ПРЕЖНЕМУ ХОРОШ, поскольку при грамотном использовании даёт быстродействие найтивного кода сравнимое с Си/C++ при гораздо меньшей вероятности выстрелить самому себе в ногу.


    1. HemulGM
      20.10.2025 11:15

      Я использую Delphi + FMX для создания десктопа и кроссплатформенных приложений. Прекрасно справляется


      1. Chaos_Optima
        20.10.2025 11:15

        А можно названия этих приложений?


        1. HemulGM
          20.10.2025 11:15

          Для поиска?


  1. D7ILeucoH
    20.10.2025 11:15

    Ооо, а какую статью чел напишет когда узнает о настоящей типобезопасности? О том что существует язык где разделены nullable и notnull типы?

    Давайте я ему скажу, а вы через месяц мне доложите что он там накорябает.

    Язык называется Kotlin, и это просто лучшее (c# не дотянул до java, а kotlin это шаг вперёд от java)


  1. ugv_ugv
    20.10.2025 11:15

    Не понял названия статьи... Ничего не потеряли вместе с Pascal - множество разработчиков по всему миру реализуют отличные приложения на FreePascal


  1. orcy
    20.10.2025 11:15

    Что думаете по явные объявления типов локальных переменных? В паскале такого не было, а появилось в относительно свежих языках или let в расте или auto в C++. В плане написание кода удобнее, но что насчет читаемости?


    1. vadimr
      20.10.2025 11:15

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


  1. Turbo_Pascal_55
    20.10.2025 11:15

    Я жив :)

    Паскаль форева :)