Как стать автором
Обновить
47
0.2
Valentin Nechayev @netch80

Программист (backend/сети)

Отправить сообщение
Если взять вместо мотаний взад-вперёд по строке последовательное движение с рекурсией, которая всё равно неизбежна в случае выражений типа ((a+b)*(c-d))*e (ваш алгоритм будет вынужден считать скобки, чтобы определить пару первой скобке...) — получится самый типовой нисходящий ручной парсер типа того, что в книге Страуструпа по C++. А если добавить разбор по приоритетам операций — получится парсер Пратта. И, заметьте, никаких мотаний.

Поэтому я бы сказал, что вопрос надо заменить на другой — «если так просто писать ручные парсеры, зачем нас мучают всеми этими LL и LALR?» И вот на него уже сложно ответить методологически корректно, потому что тут как раз тот случай, когда преждевременная математизация убивает понимание.
> Кто-то очень не умный в Обратной Польской Записи добавил слово «обратная», это и приговорило этот способ записи всегда быть «неправильным».

«Добавил» потому, что «прямая польская» запись это префиксная, как в LISP. И идут эти термины «прямая» и «обратная» от работ Яна Лукасевича в 1920-е годы. Слово «польская» добавили уже после него, но в его честь. И это были очень умные люди, которые основали нынешнюю Computer Science.

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

> Естественную Польскую Запись

Своими нововведениями вы нарушаете устоявшуюся терминологию. Не думаю, что это будет принято обществом.
> Модификатор async никак не влияет на тип возвращаемого методом значения, то есть к типизации не имеет вообще никакого отношения.

Это если считать, что T и Task<T> это принципиально несовместимые сущности из разных вселенных. Но есть и другая трактовка — где это разные, но родственные типы, и где можно сложить T и Task<T> и получить новый Task<T>.
Собственно, построение через async или futures делает почти это (нет синтаксической прозрачности).
> Вы сами правильно заметили, что она редко когда нужна.

Категорически прошу внимательно читать и не подтасовывать. Я не сказал, что она редко _нужна_, я сказал, что она редко _используется_. А используется она редко, в частности, из-за того, что мало где адекватно реализована, и из-за критиканства неосиляторов. Я её использовал и в Python, и в C++ (без общего базового класса), и как-то программы не рухнули и работают без проблем.

Остальной ваш пафос пропускаю мимо за непрактичной банальностью.
Тормоза сборки C++ на ~99% заключаются в обработке шаблонов, а не в множественном наследовании (которое используется чуть чаще, чем никогда).

Задача 1 — почему область видимости obj заканчивается? Потому что дальше не используется?

> Но причем тут сам процесор?!

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

> Но архитектура Spark с более чем сотней регистров не стала преобладающей.

Вы с IA-64 не путаете? SPARC имел с точки зрения пользовательского кода 32 регистра (включая пустой). Системному позволялось видеть полный ротор регистров, но к вопросу плотности обычного кода это уже не относится.
Использовать нулевую страницу 6502 в качестве «почти регистров» не годилось. Проблема в том, что, говоря современным термином, регистры бывают общего назначения и служебные (в x86 последние это то, что MSR), так вот нулевая страница несла оба набора, и все участвующие использовали какие-то её ячейки непредсказуемым образом (надо было вычислять по исходникам).
Для полностью самостоятельного приложения, которое берёт на себя всю работу с аппаратной частью и вокруг, это было неважно. А вот если хотел сделать что-то такое, что и было хитрое на ассемблере, и сочеталось даже просто с местным бейсиком (хотя бы не сломать его по выходу из своего кода!) — уже возможность использовать нулевую страницу резко сокращалась. А какая-нибудь Рапира использовала её реально всю — оставляя только несколько ячеек нетронутыми — причём какие именно, документация подвирала.

Да, с этим можно было банально не столкнуться. Но с тех пор утверждение «нулевая страница это те же регистры» вызывает у меня только саркастическую ухмылку — и применяется как объяснение, почему процессору нужны настоящие регистры, а не суррогаты.
> 8080A и КР580ВМ80А также использовали три напряжения — см. документацию.

Хм, я не нашёл с ходу упоминания специфики именно 8080A, все почему-то универсально говорят про оба. OK, сочтём это за сбой памяти.

> непредсказуемых эффектов PDP-11

Про это уже ответили — неродные процессоры могли как-то лажать, но DEC, насколько я знаю, чётко держал планку.
И эти эффекты не касаются самых важных вопросов — например, порядок выбора дополнительных слов в командах типа mov #1, 20(%2).

