Кортежи в языках программирования
От: NeoCode  
Дата: 24.10.12 09:34
Оценка: 1 (1)
Пытаюсь построить идеальную модель кортежей в некотором языке программирования.
Кортеж — это просто некоторая группа объектов (переменных, констант), не имеющая собственного типа, а существующая на этапе компиляции просто для удобства.
Записывается просто как список объектов в круглых скобках через запятую.

Такие варианты использования выглядят наиболее логично и красиво:

1. возврат нескольких значений из функции
(int,char,float) Foo()
{
  return (100,'a',3.14);
}


2. групповые операции
(i,j,k) = (1,2,3);


3. множественные операции
(i,j,k) = 100;
myobj.(i, c, f) = (100, 'q', 0.25);
sum += (i, j, k);


4. групповая и множественная индексация массивов (раскрытие массива в кортеж)
arr[2,4,8] = (10, 20, 30);
arr[10,20,30] = 0;
arr[indexes[0..size-1]] ++;


На простых примерах вроде все хорошо, но дальше начинаются противоречия и ужасы.
— поведение таких групп внутри сложных выражений ?
— простая, понятная и правильная логика обработки операций над двумя и более кортежами разных размеров ?
— передача кортежей в функции; по аналогии с возвращаемыми значениями, список аргументов функции тоже кортеж, но если возможен например инкремент сразу трех переменных, то что делать если программист хочет вызвать функцию сразу для трех переменных?
Foo((i,j,k)); //???
— соответственно, получение множественного возврата из обычных функций, в которые передали кортеж (по аналогии с операциями!)
(d1,d3,d3,d4) = sin(0.2, 0.4, 0.6, 0.8); // double sin(double x)
— ну и если рассматривать наложение ситуаций множественного возврата и множественных аргументов, то вообще бред получается.

Посмотрел в Питоне, там это просто структура данных. В Nemerle немного ближе (есть "раскрытие" кортежа в группу переменных) но "множестенных" операций и прочих наворотов нет.
Интересно было бы посмотреть, существует ли что-то похожее на эти идеи в других языках?
Re: Кортежи в языках программирования
От: RomikT Германия  
Дата: 24.10.12 10:08
Оценка:
Здравствуйте, NeoCode, Вы писали:

NC>Интересно было бы посмотреть, существует ли что-то похожее на эти идеи в других языках?


Посмотрите на HList в Scala, это в некотором роде расширение идеи кортежей.
Re: Кортежи в языках программирования
От: AlexRK  
Дата: 24.10.12 11:05
Оценка: +2
Здравствуйте, NeoCode, Вы писали:

NC>3. множественные операции


Я правильно понял, что

NC>
(i,j,k) = 100;

- присваивание каждому элементу значения 100?

NC>myobj.(i, c, f) = (100, 'q', 0.25);

- присваивание свойствам i, c, f значений 100, 'q' и 0.25 соответственно?

NC>sum += (i, j, k);


Добавление к sum суммы всех элементов кортежа?

ИМХО, все три действия сильно неинтуитивны.


NC>4. групповая и множественная индексация массивов (раскрытие массива в кортеж)

NC>arr[indexes[0..size-1]] ++;[/code]

Вот это тоже не понял.


NC>- поведение таких групп внутри сложных выражений ?


Либо запретить, либо вводить наименования полей (возможно, опциональные).

NC>- простая, понятная и правильная логика обработки операций над двумя и более кортежами разных размеров ?


Например, какие операции?

NC>- передача кортежей в функции; по аналогии с возвращаемыми значениями, список аргументов функции тоже кортеж, но если возможен например инкремент сразу трех переменных, то что делать если программист хочет вызвать функцию сразу для трех переменных?

NC>Foo((i,j,k)); //???

Я думал над этим вопросом, пришел к выводу, что вообще эта идея — аргументы функции есть кортеж — плохая. Но почему, уже не помню.
В данном конкретном случае, вероятно, должна быть просто ошибка компиляции (двусмысленность).

NC>- соответственно, получение множественного возврата из обычных функций, в которые передали кортеж (по аналогии с операциями!)

NC>(d1,d3,d3,d4) = sin(0.2, 0.4, 0.6, 0.8); // double sin(double x)
NC>- ну и если рассматривать наложение ситуаций множественного возврата и множественных аргументов, то вообще бред получается.

Я бы эту путаницу — с произвольным количеством аргументов вместо одного — просто запретил. Читаемость кода, ИМХО, будет очень низкая.

NC>Интересно было бы посмотреть, существует ли что-то похожее на эти идеи в других языках?


По-моему, в нормальном, продуманном, последовательном виде — нет нигде. Разной степени кривизны много где.
Re[2]: Кортежи в языках программирования
От: NeoCode  
Дата: 24.10.12 11:31
Оценка:
Здравствуйте, AlexRK, Вы писали:

ARK>Я правильно понял, что

NC>>
(i,j,k) = 100;
ARK>- присваивание каждому элементу значения 100?
NC>>myobj.(i, c, f) = (100, 'q', 0.25);
ARK>- присваивание свойствам i, c, f значений 100, 'q' и 0.25 соответственно?
NC>>sum += (i, j, k);

ARK>Добавление к sum суммы всех элементов кортежа?

Да, все верно.

ARK>ИМХО, все три действия сильно неинтуитивны.

Почему?

NC>>4. групповая и множественная индексация массивов (раскрытие массива в кортеж)

NC>>arr[indexes[0..size-1]] ++;[/code]

ARK>Вот это тоже не понял.

Ну это я наверное не написал подробно... массив, проиндексированный несколькими индексами (кортежем) раскрывается в кортеж.
 (x,y,z) = arr[0,1,2];
(x,y,z) = arr[0..2];


NC>>- поведение таких групп внутри сложных выражений ?

ARK>Либо запретить, либо вводить наименования полей (возможно, опциональные).

А подробнее про наименования полей?

NC>>- простая, понятная и правильная логика обработки операций над двумя и более кортежами разных размеров ?

ARK>Например, какие операции?
(x,y,z)  = (i,j);
(x,y,z) += (i,j);
(x,y)  = (i,j,k);
(x,y) += (i,j,k);

что делать в этих случаях — ругаться? цикл по наименьшему размеру? цикл по наибольшему размеру с "переполнением" (индекс каждого кортежа делится по модулю на длину кортежа) ? цикл по наибольшему размеру с "насыщением" (индекс каждого кортежа при достижении максимума остается на максимуме)? декартово произведение (двойной цикл по обоим кортежам)?)

NC>>- передача кортежей в функции; по аналогии с возвращаемыми значениями, список аргументов функции тоже кортеж, но если возможен например инкремент сразу трех переменных, то что делать если программист хочет вызвать функцию сразу для трех переменных?

NC>>Foo((i,j,k)); //???
ARK>Я думал над этим вопросом, пришел к выводу, что вообще эта идея — аргументы функции есть кортеж — плохая. Но почему, уже не помню.
ARK>В данном конкретном случае, вероятно, должна быть просто ошибка компиляции (двусмысленность).

Если еще кортежи сделать именованными (хотя-бы через аналог #define) то возникнет еще одно некрасивое место:
define (1,2,3) FOO;
define(4,5) BAR;
//void Func(int a1,int a2,int a3,int a4,int a5,int a6,int a7)
Func(100,FOO,BAR,200); // если рассматривтаь это как конкатенацию кортежей, некрасиво то что не видно сколько реально аргументов и какие значения в них ложатся; а если рассматривать как мультвызов - то бред, сколько раз вызывать функцию
Re[3]: Кортежи в языках программирования
От: AlexRK  
Дата: 24.10.12 12:43
Оценка:
Здравствуйте, NeoCode, Вы писали:

ARK>>ИМХО, все три действия сильно неинтуитивны.

NC>Почему?

Ну вот это — "myobj.(i, c, f) = (100, 'q', 0.25);" — вообще со стандартной статической типизацией несовместимо, плюс мало читаемо.
myobj.t = u; — чего здесь происходит, если t и u — кортежи? Совершенно непонятно.

(i,j,k) = 100; можно записать как и (i,j,k) = (100,100,100);
Опять лишняя путаница.

sum += (i, j, k);
В принципе более-менее, но это скорее для массивов должно подходить, чем для кортежей. Кортежи могут ведь содержать поля разных типов, зачем для них такой специфичный функционал?

Вообще, ИМХО, кортежи не стоило бы рассматривать как последовательности однотипных данных.

NC>Ну это я наверное не написал подробно... массив, проиндексированный несколькими индексами (кортежем) раскрывается в кортеж.

NC>
 (x,y,z) = arr[0,1,2];
NC>(x,y,z) = arr[0..2];


А, понятно.
Фиг знает, лично мне не нравится смешивание массивов и кортежей — это же разные вещи в общем случае.

NC>>>- поведение таких групп внутри сложных выражений ?

ARK>>Либо запретить, либо вводить наименования полей (возможно, опциональные).
NC>А подробнее про наименования полей?

Ну чего-то типа:
var tuple = (Name => "Sam", Age => 30, Sex => Sexes.Male);

var expr = 10 + tuple.Age;


NC>>>- простая, понятная и правильная логика обработки операций над двумя и более кортежами разных размеров ?

ARK>>Например, какие операции?
NC>
(x,y,z)  = (i,j);
NC>(x,y,z) += (i,j);
NC>(x,y)  = (i,j,k);
NC>(x,y) += (i,j,k);

NC>что делать в этих случаях — ругаться? цикл по наименьшему размеру? цикл по наибольшему размеру с "переполнением" (индекс каждого кортежа делится по модулю на длину кортежа) ? цикл по наибольшему размеру с "насыщением" (индекс каждого кортежа при достижении максимума остается на максимуме)? декартово произведение (двойной цикл по обоим кортежам)?)

