juan_gandhi: (VP)
Тут на днях завелась дискуссия на интернетах, мол, ваше фп сакс, потому что нет нормального способа, к примеру, имея элемент списка, определить, кто перед ним, а кто сзади.

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

Но это ладно.

Что за притча, однако, почему в этой оперденной джаве всё так удобно, а в премудром хаскеле хрен ты что достанешь?

А, извините, что это, собственно, мы достаём в джаве? Вот есть список, скажем, List(3, 1, 4, 1, 5, 9, 2); ну хорошо. Так что теперь, нам известно, что за цифрой 5 идёт цифра 9? А не 6, как все думали? А что идёт за цифрой 1? Э... смотря за какой, скажет нам хорошоплачиваемый джава-программист (далее - ХОДП).

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

Так вот, хотя у ХОДП и есть тенденция путать порядок и перечисление, здравомыслящий человек как-то видит разницу.

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

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

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

Тут два момента. Во-первых, мы вполне можем налететь на IndexOutOfBoundsException - каковой обычно ХОДП просто регистрирует в логе, чтобы потом младшие практиканты пофиксили; во-вторых, а какой же у нашего элемента индекс? Вот у цифры 1 в вышеприведённом примере какой индекс? А... а это... а мы сначала поищем.

И тут мы наталкиваемся на очень интересную практику. Программисты, особенно ХОДП, всё время что-то ищут. Ищут что-то в списке, ищут что-то в дереве, в хеш-мапе, в файле, в базе данных, на интернетах (ну хорошо, на интернетах они жж читают, теперь порнуха никого не интересует, не тот век).
В нашем случае мы ищем значение в списке; на самом деле мы ищем индекс, на котором список принимает заданное значение.

Ну можно ж было это значение как-то запомнить. Когда ХОДП преждевременно оптимизирует свой код, он использует HashMap (это круто, хаш, он ускоряет поиск), и, сканируя, запоминает пару, MapEntry:

  for (Map.Entry<Key, Value> entry : map.entrySet()) {
    Key key = entry.getKey();
    Value value = entry.getValue();
    // do what you like with the stuff you so bravely extracted
  }


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

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


Ну это ладно, не будем ругаться.

Просто, человек, привыкший к "спискам" (в джаве это не списки обычно), т.е. де-факто к "массивам", и чувствующий себя вполне уверенно, если нужно выбирать три последовательных члена ряда, вдруг совершенно теряется, когда оказывается, что список никакого индекса не имеет... и вообще может быть и бесконечным. Тут ХОДП начинает кипятиться - ну и на хрена мне ваш хаскель, если на нём даже исёдел нету нельзя ни вставить элемент в список, ни заменить значение, на даже узнать, кто раньше был, а кто следующий.

Что любопытно, когда ХОДП читает файл "с диска" (я не знаю, они что, действительно круглые внутри?), он не кипятится, что нельзя узнать, кто следующий, пока не прочитаешь следующего, и нельзя узнать, кто предыдущий, если не запомнил.

Ну так и в Хаскеле та ж картина. Я не буду говорить слово "комонада", а то сразу тут Мунк пойдёт, пойдёт Мунк. Хрен с ней с комонадой. Есть просто источник, и если мы хотим запоминать, шо он раньше испустил, то давайте ж запомним где-то. Между прочим, ваши массивы вы вообще целиком запоминаете.

Ну и можно же просто взять зип с хвостом, грубо говоря.
list zip (list tail) - это у нас будет список пар.

Разве это сложно для ХОДП? ХОДП может возмутиться, мол ё, это чё, два раза один и тот же список сканировать, это ж неэффективно, где моя преждевременная оптимизация? Да релакс, тут всё уже без вас заоптимизировано, списки ленивые.

Так в чём проблема-то?
juan_gandhi: (Default)
Subclassing errors, OPP, and practically checkable rules to prevent them

P.S. I believe the problem is that with stateful objects, we do not know exactly which category are we dealing with; roughly speaking, for class A subclassing class B, there are actually two monads, with a natural transformation from one to another; and we think we have a functor from, not sure yet, one Kleisli category to another, or from one Eilenberg-Moore category to another, or even an interesting relationship between two categories of adjoints generated by the monads.

Have to look closer; maybe this explains the problem with "Liskov substitution".

Profile

juan_gandhi: (Default)
Juan-Carlos Gandhi

June 2025

S M T W T F S
1 2345 6 7
8 91011121314
15161718192021
22232425262728
2930     

Syndicate

RSS Atom

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Jun. 10th, 2025 01:40 am
Powered by Dreamwidth Studios