Re[7]: Почему программисты прошлого были умнее
От: Sinclair Россия https://github.com/evilguest/
Дата: 28.11.22 08:54
Оценка:
Здравствуйте, vdimas, Вы писали:

V>Уровень владения технологиями, технический кругозор.

V>В общем, всё, что можно выяснить на собеседовании.
Имеется в виду — табличка вида "собеседовал, дата, результат". Ну, чтобы видеть, что вот это вот смутное ощущение "все стало хуже" имеет под собой какие-то основания, кроме интуитивных.

V>Трындёж — это не иметь возможности сравнить претендентов из разных эпох, но делать заявления.



V>Верно, сейчас вменяемых 1-2 человека из выпускаемой группы ВУЗ-а в 20+ человек.

V>Я так и говорил, а ты споришь.
С этим я не спорю. Я спорю с тем, что раньше были какие-то особенные урожаи программистов.

V>Никто не говорил о том, что сейчас в IT стало меньше грамотных людей.

Если под "никто" понимается ТС, то он именно что это и говорил.

V>Говорят, что их доля резко упала.

V>Т.е. резко упала средняя температура по больнице.
Это смотря как мерить.

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

Более того — если брать средний уровень программирования среди "всего населения", то он ещё и поднялся.

V>Разговоры про "планку входа" у нас шли вовсю шли уже в первой половине нулевых.

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

V>Я не могу себе представить эти разговоры в твоём 93-м, потому что за пределами требуемой на тот момент "планки входа" этих людей просто не было в профессии — они получали "корочку", но занимались другой деятельностью.

Я эту фразу не понимаю. Что за планка, кого именно не было в профессии?
В наших краях, к примеру, "корочек" по программированию не было примерно ни у кого. В профессии были кто угодно, кроме программистов — математики, физики, химики, экономисты, связисты.
В основном — потому, что "профильного образования" как такового не существовало до нулевых.

V>Ты ж учился не на IT, откуда у тебя статистика по однокурсникам, учившимся на IT?

У меня статистика по однокурсникам, учившимся на ФФ. Из них многие стали программистами.

V>Отож, 90% нынеших программистов принципиально неспособны писать те программы.

V>Думаю, конкретно ты был бы способен, но тебе пришлось бы многое пересмотреть из нынешних своих представлений.
V>Ну и прокачать некоторые навыки, например, внимательность и объективность.


S>>У меня инсайд из НИИ Автоматизированных Систем — типичное учреждение промышленного программирования.

S>>Уверяю вас: никакого "любопытства", никаких "исследователей". Совершенно простые смертные. Тётеньки, которые писали унылые программы на фортране.

V>И они получают свои 5-10 тыс $$ в месяц, поэтому сидят там? ))

Какие 5-10 тыс $$ в 1980х? Очнитесь. 135р в месяц — вот их зарплата. 200 — у ведущих специалистов.

V>А тут нагло ходят на собеседования.

Это показывает не уровень образования, а тупо желание попасть на работу.

V>Я не могу представить себе подобное в других областях, где требуются определённые непростые навыки.

V>Например, придти устраиваться танцором в балет, но растяжки нет, классика хромает, прыгучесть нулевая...
Как только в балете начнут платить по 5-10 $$$ в месяц, туда будут идти примерно все. Посмотрите на отборочные этапы Танцев на ТНТ — ровно то, о чём вы говорите.

V>Решат, что чел просто прикалывается. ))

Ну, так и вы решайте. Делов-то. Но вообще, это означает, что ваш HR просто отлынивал от первичной фильтрации. К нам и в 2002, и в 2005, и в 2010, и в 2015, и в 2020 приходили очень и очень вменяемые люди.

V>А сейчас аналогичные ребята уверены, что хоть где-то их возьмут, бо дефицит и всё в этом роде.

Ну, раз они уверены, то никакой проблемы нет.

V>Это в твоей непрофильной специальности из группы 1-2 любопытсвовали в IT, оттуда статистика? ))

V>Вообще странно, что ты сразу не пошёл на интересующую тебя специальность.
Не существовало у нас интересующей меня специальности. ФИТ открыли уже в нулевых — я к тому моменту давно свой диплом защитил.