Нда, жесть. Представьте, что в процессе отладки программы марсохода "Спирит", вылетающего завтра на Марс, вы встретите подобные конструкции. Я думаю, это будет не особо весело.
Мое мнение — должна быть ошибка компиляции.
А если фигакнуть еще вложенных кортежей, то вообще все круто будет: ((a, b), ((c, d), e, f), g) = (100, (21, 'q'))

NC>Если еще кортежи сделать именованными (хотя-бы через аналог #define) то возникнет еще одно некрасивое место:

NC>
define (1,2,3) FOO;
NC>define(4,5) BAR;
NC>//void Func(int a1,int a2,int a3,int a4,int a5,int a6,int a7)
NC>Func(100,FOO,BAR,200); // если рассматривтаь это как конкатенацию кортежей, некрасиво то что не видно сколько реально аргументов и какие значения в них ложатся; а если рассматривать как мультвызов - то бред, сколько раз вызывать функцию


Ну, как мультивызов рассматривать — это просто контр-интуитивно, по крайней мере для среднестатистического программиста. Может быть, только если человека тренировать на таких языках с мультивызовами, то ему это будет очевидно.
Остается конкатенация, но это тоже не особо понятно.
В общем, я бы операцию распаковки кортежа не стал совмещать с операцией вызова функции.
Re: Кортежи в языках программирования
От: D. Mon Великобритания http://thedeemon.livejournal.com
Дата: 24.10.12 16:10
Оценка:
Здравствуйте, NeoCode, Вы писали:

NC>Интересно было бы посмотреть, существует ли что-то похожее на эти идеи в других языках?


Це ж обычный product type, больше известный как tuple. Есть во всех основных функциональных языках, и на первых страницах книжек по теории типов.
Re[2]: Кортежи в языках программирования
От: NeoCode  
Дата: 24.10.12 17:02
Оценка: +1
Здравствуйте, D. Mon, Вы писали:

DM>Це ж обычный product type, больше известный как tuple. Есть во всех основных функциональных языках, и на первых страницах книжек по теории типов.


tuple обычно и переводится как кортеж.
А в функциональных языках что есть множественные операции по типу тех, которые я привел в качестве примера?
Re[3]: Кортежи в языках программирования
От: D. Mon Великобритания http://thedeemon.livejournal.com
Дата: 24.10.12 17:31
Оценка:
Здравствуйте, NeoCode, Вы писали:

NC>А в функциональных языках что есть множественные операции по типу тех, которые я привел в качестве примера?


Только некоторые, вроде множественного присваивания, ну и передача туда-сюда в функции, само собой, т.к. это обычный тип получается. Операции с массивами можно реализовать самому при желании. И кортеж там это не "группа объектов (переменных, констант), не имеющая собственного типа", тип там автоматически генерится из типов входящих в кортеж значений. Так, кортеж (1, 2.0, "three") в хаскеле может иметь тип (Int, Float, String), в окамле — int * float * string, а в каком-нибудь D — Tuple!(int, float, string).
Re: Кортежи в языках программирования
От: batu Украина  
Дата: 24.10.12 18:00
Оценка:
Здравствуйте, NeoCode, Вы писали:

NC>- поведение таких групп внутри сложных выражений ?

NC>- простая, понятная и правильная логика обработки операций над двумя и более кортежами разных размеров ?
Согласен с AlexRK. Проблема в неопределенности операций. Обычно это функция над двумя параметрами (хотя я считаю что операции надо определять иначе.). Если с суммой еще можно сынтуичить, то с вычитанием и делением возникает проблема с порядком выполнения. Это же касается и логических сравнения. Если два элемента то понятно. А если несколько, то что с чем и в каком порядке сравнивать? И как поступать если часть равны, а часть нет. Появляются варианты.
Я у себя определил изначально операции над группами. Т.е. сумма понятно, вычитание из последнего вычитается предпоследний и т.д.. Логических операций и опреаций сравнения пришлось определять несколько. AllEqv (все равны) и некоторые не равны.. Заметь что Не все равны это не одно и тоже что некоторые не равны Ну, а дальше сам додумаешь. Удачи!
Re: Кортежи в языках программирования
От: os24ever
Дата: 24.10.12 18:05
Оценка: :)
NC>Интересно было бы посмотреть, существует ли что-то похожее на эти идеи в других языках?

Если в языке есть дерево типов данных, в корне которого "Any" и затем "AnyVal" и "AnyRef", то это просто массив элементов "AnyRef".
То есть, динамический массив чего угодно. А все действия с ним — функции.

То есть, можно было бы написать просто:

Call ArraySlice Old_tuple, i, j, New_tuple
Call ArraySort New_tuple

Но обычно в язык насыпают 100500 кг синтаксического сахара вроде:

new_tuple = old_tuple[i..j].sort()

На самом деле, никакой разницы нет.
Re[2]: Кортежи в языках программирования
От: NeoCode  
Дата: 25.10.12 06:57
Оценка:
Здравствуйте, os24ever, Вы писали:

O>Если в языке есть дерево типов данных, в корне которого "Any" и затем "AnyVal" и "AnyRef", то это просто массив элементов "AnyRef".

O>То есть, динамический массив чего угодно. А все действия с ним — функции.
O>То есть, можно было бы написать просто:

O>
O>Call ArraySlice Old_tuple, i, j, New_tuple
O>Call ArraySort New_tuple
O>

O>Но обычно в язык насыпают 100500 кг синтаксического сахара вроде:

O>
O>new_tuple = old_tuple[i..j].sort()
O>

O>На самом деле, никакой разницы нет.

Я предполагаю что все эти кортежи на этапе компиляции будут раскрываться в последовательности одиночных операций, то есть никакие это не массивы. Например,
(x, y)++;

будет превращен в
x++; y++;

а
(x, "Hello world")++;

приведет к ошибке компиляции. То есть я здесь понимаю под tuple не еще один тип данных (как массив, список, ...) а некое языковое средство для синтаксической группировки объектов.
Например в go есть операция группового присваивания
i, j = 100,200

никаких массивов тут нет. Интересно, как далеко можно расширить такие групповые операции?
Re[2]: Кортежи в языках программирования
От: NeoCode  
Дата: 25.10.12 06:58
Оценка:
Здравствуйте, batu, Вы писали:

B>Я у себя определил изначально операции над группами. Т.е. сумма понятно, вычитание из последнего вычитается предпоследний и т.д.. Логических операций и опреаций сравнения пришлось определять несколько. AllEqv (все равны) и некоторые не равны.. Заметь что Не все равны это не одно и тоже что некоторые не равны Ну, а дальше сам додумаешь. Удачи!


Можно подробнее?
Re[3]: Кортежи в языках программирования
От: Sinix  
Дата: 25.10.12 08:06
Оценка: +1
Здравствуйте, NeoCode, Вы писали:


NC>Я предполагаю что все эти кортежи на этапе компиляции будут раскрываться в последовательности одиночных операций, то есть никакие это не массивы. Например,

(x, y)++;


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

В плюсе — возможность одновременно выполнять операции над несколькими переменными, всё остальное достигается обычным синтаксисом.

В минусе (навскидку):

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

— этот синтаксис нужен только для очень редких случаев — для операций над статическим списком переменных/значений — но затрагивает весь язык.

— этот синтаксис провоцирует плохой стиль кодирования, когда изменение состояния размазано по нескольким переменным, или в одной операции производятся семантически разные вещи.

Пример раз:
(checksPassed, personAge)++;