> Только это «сильно раньше» было без процессоров-чипов, о которых статья.

Не сходится: вы VAXʼу отдельную главу посвятили.
Не принципиально, но считаю необходимым заметить.

> Посмотрите на команду LDA ($55,X) — тaкое на z80 не представить.

И смысла в ней где-то на уровне ноль целых фиг десятых. Я ещё в те времена как-то заинтересовался осмысленностью этой адресации, пересмотрел (чёрт, грепа не было, листал и глазами смотрел) код стандартных программ типа Бейсика, Школьницы — случаи были просто единичные и тупо сомнительные, в отличие от $ABCD,X или ($AB),Y — последняя вообще использовалась на каждом шагу (ну ещё бы).
Был какой-то паттерн написания, при котором именно такая адресация была полезна? Если да, я его не знаю и не использовал.
В остальном, под что легче писать — вкусовщина, но меня постоянное гоняние байтиков через аккумулятор просто доставало, особенно видя рядом вкусные аналоги типа клонов PDP-11.
Если бы конкуренты не тратили попусту по 4 такта на ерунду, тот 6502 просто не взлетел бы.
undo tree есть изначально в vim, но сколько пользователей его реально используют?

Автоустановка на ошибку — хороший вариант, но пойдёт не всем, должно отключаться.
8080 требовал три напряжения, а 8080A — только одно — +5V. Наши клоны были соответственно K580ИК80 (позднее ВМ80) и КР580ВМ80А; причём, 80 был в тонком корпусе с мягкими выводами (только пайка), а 80А — в обычной многоножке (соответственно, легко ставился на розетку). Реально у нас использовался только 8080А/ВМ80А — во всех компьютерах местной разработки. В вики есть фото Квазаровского ИК80 — у меня когда-то лежало несколько таких без дела.
Тут интеловский 8080A был конкурентом их же 8085, и Z80 — наверно, поэтому 8085 оказался никому не нужен.

> Есть основание полагать, что GNU ассемблер для x86 делали под влиянием именно ассемблера PDP-11.

Да, но не напрямую. Сначала был порт System V на i386, сделанный AT&T. Именно в нём было принято такое решение — и множество других, напрямую склонированных с Unix ассемблера PDP-11 и VAX-11 — таких, например, как команды ассемблера, начинающиеся с точки (.byte, .word, .align...) Эти наработки были куплены и перенесены в SCO Unix. И уже под влиянием SCO был сделан GNU as.

Некоторые особенности их решений сохраняются до сих пор. Например, в AT&T отличие fsubr от fsub в том, что суффикс r означает укладку результата не в st(0), а в другой регистр — хотя в оригинальном Intel синтаксисе это означало укладку в регистр вычитаемого, а не уменьшаемого. Или, они заменили идиотски путаные обозначения Intel для команд расширений знака (кто помнит навскидку отличие cwde от cwd?) на свои такие же путаные (cltd против cltq).

> Очень странные и непредсказуемые эффекты можно получить, используя счётчик команд как обычный регистр.

У PDP-11 они как раз очень предсказуемые — порядок отработки побочных эффектов аргументов чётко задан.

80188 использовался в некоторых моделях PC XT. Но самое знаменитое его применение — это в модемах USR Courier. В бСССР для него писали прошивки с заточкой под местную специфику, пользуясь лёгкостью понимания.

> с тех пор деление делать быстрее так и не научились!

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

Про условные переходы:
> С 80386 стало возможным использовать смещения из двух байт

В 32-битном режиме — все 4.

> С этого процессора начинается использование страничной виртуальной памяти – сегодня это доминирующая технология.

Мнэээ… IBM 370, VAX умели страничную адресацию сильно раньше.

Про 6502… он был удачный с точки зрения внутренней конструкции, да. Но писать что-то серьёзное под него было пыткой — говорю как краевед (Агаты в школе), из-за единственного аккумулятора и постоянных конфликтов за ячейки нулевой страницы. Если бы ему дали хотя бы 3 нормальных почти универсальных 16-битных регистра, он бы точно побил всех конкурентов. Боюсь, помешали этому те же причины, что потом убили его развитие.
Да и самому мне они претят, уродливо выглядит оно как-то.

Мне тоже немного не нравятся. Но я осознаю, что это вопрос привычки. А объективная польза от них достаточно высока, чтобы это терпеть.