V>На IT-специальностях так не было, разумеется.

Как по мне, так это вообще на всех специальностях. Значительная доля народу идёт в ВУЗ чтобы пересидеть армию или выйти замуж. Ещё сколько-то — потому что "мама заставила" или "подруга посоветовала".
Из нашей не-IT специальности программистов вышло больше, чем физиков.

V>Та не мог твой ВУЗ быть совсем отсталым, даже в пик развала в 93-м.

V>Просто у тебя выборка по непрофильной специальности.
Распределение IQ примерно одинаковое, от специальности не зависит. Распределение уровня мотивации примерно одинаковое, от специальности не зависит.
Распределение произведения этих двух параметров даёт неплохую оценку результирующей эффективности.

V>В Lisp и Algol абсолютно идентичные nil, никакого NULL в Algol нет, RTFM!

Продолжаете жечь?
https://www.algol60.org/docsW/algolw.pdf, раздел 4.5 References.
В Lisp nil — это не "невалидная ссылка", а пустой список.
(sigh).

V>Защита от nil всегда через проверки, что в Lisp, что в Algol, безальтернативно.

(sigh).

V>Как думаешь, какой чертой пользовался сам Хоар приличную часть своей карьеры еще до всяких Windows? ))

Думаю, что прямой. Вряд ли Хоар много работал в DOS.

V>Сам термин IoC из объектно-ориентированной среды, я его использовал сугубо удобства ради.

Скорее, ради красного словца.

V>Я тебе заранее на это уже отвечал — смотри как это обыгрывается в функциональных языках или в том же Kotlin, т.е. в языках, где присутствуют исключения.

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

V>В общем, ты сначала прикинь хотя бы минимально, как всё это обыграть для решения реальных задач.

Да что тут прикидывать? Всё известно от зари времён. В том-то и дело, что Хоар это понял, хоть и задним числом. А вы не понимаете по-прежнему.

V>Далее.

V>Если в языке есть возможность описывать пользовательские типы, выбрасывать и перехватывать исключения, переопределять операторы и вводить алиасы типов (как typedef в С/С++), то проблема упрощается.
Ну, это просто длинный способ сделать "примерно то же самое", хоть и не совсем. В языках с нормальной системой типов приведение Null к NotNull является ошибкой времени компиляции, а не рантайм-исключением.

V>У меня выше тоже SomeTypeRef статически отличается от SomeType*.

V>И никаких дополнительных фич языка не потребовалось.

V>А теперь давай про интероперабельность nullable и non-nullable типов.

V>Вот проверь статически Optional<T*> без IoC или исключений. ))
Охтыж боже мой. Ну да, на С++ по-другому никак, т.к. паттерн матчинг не завезли.
А в нормальных языках с современной системой типов мы имеем
a = dictionary.FindKey("foo"); // Maybe<int>

avalue = a ?? 0; 
/* sugar for: 
avalue = switch(a)
{
   Some(d): d;
   None(): 0;
} */


Никакого IoC тут нет, как нет и никаких функций для вызова.

V>В Хаскеле возможен только IoC вариант, т.е. рантайм-диспетчеризация как в последней строчке:

V>
V>data Optional t = Default | Specific t;

V>func :: Optional SomeType -> Void
V>func (Specific ptr) = someFunc ptr
V>func Default        = reportEmpty
V>


V>Да, до некоторого предела вложенности компилятор при оптимизации производит распространение констант, поэтому часто рантайм-диспетчеризация заменяется на прямо вызов, но в современных С++ эта оптимизация куда глубже/качественней, так шта мой С++ вариант будет соптимизирован лучше.




S>>А nullable reference нужны не чаще чем, скажем, Nullable<int>. Как-то же работает C# с int? безо всяких IoC и коллбеков. Удивительно, да?


V>Не работает, RTFM! ))

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


V>ОК, дай мне пример языка, которым ты владеешь хотя бы на самом начальном уровне, где есть строгая первоклассная поддержка non-nullable ссылок.

Любой с поддержкой паттерн-матчинга и монады Maybe.

V>В общем, такие языки есть, но их нет в мейнстриме.

V>Более того, многие из них достаточно старые.
Вот именно. В том-то и юмор, что речь не о каких-то суперновых изобретениях, а о давно известных вещах. Именно это и имеет в виду Хоар.


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