Пример два:
(a,b,c) = InitVars();
выглядит красивее, чем
int a,b,c;
InitVars(out a, out b, out c);
но оно скрывает одну проблему: ужасен не вызов метода, ужасен сам метод, который совершает операции над тремя логически несвязанными объектами.
Re[3]: Кортежи в языках программирования
От: batu Украина  
Дата: 25.10.12 08:09
Оценка:
Здравствуйте, NeoCode, Вы писали:

NC>Здравствуйте, batu, Вы писали:


B>>Я у себя определил изначально операции над группами. Т.е. сумма понятно, вычитание из последнего вычитается предпоследний и т.д.. Логических операций и опреаций сравнения пришлось определять несколько. AllEqv (все равны) и некоторые не равны.. Заметь что Не все равны это не одно и тоже что некоторые не равны Ну, а дальше сам додумаешь. Удачи!


NC>Можно подробнее?

Что именно подробней? Операция вычитания группы может быть определена по разному.. Из первого вычитается второй, из результата вычитается третий и т.д.. А можно и с последнего начать.. Тоже самое и для остальных операций.. Придумываешь и реализуешь. С суммой и умножением просто потому как там вариантов нет. Остальные операции крути как хочешь. В смысле как считаешь разумным.
Re[4]: Кортежи в языках программирования
От: NeoCode  
Дата: 25.10.12 08:23
Оценка:
Здравствуйте, batu, Вы писали:

B>Что именно подробней? Операция вычитания группы может быть определена по разному.. Из первого вычитается второй, из результата вычитается третий и т.д.. А можно и с последнего начать.. Тоже самое и для остальных операций.. Придумываешь и реализуешь. С суммой и умножением просто потому как там вариантов нет. Остальные операции крути как хочешь. В смысле как считаешь разумным.


Элементы группы не взаимодействуют между собой при групповых операциях, имеется в виду только взаимодействие i-того элемента группы и другого операнда.
x -= (1,2,3); // x-=1; x-=2; x-=3;
(x,y,z) -= 10; // x-=10; y-=10; z-=10;
(x,y,z) -= (1,2,3); // x-=1; y-=2; z-=3;
Re[5]: Кортежи в языках программирования
От: maykie Россия  
Дата: 25.10.12 09:11
Оценка:
Здравствуйте, NeoCode, Вы писали:

NC>Здравствуйте, batu, Вы писали:


B>>Что именно подробней? Операция вычитания группы может быть определена по разному.. Из первого вычитается второй, из результата вычитается третий и т.д.. А можно и с последнего начать.. Тоже самое и для остальных операций.. Придумываешь и реализуешь. С суммой и умножением просто потому как там вариантов нет. Остальные операции крути как хочешь. В смысле как считаешь разумным.


NC>Элементы группы не взаимодействуют между собой при групповых операциях, имеется в виду только взаимодействие i-того элемента группы и другого операнда.

NC>
x -= (1,2,3); // x-=1; x-=2; x-=3;
NC>(x,y,z) -= 10; // x-=10; y-=10; z-=10;
NC>(x,y,z) -= (1,2,3); // x-=1; y-=2; z-=3;


А почему третий пример раскрывается так, а не x -= (1,2,3);y -= (1,2,3);z -= (1,2,3); ?
Re[6]: Кортежи в языках программирования
От: NeoCode  
Дата: 25.10.12 09:19
Оценка:
Здравствуйте, maykie, Вы писали:

NC>>
x -= (1,2,3); // x-=1; x-=2; x-=3;
NC>>(x,y,z) -= 10; // x-=10; y-=10; z-=10;
NC>>(x,y,z) -= (1,2,3); // x-=1; y-=2; z-=3;


M>А почему третий пример раскрывается так, а не x -= (1,2,3);y -= (1,2,3);z -= (1,2,3); ?


На самом деле третий пример — это как раз основной режим этих tuples, реализованный в той или иной мере в различных языках, и напрямую следующий из синтаксиса возврата нескольких значений. Если ограничиться только этим режимом, то все получаетя вполне логично и никаких противоречий нет.

А вот если захотеть, чтобы работали первые два примера — начинаются проблемы в более сложных случаях, о чем и тема
Re[4]: Кортежи в языках программирования
От: hardcase Пират http://nemerle.org
Дата: 25.10.12 09:31
Оценка: 20 (1) +1
Здравствуйте, Sinix, Вы писали:


S>
S>int a,b,c;
S>InitVars(out a, out b, out c);
S>
но оно скрывает одну проблему: ужасен не вызов метода, ужасен сам метод, который совершает операции над тремя логически несвязанными объектами.


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

А в остальном, да я согласен. Замечу, что кортежи имеют смысл лишь в языках, поддерживающих сопоставление с образцом — декомпозиция кортежа это частный случай такой операции, в противном случае кортежи вырождаются до примитивных контейнеров безымянных данных.
/* иЗвиНите зА неРовнЫй поЧерК */
Re: Кортежи в языках программирования
От: vl690001x Россия  
Дата: 25.10.12 10:15
Оценка:
Я только недавно узнал что в C# есть кортежи, но активно их использую, чтобы не создавать новые типы.
Например, у меня есть метод, который возвращает строку — содержимое некого url. Также, если сервер недоступен, надо как-то передать эту информацию из метода. Можно конечно вернуть null, и возможно это проще, но правильней было бы создать класс:
class ReturnedValue
{
  public bool HostAvailable;
  public string HostValue;
}


и возвращать объект этого класса.

Только аналогичных методов может быть много, поэтому для каждого создавать класс слишком утомительно, можно просто вернуть кортеж:
new Tuple<bool,string>(true, "value");


или:
new Tuple<bool,string>(false,null);


и считывать информацию из кортежа так:
if(tuple.Item1)
{
  Console.WriteLine(tuple.Item2);
}
else
{
 Console.WriteLine("Сервер недоступен");
}
)
Re[2]: Кортежи в языках программирования
От: hardcase Пират http://nemerle.org
Дата: 25.10.12 10:27
Оценка: +2
Здравствуйте, vl690001x, Вы писали:

V>Только аналогичных методов может быть много, поэтому для каждого создавать класс слишком утомительно, можно просто вернуть кортеж:


V>new Tuple<bool,string>(true, "value");


V>или:


V>new Tuple<bool,string>(false,null);


1) Кортежи в C# можно и нужно изготавливать так:
Tuple.Create(true, "value");


2) Для вашей задачи есть отличный паттерн "монада Maybe". В ML-подобных языках для ее поддержки существует обобщенный тип option[T], который нетрудно воспроизвести в .NET (как обобщение типа Nullable<T>, только за исключением ограничение на value-типы).
/* иЗвиНите зА неРовнЫй поЧерК */
Re: Кортежи в языках программирования
От: AlexCab LinkedIn
Дата: 25.10.12 10:50
Оценка:
Здравствуйте, NeoCode, Вы писали:
NC>Пытаюсь построить идеальную модель кортежей в некотором языке программирования.
NC>Кортеж — это просто некоторая группа объектов (переменных, констант), не имеющая собственного типа, а существующая на этапе компиляции просто для удобства.
NC>Записывается просто как список объектов в круглых скобках через запятую.
Тоже думал о таком, и вот что придумал:
1)Вам необходимо представить кортеж как группу(линейную последовательность или вектор) значений/ООП-объектов, а не переменных и не констант, т.е. значение может быть получено из переменной, задано при помощи константы и т.п.
2)Вам нужно представить выполнение оператора/вызова в три этапа(например для "r = s + 2"(s: "int s = 1")):
a)Извлечение из источника/создание значений-аргументов, в примере извлечение "1" из "s" и создание непосредственно определённого "2".
b)Выполнение операции над значениями-аргументами и получение значения-результата, в примере сложение "1" и "2", результат "3".
c)Помещение значения-результата в приёмник, в примере помещение "3" в переменную "r".
Выражения (типа "r = s + (1 / g) — d * 3") выполняются точно так же, но имеют несколько шагов b), а значение-результат предыдущего шага передаётся в следующий.
Для кортежей это будет соответственно(для "r,g = s,d + 1,2"(s: "int s = 3", d: int d = 4")):
a)"s,d","1,2" -> [3,4],[1,2]
b)[3,4]+[1,2] = [4,6]
c)[4,6] -> "r,g"
3)Кортежи "существуют"(на самом деле их вообще не существует, это ментальный сахар) только пока выполняется оператор/выражение, т.е. их нельзя просто сохранить в переменную(одну).
4)Если в вашем ЯП есть структуры/массивы или что-то подобно необходимо предусмотреть сретсва/правила их декомпозиции в кортеж(на a)) и композиции из кортежа(на b)).
NC>На простых примерах вроде все хорошо, но дальше начинаются противоречия и ужасы.
NC>- поведение таких групп внутри сложных выражений ?
Сложные выражения разбиваются на простые.
NC>- простая, понятная и правильная логика обработки операций над двумя и более кортежами разных размеров ?
Правило дополнения: меньший кортеж дополняется до размера большего копиями своего последнего значения. Например:
s,t,g = 1 //s = 1,t = 1,g = 1
s,t,g = 1,2 //s = 1,t = 2,g = 2
NC>- передача кортежей в функции; по аналогии с возвращаемыми значениями, список аргументов функции тоже кортеж, но если возможен например инкремент сразу трех переменных, то что делать если программист хочет вызвать функцию сразу для трех переменных?
NC>Foo((i,j,k)); //???
NC>- соответственно, получение множественного возврата из обычных функций, в которые передали кортеж (по аналогии с операциями!)
NC>(d1,d3,d3,d4) = sin(0.2, 0.4, 0.6, 0.8); // double sin(double x)
Тут ничего не подскажу(у меня в ЯП функции принимают только один аргумент, и возвращают только один результат или ничего).
NC>- ну и если рассматривать наложение ситуаций множественного возврата и множественных аргументов, то вообще бред получается.
Этого не понял.
Между тем,что я думаю,тем,что я хочу сказать,тем,что я,как мне кажется,говорю,и тем,что вы хотите услышать,тем,что как вам кажется,вы слышите,тем,что вы понимаете,стоит десять вариантов возникновения непонимания.Но всё-таки давайте попробуем...(Э.Уэллс)
Re[3]: Кортежи в языках программирования
От: vl690001x Россия  
Дата: 25.10.12 10:53
Оценка:
Здравствуйте, hardcase, Вы писали:

