Почему программисты прошлого были умнее
26.05.2022
|
velkin |
Введение
В этой статье я попытаюсь ответить на вопрос, почему программисты прошлого были умнее, а качество образования с каждым годом только падало.
Поколения программистов
Для начала разделю программистов по поколениям на основе источников доступной информации, а так же способам программирования, они же парадигмы программирования.
1. Поколение программистов математиков (1940-1960)
Как известно более старые книги по математике времён СССР лучше более поздних того же СССР и России. В некотором роде книги по математике деградировали так же, как и книги по программированию. Люди, до 60-ых годов получали гораздо более простые и насыщенные источники информации, просто потому, что у них не было выбора взять худшие варианты из будущего. Похожее случилось и с программированием.
Для начала стоит отметить, что в те времена компьютеры ещё не получили широкое развитие. И даже более того, алгоритмы в описании не использовали парадигмы программирования. Для тех кто не помнит, что это такое, краткий экскурс.
1) Структурное программирование
инструкции: блоки, ветвления, циклы.особенность: отказ от безусловного перехода.
2) Процедурное программирование
инструкции: подпрограммы (процедуры и функции).особенность: значения как аргументы.
3) Функциональное программирование
инструкции: функции.особенность: функции как аргументы.
4) Модульное программирование
инструкции: логические (пространства имён).особенность: физические (включение файлов).
5) Объектно-ориентированное
инструкции: классы.особенность: наследование, инкапсуляция, полиморфизм.
6) Обобщённое-программирование
инструкции: шаблоны функций и классов.особенность: типы как аргументы.
С одной стороны кто-то спросит, а в чём преимущество отсутствия парадигм?
1) Алгоритмы находятся в одном месте без размазывания по тысячам файлов.
2) Не нужно учить парадигмы, чтобы написать алгоритм, достаточно здравого смысла.
3) Парадигма программирования это всегда ограничение возможностей.
Для примера Си не даёт вам написать инструкции структурного программирования вне парадигмы процедурного программирования.
test01.c
int c = 0;
int main()
{
{} // блок правильно
if (c) {} // ветвление правильно
while (c) {} // цикл правильно
return 0;
}
test02.c
int c = 0;
{} // блок неправильно
if (c) {} // ветвление неправильно
while (c) {} // цикл неправильно
int main()
{
return 0;
}
Но с тем же языком Lua таких проблем нет, глобальные структурные инструкции такие как блоки, ветвления и циклы разрешены.
test03.lua
c = false
do end -- блок правильно
if c then end -- ветвление правильно
while c do end -- цикл правильно
А некоторые языки программирования пошли ещё дальше, они требуют точку входа в приложение не в виде глобальной функции, то есть в процедурном стиле, а в виде функции принадлежащей классу или по другому методу.
C#
using System;
class HelloWorld
{
static void Main()
{
Console.Write("Hello, world!");
}
}
Java
public class HelloWorld
{
public static void main(String[] args)
{
System.out.println("Hello, world!");
}
}
Поколение математиков были лишены всего этого безобразия, в том числе и структурной парадигмы заложенной в языке.
2. Поколение программистов аппаратчиков (1960-1980)
С развитием компьютерной техники приходит поколение аппаратчиков. Это моё определение выдуманное только что, можете обозвать их сами. Их отличие в том, что в 60 годах и позже поколения программистов математиков начали внедрять устойчивые программные конструкции в языки программирования. Такие конструкции назвали инструкциями, а их набор парадигмами программирования.
Как показала практика не все парадигмы одинаково полезны. Некоторые приводят к размазыванию алгоритмов по огромному количеству файлов. Вроде бы код открыт и даже свободен, читай и используй, но нет, не получается. Отсюда и мем, что проще написать программу с нуля, чем дописать готовую.
Но давайте пока возьмём другой случай, а именно ограничения, которые приносят с собой парадигмы. Возьмём простую задачу, обмен двух значений, то есть значение A должно принять значение B, и наоборот, значение B должно принять значение A. Да, можно использовать буфер обмена, или хитрые арифметические операции. Но согласится ли с таким подходом пользователь ассемблера.
Если поколение математиков было сосредоточено на алгоритмах включая математические, то с развитием компьютеростроения поколение аппаратчиков сосредоточено на машинных командах. По мере появления парадигм программирования аппаратчиков, то есть людей понимающих как на самом деле работает аппаратура, становится меньше.
Постепенно парадигм программирования становится больше. По ним пишутся книги и всё больше связь с реальностью, то есть аппаратным обеспечением утрачивается. Однако, всё ещё не так плохо, ведь алгоритмы хоть и представлены в иных парадигмах программирования, но всё же это ещё полноценные алгоритмы, а не вызови вот это, получи результат, а как оно там работает не важно.
Давайте я очень условно возьму, что поколение аппаратчиков это 60-80 годы. Ну, а что вы хотите, если в начале 80-ых уже появился Си с классами, а это уже даже не Си. Далее перейдём к следующему поколению.
3. Поколение программистов абстракционистов (1980-2000)
Опять же все даты условны чисто для красоты изложения. Программисты математики и аппаратчики всё ещё живы, но благодаря накоплению парадигм и попытки их использовать начали накапливаться абстрактные проекты. Думаю многие слышали про языки низкого уровня абстракции, и языки высокого уровня абстракции. Так вот некоторые ошибочно полагают, что тот же Си это язык низкого уровня абстракции. А на самом деле машинный код и ассемблер это языки низкого уровня абстракции. А вот всё, что выше это языки высокого уровня абстракции.
И здесь вот какое дело, к этому времени книги по математике уже испортились. А так же появились книги по программированию, которые не описывают алгоритмы, а впаривают какую-нибудь готовую библиотеку алгоритмов без объяснения как она на самом деле работает. Да и сама библиотека на языке высокого уровня абстракции, и нормальному человеку исследовать её удобно лишь в режиме чёрного ящика, когда знаешь, что если вызовешь вот это, произойдёт то.
Собственно уже на этом этапе становится понятно, что поколение программистов, которые пишут алгоритмы вырождается. Книги засраны абстракциями с которыми и с пол бутылки водки не разберёшься. Ну или там ещё какая-нибудь толстая книжонка типа MFC для дурачка. Те люди которые писали эти библиотеки, они да, действительно получали какой-то опыт. Но те кто используют эти библиотеки превратились в обычных пользователей.
Но это ещё не закат эры. Давайте перейдём к следующему поколению.
4. Поколение программистов пользователей (2000-2020+)
Всё уже написано до нас, хотя на самом деле нет. Но квалификации опровергнуть это утверждения есть не у всех. Вот смотрите, математики могли идти по пути только математиков. Аппаратчики уже могли идти по пути математиков и аппаратчиков. А абстракционисты могли идти по пути математиков, аппаратчиков и абстракционистов. Казалось бы компьютеры стали быстрее и поколение пользователей могли бы идти по пути математиков, аппаратчиков, абстракционистов и пользователей.
Проблема в том, что в каждом поколении есть свои тренды. Если человек начал как пользователь какой-то библиотеки, то ему сложно будет пройти по предыдущим путям. Да и захочет ли он так делать, ведь вызывать готовую функцию всяко проще, чем писать её самому. А даже если и захочет, то появилось куча мусорной литературы. Я бы даже сказал так, поколение программистов пользователей может даже не понимать, что у них в образовании имеются некие проблемы, да и не для всех это действительно проблемы.
Проблемы программистов
Далее перечислю основные проблемы программистов.
Мусорная литература
Литературы много, но нет универсальной. Чтобы получить какие-то ответы нужно перелопатить тонну учебников читая одно и тоже, и не факт, что в этой тонне будет то, что нужно. Тогда придётся перелопачивать следующую тонну. Так же литература страдает словоблудием и плохой организацией.
Можно, конечно, и перелопатить тонны книг, но здесь нужен грамотный подход. Хотя бы какая-нибудь программа, которая позволит писать и документировать код, вроде AsciiDoctor. В любом случае решение проблемы остаётся исключительно за каждым программистом.
Мусорные алгоритмы
Почему люди не стремятся читать код свободных библиотек алгоритмов или программ. Да потому, что там всё на абстракциях. Принцип разделяй и властвуй на многих парадигмах не работает. То же ООП называют катастрофой на триллион долларов.
Но давайте представим, что нашёлся герой, который готов прочитать библиотеку алгоритмов. Только вот реализаций огромное количество. И каждую реализацию писал кто-то со своим словарным запасом. Мало того, что для большинства жителей Земли, английский не родной, так ещё и имена выдумывают как попало.
Уже не раз проскакивало такое высказывание, что сложно написать алгоритм понятный другим программистам, а не только машине. Вот только те, кто это говорят не сказал бы, что пишут что-то понятное и вменяемо структурированное. Мысль то может и правильная, где реализация.
Итоги
В принципе я обозначил проблему. И не только я, в интернете иногда об этом говорят. Что касается решения, то здесь как всегда нужно проводить опыты.
26.05.2022 67 комментариев |
Можно было бы обойтись несколько менее пространным и более простым объяснением.
В прошлом программистов было десяток-сотня реально увлеченных фанатиков, а сейчас — миллионы, для многих из которых это все та же конвеерная сборка.
Падение среднего уровня подготовки программиста это не проблема, а результат многолетних трудов по снижению барьера входа. Чтобы профессия могла быть массовой, работники — дешевыми, количество сделанной работы — большим. А если бы программирование было столь же сложным, как 50 лет назад, фигу бы мы имели, а не work from home.
SD>Можно было бы обойтись несколько менее пространным и более простым объяснением.
SD>В прошлом программистов было десяток-сотня реально увлеченных фанатиков, а сейчас — миллионы, для многих из которых это все та же конвейерная сборка.
Дело в том, что объяснение в стиле, вот раньше были реально увлечённые фанатики, не учитывает тот контингент людей, которые очень хотели быть программистами, потратили кучу времени, но поняли, что не смотря на все свои усилия они сильно уступают другим программистам. Иными словами они не стали профессионалами, но не потому, что не хотели и не пытались, а потому что шли по неверному пути.
SD>Падение среднего уровня подготовки программиста это не проблема, а результат многолетних трудов по снижению барьера входа.
Да, это так. Только проблема в том, что попытка снизить уровень входа так же сильно его повысила. Сильнее всего вход снижается, когда используются готовые библиотеки. Когда человек хочет программировать сам, то он натыкается на сложные парадигмы программирования вроде ООП или даже обобщённое, на которых ему предлагают использовать шаблоны проектирования.
В итоге огромное количество усилий тратится на то, что не даёт никакого прироста в умении алгоритмизации. Возьмём для примера STL языка C++. Много ли книг, которые объясняют как устроены алгоритмы из этой библиотеки алгоритмов. Опять же всё вроде должно быть просто, но нет, там внутри жуткая иерархия из типов, впрочем как и во многих других библиотеках.
V>Да, это так. Только проблема в том, что попытка снизить уровень входа так же сильно его повысила. Сильнее всего вход снижается, когда используются готовые библиотеки. Когда человек хочет программировать сам, то он натыкается на сложные парадигмы программирования вроде ООП или даже обобщённое, на которых ему предлагают использовать шаблоны проектирования.
Звучит примерно как "хочу махать молотком, а на работе заставляют пользоваться станком ЧПУ"
M>Звучит примерно как "хочу махать молотком, а на работе заставляют пользоваться станком ЧПУ"
Здесь речь про фундаментальные знания. Простой вопрос, нужно ли изобретать алгоритм самому, если он уже изобретён. Лично я считаю, что не обязательно, достаточно заучить. В конце концов люди учатся не переизобретая теоремы с нуля.
Но что, если алгоритм написан абстракциями препятствующими его прочтению. И вот здесь нужно понимать разницу между учебным алгоритмом и тем, который находится в производстве.
А фундамент знаний логично составлять из учебных алгоритмов работа которых досконально известна и видна с первого взгляда. Опять же возникает вопрос, что такое учебный алгоритм. И вот здесь часто проявляется мусорность литературы.
Ты, если хочешь полностью разобраться с тем почему происходит так, а не иначе, должен рассматривать не только минусы, но и плюсы. Тогда все сразу же встанет на свои места.
V>Здесь речь про фундаментальные знания. Простой вопрос, нужно ли изобретать алгоритм самому, если он уже изобретён. Лично я считаю, что не обязательно, достаточно заучить.
Всё ещё проще: если готовый алгоритм решает поставленную задачу, берём и используем. Если не решает, то не используем — придумываем свой.
V>Но что, если алгоритм написан абстракциями препятствующими его прочтению. И вот здесь нужно понимать разницу между учебным алгоритмом и тем, который находится в производстве.
Можно пример?
Что за алгоритм, что за абстракции?
Ощущение, что писал ӍїϛϮϠǷiя-ȺҜ под веществами.
V>А фундамент знаний логично составлять из учебных алгоритмов работа которых досконально известна и видна с первого взгляда. Опять же возникает вопрос, что такое учебный алгоритм. И вот здесь часто проявляется мусорность литературы.
Отлично! Берём классику — книжку Кнута/Кормена/Ульмана/Седжвига/Скиены — кто нравится больше и начинаем составлять фундамент . Просто, доступно, безо всяких абстракций.
Какую-то проблему сочинил и предлагаешь с ней бороться. Нет проблемы. Есть разделение труда. Есть "пользователи", которые программы составляют из кирпичиков и есть "математики"/"аппаратчики", создающие эти кирпичики. Все заняты, все счастливы.
тут вроде вышло
SD> работники — дешевыми,
а тут как то не очень
В этом предложении пропущено слово "в среднем".
А вообще, программистов настолько же умных как и 50 лет назад, сегодня на порядки больше.
Ну, и как обычно, ты путаешь причины и следствия. Это не программисты были 50 лет назад в среднем умнее из-за отсутствия парадигм; это парадигмы были придуманы специально чтобы облегчить программирования для широкого круга программистов разного уровня, в связи с тем что круг задач, решаемых программированием сегодня, сильно отличается от того что было в то время.
V>Почему люди не стремятся читать код свободных библиотек алгоритмов или программ. Да потому, что там всё на абстракциях. Принцип разделяй и властвуй на многих парадигмах не работает. То же ООП называют катастрофой на триллион долларов.
Что такое абстракции в реализации алгоритмов? Ну вот сортировка, какие там могут быть абстракции в реализации? Алгоритм сам по себе абстракция и может быть описан любым языком в т.ч. и разговорным. И почему алгоритм нужно учить по какой-то конкретной реализации?
А про ООП так говорят те, кто либо не написал на нём ни строчки, либо зазубрил бучизмы и применял их где надо и не надо. Последних уравновешивают не менее упоротые последователи Александреску.
V>В принципе я обозначил проблему ...
Спасибо, прямо глаза открыл.
V>... Что касается решения, то здесь как всегда нужно проводить опыты.
Вот, займись и нам расскажешь.
V>В этой статье я попытаюсь ответить на вопрос, почему программисты прошлого были умнее, а качество образования с каждым годом только падало.
Когда вы задаёте вопрос о причинах некоторого явления, надо для начала обосновать наличие этого явления.
Я вот не вижу однозначного подтверждения ни тому, что "программисты прошлого были умнее", ни тому, что "качество образования с каждым годом только падало".
Зато я вижу множество фундаментальных ошибок, сделанных программистами прошлого. Не багов в коде, а именно провальных концепций.
Вижу, что до сих пор в самых вытоптанных областях появляются новые решения, которые были бы вполне доступны программистам прошлого, но почему-то ускользнули от их внимания.
S>Я вот не вижу однозначного подтверждения ни тому, что "программисты прошлого были умнее", ни тому, что "качество образования с каждым годом только падало".
А как ты увидишь, если речь об усреднённых вещах?
Ты собирал статистику, проводил собеседования в разные годы?
S>Зато я вижу множество фундаментальных ошибок, сделанных программистами прошлого. Не багов в коде, а именно провальных концепций.
Например?
Я вижу, что принятые ранее решения исходили (а) из ограничений аппаратуры и (б) были расчитаны в среднем на более способного программиста.
S>Вижу, что до сих пор в самых вытоптанных областях появляются новые решения, которые были бы вполне доступны программистам прошлого, но почему-то ускользнули от их внимания.
Концептуально нового? ))
Например?
Я, наоборот, концептуально нового уже давно не вижу.
V>А как ты увидишь, если речь об усреднённых вещах?
V>Ты собирал статистику, проводил собеседования в разные годы?
Бремя доказательства лежит на утверждающем. Это оппонент делает утверждение о снижении среднего уровня программистов. Так что давайте адресуем вопрос про статистику и собеседования к нему.
А так — да, конечно же я проводил собеседования в разные годы.
Ну, и кроме собеседований я преподаю в ВУЗе, поэтому могу оценивать распределение уровней квалификации сегодняшних бакалавров и магистров. Никаких признаков проблемы, обозначенной ТС, не наблюдается ни там, ни там.
V>Например?
Из самого известного — "ошибка на миллиард долларов" Тони Хоара. (К квалификации Тони вопросы есть?)
Из чуть менее известного — thread.stop()/suspend()/resume() в Java 1.0. Гослинг вроде тоже отнюдь не новичок, но тем не менее принял заведомо неудачное решение.
Ещё в ту же коробку — Java.util.Date.
Это практически хрестоматийный пример того, как можно сделать неправильно буквально всё. Начиная с того, что тип с value-семантикой реализован как mutable, и заканчивая тонкими проблемами взаимодействия с календарём.
https://programminghints.com/2017/05/still-using-java-util-date-dont/
V>Я вижу, что принятые ранее решения исходили (а) из ограничений аппаратуры и (б) были расчитаны в среднем на более способного программиста.
Приведённые мной примеры — это грабли, которые никакого отношения к ограничениям аппаратуры не имеют, и от программиста ожидают не каких-то особенных способностей.
Ну, вот к примеру — с т.з. той же java.util.Date, "способный" программист отличается от "неспособного" тем, что в геттерах свойств выполняет defensive copy.
При этом никакого существенного улучшения качества программы не происходит — помимо замусоривания хипа и увеличения нагрузки на GC (что там у нас по ограничениям аппаратуры), клиентский код по-прежнему работает не так, как ожидают его авторы.
V>Концептуально нового? ))
V>Например?
Ну, например, я не ожидал, что в 21 веке смогут придумать какой-то новый вид скалярных индексов для СУБД. Казалось бы — после B-trees, hash, и bitmap индексов в этой области уже ничего нового не придумать.
Ан нет — апрель 2020, PGM-index.
Прекрасная штука — все преимущества B-tree (range queries, nearest search), плюс значительная компактность (а, значит, меньше io-нагрузка, более высокий cache hit ratio, и все вытекающие).
Был ли возможен такой индекс в 1963? Да, конечно. Это не нейронки, обучение которых стало практически пригодным только после массового распространения многоядерных видеокарточек.
Математика в основе лежит общеизвестная, сложность алгоритмов — не выше, чем у B-tree. Просто — не додумались.
V>Я, наоборот, концептуально нового уже давно не вижу.
S>Ан нет — апрель 2020, PGM-index.
Лекция Максима Бабенко (ссылка на Яндекс.Диск)
V>>А как ты увидишь, если речь об усреднённых вещах?
V>>Ты собирал статистику, проводил собеседования в разные годы?
S>Бремя доказательства лежит на утверждающем.
Я собеседовал десятки, если не больше сотни в разные годы.
И тенденция слишком однозначная, чтобы это было простым совпадением на многих десятках людей.
S>Это оппонент делает утверждение о снижении среднего уровня программистов. Так что давайте адресуем вопрос про статистику и собеседования к нему.
Так это хорошо видно по молодняку, если отслеживать появляющийся в конторах молодняк в течении длительного времени.
И дело не в уровне программистов, дело кое в чём катастрофическом другом — профессия воспринимается всё более обыденно, всё меньше горят глаза, всё менее ЛЮБОПЫТНО.
http://www.rsdn.org/forum/philosophy/2130680.1
Наше поколение — это поколение исследователей, без преувеличения.
Чем дальше, тем такие товарищи встречаются всё реже.
Да, встречаются, но это теперь, скорее, исключение.
Раньше было редким исключением наоборот.
Мы ж бессеребреники были, ЗП были вовсе не космические, шли осознанно, испытывая тягу к предмету.
Теперь часто идут потому что это способ неплохо устроиться в этой жизни.
Ей-богу не знаю как на Западе (они мне в среднем намного слабее казались уже во второй половине 90-х), но у нас финансовый вопрос влияет на мотивацию, бо 300+ тыс в месяц для 3-5- лет стажа на дороге не валяются, т.е. отсутствует чистота эксперимента. ))
S>А так — да, конечно же я проводил собеседования в разные годы.
S>Ну, и кроме собеседований я преподаю в ВУЗе, поэтому могу оценивать распределение уровней квалификации сегодняшних бакалавров и магистров. Никаких признаков проблемы, обозначенной ТС, не наблюдается ни там, ни там.
А с чем ты сравниваешь?
И в насколько разные это были годы?
Прблема стала себя проявлять в полный рост примерно с середины нулевых, когда ЗП программеров у нас доросли до неадекватных величин.
До этого неуклонный рост ЗП был примерно с 97-го года, по мере покрытия интернетом экс-СССР.
Проблема примерно в следующем — увлекающийся программист осваивал материала по специальности примерно раз в 10 больше, чем давала программа ВУЗ-а.
Сейчас доля таких студентовв разы ниже, дай бог 1-2 на группу.
И у тебя разве есть достаточная выборка по однокурсникам хотя бы до начала нулевых, чтобы сравнивать с тем, как оно есть сейчас?
А меня есть по тем временам и по нынешним, бо несколько студентов вытягивал из болота за волосы как раз по специальностям IT (детей друзей и родственников, своих подтянул лишь однажды, и то задание было несколько непрофильным — по цифровой обработке сигналов, им давали теорию на слабом уровне, в сравнении с тем, как давали нам).
Я в курсе среднего нынешнего уровня студентов в группах в различных ВУЗ-ах Украины, России, и даже двух европейских.
Буквально полтора года назад помог с курсовой работой одному человеку из европейского ВУЗ-а, потом тщательно спросил про уровень работ остальных сокурсников.
В общем, справились на должном уровне всего трое, включая моего подопечного (который самостоятельно не справился), а там была сущая херня, примерно которую мы делали на 3-м курсе.
Только условия для выполнения этой херни на порядки более удобные — из Arduino IDE, доступен ЯВУ, схема выч. модуля дана, её проектировать не надо, перед тем как для модуля писать ПО, и вообще "всё работает само", тепличные условия, нам когда-то это и не снилось. ))
И всё-равно 20 чел из 23-х на должном уровне ниасилили.
У нас осиливал десяток запросто и еще десяток с пары подсказок.
Не осиливали самостоятельно большинство девочек и буквально один случайный мальчик в группе.
Блин, у нас несколько девах в группе САМОСТОЯТЕЛЬНО справились с менеджерами памяти, с пакетными шедуллерами IO и прочими такими задачами на 3-м курсе.
По сравнению с этим тот западный курсовик за 4-й курс — тьфу полнейшее.
Да еще в тепличных условиях тулсетов/окружения.
В группе сыновей тоже десятка внемяемых не набралось, хотя там один из 3-х топовых ВУЗ-ов РФ.
V>>Например?
S>Из самого известного — "ошибка на миллиард долларов" Тони Хоара. (К квалификации Тони вопросы есть?)
Вот тут звиздёшь:
Чел попытался присвоить себе "ошибку", которая до него была уже "сделана" эдак тысячекратно, например, тот же nil в Lisp.
И вообще, основные динамические структуры данных на тот момент давно были разработаны, не только связанный список.
Без nil никуда.
И альтернатив в процедурном программировании нет до сих пор, даже в Kotlin.
Альтернатива тут возможна только через IoС, т.е. в функциональных языках, когда некоему акцессору (итератору, скажем), подаётся колбэк.
Или когда некоему optional<T> подаётся пара колбэков — для наличия значения и для его отсутствия.
(примерно как работает диспетчеризация ф-ий в Хаскеле над размеченными union)
Других техник борьбы с nil, кроме диспетчеризации на манер IoC, в природе не существует, даже в Kotlin.
И да, в 60-е годы эта техника была уже известна и показывала себя откровенно хреново, как и сегодня, собсно.
А фраза целиком лишь характеризует уже старого и недостаточно умного человека:
С возрастом строить сложные конструкты в голове всё сложнее, т.е. ему сложнее удержать в памяти кучу одновременных противоречивых требований прямых и порождаемых ими зависимых.
Сохрани он эту способность до сих пор — не писал бы откровенные глупости.
В молодости был умнее, мог оперировать большей размерностью условий, в которых принимал решения.
Далее.
В точности проблема нулевых ссылок повторяется в массивах, к которым обращаются по индексу.
И чего ж старик не упомянул эту проблему, хотя проблема в точности идентичная?
Это ровно один и тот же класс ошибок, вызванных одной и той же причиной — невозможностью в compile-time выразить ВСЕ требуемые ограничения из runtime.
(в языках, которые претендуют на хоть какую-то эффективность)
И до изобретения исключений, без техники IoC, т.е. без функциональных ср-в в языке, ошибок такого рода в процедурных языках избежать было нельзя, можно было лишь сгенерировать проверочный код компилятором (или использовать какой-нить другой трюк, например как обращение к NULL как к невалидной области памяти, как оно специально сейчас организуется в мейнстримовых архитектурах с защищённой памятью, через аппаратное инициирование исключительной ситуации) и аварийно завершить программу, если проверка на индекс или nil была неудачной. Аналогично некоторые адерс-санитайзеры обкладывают массивы незакоммиченной памятью, чтобы иметь возможность уловить "промахи". Но там улавливание только в рамках этих отступов, т.е. всё-равно ничего не гарантируется, можно "промахнуться" уже на следующую валидную область памяти.
Далее.
Критикуя — предлагай!
Даже если критикуешь себя.
Наверно, Хоар еще не совсем выжил из ума, раз не озвучивает альтернативу, потому что альтернатива была проста:
— их доработка Алгола вышла бы УГ, была бы отдвинута конкурирующими более вменяемыми языками, а Хоар заслужил бы себе реноме дурачка, который обращает в г-но всё, что попадает к нему в руки.
Или, если бы весь мир сошёл с ума одновременно с ним, то эта ошибка стоила бы индустрии не смешные миллиарды долларов, а ВСЕМУ МИРУ сотни триллионов, по причине задержки примерно на 30 лет развития IT из-за неадекватного железу ПО.
Последствия "правильного" решения (если бы оно было принято обязательно в любых ЯВУ на нашем шарике) были бы таковы, что сегодня население Земли никак не могло бы вырасти до 8 млрд, потому что этот рост вызван лишь ростом среднего благосостояния людей и ничем больше.
Ты же на голубом глазу рассуждаешь о том, что ради "идейной чистоты" со всем этим можно было бы подождать примерно 30 лет, до эпохи, когда начался резкий рост производительности компьютеров.
S>Из чуть менее известного — thread.stop()/suspend()/resume() в Java 1.0. Гослинг вроде тоже отнюдь не новичок, но тем не менее принял заведомо неудачное решение.
ЧТД, еще более слабый пример.
Да и при чём тут Java, это надо совсем не разбираться в вопросе. ))
Это АПИ потоков современных ОС, Java лишь даёт доступ к этому АПИ, как и ко многому другому АПИ.
Не хочешь, пройтись по сокетам, обычным и NIO из Java?
С высоты сегодняшнего понимания проблематики — уродство и то, и это.
Но это уродство — тоже лишь языковая обертка над обычными и асинхронными сокетами в ОС.
А откуда сокеты таковы в ОС?
Из-за уродства сетевой модели, даже OSI 7, рядом с которым семейство IP выглядит вовсе имбициллом.
А откуда это уродство вообще берется? — из-за необходимости разделять на независимые уровни различные задачи.
Из-за необходимости пользоваться сетевым транспортом не только высокоуровневым программам, но и низкоуровневыми.
Даже устройствам размером со спичечный коробок, как сказали бы в 90-х, или размером со спичечную головку сегодня.
К уродству приводит выбор из сомна противоречивых требований, из необходимости учесть кучу больших и малых факторов, из необходимости обеспечивать затем обратную совместимость в течении многих десятков лет жизни технологии, дабы технологии хотя бы успевали себя окупать.
В таком выборе обязательно что-нибудь приносится в жертву.
Например, в случае OSI в жертву было принесено доверие иерархических уровней сетей друг другу, т.е. в целом там выходит плохая защита от злоумышленничества.
Этот казус более-менее решает семейство IP, но уже в жертву был принесён здравый смысл — в одних случаях имеем многократное неоправданное дублирование служебных данных пакетов, в других случаях имеем невозможность дополнить пакеты нужной служебной информацией. Такая возможность есть лишь на прикладном уровне протокола. На прикладном, Карл, т.е. на одном из возможных из 7-ми.
Собсно, принципы разметки пакетов IP придумали имбициллы. Это не ругательство, это факт. Видна рука, скажем прямо, полупрофессионалов.
Скорее всего, этим занимались не системотехники, а смежники или вообще спецы в других дисциплинах, типа тебя, которые нахватались IT сугубо из любопытства.
Отсюда детские ошибки.
А вот "ошибка" с nil нифига не детская и не ошибка вовсе.
Чел прямо говорит, что принял это решение осознанно.
Просто из-за возраста не в состоянии восстановить полный ход тех своих рассуждений.
Жаль, конечно, но нас всех это ждёт в старости.
Уважаю Хоара за что он делал тогда, и не собираюсь принимать во внимание то, что он говорит сейчас.
В деле разработки языков вклад Хоара скромен и мне на эту часть его деятельности несколько пофик.
Хоар внёс заметный вклад в анализ и выработку решений, лежащих в основе современных многозадачных ОС.
И не только в плане механизмов синхронизации, но даже в современных менеджерах памяти.
И да, весь этот код в той области задач писан через nil и обращения к массивам через индексы. ))
Добро пожаловать в реальность, Нео.
S>Ещё в ту же коробку — Java.util.Date.
S>Это практически хрестоматийный пример того, как можно сделать неправильно буквально всё. Начиная с того, что тип с value-семантикой реализован как mutable
Синклер, ты всё-таки определись, ты демагог или ты просто неисправимый нуб?
Когда разрабатывались эти классы (в среде, где всё выделяется из кучи), вменяемого escape-анализа не существовало.
Поэтому решение было единственно верным.
Да и сейчас вменяемого escape-анализа не существует и все серьёзные работы на эту тему сходятся в итоге на том, что в рамках динамического JIT это принципиально невозможно.
То бишь, протестовать тут можно лишь по классике — как двоечники протестуют против невыученных уроков, и тогда ты неисправимый нуб, обреченынй вызывать насмешки до старости.
Или ты всё это понимаешь — и тогда ты нечестивый демагог, наше вам фи.
V>>Я вижу, что принятые ранее решения исходили (а) из ограничений аппаратуры и (б) были расчитаны в среднем на более способного программиста.
S> Приведённые мной примеры — это грабли, которые никакого отношения к ограничениям аппаратуры не имеют
Всё-таки неиправимый нуб?
S>и от программиста ожидают не каких-то особенных способностей.
Судя даже по этому обсуждению — без способностей в нашей области некоторым непросто.
S>Ну, вот к примеру — с т.з. той же java.util.Date, "способный" программист отличается от "неспособного" тем, что в геттерах свойств выполняет defensive copy.
Ты действительно не понимаешь, почему так было сделано?
Так ты нуб, или демагог.
Ты уже показываешь что плаваешь совсем в азах взаимодействия управляемого и нейтивного кода.
Поэтому я так до сих пор и не могу определиться.
Но неужели столь вопиющий нуб так ловко играет хотя бы продвинутого юзера? ))
Хотя, по переписке оно проще, конечно, водить окружающих за нос.
В живом разговоре, когда к гуглу за ответом па бырому не сбегаешь, лучше видно, ху из ху.
S>При этом никакого существенного улучшения качества программы не происходит — помимо замусоривания хипа и увеличения нагрузки на GC (что там у нас по ограничениям аппаратуры), клиентский код по-прежнему работает не так, как ожидают его авторы.
Код работает так, как написано в документации, а не как ожидают те, кто сам себе чего-то надумал.
V>>Концептуально нового? ))
V>>Например?
S>Ну, например, я не ожидал, что в 21 веке смогут придумать какой-то новый вид скалярных индексов для СУБД.
Во-первых, у тебя хромает русскоязычная терминология, т.е. ты не знаешь, о чём ты говоришь.
Во-вторых, никаких видов индекса не придумали ни одного в 21-м веке.
S>Казалось бы — после B-trees, hash, и bitmap индексов в этой области уже ничего нового не придумать.
Ты забыл еще time series, и целое семейство вероятностных, как надстройки над иерархическими индексами (не обязательно B-trees, бо сами B-trees лишь вырожденный случай из своего класса).
S>Ан нет — апрель 2020, PGM-index.
Не вижу ничего нового.
Вижу попытку сочетаний уже имеющихся подходов.
Итого, Синклер лжец. ))
Или нуб, опять самостоятельно не разобрался, как маленький.
S>плюс значительная компактность
Но я не вижу изобретённого способа компактификации.
Где формула изобретения?
Или мне тебе на пальцах показывать, как можно хранить иерархические данные не только в бинарных узлах, где оверхед по занимаемой памяти чуть ли не втрое? ))
Мы же именно с тобой обсуждали реализации n-tree.
Собсно, любые n-tree выразимы через b-tree, но решают недостатки b-tree по оверхеду служебной памяти, по локальности данных и т.д.
S>(а, значит, меньше io-нагрузка, более высокий cache hit ratio, и все вытекающие).
Зевал так, что чуть рот не порвался...
Синклер, ты обещал новые концепции...
Значительные изобретения...
А кормишь булшитом, уровня инженерной разработки.
Блин, различные шедуллеры в современных ОС и то в разы сложнее в плане использованного понимания происходящего, а тут статейка от новичков в IT (зародышей-аспирантов) по ссылке.
Ты бы не мог впредь не засорять эфир, где тусуются опытные инженеры, всякой наивной мутью от учащихся?
Многие оформляют кандидатские к 27-28 годам, будучи еще при этом совсем еще зелеными в области IT, поражающими воображение своей наивностью и отсутствием "набитости руки" в этой области человеческой деятельности, бо копают один-два направления в аспирантуре, причём, весьма изолированно от других областей.
В этом и заключается отличие инженерной от научной работы в IT — научники изучают изолированные аспекты, а инженеры изобретают способы совмещения аспектов.
Характер и тех и других работ исследовательский, но объем одновременно оперируемой информации у инженера обычно в разы больше.
Нескольким таким горе-кандидатам я когда-то помогал, да и не только я.
Опытные инженеры всегда помогают зеленым аспирантам, это нормально и правильно.
Ненормально, когда опытных инженеров в аспирантов тыкают. ))
Брысь по яслям, как грится.
S>Был ли возможен такой индекс в 1963? Да, конечно. Это не нейронки, обучение которых стало практически пригодным только после массового распространения многоядерных видеокарточек.
S>Математика в основе лежит общеизвестная, сложность алгоритмов — не выше, чем у B-tree. Просто — не додумались.
Просто ты живешь в параллельной Вселенной.
Первые примитивнейшые СУБД появились в начале 80-х.
А первые вменяемые — к 89-му, а на самом деле в 92-м, после исправления детских ошибок.
И там до перебора комбинаторики всевозможных видов индексов еще столько вопросов решить надо было, особенно в плане ХРАНЕНИЯ данных и сопротивляющихся их целостности дисковых операционных систем — у-у-у...
Т.е. этот вопрос был даже не десятый.
Плюс сама эта проблематика не стояла, бо она начинает вовсю стоять на больших объемах данных, а их тогда физически не существовало.
И вот ты заламываешь руки, что в 60-х годах на несуществующих тогда СУБД (сама теория в 70-х только-только начала прорабатываться) не решали задачи эфффективного индексирования чудовищных размеров данных, пригодных к обработке, хранящихся на хранителях, которых требуемых размеров на тот момент тоже физически не существовало.
В этом сюрре прекрасно всё. ))
Дисциллированное нубство какое-то...
V>>Я, наоборот, концептуально нового уже давно не вижу.
S>
==========================
Тебе не надоело, случаем, делать громкие заявления и быть выпоротым в итоге?
Зачем так орать-то громкими заявлениями?
Разумеется, новое дыхание в конце 90-х и начале 2000-х получили теории языков.
Причина была очевидной — производительность компьютеров росла экспоненциально, виделось, что IT сможет позволить себе, наконец, "излишества".
Но что характерно — в этих иследованиях были подняты нафталиновые вопросы.
Без изобретения нового.
Я когда-то уже высказывался на эти темы ~12 лет назад в ответ молодому и горячему в те года Вольфхаунду:
http://www.rsdn.org/forum/philosophy/4247637.1
С середины нулевых халява закончилась, т.к. закончился экспоненциальный рост производительности.
Вот тогда опять повернулись лицом к нейтиву (С++0x инициатива во второй половине нулевых), а все эти теории языков опять поклали под нафталин до лучших времён.
C# тоже повернулся лицом к нейтивной платформе собственного исполнения.
Потому что добро пожаловать в реальный мир.
V>Я собеседовал десятки, если не больше сотни в разные годы.
V>И тенденция слишком однозначная, чтобы это было простым совпадением на многих десятках людей.
Есть какие-то объективные данные? Без них это так — трендёж о том, как раньше девки были краше.
V>И дело не в уровне программистов, дело кое в чём катастрофическом другом — профессия воспринимается всё более обыденно, всё меньше горят глаза, всё менее ЛЮБОПЫТНО.
Угу. Я закончил школу в 1993 году. Из параллели в 50 человек в программирование пошло двое с половиной.
И сейчас успеха в программировании добивается примерно 1 из 20. То, что теперь пытаются идти в программирование 15 из 20, общей картины никак не меняет.
V>Наше поколение — это поколение исследователей, без преувеличения.
V>А с чем ты сравниваешь?
С девяностыми. Ну, и с тем, какие программы и какими программистами писались в 80х. У меня инсайд из НИИ Автоматизированных Систем — типичное учреждение промышленного программирования.
Уверяю вас: никакого "любопытства", никаких "исследователей". Совершенно простые смертные. Тётеньки, которые писали унылые программы на фортране.
V>И в насколько разные это были годы?
Лично я — с конца 90х и до сих пор.
V>Проблема примерно в следующем — увлекающийся программист осваивал материала по специальности примерно раз в 10 больше, чем давала программа ВУЗ-а.
У нас и в 100 раз можно было больше, т.к. специальности не преподавали.
V>Сейчас доля таких студентовв разы ниже, дай бог 1-2 на группу.
Их всегда и было 1-2 на группу. Если в одной группе окажется 3-4, то в другой будет 0-1.
V>И у тебя разве есть достаточная выборка по однокурсникам хотя бы до начала нулевых, чтобы сравнивать с тем, как оно есть сейчас?
Конечно есть выборка.
Ваш очередной сеанс самовосхваления я поскипаю — скучно.
V>Чел попытался присвоить себе "ошибку", которая до него была уже "сделана" эдак тысячекратно, например, тот же nil в Lisp.
Да, с самомнением у вас всё хорошо. Хоар, оказывается, тупой — сам не знает, что сделал. И то, что вы nil в lisp не отличаете от NULL в Алголе — тоже плохо.
V>Альтернатива тут возможна только через IoС, т.е. в функциональных языках, когда некоему акцессору (итератору, скажем), подаётся колбэк.
Ок, самовосхваление кончилось. Пошёл чистый, незамутнённый бред. IoC и функциональные языки соотносятся примерно никак.
Нормальная альтернатива — это собственно выразимость требования непустоты ссылки в терминах системы типов.
Колбек тут совершенно ни при чём — в нормальной системе типов у меня nullable reference отличается от non-nullable reference, и это всё статически проверяется.
Внезапно значительная часть ссылок оказывается non-nullable. А nullable reference нужны не чаще чем, скажем, Nullable<int>. Как-то же работает C# с int? безо всяких IoC и коллбеков. Удивительно, да?
V>Других техник борьбы с nil, кроме диспетчеризации на манер IoC, в природе не существует, даже в Kotlin.
(facepalm). Тут прекрасно всё — и "даже" Котлин, как вершина развития языкостроения, и применение IoC для борьбы с nil, и диспетчеризация...
Жаль, что всё современное программирование прошло мимо вас.
V>А фраза целиком лишь характеризует уже старого и недостаточно умного человека.
Забавно, что вы тут усердно опровергаете утверждение "программисты прошлого были умнее". Видите, и Хоар вам недостаточно умён. Да, я помню, для вас и Билл Гейтс недостаточно успешен
V>В молодости был умнее, мог оперировать большей размерностью условий, в которых принимал решения.
V>В точности проблема нулевых ссылок повторяется в массивах, к которым обращаются по индексу.
Эта фраза показывает, что вы не понимаете сути "проблемы нулевых ссылок".
V>И чего ж старик не упомянул эту проблему, хотя проблема в точности идентичная?
Надо полагать, оттого, что проблема — не в точности идентичная.
V>Это ровно один и тот же класс ошибок, вызванных одной и той же причиной — невозможностью в compile-time выразить ВСЕ требуемые ограничения из runtime.
Это какой-то очень широкий класс ошибок. Ну, то есть понятно, что в общем случае проблема — ровно в том, что статическое доказательство корректности произвольной программы сводится к проблеме останова, которая неразрешима.
Но нормальному инженеру недостаточно такого общего доказательства, поэтому мы вводим разные виды и классы ошибок, с которыми и боремся.
В частности, "проблема" нулевой ссылки легко статически разрешима на более-менее любой современной платформе. Даже настольные языки, собранные на коленке энтузиастами, прекрасно обходятся без нулевых ссылок.
Кстати, вопросы индексов в массивах давно закрыты: https://www.cs.cmu.edu/~fp/papers/pldi98dml.pdf. Так то про "невозможность в компайл-тайм" — это лично ваши заблуждения. Развивайтесь, читайте.
V>(в языках, которые претендуют на хоть какую-то эффективность)
Эта фраза тоже выдаёт непонимание сути проблемы. Как раз неэффективное решение проблемы и состоит в переносе проверок в ран-тайм.
Любое компайл-тайм решение получается более эффективным, как только время ожидаемой работы программы становится достаточно большим.
V>И до изобретения исключений, без техники IoC, т.е. без функциональных ср-в в языке, ошибок такого рода в процедурных языках избежать было нельзя, можно было лишь сгенерировать проверочный код компилятором (или использовать какой-нить другой трюк, например как обращение к NULL как к невалидной области памяти, как оно специально сейчас организуется в мейнстримовых архитектурах с защищённой памятью, через аппаратное инициирование исключительной ситуации) и аварийно завершить программу, если проверка на индекс или nil была неудачной. Аналогично некоторые адерс-санитайзеры обкладывают массивы незакоммиченной памятью, чтобы иметь возможность уловить "промахи". Но там улавливание только в рамках этих отступов, т.е. всё-равно ничего не гарантируется, можно "промахнуться" уже на следующую валидную область памяти.
И опять вы складываете в одну кучу рантайм и компайл-тайм проверки. Это вы мухлюете или вправду не видите разницы?
V>Даже если критикуешь себя.
V>Наверно, Хоар еще не совсем выжил из ума, раз не озвучивает альтернативу, потому что альтернатива была проста:
V>- их доработка Алгола вышла бы УГ, была бы отдвинута конкурирующими более вменяемыми языками, а Хоар заслужил бы себе реноме дурачка, который обращает в г-но всё, что попадает к нему в руки.
V>Ты же на голубом глазу рассуждаешь о том, что ради "идейной чистоты" со всем этим можно было бы подождать примерно 30 лет, до эпохи, когда начался резкий рост производительности компьютеров.
Какие ещё 30 лет? Все нужные решения были известны уже тогда, в 60х.
V>ЧТД, еще более слабый пример.
V>Да и при чём тут Java, это надо совсем не разбираться в вопросе. ))
Вижу, что вы совсем не разбираетесь. Зря — потратьте 15 минут, разберитесь в вопросе. Поможет стать лучшим специалистом.
V>Это АПИ потоков современных ОС, Java лишь даёт доступ к этому АПИ, как и ко многому другому АПИ.
Уже не даёт. В том-то и дело — оказалось, что прямой доступ к такому АПИ сильно мешает писать корректные Java-программы.
V>В деле разработки языков вклад Хоара скромен и мне на эту часть его деятельности несколько пофик.
)
V>Хоар внёс заметный вклад в анализ и выработку решений, лежащих в основе современных многозадачных ОС.
А ещё — в верификацию корректности программ. Поэтому когда Тони говорит о проблемах в системе типов Алгола, он понимает, о чём говорит.
V>Синклер, ты всё-таки определись, ты демагог или ты просто неисправимый нуб?
Ну вот, дошли и до перехода на личности. Не умеете вы всё-таки обсуждения вести.
V>Когда разрабатывались эти классы (в среде, где всё выделяется из кучи), вменяемого escape-анализа не существовало.
V>Поэтому решение было единственно верным.
Зачем вы пишете чушь? Не было оно ни единственным, ни верным. Escape-анализ здесь совершенно точно ни при чём.
Я же вам русским по белому написал: в новом стандарте нагрузка на GC меньше, чем в старом — независимо от наличия escape-анализа.
Если непонятно, почему — не стесняйтесь, спрашивайте. Если уж вам трудно на английском пару страничек прочитать и выводы сделать — я могу и перевести, и объяснить.
V>Судя даже по этому обсуждению — без способностей в нашей области некоторым непросто.
V>Ты уже показываешь что плаваешь совсем в азах взаимодействия управляемого и нейтивного кода.
И взаимодействие управляемого и нейтивного кода тут строго ни при чём. Я уже вообще начинаю сомневаться, что вы понимаете семантику Java.
V>Хотя, по переписке оно проще, конечно, водить окружающих за нос.
Это вам так кажется. Вот, к примеру, вам постоянно кажется, что вы по переписке поражаете всех своей широтой кругозора и глубиной знаний.
А на практике большинство читателей от этих ваших прогонов ржёт молча или в голос. Увы.
V>Код работает так, как написано в документации, а не как ожидают те, кто сам себе чего-то надумал.
(facepalm).
V>Ты забыл еще time series, и целое семейство вероятностных, как надстройки над иерархическими индексами (не обязательно B-trees, бо сами B-trees лишь вырожденный случай из своего класса).
Да, забыл. Поделитесь ссылкой, для освежения памяти?
V>Не вижу ничего нового.
V>Вижу попытку сочетаний уже имеющихся подходов.
Скорее всего, вы просто не поняли сути подхода.
S>>плюс значительная компактность
V>Но я не вижу изобретённого способа компактификации.
Это нормально. Вы, помнится, и в статье про оптимизации блокировок для MySQL блуждали в десятке строк псевдокода.
V>Где формула изобретения?
Я же ссылку дал. Читайте. Если непонятно — спрашивайте. Хотя рядом уже даже ссылку на видеолекцию дали, где всё разжёвано максимально понятно, но за 90 минут.
V>Собсно, любые n-tree выразимы через b-tree, но решают недостатки b-tree по оверхеду служебной памяти, по локальности данных и т.д.
Простите моё невежество, а что такое n-tree? И как именно они недостатки B-tree по оверхеду решают?
Или вы B-tree принимаете за бинарные деревья?
В любом случае:
Это к вопросу о "компактификации".
V>Ты бы не мог впредь не засорять эфир, где тусуются опытные инженерами, всякой наивной мутью от учащихся?
Воинствующее невежество, как оно есть. Увы.
>Просто ты живешь в параллельной Вселенной.
V>Первые примитивнейшые СУБД появились в начале 80-х.
О, ещё порция булшита.
V>А первые вменяемые — к 89-му, а на самом деле в 92-м, после исправления детских ошибок.
V>И там до перебора комбинаторики всевозможных видов индексов еще столько вопросов решить надо было, особенно в плане ХРАНЕНИЯ данных и сопротивляющихся их целостности дисковых операционных систем — у-у-у...
V>Т.е. этот вопрос был даже не десятый.
Вот зачем, зачем вы корчите из себя идиота, пытаясь лезть в области, в которых ничего не знаете?
Удивительная ведь вещь — только я с вами СУБД обсуждаю прямо тут уже лет десять, не меньше. Можно за это время было с нуля всю эту область выучить на уровень эксперта. В профиле у вас с какого-то хрена специализация по MS SQL указана. Нет — упорствуете в невежестве.
Домашнее задание — подготовить ответы на следующие вопросы:
1. В каком году была разработана СУБД IMS?
2. В каком году была разработана СУБД Ingres?
3. В каком году была разработана СУБД System R?
4. С какого года в СУБД применяются B-Tree индексы?
5. В каком году была опубликована первая коммерческая реализация bitmap индексов?
V>Плюс сама эта проблематика не стояла, бо она начинает вовсю стоять на больших объемах данных, а их тогда физически не существовало.
Феерия. Вот прямо жжоте.
V>И вот ты заламываешь руки, что в 60-х годах на несуществующих тогда СУБД (сама теория в 70-х только-только начала прорабатываться) не решали задачи эфффективного индексирования чудовищных размеров данных, пригодных к обработке, хранящихся на хранителях, которых требуемых размеров на тот момент тоже физически не существовало.
Да конечно же решали. Ответ на вопрос 4 найдёте — узнаете, как оно обстояло на самом деле, а не в вашей вымышленной вселенной. Достаточно название статьи прочитать и устыдиться.
V>Тебе не надоело, случаем, делать громкие заявления и быть выпоротым в итоге?
Ах если бы. Всё же ровно наоборот — вы чем больше пишете, тем больше в лужу садитесь.
V>Разумеется, новое дыхание в конце 90-х и начале 2000-х получили теории языков.
Вот как раз тут прямо таки нового появилось не очень много.
V>Без изобретения нового.
Воот! В основном то, что мы наблюдаем — приезд в мейнстрим идей и концепций из 1960х. Так что "теории языков" вычёркиваем.
V>Я когда-то уже высказывался на эти темы ~12 лет назад в ответ молодому и горячему в те года Вольфхануду:
V>http://www.rsdn.org/forum/philosophy/4247637.1
Ну, так и зачем самому себе противоречить?
V>>Я собеседовал десятки, если не больше сотни в разные годы.
V>>И тенденция слишком однозначная, чтобы это было простым совпадением на многих десятках людей.
S>Есть какие-то объективные данные?
Уровень владения технологиями, технический кругозор.
В общем, всё, что можно выяснить на собеседовании.
S>Без них это так — трендёж о том, как раньше девки были краше.
Трындёж — это не иметь возможности сравнить претендентов из разных эпох, но делать заявления.
V>>И дело не в уровне программистов, дело кое в чём катастрофическом другом — профессия воспринимается всё более обыденно, всё меньше горят глаза, всё менее ЛЮБОПЫТНО.
S>
S>Угу. Я закончил школу в 1993 году. Из параллели в 50 человек в программирование пошло двое с половиной.
Наверно потому что им было интересно и до ВУЗ-а.
S>И сейчас успеха в программировании добивается примерно 1 из 20.
Верно, сейчас вменяемых 1-2 человека из выпускаемой группы ВУЗ-а в 20+ человек.
Я так и говорил, а ты споришь.
Зато у нас из группы примерно треть достаточно успешны, т.е. примерно как эти 1-2 сегодня.
И так же из других групп в потоке и еще на 2-х родственных специальностях.
S>То, что теперь пытаются идти в программирование 15 из 20, общей картины никак не меняет.
Никто не говорил о том, что сейчас в IT стало меньше грамотных людей.
Говорят, что их доля резко упала.
Т.е. резко упала средняя температура по больнице.
А так-то вероятнее всего обратное, грамотных в абсолютном выражении могло стать больше из-за того, что в IT стали идти "все подряд" (по крайней мере у нас, в экс-СССР), т.е. вполне могут "раскрываться" как специалисты те люди, которые в 90-х не пошли бы учиться на программиста.
А сейчас пошли и у них всё стало получаться, "загорелись" профессией и всё в этом роде.
Но это всё неспособно компенсировать всё более возрастающий поток "балласта".
И этот "балласт" уже давно и серьёзно влияет на индустрию.
Разговоры про "планку входа" у нас шли вовсю шли уже в первой половине нулевых.
Я не могу себе представить эти разговоры в твоём 93-м, потому что за пределами требуемой на тот момент "планки входа" этих людей просто не было в профессии — они получали "корочку", но занимались другой деятельностью.
V>>А с чем ты сравниваешь?
S>С девяностыми.
Ты не ответил на вопрос.
Ты ж учился не на IT, откуда у тебя статистика по однокурсникам, учившимся на IT?
S>Ну, и с тем, какие программы и какими программистами писались в 80х.
Отож, 90% нынеших программистов принципиально неспособны писать те программы.
Думаю, конкретно ты был бы способен, но тебе пришлось бы многое пересмотреть из нынешних своих представлений.
Ну и прокачать некоторые навыки, например, внимательность и объективность.
S>У меня инсайд из НИИ Автоматизированных Систем — типичное учреждение промышленного программирования.
S>Уверяю вас: никакого "любопытства", никаких "исследователей". Совершенно простые смертные. Тётеньки, которые писали унылые программы на фортране.
И они получают свои 5-10 тыс $$ в месяц, поэтому сидят там? ))
Или там остались только те, кто не способен столько получать?
V>>И в насколько разные это были годы?
S>Лично я — с конца 90х и до сих пор.
Лично я обратил внимание на проблему уже в 2002-м году на собеседованиях.
Заметным потоком пошли претенденты из разряда "да вы издеваетесь!", пока не понял, что это такая новая реальность.
В моё время подобные ребята даже не рыпались.
А тут нагло ходят на собеседования.
Я не могу представить себе подобное в других областях, где требуются определённые непростые навыки.
Например, придти устраиваться танцором в балет, но растяжки нет, классика хромает, прыгучесть нулевая...
Решат, что чел просто прикалывается. ))
В общем, подобного уровня "программисты" из выпускников нашей группы программистами работать так и не стали, нашли себя в другом.
А сейчас аналогичные ребята уверены, что хоть где-то их возьмут, бо дефицит и всё в этом роде.
V>>Проблема примерно в следующем — увлекающийся программист осваивал материала по специальности примерно раз в 10 больше, чем давала программа ВУЗ-а.
S>У нас и в 100 раз можно было больше, т.к. специальности не преподавали.
V>>Сейчас доля таких студентовв разы ниже, дай бог 1-2 на группу.
S>Их всегда и было 1-2 на группу.
Это в твоей непрофильной специальности из группы 1-2 любопытсвовали в IT, оттуда статистика? ))
Вообще странно, что ты сразу не пошёл на интересующую тебя специальность.
S>Если в одной группе окажется 3-4, то в другой будет 0-1.
На IT-специальностях так не было, разумеется.
Специальность была нифига не престижная, туда люди обычно знали, зачем шли.
За вычетом буквально нескольких, которые непонятно как в этой специальности оказались.
Мне проще вспомнить тех, кому специальность была не интересна и кто к окончанию ВУЗ-а был от неё далёк, чем наоборот.
В нашей группе было "совсем сильных" 5 человек и еще десяток с лишним достаточно вменяемых, включая двух девушек.
Когда искал себе людей на проект когда-то (нужно было достаточно много людей), то расчитывал хотя бы на вменяемых.
Что касается девочек — им системное программирование даётся объективно тяжелей, но многие грамотные девочки нашли себя в прикладном направлении, в 1C, и неплохо себя чувствуют.
Из одногруппниц — руководитель отдела 1С крупного поставщика решений, еще одна владелица-руководитель собственного такого предприятия помельче.
V>>И у тебя разве есть достаточная выборка по однокурсникам хотя бы до начала нулевых, чтобы сравнивать с тем, как оно есть сейчас?
S>Конечно есть выборка.
Та не мог твой ВУЗ быть совсем отсталым, даже в пик развала в 93-м.
Просто у тебя выборка по непрофильной специальности.
V>>Чел попытался присвоить себе "ошибку", которая до него была уже "сделана" эдак тысячекратно, например, тот же nil в Lisp.
S>Да, с самомнением у вас всё хорошо. Хоар, оказывается, тупой — сам не знает, что сделал. И то, что вы nil в lisp не отличаете от NULL в Алголе — тоже плохо.
Оба на!
Пошёл юмор! ))
В Lisp и Algol абсолютно идентичные nil, никакого NULL в Algol нет, RTFM!
И распространённой практикой в те годы были списки на манер лисповых — cons/car-cdr.
Защита от nil всегда через проверки, что в Lisp, что в Algol, безальтернативно.
Далее.
Lisp не в вакууме жил, решал в т.ч. реальные задачи.
В том числе обращался к низлежащим АПИ и точно так же мог спровоцировать проходы по памяти.
Абсолютно идентично это было и в Algol.
Ответственность по-прежнему лежала на программисте — проверил ли он аргументы перед вызовом низлежащих опасных вызовов или нет.
Разумеется, идущие в поставке стандартные библиотеки обоих языков проверяли аргументы, в т.ч. на nil, т.е. были безопасны как в Lisp, так и в Algol, но речь не о стандартных библиотеках, верно?
Речь о пространстве допустимых ошибок.
В Лиспе вообще много чего проверять надо было, чтобы программа не улетела не туда в своём исполнении. ))
Таки, сильно динамический язык.
Ну и, тот же Лисп и им подобные языки тоже на чём-то писать надо — не всё же на асме?
Просто Хоар реально загоняет, я же приводил выдержки:
Ну какая еще Windows, хосподя...
Это из DOS.
А там из CP-M.
В 70-х годах Хоар об этом знал хорошо, но сейчас забыл, увы, поэтому несёт тихий бред.
Как думаешь, какой чертой пользовался сам Хоар приличную часть своей карьеры еще до всяких Windows? ))
V>>Альтернатива тут возможна только через IoС, т.е. в функциональных языках, когда некоему акцессору (итератору, скажем), подаётся колбэк.
S>Ок, самовосхваление кончилось. Пошёл чистый, незамутнённый бред. IoC и функциональные языки соотносятся примерно никак.
Оба на, юмор продолжается! ))
В общем, функциональные языки целиком на парадигме IoC живут.
Прямо начиная с Lisp.
Сам термин IoC из объектно-ориентированной среды, я его использовал сугубо удобства ради.
В Алгол68 ф-ии тоже поддерживаются как первоклассные типы, если что.
S>Нормальная альтернатива — это собственно выразимость требования непустоты ссылки в терминах системы типов.
Я тебе заранее на это уже отвечал — смотри как это обыгрывается в функциональных языках или в том же Kotlin, т.е. в языках, где присутствуют исключения.
В той версии Алгола не было исключений и не было первоклассных ф-ий.
Он появились в Алгол68.
Поэтому — никак от слова совсем.
В общем, ты сначала прикинь хотя бы минимально, как всё это обыграть для решения реальных задач.
Далее.
Если в языке есть возможность описывать пользовательские типы, выбрасывать и перехватывать исключения, переопределять операторы и вводить алиасы типов (как typedef в С/С++), то проблема упрощается.
У нас прямо в боевых проектах на С++ из базовой нашей библиотеки используется:
Реализация NotNull тривиальна в единицы строк, а используется широко:
S>Колбек тут совершенно ни при чём — в нормальной системе типов у меня nullable reference отличается от non-nullable reference, и это всё статически проверяется.
Это, как раз, самая простая часть, не вызывающая сложностей.
У меня выше тоже SomeTypeRef статически отличается от SomeType*.
И никаких дополнительных фич языка не потребовалось.
А теперь давай про интероперабельность nullable и non-nullable типов.
Вот проверь статически Optional<T*> без IoC или исключений. ))
В Хаскеле возможен только IoC вариант, т.е. рантайм-диспетчеризация как в последней строчке:
Да, до некоторого предела вложенности компилятор при оптимизации производит распространение констант, поэтому часто рантайм-диспетчеризация заменяется на прямо вызов, но в современных С++ эта оптимизация куда глубже/качественней, так шта мой С++ вариант будет соптимизирован лучше.
S>Внезапно значительная часть ссылок оказывается non-nullable.
Какое открытие! ))
S>А nullable reference нужны не чаще чем, скажем, Nullable<int>. Как-то же работает C# с int? безо всяких IoC и коллбеков. Удивительно, да?
Не работает, RTFM! ))
Выбрасывает исключения.
V>>Других техник борьбы с nil, кроме диспетчеризации на манер IoC, в природе не существует, даже в Kotlin.
S>(facepalm). Тут прекрасно всё — и "даже" Котлин, как вершина развития языкостроения, и применение IoC для борьбы с nil, и диспетчеризация...
S>Жаль, что всё современное программирование прошло мимо вас.
Жаль, что мы в разных весовых категориях по этому вопросу, я даже качественно надо тобой поизмываться не смогу в ответ на подобное хамство, бо ты даже не поймёшь сути измывательств.
ОК, дай мне пример языка, которым ты владеешь хотя бы на самом начальном уровне, где есть строгая первоклассная поддержка non-nullable ссылок.
Скорее всего, у тебя в копилке ни одного такого языка нет.
Но очередное громкое заявление про "современное программирование" было! ))
В общем, такие языки есть, но их нет в мейнстриме.
Более того, многие из них достаточно старые.
В общем, RTFM! как эту проблему решают языки, которые обладают требуемым свойством.
И да, в Kotlin всё хорошо именно в этом аспекте (не берусь обсуждать другие "достоинства" языка), т.е. там не хуже, чем в других языках, которые нельзя отнести, скажем, к чисто функциональным, т.е. где нет поддержки исключений.
Посмотри, например, языки, со встроенной поддержкой зависимых типов, как там обыгрывают подобные сценарии.
V>>А фраза целиком лишь характеризует уже старого и недостаточно умного человека.
S>Забавно, что вы тут усердно опровергаете утверждение "программисты прошлого были умнее".
Хоар и был умнее.
Человеку почти 90 лет, тут не стоит манипулировать/спекулировать.
S>Видите, и Хоар вам недостаточно умён.
1. Один из распространённых приёмов демагогии.
2. Я ответил на эти спекуляции заране, зная тебя. Увы, не помогло. ))
Я уверен, что стоит тебе только начать копать проблематику первоклассной поддержки non-null ссылок в языках, и тебе станет мучительно стыдно за вопросы про диспетчеризацию или про обязательную поддержку исключений как альтернативу явной или неявной (как в Хаскель) диспетчеризации.
(Хотя, поддержка исключений — это тоже своего рода неявная диспетчеризация, бгг...)
S>Да, я помню, для вас и Билл Гейтс недостаточно успешен
Цитату или балабол.
Там ты мне это приписывал, помнится, примерно как здесь приписываешь, что я считаю Хоара глупым.
Я считаю высказывания постаревшего Хоара глупыми, и они, действительно, глупы, чего только стоит сравнение с косой чертой.
А когда он принимал те или иные решения, он был в расцвете своих способностей, принимал эти решения куда как осмысленней.
V>>В точности проблема нулевых ссылок повторяется в массивах, к которым обращаются по индексу.
S>Эта фраза показывает, что вы не понимаете сути "проблемы нулевых ссылок".
Да нет, эта фраза показывает, что ты не понимаешь зависимых типов.
Проблема же не только в null, ссылка вообще может ссылаться на мусор в памяти.
Т.е. простая проверка на не null не решает вопрос окончательно.
В языках с зависимыми типами индекс не может вылезти за пределы массива никак, прямо на уровне типов.
Точно так же, как ненулевая ссылка не может принять нулевое значение.
Ссылка вообще не может принять невалидное значение.
V>>И чего ж старик не упомянул эту проблему, хотя проблема в точности идентичная?
S>Надо полагать, оттого, что проблема — не в точности идентичная.
V>>Это ровно один и тот же класс ошибок, вызванных одной и той же причиной — невозможностью в compile-time выразить ВСЕ требуемые ограничения из runtime.
S>Это какой-то очень широкий класс ошибок.
Уфф...
Адрес — это индекс ячейки памяти.
Проблема невалидного адреса в точности равна проблеме невалидного индекса.
И ведет к асболютно идентичным ошибкам — к неверной реентерпретации памяти.
Я тебе в C# запросто создам управляемую ссылку на мусор в памяти (произвольный адрес, не обязательно null).
И никакое #nullable enable не спасёт.
Да и оно сейчас пока живёт как ворнинги.
И запросто обходится через !, без рантайм-проверок.
Это ты вот это всё имел ввиду под "современным программированием"? ))
В общем, в языках с зависимыми типами нет принципиальной разницы на допустимые ограничения, контроллируемые системой типов, будь это [0, 1, 2] или [0, 1..]
Там работает один и тот же механизм.
Синтаксически в разных языках это может выглядеть по-разному, но по-сути происходящего — идентично.
Опять же, зависит от наличия или нет исключений в языке!
Например, в языках с зависимыми типами без исключений может применяться flow control,
т.е., некий uint[0..MAX_UINT] может быть приведёт к ограниченному типу uint[0..10] через простой if:
S>Ну, то есть понятно, что в общем случае проблема — ровно в том, что статическое доказательство корректности произвольной программы сводится к проблеме останова, которая неразрешима.
Про произвольную программу речи не идёт, речь идёт об одном аспекте — о программировании в ограничениях на уровне системы типов.
Эти ограничения не дают неверно интерпретировать память.
Программа может содержать ошибки и при верной интерпретации памяти, но эти ошибки проще искать и они не столь непредсказуемы в своих проявлениях.
Плюс не оставляют простора для хакерских атак.
Далее.
Способ выражения ограничений в языке в свою очередь накладывают ограничения на дизайн программы.
Например, во многих языках с зависимыми типами ты не можешь прочитать массив данных из файла и передать его куда-то дальше, примерно так (псевдокод):
Ты можешь действовать только через IoC:
Т.е., с т.з. "обычных" языков, имеющих генерики/шаблоны, каждый вызов loop не является рекурсией, т.к. вызывается ф-ия другого типа.
Но для зависимых типов это обычная рекурсия, которая в случае хвостовой раскручивается компилятором в цикл.
S>Но нормальному инженеру недостаточно такого общего доказательства, поэтому мы вводим разные виды и классы ошибок, с которыми и боремся.
Давай не будем о нормальности.
Теория зависимых типов была разработана не с 0-ля в 70-е, а первые работы на эту тему были еще в 1925-м, задолго до первых компьютеров.
Не надо считать всех идиотами. ))
Речь тут не о теоретических вещах, бо с теорией давно всё хорошо, а сугубо об инженерных — о реализуемости, стоимости, практичности.
S>В частности, "проблема" нулевой ссылки легко статически разрешима на более-менее любой современной платформе.
Если ты про C#, то анекдот хороший.
S>Даже настольные языки, собранные на коленке энтузиастами, прекрасно обходятся без нулевых ссылок.
Фортран тоже обходился без нулевых ссылок.
Да и вообще любые языки, где явное оперирование динамическими структурами невозможно. ))
А этих структур огромное кол-во, всё их разнообразия в виде встроенных типов данных не предусмотришь, поэтому большинство таких наколенных "безопасных" языков имеют один тип динамических данных — связанный список. ))
В общем, интерес предоставляют не наколенные языки, а те, которые позволяют экспериментировать с произвольным лейаутом динамических данных в памяти с типизированной гарантией безопасности обращения к данным.
Т.е., неверно обращающаяся к данным программа не должна уметь компиллироваться.
S>Кстати, вопросы индексов в массивах давно закрыты: https://www.cs.cmu.edu/~fp/papers/pldi98dml.pdf. Так то про "невозможность в компайл-тайм" — это лично ваши заблуждения. Развивайтесь, читайте.
— Ты куда, в баню?
— Да нет, в баню!
И зачем ты даёшь столь неинформативную статью со столь бедными примерами, если есть полно отличных статей, описывающих проблематику и способы их решения, а так же ограничения на конструкты, которые допускают "распространение" типизированности по данным?
В т.ч. на русском.
Это тебе первая ссылка на англоязычном гугле подкинула и ты не читая кинул, чтобы поднадуть щеки?
И статью ты ниасилил, иначе бы не сверкал невежеством тут:
А теперь правильный ответ:
— вопрос не то, что еще не закрыт, а даже не планируется быть закрытым в мейнстриме в ближайший десяток-другой лет.
Ты обратил по ссылке внимание на сам принцип написания программ?
Это другой принцип проектирования.
Показан один из беднейших инструментов реализации ЗТ — хвостовая рекурсия, каждый раз вызывается локальная ламбда с новым типом аргументов.
И вот как раз конечный результат вычислений можено будет подать куда-нибудь далее в вычислениях поданному как аргумент функциональному объекту, потому-то и IoC, что список неизвестного размера нельзя вернуть из ф-ии. ))
Можно только вызывать другую ф-ию в типизированном контексте.
V>>(в языках, которые претендуют на хоть какую-то эффективность)
S>Эта фраза тоже выдаёт непонимание сути проблемы. Как раз неэффективное решение проблемы и состоит в переносе проверок в ран-тайм.
Проверки в рантайм всё-равно есть, вопрос в том — сколько их.
Ведь достаточно проверить один раз (или достоверно получить валидное значение по new) и далее распространять значение уже с признаком валидности.
Насчёт "непонимания сути" — опять улыбнуло.
Это ты в своём C# не понимаешь сути, потому что нет алиасов типов, невозможно отсутствие конструктора структуры без параметров.
Поэтому ср-вами языка проблему не решить — нужен встроенный костыль.
А я тебе выше показал примеры на C++, которую столь узкую постановку вопроса решают на раз-два.
Причём, с нулевым оверхедом, в сравнении с обычными указателями.
И без переделки исходников, т.к. Optional<T*> и NotNull<T> — это умные указатели, с переопределёнными operator-> и operator*, т.е. их можно использовать там, где ожидался обычный указатель, только теперь можно распространять non-nullable указатели без лишних проверок.
S>Любое компайл-тайм решение получается более эффективным, как только время ожидаемой работы программы становится достаточно большим.
Увы, увы.
Программы, написанные в этом стиле, как по ссылке, построены таким образом, что в функции всегда передаются другие функции-"продолжения".
Т.е. вся работа основной программы — это бесконечный вызов ф-ий из ф-ий.
Но стек ведь не бесконечен? Отсюда монады и ленивость.
То бишь, "энергичный" вызов ф-ий заменяется динамически выстроенным графом продолжений, где вычисления передаются динамически же вычисленным в процессе работы программы веткам графа через явные if или неявную дистептчеризацию, на манер Хаскеля.
То бишь, никакого call не происходит, вычислительная модель языка в ленивой манере протягивает монаду процесса/потока по этому графу вычислений.
То бишь, вычисления выглядят в рантайме так:
func1 -> result1 -> func2 -> result2 -> func3 -> ...
И до чудес быстродействия там как до звёзд.
V>>И до изобретения исключений, без техники IoC, т.е. без функциональных ср-в в языке, ошибок такого рода в процедурных языках избежать было нельзя, можно было лишь сгенерировать проверочный код компилятором (...) и аварийно завершить программу, если проверка на индекс или nil была неудачной.
S>И опять вы складываете в одну кучу рантайм и компайл-тайм проверки. Это вы мухлюете или вправду не видите разницы?
Это ты не понял прочитанного. ))
Медитируй до просветления, плиз.
V>>Разумеется, новое дыхание в конце 90-х и начале 2000-х получили теории языков.
S>Вот как раз тут прямо таки нового появилось не очень много.
V>>Без изобретения нового.
S>Воот! В основном то, что мы наблюдаем — приезд в мейнстрим идей и концепций из 1960х. Так что "теории языков" вычёркиваем.
В 70-х только начали классифицировать типизированные лямбда-исчисления.
Классификация была нужна для понимания (1) необходимого и достаточного набора конструктов языка для соответствия выранным критериям и (2) для понимания необходимых техник программирования в данном классе ограничений, см лямбда куб (наглядное представление классификации).
В 60-х еще вопрос так не стоял, т.к. выразительные ср-ва компилятора диктовались сугубо объемом оперативной памяти, которой располагал компилятор в процессе своей работы.
Ну и, в 60-х годах, таки, разработкой языков занимались математики, поэтому языки те были полны в рамках выбранных концепций, в отличие от наколенных языков от энтузиастов сегодня.
Сегодняшние столь же "академические" языки в мейнстриме — это Golang, Dart, Хаскель.
И то, мейнстрим весьма условный. ))
F# (OCaml), Scala, Kotlin — уже нет.
C# — совсем нет.
В рамках выбранной концепции он далеко не полон, не обладает всеми необходимыми выразительными св-вами.
Собсно, поэтому развитие языка запросто идёт дальше при сохранении бинарного формата сборок еще аж со времён 2-го дотнета.
Блин, указатели на ф-ии только-только ввели.
Через stackalloc стало можно размещать не только примитивные целочисленные типы вот только недавно.
И т.д. и т.п.
V>>Я когда-то уже высказывался на эти темы ~12 лет назад в ответ молодому и горячему в те года Вольфхануду:
V>>http://www.rsdn.org/forum/philosophy/4247637.1
S>Ну, так и зачем самому себе противоречить?
Нет никакого противоречия.
Действительно, было повышенное внимание к теории языков, т.к. была надежда в продвижении статического анализа программ, что необходимо для эффективной компиляции языков с ленивой вычислительной моделью.
Т.е., одно дело понятно в теории, другое дело практическое воплощение.
В экспериментах над "окончательной оптимизацией" (как оно достижимо в теории) не самых больших программ работали суперкомпьютеры часами.
Как тебе задача — выделить из данной цепочки символов всевозможные подцепочки максимальной длины, встречающиеся более одного раза.
Оцени сложность в терминах O.
Умножь на многие мегабайты размеров современных программ.
Это всего лишь одна из подзадач в процессе оптимизации — склейка самоповторов после стирания типов на одной из стадий оптимизации.
Сначала над типами работает бета-редукция и генерирование уникального кода из генерик-представления.
(А чуть ли не весь код на Хаскель — это сплошные генерики в терминах C#)
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 или исключений. ))
Охтыж боже мой. Ну да, на С++ по-другому никак, т.к. паттерн матчинг не завезли.
А в нормальных языках с современной системой типов мы имеем
Никакого IoC тут нет, как нет и никаких функций для вызова.
V>В Хаскеле возможен только IoC вариант, т.е. рантайм-диспетчеризация как в последней строчке:
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>
Ну, всё верно. А к чему тогда все разговоры о какой-то невозможности?
Там же даже проверок значения 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#)
V>Например, в языках с зависимыми типами без исключений может применяться flow control,
V>т.е., некий uint[0..MAX_UINT] может быть приведёт к ограниченному типу uint[0..10] через простой if:
V>
Это все конечно здорово, но не в учебных задачах, а на практике чаще нужно работать примерно так:
И идут все эти зависимые типы лесом в этом случае и остается просто проверка в рантайме, что x<n
S>Прекрасная штука — все преимущества B-tree (range queries, nearest search), плюс значительная компактность (а, значит, меньше io-нагрузка, более высокий cache hit ratio, и все вытекающие).
S>Был ли возможен такой индекс в 1963? Да, конечно.
Не могли. Через познание и опыт перешагнуть невозможно.
B-tree, насколько помню, придумали только в 1971 году.
После чего и пошло развитие БД.
S>>Ан нет — апрель 2020, PGM-index.
S>>Прекрасная штука — все преимущества B-tree (range queries, nearest search), плюс значительная компактность (а, значит, меньше io-нагрузка, более высокий cache hit ratio, и все вытекающие).
S>>Был ли возможен такой индекс в 1963? Да, конечно.
LVV>Не могли. Через познание и опыт перешагнуть невозможно.
LVV>B-tree, насколько помню, придумали только в 1971 году.
LVV>После чего и пошло развитие БД.
Развитие БД началось немножко раньше. Программисты прошлого, хоть и не были шибко умнее нонешних, но и не тупее нас. Поэтому задача по разработке систем и стандартов по обработке данных (независимо от конкретных прикладных программ) была поставлена примерно в конце 50х. Помните такой Комитет по Языку Систем Данных, он же CODASYL? Создан в 1959 году. Кобол с самого начала проектировался не как язык общего назначения в современном понимании, а как язык для обработки данных. К середине шестидесятых работу над языком и моделью данных разделили по подкомитетам. К 1969 ребятушки опубликовали первую публичную версию стандарта CODASYL Data Model.
Примерно в те же времена появились первые промышленные СУБД. Например, IDS вышла в 1963 году.
Авторство B-tree приписывают Байеру с МакКреем — черновик статьи был готов (и доступен) в 1970м, опубликован в 1972.
Но есть свидетельства того, что аналогичные решения применялись в СУБД ещё в шестидесятых, просто их авторы не затруднили себя публикацией статей и формальными математическими доказательствами асимптотики.
И всё-таки — между 1970 и 2020 прошло 50 лет. И проблема индексации данных была актуальна все эти годы, а не внезапно возникла в 21 вее.
В PGM нет никакой математики, которой не существовало в шестидесятых. Поэтому теоретически — могли придумать уже тогда.
А вот то, что через познание и опыт перешагнуть невозможно — это в чём-то верно.
Нужно было придумать решения задач; попробовать их на практике; столкнуться с новыми вызовами (не все из которых были очевидны на момент изобретения тогдашних решений), придумать новые решения, и так далее.
Поэтому современные программисты продолжают придумывать вполне себе новые и интересные вещи, опираясь как на дедовские наработки, так и на отцовский опыт. Нормально всё.
У мееня даже была эта книжка в русском переводе.
Оттуда я почерпнул знание о 3 моделях данных того времени.
S>Примерно в те же времена появились первые промышленные СУБД. Например, IDS вышла в 1963 году.
Ну, я с БД впервые столкнулся на СМ1420 — adabas.
S>И всё-таки — между 1970 и 2020 прошло 50 лет. И проблема индексации данных была актуальна все эти годы, а не внезапно возникла в 21 вее.
S>В PGM нет никакой математики, которой не существовало в шестидесятых. Поэтому теоретически — могли придумать уже тогда.
Для практики, наверное, не очень было нужно — не было таких объемов, как сейчас.
Вот особо и не парились.
Это как с нейронками — можностя не позволяли.
А когда стали позволять — резкий рывок
S>Нормально всё.
Да, все идет свои чередом
LVV>У мееня даже была эта книжка в русском переводе.
LVV>Оттуда я почерпнул знание о 3 моделях данных того времени.
LVV>Для практики, наверное, не очень было нужно — не было таких объемов, как сейчас.
Вы совершаете ту же ошибку, что и vdimas. Дело не в объёмах, как таковых, а в соотношении объёмов данных и объёмов RAM.
LVV>Вот особо и не парились.
Как это "не парились"??? Вопросы индексации в СУБД привлекали огромное внимание.
Ещё раз прочитайте название статьи Байера и Маккрея — то есть и данные были, и потребность была, и статьи писали.
Та же IBM из своей System R сделала вообще тестовый полигон для всяких индексов. Я в своё время, лет 20 тому, когда пошёл в аспирантуру, накачал несколько десятков статей про всякие префиксные компрессии в текстовых Bx-индексах, про delta encoding для значений ключей — и так далее. Потом, правда, аспирантуру бросил и все эти материалы выкинул.
LVV>Это как с нейронками — можностя не позволяли.
Позволю себе процитировать ответ, который я заранее дал на эту вашу реплику:
LVV>А когда стали позволять — резкий рывок
S>>Нормально всё.
LVV>Да, все идет свои чередом
V>>Например?
S>Из самого известного — "ошибка на миллиард долларов" Тони Хоара. (К квалификации Тони вопросы есть?)
Квалификации — нет, а вот её оценке — есть.
Я считаю, что на момент принятия того самого решения — иметь null как вариант значения указателя — оно было правильно, потому что практически реализуемо. Альтернатива была просто неподъёмна с тогдашними средствами.
Главный вопрос — когда же это стало не просто подъёмно, но и необходимо. А вот это, я думаю, уже около 2000.
Пусть Хоар критикует себя тогдашнего сколько угодно, он прав в идеале, но неправ на практике. Конечно, лучше такая самокритичность, чем мания непогрешимости, но трезвый подход — ещё лучше.
V>>Концептуально нового? ))
V>>Например?
S>Ну, например, я не ожидал, что в 21 веке смогут придумать какой-то новый вид скалярных индексов для СУБД. Казалось бы — после B-trees, hash, и bitmap индексов в этой области уже ничего нового не придумать.
LSM tree забыл. Это уже ~2000, граница века.
S>Ан нет — апрель 2020, PGM-index.
Где алгоритмы обычных операций с индексами — добавление, удаление ключа? Как управлять эффективностью хранения? Или это индекс из тех, что строятся один раз для постоянного набора?
Как у него с конкурентностью? Для B-деревьев есть давно разработки с одновременным доступом из нескольких участников с адекватной синхронизацией, а тут?
S>Был ли возможен такой индекс в 1963? Да, конечно. Это не нейронки, обучение которых стало практически пригодным только после массового распространения многоядерных видеокарточек.
S>Математика в основе лежит общеизвестная, сложность алгоритмов — не выше, чем у B-tree. Просто — не додумались.
Или не был такой нужен.
N>Квалификации — нет, а вот её оценке — есть.
N>Я считаю, что на момент принятия того самого решения — иметь null как вариант значения указателя — оно было правильно, потому что практически реализуемо. Альтернатива была просто неподъёмна с тогдашними средствами.
Интересная гипотеза. В LISP, к примеру, обошлись без null, и ничего, тогдашними средствами всё поднялось.
N>Главный вопрос — когда же это стало не просто подъёмно, но и необходимо. А вот это, я думаю, уже около 2000.
Как видим, языки без нулевых указателей были подъёмны в 1960.
N>Пусть Хоар критикует себя тогдашнего сколько угодно, он прав в идеале, но неправ на практике.
Хороший ход. Ещё можно сказать, что он имел в виду совсем другое.
N>Конечно, лучше такая самокритичность, чем мания непогрешимости, но трезвый подход — ещё лучше.
Я уверен, что у Тони вполне трезвый подход.
N>LSM tree забыл. Это уже ~2000, граница века.
Да, тоже верно.
N>Где алгоритмы обычных операций с индексами — добавление, удаление ключа? Как управлять эффективностью хранения? Или это индекс из тех, что строятся один раз для постоянного набора?
N>Как у него с конкурентностью? Для B-деревьев есть давно разработки с одновременным доступом из нескольких участников с адекватной синхронизацией, а тут?
Настолько детально я не разбирался. С модификациями там всё не вполне очевидно. А вот с конкурентностью всё хорошо известно — все древовидные структуры обрабатываются одинаково.
N>Или не был такой нужен.
Эту гипотезу коллега vdimas уже высказывал. Контраргументы те же — вопросы компресии индексов интересовали разработчиков ещё в ранних 1980х. Это хорошо видно по публикациям статей.
Так что возможность уменьшить размер индекса в пару тысяч раз конечно же была востребована.
N>>Квалификации — нет, а вот её оценке — есть.
N>>Я считаю, что на момент принятия того самого решения — иметь null как вариант значения указателя — оно было правильно, потому что практически реализуемо. Альтернатива была просто неподъёмна с тогдашними средствами.
S>Интересная гипотеза. В LISP, к примеру, обошлись без null, и ничего, тогдашними средствами всё поднялось.
В LISP не обошлись без null. В LISP он есть в виде NIL. Только не надо повторять ещё и ко мне ту чушь, что, мол, NIL это "пустой список", а не пустой указатель.
Нет, как раз пустой список реализован в LISP в виде пустого указателя, и тут он ничем не отличается от какой-нибудь C-подобной реализации где struct node с struct node *next, а NULL значит, что список пуст (длины 0).
Чтобы понять это глубже, посмотри, как в LISP работает хак (A.B) для неспискового B, где его используют и почему он нежелателен для общего применения.
N>>Главный вопрос — когда же это стало не просто подъёмно, но и необходимо. А вот это, я думаю, уже около 2000.
S>Как видим, языки без нулевых указателей были подъёмны в 1960.
Как видим, твой пример не проходит. Но даже если бы это было так, то специфично функциональный язык надо рассматривать иначе, нежели процедурный.
N>>Пусть Хоар критикует себя тогдашнего сколько угодно, он прав в идеале, но неправ на практике.
S>Хороший ход. Ещё можно сказать, что он имел в виду совсем другое.
Ну с тем, кто так скажет, и дискутируй. Мне-то зачм твои ветряные мельницы?
N>>Где алгоритмы обычных операций с индексами — добавление, удаление ключа? Как управлять эффективностью хранения? Или это индекс из тех, что строятся один раз для постоянного набора?
N>>Как у него с конкурентностью? Для B-деревьев есть давно разработки с одновременным доступом из нескольких участников с адекватной синхронизацией, а тут?
S>Настолько детально я не разбирался. С модификациями там всё не вполне очевидно. А вот с конкурентностью всё хорошо известно — все древовидные структуры обрабатываются одинаково.
Точно все?
N>>Или не был такой нужен.
S> Эту гипотезу коллега vdimas уже высказывал. Контраргументы те же — вопросы компресии индексов интересовали разработчиков ещё в ранних 1980х. Это хорошо видно по публикациям статей.
S>Так что возможность уменьшить размер индекса в пару тысяч раз конечно же была востребована.
Теоретическая. Практически же тут есть непреодолимая пропасть — даже две — между 1) реализуемым в теории, 2) реализуемым на практике для константных деревьев и 3) реализуемым на практике для активно изменяемых деревьев. И что "реализуемо на практике" зависит от 100500 факторов.
То же LSM tree тоже ничто не мешало изобрести, например, в 1972 (возьмём за базу публикацию B-деревьев), он в разы проще тех же B-деревьев, но мешали аж три вещи:
1) недостаток места (чтобы индекс занимал место в 2-4 раза больше — не могли себе позволить);
2) отсутствие потребности в алгоритме для потоковой записи крупными порциями вместо одного блока;
3) проблема с организацией фоновых сжатий индекса (сейчас решается, например, через фоновые нити — а тогда надо было делать машину состояний и мириться с замираниями на сбор крупных порций).
Возможно, его тогда и изобретали кучу раз. А потом думали "и зачем эта фигня?" и забывали.
А вот ближе к 2000 начали давить тормоза позиционирования HDD, добило — появление SSD с записями порциями типа 128KB. А дисковое место на индексы стало доступно.
Вот то же самое и с потребностями при разработке языков.
S>Здравствуйте, netch80, Вы писали:
N>>Квалификации — нет, а вот её оценке — есть.
N>>Я считаю, что на момент принятия того самого решения — иметь null как вариант значения указателя — оно было правильно, потому что практически реализуемо. Альтернатива была просто неподъёмна с тогдашними средствами.
S>Интересная гипотеза. В LISP, к примеру, обошлись без null, и ничего, тогдашними средствами всё поднялось.
А что имеется в виду под неподъемностью без null в ЯП того времени? Доп. анализ от компилятора?
S>А что имеется в виду под неподъемностью без null в ЯП того времени? Доп. анализ от компилятора?
Это не ко мне вопрос, а к netch80.
Хоар считает, что уже в ALGOL W можно было обойтись без константы NULL. Пришлось бы для каких-то случаев реализовывать паттерн null objeсt, но уже при системе типов ALGOL W это означало возможность описания non-nullable types, контролируемых компилятором.
V>В этой статье я попытаюсь ответить на вопрос, почему программисты прошлого были умнее, а качество образования с каждым годом только падало.
V>...
Может всё гораздо проще? Просто велосипедостроение порицаемо окружающими
https://www.youtube.com/watch?v=nA-YFafnV68&t=2271s
V>>В этой статье я попытаюсь ответить на вопрос, почему программисты прошлого были умнее, а качество образования с каждым годом только падало.
_>Может всё гораздо проще? Просто велосипедостроение порицаемо окружающими
Здесь нужно вспомнить причину почему это так. Проработанная на протяжении многих лет или даже десятилетий библиотека алгоритмов скорее всего будет более оптимизирована и содержать меньше ошибок, чем если бы её писал новичок.
Хотя главный демотиватор программистов новичков и не только не писать самим это то, что каждый труд требует:
1) времени.
2) мозговых усилий.
3) знаний.
В итоге велосипедостроение может быть порицаемо даже в профессиональной среде, но только в производстве, не в обучении. Но новичок так и остаётся новичком выбирая путь пользователя (поколение пользователей). Выражается это в том, что продумывая детали программы он не представляет как работает система на алгоритмическом (поколение математиков) и аппаратном (поколение аппаратчиков) уровне.
Опять же до поколения пользователей было поколение абстракционистов с книгами, которые не описывают алгоритмы или аппаратную часть, а описывают лишь абстракции ради абстракций, то есть как создать абстрактные абстракции, причём даже это делают плохо. Это так же затрудняет естественное изучение алгоритмов, а так же принципы по которым они на самом деле работают, то есть вне абстракций, которые не имеют отношения к алгоритмам.
Ещё раз отмечу мысль статьи про поколения программистов. Раньше ты или идёшь и изучаешь хорошую книгу по математике, аппаратной части, или ты ничего не можешь сделать в программировании. Ты не можешь не написать велосипед, потому что нет готовых библиотек алгоритмов, а даже если и есть, они ещё не достаточно абстрактны, чтобы их сложно было понять.
Но сейчас полно плохих книг, и начинать можно с чего угодно. Не знаешь как работает процессор, алгоритмы, такие как математические, управление потоком исполнения и многие другие, ну и как бы ладно. Порой даже кажется, что отсутствие фундаментальных знаний не мешает, но на самом деле мешает. И не даёт понимать не только алгоритмическую и аппаратную части, но внезапно так же и абстрактную.
Например, какая разница между одномерным массивом (программирование), строкой (программирование) и последовательностью (математика). Можно ли считать последовательность частным случаем (подмножеством) графа (математика). В абстрактном плане какую структуру из себя представляет файловая система. По сути в программировании мы получаем одни и те же абстракции реализованные тысячами разных способов, что не добавляет понимания без фундаментальных, то есть основных знаний.
И ещё на последок подчеркну мысль, умность программистов прошлого, то есть прошлых поколений в том, что им не давали выбор, что изучать. А современные технологии они уже изучили позже с приходом нового времени. Однако у современных программистов выбор есть. И ладно если человек ленивый, ему ничего не надо. Но как тут писали выше про фанатиков, в современных реалиях фанатизм может завести не туда.
V>Однако у современных программистов выбор есть. И ладно если человек ленивый, ему ничего не надо. Но как тут писали выше про фанатиков, в современных реалиях фанатизм может завести не туда.
У современных программистов жилья нет. А чтобы оно было, нужна ипотека. А на работе за ипотеку велосипеды писать не дадут, там велью (value) ковать надо. Можно и без жилья, с родителями жить, но тогда девушки давать не будут, сейчас не 60ые с романтикой, а 2020ые с рейсами инстаграмщиц в Дубай.
V>В этой статье я попытаюсь ответить на вопрос, почему программисты прошлого были умнее, а качество образования с каждым годом только падало.
Такой сумбур, перепутаны причины и следствия. По моему скромному мнению, условных "программистов прошлого" отличают:
1. Более глубокая математическая подготовка — на программистов не учили, учили на математиков-кибернетиков.
2. Широта знаний — когда нет готовых библиотек, приходится всё писать самому.
3. Отсутствие глубины знаний — вытекает из пункта 2, потому как невозможно быть "и тут, и там". А ещё нет накопленного опыта предков. Оттого и чрезвычайно глупые и "детские" ошибки в старых стандартах и алгоритмах.
4. Отсутствие культуры программирования — те самые парадигмы вместе с общепринятыми приёмами, которые позволяют сотне-другой человек работать над общей кодовой базой без желания уничтожить друг-друга.
При желании можно ещё добавить, я просто взял из головы основное. Но как бы то ни было, их нельзя назвать глупее или умнее, потому что срез культуры программирования в любой момент определяется уровнем развития аппаратного обеспечения и культурой потребления ПО на момент среза. Было время, когда изощрённый алгоритм мог обеспечить компании годовую доходность, тогда и у руля стояли "гении-задроты". Сейчас успех определяется скоростью выхода на рынок, поэтому есть спрос на голодных студентов, готовых перерабатывать сублимированную лапшу в виртуальную 24/7.
C>Сейчас успех определяется скоростью выхода на рынок, поэтому есть спрос на голодных студентов, готовых перерабатывать сублимированную лапшу в виртуальную 27/7.
Если говорить не о спросе, а о дефиците, то в этом плане сейчас есть спрос на тех, кто сможет из этой ситуации выжать работоспособный продукт. А именно: отобрать нужных студентов, организовать их работу, выбрать правильные технологии, закрыть все сложные места, ибо чудес не бывает и периодически возникают проблемы, с которыми студенты не могут справиться, а решать их надо.
C>При желании можно ещё добавить, я просто взял из головы основное.
Я уже выше всё это написал, и в статье, и в комментариях.
C>Но как бы то ни было, их нельзя назвать глупее или умнее, потому что срез культуры программирования в любой момент определяется уровнем развития аппаратного обеспечения и культурой потребления ПО на момент среза.
И это я тоже выше написал.
У тебя просто идёт повторение моих мыслей из статьи.
В самом начале пути бытие определяет сознание, а не сознание определяет бытие
Давай я лучше ещё раз поясню главную мысль, если она по каким-то причинам всё ещё не понятна.
Возьмём Мартина Роберта (рождение 1952, карьера 1969) аппаратчик
У него много книг, такие как:
1) Чистый код.
2) Чистая архитектура.
3) Чистый Agile.
4) Идеальный программист.
5) Быстрая разработка программ.
6) Принципы паттерны и методики гибкой разработки на языке C#.
7) Гибкая разработка программ на Java и C++.
Он часто упоминает как писал свои первые программы, внимание, на перфокартах. Ещё раз уточню, программисты не умирают через поколение. Поколение это точка старта становления программистом. Некоторые люди застали все поколения, кто-то вынужден начинать позже, вплоть до поколения пользователей.
Того кто начинал с перфокарт не пугают современные языки и библиотеки алгоритмов такие как фреймворки и прочие. И дело не в том, что это он такой врождённо умный. Да, может и умный, но он просто не мог начать программировать в то время, не изучив хотя бы аппаратную часть. По году началу карьеры я вижу, что это аппаратчик.
В книге "Идеальный программист" он пишет, что начинал в 1969 году.
Мартин Роберт
И пример его программы выдаёт в нём то поколение аппаратчиков.
А теперь давай возьмём Дональда Кнута (рождение 1938, карьера 1960) математик
Его книги:
1) Конкретная математика. Основание информатики.
2) Искусство программирования.
3) Компьютеры и набор текста.
4) Всё про ΤΕΧ.
5) Всё про METAFONT».
По одним только названиям я могу сказать, что Дональд Кнут больше уделял внимание математике и набору текста, он из поколения математиков. Тогда как Мартин Роберт больше зациклен на чистоте от абстракций. Да, книги "Чистый код", "Чистая архитектура", да и не только это всё про загрязнение кода абстракциями. Чистый алгоритм, вот основная идея идущая через его творчество.
Далее возьмём Страуструпа Бъёрна (рождение 1950, карьера 1975) абстракционист
Казалось бы он чуть старше Мартина Роберта, хотя и гораздо младше Дональда Кнута. Но он создатель языка C++, то есть человек повёрнутый на парадигмах. Закончил университет в 1975 году, стал доктором философии в 1979 году и тогда же стал работать в "Bell Telephone Laboratories". А Си с классами появился в 1980 году.
Страуструп Бъёрн типичный абстракционист. А начал бы раньше, вполне возможно был бы аппаратчиком, как Мартин Роберт. И если вы впервые начали учиться по книжкам Страуструпа, то вы сами станете абстракционистом. Сначала придумываются заумные парадигмы вроде объектно-ориентированного и обобщённого, потом на основе их создаются абстрактные абстракции над абстракциями.
Потом абстракционистов уже волнуют даже не алгоритмы, а как создать хитровывернутые шаблоны проектирования завёрнутые в другие шаблоны проектирования. Да так, чтобы это ещё всё работало с чужими шаблонами проектирования завёрнутые в десятки слоёв связывающих абстракций. Я не буду говорить, что это плохо, но это путь абстракциониста.
Нужно понимать, что такой программист без дополнительных знаний не математик и не аппаратчик, а абстракционист. Программист математик может оценить эффективность алгоритма с точки зрения разума. А программист аппаратчик может оценить эффективность его реализации на аппаратном уровне, даже если использовался язык высокого уровня. А сам по себе абстракционист может оценить лишь правильность построения абстракций.
Вот так мы и докатились
До того, что не программисты выбирают кем им быть, а время, когда они начинают свою карьеру. Хотя производительность современных компьютеров колоссальна по сравнению с прошлым и есть цифровые копии книг в том числе "бесплатные", хотя и не лицензионные. Если бы современный начинающий программист, да пусть даже тот кто начал 20-30 лет назад понял, что он пропустил нужный путь, то чисто теоретически он мог бы его наверстать.
Моя статья о том, чтоб дать понять людям, что да, ты пропустил вот это и это. Я не говорю, что гуру программирования должны с открытыми ртами мне внимать. Но это важная тема и она периодически возникает. Об этом говорят образовательные каналы на ютубе. Об этом пишут книжки в том числе про то, как устроиться на работу "Макдауэлл Гейл.Карьера программиста", "Монган Джон.Работа мечты для программиста", причём не в прямой форме, а в косвенной, когда вам говорят, что будут вот такие тестовые задания.
Ещё раз о главной мысли
Если мы знаем, что что-то пошло не так, то мы можем это исправить. Так сказать попробовать переформатировать бытие посредством сознания, чтобы бытие не довлело над стилем нашего мышления. Но если мы об этом не знаем, то и исправить это не получится.
V>Здравствуйте, cppguard, Вы писали:
C>>При желании можно ещё добавить, я просто взял из головы основное.
V>Я уже выше всё это написал, и в статье, и в комментариях.
C>>Но как бы то ни было, их нельзя назвать глупее или умнее, потому что срез культуры программирования в любой момент определяется уровнем развития аппаратного обеспечения и культурой потребления ПО на момент среза.
V>И это я тоже выше написал.
V>[q]
V>Проблема в том, что в каждом поколении есть свои тренды. Если человек начал как пользователь… … …
V>[skipped]
V>
Далее возьмём… Далее возьмём… Далее возьмём…
А как же Эдсгер Дейкстра? Как это без него?V>>
Далее возьмём… Далее возьмём… Далее возьмём…
C>А как же Эдсгер Дейкстра? Как это без него?Так возьми Дейкстру и опиши. Программистов оставивших след в истории сотни, но речь не только о них, а обо всех. Здесь основной посыл в том, что с течением времени книги менялись, так же менялось аппаратное и программное обеспечение.
1) Представь, что современный программист перенесётся во времена молодости Дейкстры. Пусть он даже в нынешнем времени программирует смартфоны, но там ему ничего не останется как стать программистом математиком.
2) А теперь обратная ситуация, в наше время у нас есть все наработки Дейкстры. Но какова вероятность, что родись он 20-30 лет назад, то сейчас стал программистом математиком. Нужна какая-то среда, которая хотя бы намекнула, что не плохо бы почитать книжки 70-летней давности.
Заметь, циклы и прочие конструкции уже были в математике. Это не было инновационным понятием с приходом аппаратного обеспечения. И даже ООП и прочие парадигмы давно были описаны в науке логике. Более того, они там лучше описаны, чем в книгах по ООП.
Но здесь главную роль играет как человек работает с одним и тем же понятием.
1) Одно дело алгоритм написан на бумаге.
2) Другое закодирован для исполнения каким-то компьютером в машинных командах.
3) Третье используются абстракции на парадигмах программирования.
4) А четвёртое человек использует готовые библиотеки.
Вот у тебя есть бумага, карандаш, линейка? Но будешь ли ты ими пользоваться. Да и в целом бумагу с собой не потаскаешь. А вот тот же смартфон можно вынуть на ходу и посмотреть. Хотя даже со смартфоном чтобы делать что-то путное нужно сидеть или лежать. На ходу работать "свернёшь" шею.
V>В этой статье я попытаюсь ответить на вопрос, почему программисты прошлого были умнее, а качество образования с каждым годом только падало.
(c) Rob Pike, the author of Go lang.
V>
Мусорная литература
Эту проблему решает высшее образование же. Тебе в вузе преподают, дают список литературы не уровня "C++ за 21 день", а вполне нормальной. Также преподают все те достижения, которые нам остались от математиков, аппаратчиков и абстракционистов.
V>
Мусорные алгоритмы
Эту проблему решает уже не только образование (там рассказывают про алгоритмы и их надо реализовывать на разных языках), но и работа, на которой и твой код читают и ты читаешь чужой код. Джунам дают несложные задачи, проводят код ревью и т.д.
V>
Итоги
V>В принципе я обозначил проблему. И не только я, в интернете иногда об этом говорят. Что касается решения, то здесь как всегда нужно проводить опыты.А что за проблема-то? Что софт на много миллионов строк кода и разрабатываемый тысячами людей одновременно не идеален? Ну так эту проблему не не очень-то и обозначил.
V>В этой статье я попытаюсь ответить на вопрос, почему программисты прошлого были умнее, а качество образования с каждым годом только падало.
Для начала было бы неплохо доказать, что это факт имеет место быть.
V>>В этой статье я попытаюсь ответить на вопрос, почему программисты прошлого были умнее, а качество образования с каждым годом только падало.
0>Для начала было бы неплохо доказать, что это факт имеет место быть.
Кому надо тот пусть и доказывает, мне лично пока хватает представленной информации. Но я не против, если ты докажешь, а потом бесплатно опубликуешь доказательство. Так-то бы пора уже переходить к следующей части статьи, от того кто виноват, к тому что делать.
V>Кому надо тот пусть и доказывает, мне лично пока хватает представленной информации. Но я не против, если ты докажешь, а потом бесплатно опубликуешь доказательство. Так-то бы пора уже переходить к следующей части статьи, от того кто виноват, к тому что делать.
Ничего не надо делать. Надо продолжать в том же духе и дальше.
V>В этой статье я попытаюсь ответить на вопрос, почему программисты прошлого были умнее, а качество образования с каждым годом только падало.
Автор сам к какому поколению относится?
_>Автор сам к какому поколению относится?
Абстракционист.
V>В этой статье я попытаюсь ответить на вопрос, почему программисты прошлого были умнее, а качество образования с каждым годом только падало.
А такой вопрос вообще стоит? Его кто-то задал?
V>Как известно более старые книги по математике времён СССР лучше более поздних того же СССР и России. В некотором роде книги по математике деградировали так же, как и книги по программированию. Люди, до 60-ых годов получали гораздо более простые и насыщенные источники информации, просто потому, что у них не было выбора взять худшие варианты из будущего. Похожее случилось и с программированием.
Мммм, чего? Какие книги деградировали?
Например, Начала Евклида актуальны до сих пор. Чему там деградировать?
V>Поколение математиков были лишены всего этого безобразия, в том числе и структурной парадигмы заложенной в языке.
V>Поколение программистов аппаратчиков (1960-1980)
V>Поколение программистов абстракционистов (1980-2000)
V>Поколение программистов пользователей (2000-2020+)
Коллега, перед этими поколениями стояли совершенно разные глобальные задачи. И с развитием ИКТ менялись как задачи, так и подходы и средства их решения, это нормально.
V>Проблемы программистов
V>Мусорная литература
V>Мусорные алгоритмы
Это точно проблемы программистов?
V>В принципе я обозначил проблему. И не только я, в интернете иногда об этом говорят. Что касается решения, то здесь как всегда нужно проводить опыты.
Коллега, в принципе я догадываюсь о чем ты пишешь, но из приведенного текста это совсем не очевидно. Кроме того, всегда существует эволюционный путь развития любой сложной системы, не стоит форсировать события, просто занимайся своим делом наилучшим образом.
Не были они умнее — они просто не были программистами по образованию. Во всяком случае, в 50 и первой половине 60 — точно.
Если не ошибаюсь, Дейкстра был радиофизик по образованию.
А отдел системного программирования в ОИЯИ — они же физиками были.
А написали операционную систему и систему программирования на фортране для физиков.
Да даже в наше время (с 1975 года) — просто не было интернета.
Поэтому все писали сами.
Например, по одному договору делали такое:
1. Добавили в PL-1 лисп.
2. Придумали язык сверхвысокого уровня (по тем временам) типа Clojure
3. Написали его интерпретатор на PL-1лисп
4. На нем уже реализовали договор
За 2.5 года примерно.
В соответствии с планом — графиком по договору.
V>
Введение
V>В этой статье я попытаюсь ответить на вопрос, почему программисты прошлого были умнее, а качество образования с каждым годом только падало.
V>
Поколения программистов
V>Для начала разделю программистов по поколениям на основе источников доступной информации, а так же способам программирования, они же парадигмы программирования.
V>
1. Поколение программистов математиков (1940-1960)
а вы это годы рождения имели в виду ?V>>Поколения программистов
V>>Для начала разделю программистов по поколениям на основе источников доступной информации, а так же способам программирования, они же парадигмы программирования.
V>>1. Поколение программистов математиков (1940-1960)
Б> а вы это годы рождения имели в виду ?
Годы активного обучения и начала работы. Кто-то может стартовать раньше, кто-то позже. Это время вхождения в профессию. При этом если люди будут следовать текущим тенденциям, то получаем перечисленные поколения. А не следовать им тяжело, так как внешнее окружение определяет сознание. Но в итоге путь пройденный предыдущими поколениями оказывается не пройден текущими, что образует огромную дыру в образовании.