у которых за плечами лет 40 опыта, и которые не ставят скобки вокруг однострочных тел, я встречался

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

не очень монструозный, чтобы не на полчаса времени

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


Имхо, Вы ищете сложные пути решения для простой проблемы)

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


задавались вопросы, если где-то логика перехода была преподу не ясна.
И наверняка половина наобум просто не проверялась — не успевал.
> Паскаль в той или иной ипостаси существует и поныне. А смысла в претензиях к версиям давно минувших дней — немного.

Ага, «существует». В следовых количествах.

> В этом нет никакой проблемы — это можно считать вариацией неопределенного списка параметров/необязательных параметров.

Когда нельзя самому такое сделать — это не вариация неопределённого списка, это другое, недоступное.

> Ваши некорректные ожидания — ваша проблема.

Ожидания совершенно корректные и конкретные — эргономические и POLA.

> Это снижет количество визуального мусора, делает код более компактным без потери читаемости.

Среди рассмотренных четырёх вариантов опциональные begin-end — самый мусорный вариант.

> Нет, это вы не поняли. Мой ответ относился ко второй вашей фразе, а не к висящему else.

Принципиально проблема не меняется. Посмотрите тут рядом рассказы от PVS-Studio — случаев «забыли обернуть в скобки», мягко говоря, дофига.
Питонист тут как раз скорее сам всегда будет ставить скобки, для страховки.

> И если по тем или иным обстоятельствам язык Х потерял рынок и ушел на обочину, это вовсе не означает, что все его свойства и особенности (включая синтаксис) плохи.

Про «все» я и не говорил. Но упомянул те, которые однозначно плохи.
Это мобильную версию? Если бы ещё десктопную проверяли хотя бы на 2Mbit/s канале и на слабом железе…
> Взять даже обычные калькуляторы — оказывается, даже у них нет единого стандарта по приоритету операций.

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

А неадекватные приоритеты в языках постоянно лечат, где нет необходимости сохранять старые баги. В C приоритет у &, | был занижен неадекватно — ниже сравнений. В Go, Swift — & на уровне с "*" "/", | — на уровне с "+" "-" — это уже не провокация, количество ошибок от нарушенных ожиданий резко ниже.

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

Вы реально расставляете скобки даже в выражениях типа a*b+c за пределами виндового калькулятора? Позвольте не поверить…
> Это — надуманная претензия. Никто не запрещает вам отказаться от встроенных средств и использовать библиотеки в стиле Си.

И вы отказываетесь читать то, что написано прямым текстом.
Сейчас, да, есть подобные библиотеки, и их можно использовать. Тогда — не было. Поезд ушёл тогда, до середины 90-х, а не сейчас.

> Как раз наоборот: то, что все работает с handle'ами — замечательно,

И во второй раз не хотите читать. Проблема не в самой работе с хэндлами, а в том, что в writeln с компанией или есть скрытый аргумент в виде stdout (или как он там зовётся в Паскале), или его нет.

> И замечательно — второй вариант читается лучше.

С такой аргументацией прямая дорога к Лиспу. У вас может сколько угодно «лучше читаться» второе, но если не ставить скобки, то ожидаемое не соответствует реальному.

> Строго наоборот — они лучше «отчеркивают» блоки.

Необязательные begin-end — худший вариант из четырёх рассмотренных.

> Естественно, если используются примерно так же, как скобки в С в GNU style, т.е. каждый begin и end строго на отдельной строке с соблюдением отступов.

А со стилем Modula/Ruby/etc., например, не надо ставить таких искусственных условий.

> Скорее это проблема тех, кто работает с Python или просто новичок.

Вы не в теме. Проблема висячего else это проблема, которая известна давно до появления Python (а в Питоне её не может быть по определению). А что «просто новичок» — согласен, профессионал, пару раз обжёгшись, просто введёт принцип «скобки обязаны быть всегда».

> Ни разу за уже 9 лет работы с Delphi (Object Pascal т.е.) такого не было.

А у меня было, когда с ним работал. И у тех, кто сейчас учится — постоянная проблема.

> Остальное все вкусовщина — кто к чему привык.

«Остального» не было, но статистика вкусовщины это уже не вкусовщина. А по ней таки упорно движутся в сторону тех подходов, что я описал как исправленные. Только паскалисты продолжают цепляться за своё легаси, хотя даже автор языка давно советует обновиться.
> Аналоги функций с переменным количеством аргументов появлялись в последних версиях турбопаскаля, когда там даже динамических массивов ещё небыло.