H>1) Кортежи в C# можно и нужно изготавливать так:

H>
H>Tuple.Create(true, "value");
H>


А в чем разница кроме синтаксиса?
Re[4]: Кортежи в языках программирования
От: hardcase Пират http://nemerle.org
Дата: 25.10.12 10:57
Оценка: +3
Здравствуйте, vl690001x, Вы писали:

V>Здравствуйте, hardcase, Вы писали:


H>>1) Кортежи в C# можно и нужно изготавливать так:

H>>
H>>Tuple.Create(true, "value");
H>>


V>А в чем разница кроме синтаксиса?


В C# нельзя вызвать конструктор опуская параметры типов. В подобных случаях типы очевидны, и их явное указание существенно добавляет визуального мусора.
/* иЗвиНите зА неРовнЫй поЧерК */
Re[5]: Кортежи в языках программирования
От: vl690001x Россия  
Дата: 25.10.12 11:08
Оценка:
Здравствуйте, hardcase, Вы писали:

H>Здравствуйте, vl690001x, Вы писали:


V>>Здравствуйте, hardcase, Вы писали:


H>>>1) Кортежи в C# можно и нужно изготавливать так:

H>>>
H>>>Tuple.Create(true, "value");
H>>>


V>>А в чем разница кроме синтаксиса?


H>В C# нельзя вызвать конструктор опуская параметры типов. В подобных случаях типы очевидны, и их явное указание существенно добавляет визуального мусора.


Спасибо, возьму на заметку)
Re: Кортежи в языках программирования
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 25.10.12 11:52
Оценка: 8 (1) +3
Здравствуйте, NeoCode, Вы писали:

ИМХО, основная проблема кортежей — в безымянности полей. Если типы полей разные (в статике), это еще можно пережить. Но когда типы одинаковые — это ахтунг.
В этом плане анонимные типы аля C# существенно лучше. Но у них другая проблема — исключительно локальная доступность.
В идеале, мне кажется, нужны шарповские анонимные типы + синтаксис для декларации типа без создания экземпляра. Типа такого:
{string Foo, string Bar} Func()
{
  return new {Foo = "foo", Bar = "bar"};
}
... << RSDN@Home 1.2.0 alpha 5 rev. 66 on Windows 8 6.2.9200.0>>
AVK Blog
Re[2]: Кортежи в языках программирования
От: Sinix  
Дата: 25.10.12 12:31
Оценка:
Здравствуйте, AndrewVK, Вы писали:
AVK>В идеале, мне кажется, нужны шарповские анонимные типы + синтаксис для декларации типа без создания экземпляра. Типа такого:
{string Foo, string Bar} Func()
{
  return new {Foo = "foo", Bar = "bar"};
}


Если мы говорим про шарп, то для этого придётся или ограничить использование анонимных типов внутри сборки, или расширять il/рантайм. Иначе код вида
// assembly1
void Func({string Foo, string Bar} x) ...

// assembly2
void Func({string Foo, string Bar} x) ...

// assembly3
void Func2({string Foo, string Bar} x)
{
  ClassFromAssembly1.Func(x);

  ClassFromAssembly2.Func(x);
}

работать не будет.

Если всё-таки добавлять, то я бы выбрал первый вариант. Его сделать относительно несложно, плюс, внешний интерфейс сборки не будет нарушать CLS и не будет проблем с бинарной совместимостью сборок при добавлении в возвращаемый кортеж нового элемента.
Re[3]: Кортежи в языках программирования
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 25.10.12 12:39
Оценка: +1
Здравствуйте, Sinix, Вы писали:

S>Если всё-таки добавлять, то я бы выбрал первый вариант. Его сделать относительно несложно, плюс, внешний интерфейс сборки не будет нарушать CLS и не будет проблем с бинарной совместимостью сборок при добавлении в возвращаемый кортеж нового элемента.


Первый вариант, увы, отсекает очень вкусное использование такого синтаксиса при описании моделей различных. Еще такое очень удобно в сочетании с сокращенным синтаксисом для описания POCO/DTO классов в контрактных сборках.
... << RSDN@Home 1.2.0 alpha 5 rev. 66 on Windows 8 6.2.9200.0>>
AVK Blog
Re[5]: Кортежи в языках программирования
От: batu Украина  
Дата: 25.10.12 12:49
Оценка:
Здравствуйте, NeoCode, Вы писали:

NC>Элементы группы не взаимодействуют между собой при групповых операциях, имеется в виду только взаимодействие i-того элемента группы и другого операнда.

NC>
x -= (1,2,3); // x-=1; x-=2; x-=3;
NC>(x,y,z) -= 10; // x-=10; y-=10; z-=10;
NC>(x,y,z) -= (1,2,3); // x-=1; y-=2; z-=3;



Это как один из вариантов. Почему бы и нет..
Re[2]: Кортежи в языках программирования
От: AlexRK  
Дата: 25.10.12 12:53
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>В идеале, мне кажется, нужны шарповские анонимные типы + синтаксис для декларации типа без создания экземпляра. Типа такого:

AVK>
AVK>{string Foo, string Bar} Func()
AVK>{
AVK>  return new {Foo = "foo", Bar = "bar"};
AVK>}
AVK>


Да, плюс упаковка-распаковка:
string a;
string b;
(a, b) = Func();

// либо
{string Foo, string Bar} tuple; // здесь имена полей должны совпадать с теми, что в Func
tuple = Func();
Re[3]: Кортежи в языках программирования
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 25.10.12 13:03
Оценка:
Здравствуйте, AlexRK, Вы писали:

ARK>Да, плюс упаковка-распаковка:


Упаковка-распаковка нужна только для безимянных кортежей. Когда элементы кортежа имеют полноценное имя, распаковка не нужна. А эквивалентность списка параметров метода кортежу порождает слишком много синтаксических конфликтов.
... << RSDN@Home 1.2.0 alpha 5 rev. 66 on Windows 8 6.2.9200.0>>
AVK Blog
Re[4]: Кортежи в языках программирования
От: AlexRK  
Дата: 25.10.12 13:11
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Здравствуйте, AlexRK, Вы писали:


ARK>>Да, плюс упаковка-распаковка:


AVK>Упаковка-распаковка нужна только для безимянных кортежей. Когда элементы кортежа имеют полноценное имя, распаковка не нужна.


Ну хз, мне кажется, что удобно. И ничему не мешает.

AVK>А эквивалентность списка параметров метода кортежу порождает слишком много синтаксических конфликтов.


Про эквивалентность списка параметров метода кортежу я нигде не говорил.

Говорил про то, что объявления кортежей в сигнатуре метода и в точке вызова должны быть эквивалентны с точностью до наименований полей.
Re[4]: Кортежи в языках программирования
От: Sinix  
Дата: 25.10.12 13:26
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Первый вариант, увы, отсекает очень вкусное использование такого синтаксиса при описании моделей различных. Еще такое очень удобно в сочетании с сокращенным синтаксисом для описания POCO/DTO классов в контрактных сборках.


