Информация об изменениях

Сообщение Re[3]: tuple vs record от 05.02.2020 6:56

Изменено 05.02.2020 7:32 AlexRK

Re[3]: tuple vs record
Здравствуйте, MadHuman, Вы писали:

ARK>>2) Доступ к элементам сущности по имени поля НЕВОЗМОЖЕН! Доступ возможен только через распаковку ("(a, b) = entity;"), а имена полей служат "хинтом" к содержимому, лежащему в сущности. Результат: это по-прежнему тупл, только более понятный.

MH>почему не возможен? это уже детали реализации, представьте что в этой структуре данных для этого реализован интерфейс типа IRecord c GetFieldValue(string name), или прям явный с пропертями, соотвествующими именам полей (типа как namedtuple в питоне).

Нет, это не просто деталь реализации. Метод GetFieldValue написать нельзя, т.к. имена полей недоступны из кода. Мы можем только посмотреть на них глазами, точно так же, как в С — на имена входных параметров функции, находясь извне функции. Имена полей — именно что просто хинт и ничего больше. Если их можно каким-то образом использовать из кода, то это уже вариант 1 ("Доступ к элементам сущности возможен по имени поля").

MH>но тут проблема — этот тупль с косметическим улучшением (именами полей для содержимого) начинает обладать всем признаками рекорда.


Только в варианте 1.

MH>подумайте ещё над тем что возвращает select в sql. не столько с позиции как сейчас сложились в популярных реализациях, а с позиции — а как правильно.


Как правильно, это сложный вопрос. У меня недостаточно квалификации для таких суждений.

Фактически сейчас возвращается рекорд.

MH>представьте что строку из результата надо сохранить в переменную.

MH>какого типа эта переменная? кортеж? или рекорд? как сравнивать два таких значения ?

Рекорд. Сравнивать по правилам рекорда.

MH>let a=select 1 as x, 2 as y

MH>let b=select 2 as y, 1 as x

MH>a=b?


Да.

MH>можно ли делать a[0]?


Нельзя.

MH>а a.x?


Можно.
Re[3]: tuple vs record
Здравствуйте, MadHuman, Вы писали:

ARK>>2) Доступ к элементам сущности по имени поля НЕВОЗМОЖЕН! Доступ возможен только через распаковку ("(a, b) = entity;"), а имена полей служат "хинтом" к содержимому, лежащему в сущности. Результат: это по-прежнему тупл, только более понятный.

MH>почему не возможен? это уже детали реализации, представьте что в этой структуре данных для этого реализован интерфейс типа IRecord c GetFieldValue(string name), или прям явный с пропертями, соотвествующими именам полей (типа как namedtuple в питоне).

Нет, это не просто деталь реализации. Метод GetFieldValue написать нельзя, т.к. имена полей недоступны из кода. Мы можем только посмотреть на них глазами, точно так же, как в С — на имена входных параметров функции, находясь извне функции. Имена полей — именно что просто хинт и ничего больше. Если их можно каким-то образом использовать из кода, то это уже вариант 1 ("Доступ к элементам сущности возможен по имени поля").

MH>но тут проблема — этот тупль с косметическим улучшением (именами полей для содержимого) начинает обладать всем признаками рекорда.


Только в варианте 1.

MH>подумайте ещё над тем что возвращает select в sql. не столько с позиции как сейчас сложились в популярных реализациях, а с позиции — а как правильно.


Как правильно, это сложный вопрос. У меня недостаточно квалификации для таких суждений.

Фактически сейчас возвращается рекорд.

MH>представьте что строку из результата надо сохранить в переменную.

MH>какого типа эта переменная? кортеж? или рекорд? как сравнивать два таких значения ?

Рекорд. Сравнивать по правилам рекорда.

MH>let a=select 1 as x, 2 as y

MH>let b=select 2 as y, 1 as x

MH>a=b?


Да.

MH>можно ли делать a[0]?


Нельзя.

MH>а a.x?


Можно.


UPD.
Изначально в любом случае сущность одна — либо с позиционным доступом, либо с именованным. А уж потом, на основе базового доступа, можно сверху дополнительно прикрутить другой доступ — но он всегда будет в "подчиненном" положении и на операцию сравнения влиять не будет.

Как прикрутить? На основе какого-то правила, общего для всех сущностей в интересующем нас множестве. Да, обязательно общего для всех сущностей в интересующем нас множестве, иначе выйдет нелепость! Множеством может быть в общем случае что угодно. Например, для SQL это "рекордсет" (набор связанных рекордов), который возвращается каждым SELECT-запросом.

Как из позиционного доступа сделать именованный? Можно, например, добавить префикс "Field" к индексу и получить имена полей а-ля "Field1", "Field2", etc.
Как из именованного доступа сделать позиционный? Можно использовать словарь, ставящий в соответствие некоторой строке некоторое число ("{ "MyField1" => 1, "OtherField" => 2 }").


Можно, в принципе, сделать и сущность со "смешанным" доступом. Но при этом должно выполняться одно из трех условий.

Рассматриваем тот же пример:
let a=select 1 as x, 2 as y
let b=select 2 as y, 1 as x

1) Всегда явно задаются оба параметра (имя и позиция). С этом случае будет a!=b, т.к. имена совпадают, а позиция — нет.

2) Опираться на некоторое, общее для всех, правило преобразования доступов друг в друга. В зависимости от этих правил, может быть либо a!=b, либо a=b, но b[0]=1! (хе-хе )

3) Нести в себе (в своем типе) правило преобразования доступов друг в друга. Почти как вариант 2, но надо явно указывать тип:
let a=MyTupleRecordRule(select 1 as x, 2 as y)
let b=MyTupleRecordRule(select 2 as y, 1 as x)
Будет ли в этом случае a=b — неизвестно, зависит от того, что в MyTupleRecordRule.

В общем, смешанный доступ — это хрень, усложняющая все, но не приносящая особой пользы.