Ну да, когда поезд ушёл — тенденция перехода на C стала массовой.

> А насчет выражений, так в любом языке лучше расставить приоритеты явно скобками, паскаль просто подталкивает к этому порождая полезные привычки.

Извините, я не могу этот совет рассматривать всерьёз. Всегда есть какие-то естественные приоритеты, которым желательно не противоречить. В том же C, кстати, есть свои диверсии — исправленные в языках последних времён (см. таблицы приоритетов операций C и Go).

> Как в таком мире жить?

Улучшать. При любой возможности.
У Паскаля несколько тяжёлых недостатков, которые его по сути и убили, jIMHO, а в общем он просто сырой. Можно посмотреть на то, какими получились языки линии Modula, в которых некоторые самые тяжёлые проблемы были устранены.

Самое серьёзное — это стиль ввода-вывода. Язык явно задаёт особый стиль для read[ln]/write[ln], со всеми этими write(x:10:5). Программисту сделать свою функцию, которая будет уметь то же самое, нельзя. Сделать различие write() для stdout и write() для заданного хэндла — тоже нельзя. Сделать средствами языка свою реализацию файлов — тоже нельзя. В C — можно. Этого фактора было достаточно, чтобы слой хакеров (в реймондовском смысле) категорически отверг Паскаль и стал смотреть в сторону Си, у которого таких ограничений нет. Причём это не исправлено, насколько мне известно, даже в современных активно развиваемых реализациях! хотя могли давно придумать какие-то макросы, например.

Большая группа проблем при изучении языка (а каждая такая проблема вылазит и у профессионала, если он устал или не сосредоточен!) Я провёл через это нескольких школьников, пишу по своим впечатлениям:

Вечная борьба с блоковыми скобками — ставить begin/end или не ставить, ставить ';' перед else или не ставить, ставить перед end или не ставить (а некоторые психи настаивали, что перед end нельзя ставить ';')… И портит картину то, что постоянно эти скобки пропускаются в примерах и учителями, а понять, как их расставлять — например, как после then и после else раздельно ставить, или не ставить — это для совсем юных очень сложно.

В Си за счёт более коротких скобок эта проблема замаскирована, но осталась. В Modula — имплицитное begin и обязательное end — это один из лучших вариантов стиля. Go/Swift/Perl/etc. с форсированием {}, Python с отступами — это всё решения лучше, чем в Паскале. Для обучения вообще форсирование отступов очень полезно для формирования стиля.

Ещё сбивает с толку то, что repeat — until это само по себе скобки, а все прочие — нет.

И снова те же read[ln], write[ln] — тут пиши файл, а тут рыбу заворачивай — у школьников головы дымятся, у профессионалов тоже. Разделение printf/fprintf как в C — сильно лучше.

Вечная идиотская проблема с тем, что and, or приоритетнее сравнений, поэтому написать a=b and c=d нельзя, нужно (a=b) and (c=d).

Никлаус Вирт орал на весь мир «Не используйте Паскаль! Есть Modula, есть Oberon, в них все дурости Паскаля исправлены!», но так как в IT почти всегда идёт в массы не лучшее, а первое из минимально приемлемых, то застрял Паскаль.

> но это как раз и есть АД си-шечки — в более-менее сложных программах просто в глазах рябит от этих скобочек.

От begin-end рябит в разы хуже, потому что читается медленнее. И, повторюсь, блоковые скобки лучше форсировать даже для одного оператора — мировая практика постепенно пришла к этому. Сразу уходит куча дурных проблем типа «висячий не там else» или «тут воткнул ещё один оператор в теле под if, а почему старый перестал выполняться по условию?» Можно спорить, как именно должны выглядеть эти скобки, но они должны быть.
> Такая раскладка — совсем уж изврат :)

В области личных вкусов всё можно назвать извратом :) Например, я не понимаю, как можно хотеть переключать раскладки чем-то кроме CapsLock. А ещё один коллега ничего не хочет видеть в этой роли кроме правого Ctrl, благо драйвера позволяют. А за форму мышки можно глобальные войны устраивать, найдётся достаточно сторонников. Так что лучший выход — давать каждому жевать свой фломастер со вкусом нужной ягоды :)
Ссылки переслал.

Информация

В рейтинге
2 724-й
Откуда
Киев, Киевская обл., Украина
Дата рождения
Зарегистрирован
Активность