Ок, тогда можно попробовать компромисс: фактически возвращать и принимать обычный Tuple<string, string>, в il дополнительно описывать имена полей для tuple.
Re[5]: Кортежи в языках программирования
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 25.10.12 13:27
Оценка:
Здравствуйте, AlexRK, Вы писали:

ARK>Ну хз, мне кажется, что удобно. И ничему не мешает.


Чем удобно? Чем такой код:
(a, b) = Func();
a(); b();

сильно удобнее такого:
var ab = Func();
ab.a();ab.b();

?
... << RSDN@Home 1.2.0 alpha 5 rev. 66 on Windows 8 6.2.9200.0>>
AVK Blog
Re[5]: Кортежи в языках программирования
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 25.10.12 13:28
Оценка:
Здравствуйте, Sinix, Вы писали:

S>Ок, тогда можно попробовать компромисс: фактически возвращать и принимать обычный Tuple<string, string>, в il дополнительно описывать имена полей для tuple.


Так можно, да.
... << RSDN@Home 1.2.0 alpha 5 rev. 66 on Windows 8 6.2.9200.0>>
AVK Blog
Re[5]: Кортежи в языках программирования
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 25.10.12 13:36
Оценка: 10 (1) +1
Здравствуйте, Sinix, Вы писали:

S>Ок, тогда можно попробовать компромисс: фактически возвращать и принимать обычный Tuple<string, string>, в il дополнительно описывать имена полей для tuple.


Тут еще может быть стоит подумать, как унифицировать сокращенный синтаксис DTO и синтаксис анонимных типов. Т.е. что то вроде:
record NamedRecord {string X, string Y, record {string Foo, string Bar} FooBar}


Раскрывается в:
class NamedRecord
{
  private string _X;
  private string _Y;
  private Tuple<string, string> _FooBar;
  
  public NamedRecord(string X, string Y, Tuple<string, string> FooBar)
  {
    ...
  }
  
  public string X {get{...}}
  public string Y {get{...}}
  [Name(0, "Foo")]
  [Name(1, "Bar")]
  public Tuple<string, string> FooBar {get{...}}
  
  public override bool Equals(...){...}
  public override int GetHashCode()(...){...}
}
... << RSDN@Home 1.2.0 alpha 5 rev. 66 on Windows 8 6.2.9200.0>>
AVK Blog
Re[6]: Кортежи в языках программирования
От: AlexRK  
Дата: 25.10.12 13:36
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Чем удобно? Чем такой код:

AVK>сильно удобнее такого:

Ну, прям о каком-то новом уровне удобства речи нет, конечно.
Можно, например, распаковывать результат функции прямо в поля объекта — без дополнительных присваиваний.
С другой стороны, минус тоже есть — можно при распаковке перепутать поля одинаковых типов.
Re[7]: Кортежи в языках программирования
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 25.10.12 13:38
Оценка:
Здравствуйте, AlexRK, Вы писали:

ARK>Можно, например, распаковывать результат функции прямо в поля объекта — без дополнительных присваиваний.


Зачем распаковывать поля объекта, когда объект уже есть? Вот когда вместо объекта примитивный тупл, тогда да, тогда смысл имеется. А в случае анонимных типов это уже целый меппер, встроенный в язык, и необходимость его на уровне языка — вопрос открытый.
... << RSDN@Home 1.2.0 alpha 5 rev. 66 on Windows 8 6.2.9200.0>>
AVK Blog
Re[8]: Кортежи в языках программирования
От: AlexRK  
Дата: 25.10.12 13:43
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Здравствуйте, AlexRK, Вы писали:


ARK>>Можно, например, распаковывать результат функции прямо в поля объекта — без дополнительных присваиваний.


AVK>Зачем распаковывать поля объекта, когда объект уже есть? Вот когда вместо объекта примитивный тупл, тогда да, тогда смысл имеется. А в случае анонимных типов это уже целый меппер, встроенный в язык, и необходимость его на уровне языка — вопрос открытый.


Я имею в виду нечто вроде:
class Foo
{
  public static {string A, int B} GetTuple(int param) { ... }
}

class Bar
{
  private int _field1;
  private string _field2;

  void Func()
  {
    (_field2, _field1) = Foo.GetTuple(3);

    // а можно и так:
    var tup = Foo.GetTuple(3);
    _field1 = tup.B;
    _field2 = tup.A;
  }
}
Re[9]: Кортежи в языках программирования
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 25.10.12 13:46
Оценка:
Здравствуйте, AlexRK, Вы писали:

ARK>Я имею в виду нечто вроде:


Ну я и говорю — ты хочешь фактически встроенный в язык меппер.
... << RSDN@Home 1.2.0 alpha 5 rev. 66 on Windows 8 6.2.9200.0>>
AVK Blog
Re: Кортежи в языках программирования
От: igna Россия  
Дата: 25.10.12 14:06
Оценка:
Здравствуйте, NeoCode, Вы писали:

NC>1. возврат нескольких значений из функции


Возврат нескольких значений из функции должен быть таким же как и передача нескольких значений в функцию. То есть если это называется кортеж, то в обоих случаях кортеж. Или в обоих случаях не кортеж.
Re[2]: Кортежи в языках программирования
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 25.10.12 20:25
Оценка: :)
Здравствуйте, igna, Вы писали:

I>Возврат нескольких значений из функции должен быть таким же как и передача нескольких значений в функцию.


Почему?
... << RSDN@Home 1.2.0 alpha 5 rev. 66 on Windows 8 6.2.9200.0>>
AVK Blog
Re[3]: Кортежи в языках программирования
От: igna Россия  
Дата: 26.10.12 07:48
Оценка: :)
Здравствуйте, AndrewVK, Вы писали:

AVK>Почему?


Потому-что нет причин, по которым они должны отличаться.
Re[2]: Кортежи в языках программирования
От: vdimas Россия  
Дата: 26.10.12 10:19
Оценка:
Здравствуйте, igna, Вы писали:


I>Возврат нескольких значений из функции должен быть таким же как и передача нескольких значений в функцию. То есть если это называется кортеж, то в обоих случаях кортеж. Или в обоих случаях не кортеж.


Если речь всё еще о ф-ии, а не о тождестве (уравнении), то ф-ия должна возвращать одно значение. На то она и ф-ия. А тот факт, что это значение может быть составным — пусть обыгрывается системой типов.
Re[3]: Кортежи в языках программирования
От: igna Россия  
Дата: 26.10.12 11:29
Оценка:
Здравствуйте, vdimas, Вы писали:

V>Если речь всё еще о ф-ии, а не о тождестве (уравнении), то ф-ия должна возвращать одно значение. На то она и ф-ия. А тот факт, что это значение может быть составным — пусть обыгрывается системой типов.


Речь-то о функциях в контексте программирования, а не математики. Но даже если, то смотри: Functions with multiple inputs and outputs.

Обрати внимание, что статья про функцию начинается с рассмотрения случая "один аргумент и один результат", а function with multiple outputs появляются в том же разделе где и function with multiple inputs, причем всего несколькими строками ниже.
Re[2]: Кортежи в языках программирования
От: hardcase Пират http://nemerle.org
Дата: 26.10.12 13:58
Оценка:
Здравствуйте, igna, Вы писали:

I>Возврат нескольких значений из функции должен быть таким же как и передача нескольких значений в функцию. То есть если это называется кортеж, то в обоих случаях кортеж. Или в обоих случаях не кортеж.


Вот так можно возвращать несколько значений:
def foo(a : int, b : int) : int * string
{
  def sum = a + b;
  (sum, sum.ToString())
}
def (sum, str) = foo(1, 2);
/* иЗвиНите зА неРовнЫй поЧерК */
Re[3]: Кортежи в языках программирования
От: igna Россия  
Дата: 26.10.12 14:21
Оценка: :)
Здравствуйте, hardcase, Вы писали:

H>Вот так можно возвращать несколько значений:

H>def (sum, str) = foo(1, 2);


А можно так :

1, 2 >- foo -> sum, str


То, что результат находится слева, пошло видимо от арабов (как и слово алгебра). Но арабы писали (и пишут, чудаки) справа налево, и потому нормальным людям не указ. (Это впрочем касается и порядка разрядов в числе от старших к младшим, нормальным слева направо пишущим людям должно быть удобнее наоборот.)
Re[4]: Кортежи в языках программирования
От: hardcase Пират http://nemerle.org
Дата: 26.10.12 15:05
Оценка:
Здравствуйте, igna, Вы писали:

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


Это пошло из школьной математики. Исторически сложилось. Но никто не мешает сразу выполнить анализ:
match (foo(1, 2))
{
 | (1, s) => ...
 | (2, s) => ...
...
}