Исключения ортогональны ФП. Жаль, что вы этого не понимаете.

V>Посмотри, например, языки, со встроенной поддержкой зависимых типов, как там обыгрывают подобные сценарии.

Ну, и как же?

V>Да нет, эта фраза показывает, что ты не понимаешь зависимых типов.

V>Проблема же не только в null, ссылка вообще может ссылаться на мусор в памяти.
Конечно же нет. Как вы получите такую ссылку? Сославшись на объект, а потом убив его? Невозможно в языках с неявным управлением временем жизни.
Принудительно приведя какой-то мусор вроде целого числа к ссылке? Невозможно в языках без reinterpret cast.
Прибавив число к валидной ссылке? Невозможно в языках, где к ссылкам не прикрутили адресную арифметику.
Если единственный способ проинициализировать ссылку — это сослаться на заведомо существующий объект, да ещё и правильного типа, то ссылка никак не сможет сослаться на мусор в памяти.
Попробуйте сослаться на мусор в памяти на Rust или хотя бы на Lisp.

V>Т.е. простая проверка на не null не решает вопрос окончательно.

А окончательно и не надо. В языках семейства Алгол ситуация "ссылка на мусор" встречается в миллионы раз реже ситуации "ссылка на null".

V>В языках с зависимыми типами индекс не может вылезти за пределы массива никак, прямо на уровне типов.

Ну, вот видите. А говорите — невозможно, невозможно.

V>Точно так же, как ненулевая ссылка не может принять нулевое значение.

V>Ссылка вообще не может принять невалидное значение.


V>Уфф...

V>Адрес — это индекс ячейки памяти.
Это вы ссылку с указателем путаете. Технически они похожи, а с точки зрения алгебры — нет. В частности, у ссылок нет арифметики.

V>И ведет к асболютно идентичным ошибкам — к неверной реентерпретации памяти.

V>Я тебе в C# запросто создам управляемую ссылку на мусор в памяти (произвольный адрес, не обязательно null).
Ну, так С# — компромиссный язык. Я на нём и иммутабл стринг могу поменять, делов-то.

V>Это ты вот это всё имел ввиду под "современным программированием"? ))

Нет конечно.

V>В общем, в языках с зависимыми типами нет принципиальной разницы на допустимые ограничения, контроллируемые системой типов, будь это [0, 1, 2] или [0, 1..]

V>Там работает один и тот же механизм.
Отож.


V>Например, в языках с зависимыми типами без исключений может применяться flow control,

V>т.е., некий uint[0..MAX_UINT] может быть приведёт к ограниченному типу uint[0..10] через простой if:
V>
V>uint array[10] = ...;
V>uint x = readX();
V>func(array[x]); // ошибка компиляции

V>if(x < 10)
V>   func(array[x]); // OK, тип переменной x модифицируется контекстом предыдущих вычислений
V>

Ну, всё верно. А к чему тогда все разговоры о какой-то невозможности?
Там же даже проверок значения x внутри func(array[x]) нет.

V>Про произвольную программу речи не идёт, речь идёт об одном аспекте — о программировании в ограничениях на уровне системы типов.

V>Эти ограничения не дают неверно интерпретировать память.
Да, именно такую задачу Хоар перед собой и ставил при разработке Алгола.

V>Давай не будем о нормальности.

V>Теория зависимых типов была разработана не с 0-ля в 70-е, а первые работы на эту тему были еще в 1925-м, задолго до первых компьютеров.
V>Не надо считать всех идиотами. ))
Вы себе противоречите через строчку. То, по-вашему, предотвращение нулевых ссылок и выходов за границу массива — неразрешимая задача, то она была решена сто лет тому назад.
Вы уж как-нибудь определитесь с тем, что именно вы хотите аргументировать.

V>Речь тут не о теоретических вещах, бо с теорией давно всё хорошо, а сугубо об инженерных — о реализуемости, стоимости, практичности.

Ну, и что у нас с реализуемостью, стоимостью, практичностью?

V>А этих структур огромное кол-во, всё их разнообразия в виде встроенных типов данных не предусмотришь, поэтому большинство таких наколенных "безопасных" языков имеют один тип динамических данных — связанный список. ))

