Re[7]: и ещё про рекорды..
От: Sinclair Россия https://github.com/evilguest/
Дата: 16.09.20 10:05
Оценка:
Здравствуйте, MadHuman, Вы писали:

MH>Рекорды это дальнейшее развитие идеи туплов, когда вместо позиционной идентификации элементов переходят на именованную.

Имхо, это всё же другая идея, хоть и похожая на туплы. На всякий случай напомню, что в туплах с именованной идентификацией всё в порядке.
Но туплы принципиально ограничены, к примеру, в наследовании; а рекорды — нет.
И это — принципиальная штука, в отсутствие алгебраических классов: скажем, рекордами легко смоделировать иерархию классов для AST, вроде System.Linq.Expressions.Expression.
Туплами это сделать невозможно.
MH>кмк, рекорд это в 1-ю очередь структура для данных или "мешочек с данными". То что можно прицеплять методы/поведение — это вторично.
Не совсем. Если бы нам были нужны только данные, то можно было бы обойтись туплами — чего я и рекомендую делать при наличии возможности.
Сейчас у нас есть понятная логика — никакие два разноимённых рекорда не являются одинаковыми, независимо от того, являются ли их типы отнаследованными друг от друга или случайно совпадающими.

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

public record Person(name);
public record Student: Person; // тут мы ничего не добавляем
public record Teacher: Person; // и тут мы ничего не добавляем

public static bool IsSame(Person p1, Person p2)
{
  return p1.Equals(p2);
}

var s = new Student("John");
var t = new Teacher("John");

Console.WriteLine(IsSame(t, s)); // false

В структурно-эквивалентном мире p, s, и t — неразличимы, т.к. у них одинаковая структура.
Мы пишем программу, она работает корректно.
Потом мы однажды добавляем к record Student какой-то ещё атрибут — ну там, Department.
Будут ли теперь совпадать t и s хоть при каких-то параметрах конструирования? Ну там, пусть Department равен null. Отличается ли "студент без факультета" от "просто человека", если студент, по определению, "человек с факультетом"?
Какое бы решение мы не приняли, это будет континтуитивно. Если Student и Teacher потеряли эквивалентность от внесения изменений в одного из них, то написанный до этого код был крайне хрупким. Например, мы где-то делали search по списку людей, и нас вполне устраивало то, что в нём находится и студент. А потом мы немножечко поменяли код, внеся необязательное поле — и упс! Сломался какой-то совершенно отдельный от нашего кода модуль, который вообще мог быть написан не нашей командой.
Если они сохранили эквивалентность, то у нас есть большая опасность получить паразитные срабатывания там, где мы этого не ожидаем — вроде того, что прямоугольник 5*7 равен квадрату 5*5.

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

MH>согласен, у явно задефайненных разными типов невидно и особенно учитывая, неявное поле Type, и не надо.

Ну, "неявное поле Type" в дотнете есть у всего

MH>тем же самым чем рекорды лучше классов. анонимность — это способ созданий/декларации.

MH>сходу, в том же Select возвращать не анонимный класс, а рекорд
Повторю вопрос: чем возврат анонимного рекорда будет лучше возврата анонимного класса?
Рекорды лучше классов в том, что они позволяют писать меньше бойлерплейта для их описания. В анонимных классах бойлерплейта нету вовсе, поэтому мы ничего не сэкономим.
С точки зрения взаимодействия с остальным кодом, рекорды нам ничего не дадут. Вот мы написали
var list = from p in db.People select new {p.Name, p.Age};

list у нас теперь IQueryable<Something>.
Чем вам поможет то, что Something является анонимным рекордом, а не анонимным классом?

MH>Сходу затрудняюсь привести убедительный пример, но например в F# уже есть анонимные рекорды и созданные в разных местах структурно идентичные и с одинаковыми значениями компонентов такие рекорды будут равны.

MH>Наверняка они сделаны потому что были кэйсы когда посчитали что это полезно. Можно найти ишью на гитхабе, почитать про историю их появления.
Наверняка они сделаны такими потому, что было принято решение не делать структурную суб-типизацию; т.е. рекорды в F# не являются подтипами друг друга, ни именованные, ни анонимные.
Одним из нехороших последствий является, в частности, невозможность паттерн матчинга по ним.
MH>Моё интуитивное ощущение, что это правильно, такие рекорды должны быть структурно равны.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.