I>Но арабы писали (и пишут, чудаки) справа налево, и потому нормальным людям не указ. (Это впрочем касается и порядка разрядов в числе от старших к младшим, нормальным слева направо пишущим людям должно быть удобнее наоборот.)


Арабы заимствовали десятичную позиционную систему счисления в Индии.
/* иЗвиНите зА неРовнЫй поЧерК */
Re[2]: Кортежи в языках программирования
От: AlexRK  
Дата: 26.10.12 19:47
Оценка:
Здравствуйте, igna, Вы писали:

I>Здравствуйте, NeoCode, Вы писали:


NC>>1. возврат нескольких значений из функции


I>Возврат нескольких значений из функции должен быть таким же как и передача нескольких значений в функцию. То есть если это называется кортеж, то в обоих случаях кортеж. Или в обоих случаях не кортеж.


Вроде и так, но... Будет либо много синтаксических непоследовательных решений, либо просто странный синтаксис местами.

Если "список параметров" — кортеж, то, получается, можно передать и просто одиночное значение? Как внутри функции ссылаться на это одиночное значение и как ссылаться на части значения-кортежа (а-ля традиционные параметры)? Это далеко не все...

В общем, будет много запредельной кривизны. Хотя идея в целом мне нравится, я ее тоже обдумывал. Но нормального варианта реализации не придумал.
Re[3]: Кортежи в языках программирования
От: igna Россия  
Дата: 27.10.12 07:48
Оценка:
Здравствуйте, AlexRK, Вы писали:

ARK>Если "список параметров" — кортеж ...


По крайней мере для другого случая, а именно, когда список параметров не кортеж, существует простое и понятное решение (пример на C-подобном языке без операции запятая):

int*, size_t get_array_of_int()
{
    int* p;
    size_t n;
    . . .
    return p, n;
}

void f()
{
    int* p1;
    size_t n1;
    p1, n1 = get_array_of_int();
    . . .
    int* p2, size_t n2 = get_array_of_int();
}
Re[4]: Кортежи в языках программирования
От: AlexRK  
Дата: 27.10.12 10:21
Оценка:
Здравствуйте, igna, Вы писали:

I>По крайней мере для другого случая, а именно, когда список параметров не кортеж, существует простое и понятное решение (пример на C-подобном языке без операции запятая):


Предположим. Но тут другая кривость — предложенная вами функция, судя по всему, не может быть частью выражения.

if (get_array_of_int().тут_непонятно_что == 1) { ... }
Re[2]: Кортежи в языках программирования
От: VladD2 Российская Империя www.nemerle.org
Дата: 27.10.12 21:32
Оценка: +1
Здравствуйте, AndrewVK, Вы писали:

AVK>ИМХО, основная проблема кортежей — в безымянности полей. Если типы полей разные (в статике), это еще можно пережить. Но когда типы одинаковые — это ахтунг.


Как показывает реальная практика — это редко является проблемой. В большинстве случаев все очевидно. Другое дело, что в языке должен поддерживаться синтаксис декомпозиции кортежей. Это позволяет задать те самые имена в месте использования.

AVK>В идеале, мне кажется, нужны шарповские анонимные типы + синтаксис для декларации типа без создания экземпляра.


В Шарпе (и дотнете) номинативная система типов, а тут нужна структрурная, иначе типы не будут совместимы между собой. Если в одной сборке их как-то можно "намапить" на один тип, то в случае множества сборок — нет.

Ну, и естественно, эта трава уже 100 лет существует в языках группы ML и называется "запись" (record).

Для качественной реализации этой травы нужна поддержка рантайма. Такие типы должны сравниваться не по имени, а по их их структуре (вложенности и расположению).
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[6]: Кортежи в языках программирования
От: VladD2 Российская Империя www.nemerle.org
Дата: 27.10.12 21:39
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Чем удобно? Чем такой код:

AVK>
AVK>(a, b) = Func();
AVK>a(); b();
AVK>

AVK>сильно удобнее такого:
AVK>
AVK>var ab = Func();
AVK>ab.a();ab.b();
AVK>

AVK>?

Есть такая штука — паттерн-матчинг.
match (Func())
{
  | (a, SomeNestedAndComplexPattern()) => a.Foo();
}

В прочем ни с декомпозицией, ни с МП для записей особых проблем нет.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[8]: Кортежи в языках программирования
От: VladD2 Российская Империя www.nemerle.org
Дата: 27.10.12 21:41
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Зачем распаковывать поля объекта, когда объект уже есть?


Для декомпозиции и сокращения синтаксиса. Те же кортежи отлично передаются в функцию без создания промежуточных переменных. С записями можно делать тоже самое, так как они тоже структурные типы.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: Кортежи в языках программирования
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 27.10.12 21:42
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Как показывает реальная практика — это редко является проблемой.


Практика у всех разная. В моей практике отсутствие предопределенных имен для параметров лямбд (особенно описанных стандартными Action/Func) уже является проблемой. А в случае кортежей это еще важнее.

VD>В Шарпе (и дотнете) номинативная система типов, а тут нужна структрурная


Не нужна.

VD>, иначе типы не будут совместимы между собой


Это вопрос поддержки со стороны рантайма.

VD>Ну, и естественно, эта трава уже 100 лет существует в языках группы ML и называется "запись" (record).


Я в курсе, не переживай. Но рекорд все таки немного не то.

VD>Такие типы должны сравниваться не по имени, а по их их структуре (вложенности и расположению).


Разумеется.
... << RSDN@Home 1.2.0 alpha 5 rev. 66 on Windows 8 6.2.9200.0>>
AVK Blog
Re[9]: Кортежи в языках программирования
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 27.10.12 21:44
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Для декомпозиции и сокращения синтаксиса. Те же кортежи отлично передаются в функцию без создания промежуточных переменных.


Как я уже говорил — декомпозиция кортежа в параметры функции в сочетании с перегрузкой по типам параметров слишком много синтаксических конфликтов порождает. Так что теоретически оно неплохо, уметь кортеж с выхода одной функции неявно распаковать в параметры другой, но на практике вопросов очень много.
... << RSDN@Home 1.2.0 alpha 5 rev. 66 on Windows 8 6.2.9200.0>>
AVK Blog
Re[2]: Кортежи в языках программирования
От: VladD2 Российская Империя www.nemerle.org
Дата: 27.10.12 21:44
Оценка:
Здравствуйте, igna, Вы писали:

I>Возврат нескольких значений из функции должен быть таким же как и передача нескольких значений в функцию. То есть если это называется кортеж, то в обоих случаях кортеж. Или в обоих случаях не кортеж.


Справедливости ради надо заметить, что при передаче параметров функциям есть варианты:
Add(42, "text");
Add(key=42, value="text");
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[4]: Кортежи в языках программирования
От: VladD2 Российская Империя www.nemerle.org
Дата: 27.10.12 21:52
Оценка:
Здравствуйте, igna, Вы писали:

I>То, что результат находится слева, пошло видимо от арабов (как и слово алгебра). Но арабы писали (и пишут, чудаки) справа налево, и потому нормальным людям не указ. (Это впрочем касается и порядка разрядов в числе от старших к младшим, нормальным слева направо пишущим людям должно быть удобнее наоборот.)


Предлагаешь писать цифры наоборот? А что? Отличная идея для 2102 года.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[5]: Кортежи в языках программирования
От: VladD2 Российская Империя www.nemerle.org
Дата: 27.10.12 21:59
Оценка:
Здравствуйте, AlexRK, Вы писали:

ARK>Предположим. Но тут другая кривость — предложенная вами функция, судя по всему, не может быть частью выражения.


ARK>
ARK>if (get_array_of_int().тут_непонятно_что == 1) { ... }
ARK>


Это только если ты зациклен на мэйнтриме. А так без проблема:
if (get_array_of_int() is (ary, 42))
{
  ... ary[41] ...
}

Прошу заметить, что это не гипотетический код, а совершенно реальный код для немерла. Разве что if надо на when заменить, или else добавить.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[10]: Кортежи в языках программирования
От: VladD2 Российская Империя www.nemerle.org
Дата: 27.10.12 22:18
Оценка:
Здравствуйте, AndrewVK, Вы писали:

VD>>Для декомпозиции и сокращения синтаксиса. Те же кортежи отлично передаются в функцию без создания промежуточных переменных.


AVK>Как я уже говорил — декомпозиция кортежа в параметры функции в сочетании с перегрузкой по типам параметров слишком много синтаксических конфликтов порождает. Так что теоретически оно неплохо, уметь кортеж с выхода одной функции неявно распаковать в параметры другой, но на практике вопросов очень много.