V>В общем, интерес предоставляют не наколенные языки, а те, которые позволяют экспериментировать с произвольным лейаутом динамических данных в памяти с типизированной гарантией безопасности обращения к данным.
V>Т.е., неверно обращающаяся к данным программа не должна уметь компиллироваться.
Ну вот, всё верно пишете.

S>>Кстати, вопросы индексов в массивах давно закрыты: https://www.cs.cmu.edu/~fp/papers/pldi98dml.pdf. Так то про "невозможность в компайл-тайм" — это лично ваши заблуждения. Развивайтесь, читайте.


V>- Ты куда, в баню?

V>- Да нет, в баню!
V>

V>Проверки в рантайм всё-равно есть, вопрос в том — сколько их.

V>Ведь достаточно проверить один раз (или достоверно получить валидное значение по new) и далее распространять значение уже с признаком валидности.
Всё верно. Поэтому вопрос не во вклеивании рантайм-проверок внутрь оператора [], а в возможности устранения этих проверок на этапе компиляции.

V>Это ты в своём C# не понимаешь сути, потому что нет алиасов типов, невозможно отсутствие конструктора структуры без параметров.

Вы опять за деревьями не видите леса. Алиасы, конструкторы без параметров... Это всё частности.
Вопрос в выразительности системы типов.

V>И без переделки исходников, т.к. Optional<T*> и NotNull<T> — это умные указатели, с переопределёнными operator-> и operator*, т.е. их можно использовать там, где ожидался обычный указатель, только теперь можно распространять non-nullable указатели без лишних проверок.

Ну так в С++ не самая плохая система типов. Без переделки исходников — это в том случае, если у вас весь код написан с автовыводом типов. Иначе нужно править сигнатуры у всех функций, которые принимают T*, а вызывают функции с NotNull<T>.

V>Увы, увы.

V>Программы, написанные в этом стиле, как по ссылке, построены таким образом, что в функции всегда передаются другие функции-"продолжения".
V>Т.е. вся работа основной программы — это бесконечный вызов ф-ий из ф-ий.
V>Но стек ведь не бесконечен? Отсюда монады и ленивость.
Монады и ленивость ортогональны рекурсии. Можно сделать в языке прямую поддержку хвостовой рекурсии, и иметь все преимущества ФП плюс гарантию неисчерпания стека безо всяких монад и ленивости.
И наоборот, можно реализовывать ленивость без рекурсии — см. yield return в С#.

V>И до чудес быстродействия там как до звёзд.



V>В 70-х только начали классифицировать типизированные лямбда-исчисления.

V>Классификация была нужна для понимания (1) необходимого и достаточного набора конструктов языка для соответствия выранным критериям и (2) для понимания необходимых техник программирования в данном классе ограничений, см лямбда куб (наглядное представление классификации).
И тем не менее, вы же сами пишете — основы теории зависимых типов заложены ещё в 1925 Чему верить-то?
V>В 60-х еще вопрос так не стоял, т.к. выразительные ср-ва компилятора диктовались сугубо объемом оперативной памяти, которой располагал компилятор в процессе своей работы.
Это интересная гипотеза. Не очень, правда, понятно, что вы называете "выразительными средствами". Вот, скажем, что там с выразительными средствами PL/1 по сравнению, скажем, с С?
И как они соотносятся с потребностями компилятора в оперативной памяти?

V>Нет никакого противоречия.

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


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

V>Оцени сложность в терминах O.
V>Умножь на многие мегабайты размеров современных программ.
V>Это всего лишь одна из подзадач в процессе оптимизации — склейка самоповторов после стирания типов на одной из стадий оптимизации.
Это не самый эффективный способ склейки самоповторов. Вы исскусственно усложняете себе задачу, сначала складывая все типизированные "подцепочки" в одну цепочку, а потом пытаясь найти повторы внутри этой склейки.
Гораздо эффективнее сразу искать похожести между версиями подцепочек, полученных для разных типов-параметров.

V>Сначала над типами работает бета-редукция и генерирование уникального кода из генерик-представления.

V>(А чуть ли не весь код на Хаскель — это сплошные генерики в терминах C#)
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.