Нет никаких конфликтов не выдумывай. И на практике никаких проблем нет. Я передаю кортежи в функции при каждом удобном случае.

А вот в твоей логике конфликт есть. Ты забываешь, что для того чтобы типы были совместимы независимо от точки объявления они обязаны поддерживать структурную эквивалентность. Но структурная эквивалентность автоматически подразумевает игнорирование имен. Таким образом идею именованных кортежей можно легко реализовать только при условии, что имена будут не более чем подсказками и будут переписываться в кортежи. Иначе получается уже какая-то гибридная система в которой будет масса конфликтов. Ведь очень сложно в одном месте имя ни в грош не ставить, а в другом учитывать.

То что ты хочешь можно выразить через виртуальное введение жестких псевдонимов типов. Но это уже довольно сложно (в дотнете и понятия жесткого псевдонима типов то нет). Тогда тип:
{ foo : int; bar : int }

будет переписан в:
type alias foo_int = int;
type alias bar_int = int;
foo_int * bar_int

но тут мы снова получаем проблему несовместимости типов объявленных в разных сборках.

Так что как не крути, а есть всего два пути:
1. Немного доработать рантайм и ввести в него структурные типы.
2. Использовать кортежи, а имена использовать только для сахара позволяющего получать доступ к полям кортежа по именам. При этом имена просто хранить как метаинформацию функций/полей.

Других путей нет.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[4]: Кортежи в языках программирования
От: VladD2 Российская Империя www.nemerle.org
Дата: 27.10.12 22:29
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Практика у всех разная. В моей практике отсутствие предопределенных имен для параметров лямбд (особенно описанных стандартными Action/Func) уже является проблемой. А в случае кортежей это еще важнее.


Твоя практика однобока. Ты банально не используешь языки где есть поддержка кортежей. Так что это даже обсуждать не интересно.

VD>>В Шарпе (и дотнете) номинативная система типов, а тут нужна структрурная


AVK>Не нужна.


Весомое мнение. Продолжая в том же духе ты многих убедишь (себя — точно).

VD>>, иначе типы не будут совместимы между собой


AVK>Это вопрос поддержки со стороны рантайма.


Всего то? В следующий раз не забудь дочитать сообщение на которое отвечаешь хотя бы до середины.

VD>>Ну, и естественно, эта трава уже 100 лет существует в языках группы ML и называется "запись" (record).


AVK>Я в курсе, не переживай. Но рекорд все таки немного не то.


Проблема в том, что "того" просто нельзя сделать. Оно будет противоречивым и мало применимым.

VD>>Такие типы должны сравниваться не по имени, а по их их структуре (вложенности и расположению).


AVK>Разумеется.


Если ты с этим согласен, то остается ответить на вопрос — как совместить идею имен с идеей структурной эквивалентности?

У нас уже получается некий гибрид. Но даже если такой гибрид возможен, для его поддержки нужна хотя бы какая-то поддержка структурной эквивалентности.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[5]: Кортежи в языках программирования
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 27.10.12 22:38
Оценка:
Здравствуйте, VladD2, Вы писали:

AVK>>Практика у всех разная. В моей практике отсутствие предопределенных имен для параметров лямбд (особенно описанных стандартными Action/Func) уже является проблемой. А в случае кортежей это еще важнее.


VD>Твоя практика однобока.


Чья бы корова мычала. Не я тут все топики свожу к обсуждению языка на букву Н. И не я уже лет десять, наверное, занимаюсь ровно одним единственным проектом.

AVK>>Это вопрос поддержки со стороны рантайма.

VD>Всего то? В следующий раз не забудь дочитать сообщение на которое отвечаешь хотя бы до середины.

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

И, если бы ты топик до конца дочитал, ты бы увидел, что эту проблему тут уже обсудили и ты ничего нового не сказал.

VD>У нас уже получается некий гибрид. Но даже если такой гибрид возможен, для его поддержки нужна хотя бы какая-то поддержка структурной эквивалентности.


Ну, "какая то" может и нужна. "Какая то" уже в шарпе есть — и в наложении делегатов на методы, и в существующих анонимных типах. Вопрос только в том — какая. Полномасштабная — не нужна.
... << RSDN@Home 1.2.0 alpha 5 rev. 66 on Windows 8 6.2.9200.0>>
AVK Blog
Re[6]: Кортежи в языках программирования
От: VladD2 Российская Империя www.nemerle.org
Дата: 27.10.12 23:11
Оценка: -1
Здравствуйте, AndrewVK, Вы писали:

AVK>Чья бы корова мычала. Не я тут все топики свожу к обсуждению языка на букву Н.


Действительно чья бы молчала? Ну, так чисто логически?

AVK>И не я уже лет десять, наверное, занимаюсь ровно одним единственным проектом.


А кто же еще? Или ты ушел из энтерпайза и начал писать на языке отличном от C#?

В общем, не обижайся, но говорить о практике можно только имея эту практику. Попиши хотя бы пару месяцев на языке с кортежами (не обязательно на букву N, можно на F, H, M) и тогда обсудим практику. А до тех пор, давай будем доверять мнению тех из нас, кто это уже сделал. Я не только на основании своего мнения вывод делаю. Я у многих пишущих на ФЯ этот вопрос выяснял и мнение единодушное — кортежи очень удобны при наличии ПМ.

AVK>>>Это вопрос поддержки со стороны рантайма.

VD>>Всего то? В следующий раз не забудь дочитать сообщение на которое отвечаешь хотя бы до середины.

AVK>Это ты попробуй немножко голову включить




AVK> — структурная типизация необязательна. Если можно обойтись без нее в рамках одной сборки, значит нет никаких принципиальных проблем обойтись без нее и в нескольких сборках.


Обязательно. Обойтись без нее нельзя. Ее можно эмулировать в рамках одной сборки (тупо заменяя все типы с одним и тем же именем на один тип). Но это все равно будет структурня типизация. Вот только довольно странная — первого порядка.

AVK>И, если бы ты топик до конца дочитал, ты бы увидел, что эту проблему тут уже обсудили и ты ничего нового не сказал.


То что ничего нового (за последние 5 лет) не сказали — я уже видел. Но это ничего не меняет. Потому как 10 раз повторенное заблуждение не становится истиной.

VD>>У нас уже получается некий гибрид. Но даже если такой гибрид возможен, для его поддержки нужна хотя бы какая-то поддержка структурной эквивалентности.


AVK>Ну, "какая то" может и нужна. "Какая то" уже в шарпе есть — и в наложении делегатов на методы, и в существующих анонимных типах. Вопрос только в том — какая. Полномасштабная — не нужна.


В шарпе — нет (за исключением параметрического полиморфизма, которого явно не достаточно).

Да и полномасштабная тоже нужна. Правда не для шарпа, а для того, чтобы быть реально платформой для разных языков, а не только в рекламных буклетах.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[6]: Кортежи в языках программирования
От: AlexRK  
Дата: 28.10.12 07:28
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Это только если ты зациклен на мэйнтриме. А так без проблема:

VD>
VD>if (get_array_of_int() is (ary, 42))
VD>{
VD>  ... ary[41] ...
VD>}
VD>


Да нет, я ни на чем не зациклен. Но как этот ваш код может быть подставлен, например, в такое выражение:
if (myvar + Math.Pow(get_array_of_int().неясно_как_тут_вытащить_массив.Length + 10, 3) > 1) { ... }

Похоже, что никак. Надо распаковать результат функции, потом его части подставлять в выражение. А это уже непоследовательность с идеологической точки зрения.
Re[7]: Кортежи в языках программирования
От: VladD2 Российская Империя www.nemerle.org
Дата: 28.10.12 18:09
Оценка: 1 (1)
Здравствуйте, AlexRK, Вы писали:

ARK>Да нет, я ни на чем не зациклен.


ОК, "зациклен" здесь не совсем правильный термин. Скажем по другому — отсутствие знакомства с альтернативой.

ARK>Но как этот ваш код может быть подставлен, например, в такое выражение:

ARK>
ARK>if (myvar + Math.Pow(get_array_of_int().неясно_как_тут_вытащить_массив.Length + 10, 3) > 1) { ... }
ARK>


Я не уверен в том, что правильно понял пример. Но если стоит задача взять значение одного из элементов кортежа и использовать его в выражении, то в немерле это делается с помощью индексирования константным значением:
if (myvar + Math.Pow(get_array_of_int()[0].Length + 10, 3) > 1) { ... }


Кроме того есть еще много разных вкусностей вроде того, что все является выражением, так что можно объявить блок и вернуть из него значение:
{ def (x, y) = foo(); x + y } // вернет сумму элементов кортежа возвращенного функцией foo().

и многое другое.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[8]: Кортежи в языках программирования
От: AlexRK  
Дата: 28.10.12 18:52
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Я не уверен в том, что правильно понял пример. Но если стоит задача взять значение одного из элементов кортежа и использовать его в выражении


Да, именно это я и имел в виду.

VD>то в немерле это делается с помощью индексирования константным значением:

VD>
VD>if (myvar + Math.Pow(get_array_of_int()[0].Length + 10, 3) > 1) { ... }
VD>


Понял, спасибо. В принципе да, можно и такой подход применить, как вариант. Правда, есть риск при чтении кода спутать с массивом, ну и при рефакторинге можно нарваться на неприятность, если в тупле чего-нибудь изменить.
Re[9]: Кортежи в языках программирования
От: VladD2 Российская Империя www.nemerle.org
Дата: 28.10.12 21:57
Оценка:
Здравствуйте, AlexRK, Вы писали:

ARK>Правда, есть риск при чтении кода спутать с массивом,


Те же аргументы можно было бы использовать против индексаторов в классах, но вряд ли ты будешь возражать против них (так как пользуешься ими на практике и проблем не видишь).

Потом это вопрос синтаксиса. Тут можно и предопределенные поля использовать (как в Tuple<...> из дотнета). Главное, что это нет проблем получить значение одного из элементов.

ARK>ну и при рефакторинге можно нарваться на неприятность, если в тупле чего-нибудь изменить.


Тут полная аналогия с вызовом методов/функций. В большинстве сиподобных языков при вызове имена параметров опускаются, но мало кто рассуждает о проблемах при рефакторинге.

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

С кортежами имеет место банальное отсутствие практики. Они родились в ФЯ и пока еще не попали в статически-типизированные мэйнсрим-языки. На мой взгляд просто по недоразумению.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[10]: Кортежи в языках программирования
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 30.10.12 12:01
Оценка:
Здравствуйте, VladD2, Вы писали:

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


Вообще говоря останавливает, только не всех разумеется. Для примера смотри в шаблоны С++. Большая часть с++ программистов их тупо не понимает, отсюда неудивительно наблюдать здесь два лагеря, одни пишут по простому, их большинство,а другие в духе буста и александреску — их меньшинство.
Re[11]: Кортежи в языках программирования
От: VladD2 Российская Империя www.nemerle.org
Дата: 30.10.12 15:42
Оценка:
Здравствуйте, Ikemefula, Вы писали:

I>Вообще говоря останавливает, только не всех разумеется. Для примера смотри в шаблоны С++. Большая часть с++ программистов их тупо не понимает, отсюда неудивительно наблюдать здесь два лагеря, одни пишут по простому, их большинство,а другие в духе буста и александреску — их меньшинство.


Это не связанные вещи. Основной проблемой мешающей создать качественный рефакторинг в С++ — это препроцессор (особенно #include) и отсутствие полноценной модульности. Сравнивать это с применение кортежей по меньшей мере странно. Уверяю тебя, что если в шарпе или С++ появится поддержка кортежей и сопоставления с образцом, ими будут пользоваться большинство программистов.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[12]: Кортежи в языках программирования
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 30.10.12 16:01
Оценка: :)
Здравствуйте, VladD2, Вы писали:

VD>Здравствуйте, Ikemefula, Вы писали:


I>>Вообще говоря останавливает, только не всех разумеется. Для примера смотри в шаблоны С++. Большая часть с++ программистов их тупо не понимает, отсюда неудивительно наблюдать здесь два лагеря, одни пишут по простому, их большинство,а другие в духе буста и александреску — их меньшинство.


VD>Это не связанные вещи. Основной проблемой мешающей создать качественный рефакторинг в С++ — это препроцессор (особенно #include) и отсутствие полноценной модульности. Сравнивать это с применение кортежей по меньшей мере странно. Уверяю тебя, что если в шарпе или С++ появится поддержка кортежей и сопоставления с образцом, ими будут пользоваться большинство программистов.


Смотрим твою идейку:
"в коде много мест где при рефакторинге (особенно ручном) можно легко что-то сломать. Но это не останавливает людей от применения этих возможностей"

Внезпно она превратилась в следующюю
"в коде много мест где при рефакторинге (особенно ручном), кроме случаев рефакторинга в С++, можно легко что-то сломать. Но это не останавливает людей от применения этих возможностей"

Вобщем ты начал хитрить

Вообще, по моему, языки не ориентированые на полноценный качественный рефакторинг должны обладать адскими преимуществами, что бы использоваться в индустрии. У C/С++ , например, одно из преимуществ это перформанс низкоуровневого кода от которого пока что никуда не деться. Скажем, ассемблеры уже давно не дают этот перформанс, т.к. процессоры слишком сложны для ручных оптимизаций.
Re[3]: Кортежи в языках программирования
От: NeoCode  
Дата: 01.11.12 07:47
Оценка:
Здравствуйте, hardcase, Вы писали:

H>Вот так можно возвращать несколько значений:

H>
H>def foo(a : int, b : int) : int * string
H>{
H>  def sum = a + b;
H>  (sum, sum.ToString())
H>}
H>def (sum, str) = foo(1, 2);
H>


Если возможно написать def (sum, str) = foo(1, 2), то можно ли написать def (sum, str) = (1, "Hello") ?
Если sum и str определены ранее, то можно их сгруппировать без def ? то есть типа такого (синтаксиса nemerle не знаю, но думаю что понятно я имею в виду)
def sum;
def str;
/// code
(sum, str) = foo(1, 2);
Re[4]: Кортежи в языках программирования
От: hardcase Пират http://nemerle.org
Дата: 01.11.12 09:41
Оценка:
Здравствуйте, NeoCode, Вы писали:

NC>Если возможно написать def (sum, str) = foo(1, 2), то можно ли написать def (sum, str) = (1, "Hello") ?


Можно.

NC>Если sum и str определены ранее, то можно их сгруппировать без def ? то есть типа такого (синтаксиса nemerle не знаю, но думаю что понятно я имею в виду)

NC>
def sum;
NC>def str;
NC>/// code
NC>(sum, str) = foo(1, 2);


А вот так в Nemerle нельзя. Сопоставление может вводить новые переменные, но никак не изменять уже существующие.
/* иЗвиНите зА неРовнЫй поЧерК */
Re[5]: Кортежи в языках программирования
От: NeoCode  
Дата: 01.11.12 17:07
Оценка:
Здравствуйте, hardcase, Вы писали:

NC>>Если возможно написать def (sum, str) = foo(1, 2), то можно ли написать def (sum, str) = (1, "Hello") ?

H>Можно.

ОК, а можно ли кроме присваивания-инициализации использовать другие операции? Написать def (x, y) = (1, 2) + (3, 4) ?
Re[7]: FHM
От: D. Mon Великобритания http://thedeemon.livejournal.com
Дата: 02.11.12 12:36
Оценка: :))
Здравствуйте, VladD2, Вы писали:

VD> Попиши хотя бы пару месяцев на языке с кортежами (не обязательно на букву N, можно на F, H, M) и тогда обсудим практику.


O! Теперь я знаю, что означает название мужского журнала FHM — F#, Haskell, ML!
Re[6]: Кортежи в языках программирования
От: D. Mon Великобритания http://thedeemon.livejournal.com
Дата: 02.11.12 12:42
Оценка:
Здравствуйте, NeoCode, Вы писали:

NC>ОК, а можно ли кроме присваивания-инициализации использовать другие операции? Написать def (x, y) = (1, 2) + (3, 4) ?


В некоторых языках можно, если предварительно описать, что именно должна делать операция + на кортежах с такими типами.
let (+) : int * string -> int * string -> int * string = fun (a,b) (c,d) -> a + c, b ^ d;;
let (x,y) = (1, "aa") + (2, "bb");;

выдает:
val x : int = 3
val y : string = "aabb"
Re[7]: Кортежи в языках программирования
От: _NN_ www.nemerleweb.com
Дата: 05.11.12 07:39
Оценка:
Здравствуйте, D. Mon, Вы писали:

DM>Здравствуйте, NeoCode, Вы писали:


NC>>ОК, а можно ли кроме присваивания-инициализации использовать другие операции? Написать def (x, y) = (1, 2) + (3, 4) ?


DM>В некоторых языках можно, если предварительно описать, что именно должна делать операция + на кортежах с такими типами.


Например в Nemerle
using Q;

module Q
{
 public @+(l : int * string, r : int * string) : int * string { (l[0] + r[0], l[1] + r[1]) }
}
 
def a = (1, "a");
def b = (2, "b");
def c = a + b;
 
System.Console.WriteLine($"$c");
http://rsdn.nemerleweb.com
http://nemerleweb.com
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.