Inline records
От: VladD2 Российская Империя www.nemerle.org
Дата: 10.10.09 13:23
Оценка: 48 (5) +4 :)
Идея инспирирована вот этой темой
Автор: IDL
Дата: 05.10.09
, анонимными типами C# и списком аргументов.

Для начала пояснения.

Как рассматриваются кортежи (tuple-ы) в функциональных языках (ФЯ)? Не скажу за все языки (хотя почти уверен, что в других ФЯ все обстоит сходным образом), но в Nemerle кортеж — это не просто структура данных. Кортеж — это часть дизайна языка. Дело в том, что в немерле (далее, для понимания, можно смело мысленно заменять немерле на ФЯ) функция является очень важным объектом. А раз функция — это объект, то у нее должен быть тип. Так вот, тип функции описывается как "X -> Y" (без кавычек), где X и Y — это типы. X — это тип аргументов, а Y — возвращаемого значения. Заметьте, в этом описании нет списка аргументов! Аргумент один! Это не случайно. Под этим есть не хилая теоретическая основа лямбда-исчесления Чёрча. Но язык тем не менее поддерживает функции с более чем одним аргументом. Как же это возможно?

Наличие функций с более чем одним параметром возможно благодаря кортежам. Если функция принимает два параметра один из которых строка, а второй целое, то такая функция записывается как "string * int -> Y". Таким образом типом параметров такой функции является кортеж "string * int". Логично, что и возвращаемое значение может быть так же кортежем, например, "string * int -> string * int".

В чем же проблема? Проблема в том, что простые смертные оперируют конкретикой. Для них мало абстрактных типов аргументов и возвращаемого значения. Им нужны еще названия параметров. Название параметров локально для функции в которой они объявлены (для ее реализации). По сути программист думает о списке параметров функции как о наборе локальных переменных.

Теперь, собственно предложение.

А почему бы не рассматривать возвращаемое значение функции так же как набор параметров? При этом синтаксис может быть совершенно разрообразным. Например, мы можем объявлять функцию так:
Гипотетический язык:
/*in parameters*/(string param1, int param2) FuncName /*out parameters*/(string ret1, int ret2)
{
}

/*in parameters*/(string param1) FuncName /*out parameters*/(int ret2)
{
}

Расширение C#:
(string ret1, int ret2) FuncName(string param1, int param2)
{
}

(string ret1) FuncName(int param2)
{
}


Кроме того в шарпе можно использовать следующее соглашение. Функцию описанную так:
string FuncName(string param1, inout int param2)
{
}

можно рассматривать как функцию с типом: string * int -> string * int и соответственно применять без передачи параметра по ссылке.
А функцию:
string FuncName(string param1, out int param2)
{
}

можно рассматривать как функцию с типом: string -> string * int и соответственно применять:
var (str, num) = FuncName("abc");

Расширение немерле:
FuncName(param1 : string, param2 : int) -> (ret1 : string, ret2 : int)
{
}

(string ret1, int ret2) FuncName (string param1, int param2)
{
}
[/c#]

Так как в таких сигнатурах имеются имена "полей", то конструкция декомпозиции (опять же обращаемся к немерле):
def (var1, var2, var3) = f();

можно обеспечить дополнительный контроль и поддержку IDE.
Кроме того можно будет будет использовать следующий синтаксис:
def x = f();
... = x.var1 + x.var2;
... x.var3

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

Сам тип при этом остается совместимым с кортежем и может передаваться всюду где используется обычные кортежи (с не именованными полями).

Такое решение подойдет и для языков (точнее их рантаймов) в которых есть поддержка записей, и для рантаймов вроде дотнета где по недомыслию разработчиков типа "запись" нет. Причем для вторых такое решение будет даже более нужным, так как оно позволяет улучшить языки работающие на этой платформе без изменения самой платформы.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re: Inline records
От: samius Япония http://sams-tricks.blogspot.com
Дата: 10.10.09 13:58
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Наличие функций с более чем одним параметром возможно благодаря кортежам. Если функция принимает два параметра один из которых строка, а второй целое, то такая функция записывается как "string * int -> Y". Таким образом типом параметров такой функции является кортеж "string * int". Логично, что и возвращаемое значение может быть так же кортежем, например, "string * int -> string * int".


VD>В чем же проблема? Проблема в том, что простые смертные оперируют конкретикой. Для них мало абстрактных типов аргументов и возвращаемого значения. Им нужны еще названия параметров.


Проблема не только в этом. А так же в том, что запись string*int->Y не совсем соответствует действительности для платформы .NET. В немерле так принято записывать только потому что string->int->Y еще больше не соответсвует действительности.
Допустим, что мы имеем функцию string * int -> string * int, которая принимает "якобы" кортеж (а на самом деле два аргумента через запятую), а возвращает именно кортеж. Проблема в том, что чтобы подать результат функции на ее же вход, потребуется кортеж разделить на части и подать их по-частям. Очевидно, что мы не можем записывать одинаково то что физически является разными вещами (вход и выход).
Т.е. если мы оставляем запись string*int для обозначения кортежа, то функция типа string*int->string*int должна как принимать именно кортеж, так и возвращать его.

Кроме того, мы должны уметь передавать кортежи в функцию, и передача (string, string * int) не должна автоматически преобразоваться в (string * string * int).

VD>Теперь, собственно предложение.


VD>Расширение C#:

VD>
VD>(string ret1, int ret2) FuncName(string param1, int param2)
VD>{
VD>}

VD>(string ret1) FuncName(int param2)
VD>{
VD>}
VD>


Я уже где-то недавно в шутку предлагал (возможно в той теме) вариант с возвратом из метода анонимного типа.
Что-то воде
{string ret1, int ret2} FuncName(string param1, int param2)
{
}

Т.е. хочется скрестить ужа с ежом и получить анонимный тип с позиционным доступом или тупл с именованными свойствами, причем с полной совместимостью по типу, невзирая на имена свойств.
И разрешить не только возвращать такие штуки, но и принимать их и объявлять в теле метода.

{ r1, r2 } = Func(p1, p2);

и

{ string ret1, int ret2 } FuncName(string param1, { string p1, int p2 })

Причем, результат совместим с типом второго аргумента функции.
Re: Inline records
От: samius Япония http://sams-tricks.blogspot.com
Дата: 10.10.09 14:43
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Теперь, собственно предложение.


Справедливо стоит заметить, что предлагать начал Undying здесь
Автор: Undying
Дата: 06.10.09
. Правда, его предложение, хоть и с изменением синтаксиса, но было основано на расширении дженериков.
Мне же кажется, что надо идти не от туплов к анонимным типам, а от анонимных типов к туплам. И сделать-то надо небольшой шаг — зафиксировать позиции элементов, как в тупле и обеспечить совместимость с анонимными типами, имеющих аналогичные типы на тех же позициях.
Обращаться к свойствам анонимного типа даже удобнее, чем к элементам тупла:

var x = Foo(); // возвращает анонимный тип с сигнатурой, вынесенной в сигнатуру метода Foo()
Console.WriteLine(x.a);

vs
{ a1, b1 } = Foo();
Console.WriteLine(a1);
Re: Inline records
От: Nuzhny Россия https://github.com/Nuzhny007
Дата: 10.10.09 14:48
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Идея инспирирована вот этой темой
Автор: IDL
Дата: 05.10.09
, анонимными типами C# и списком аргументов.

VD>...
VD>А почему бы не рассматривать возвращаемое значение функции так же как набор параметров? При этом синтаксис может быть совершенно разрообразным.

В lua функция может возвращать несколько значений. И я не думаю, что это какая-то инновационная идея.
Re[2]: Inline records
От: VladD2 Российская Империя www.nemerle.org
Дата: 10.10.09 15:23
Оценка: +2
Здравствуйте, samius, Вы писали:

S>Проблема не только в этом. А так же в том, что запись string*int->Y не совсем соответствует действительности для платформы .NET. В немерле так принято записывать только потому что string->int->Y еще больше не соответсвует действительности.


-1

S>Допустим, что мы имеем функцию string * int -> string * int, которая принимает "якобы" кортеж (а на самом деле два аргумента через запятую), а возвращает именно кортеж. Проблема в том, что чтобы подать результат функции на ее же вход, потребуется кортеж разделить на части и подать их по-частям.


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

S>Очевидно, что мы не можем записывать одинаково то что физически является разными вещами (вход и выход).


Очевидно, что твоя теория неверна, в следствии не верности предпосылок.

S>Т.е. если мы оставляем запись string*int для обозначения кортежа, то функция типа string*int->string*int должна как принимать именно кортеж, так и возвращать его.


Она так и делает. Вот так записывается конструктор кортежа:
("aaa", 12)

а вот так вызов функции:
f("aaa", 12)

найдите 10 различий.

S>Кроме того, мы должны уметь передавать кортежи в функцию, и передача (string, string * int) не должна автоматически преобразоваться в (string * string * int).


Нет никаких "string, string * int" есть описание типа в котом всегда используются "*" для отделения типов, и описание конструктора кортежа в котором всегда используются запятые в качестве разделителей. Но это все условности и ни что не мешает описывать типы так же через запятую.

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


Ёж и уж видны только тем, кто кроме ООП в своей жизни больше ничего не видел. Практически во всех языках отличных от С++ и его наследников есть такие типы как кортеж и запись, причем кортеж считается записью у которой отсутствуют имена полей. Так что это совершенно нормальная вещь.

А "с полной совместимостью по типу, невзирая на имена свойств" называется структурной эквивалентностью. Она тоже есть почти во всех языках, даже в С++ (но не в Яве и Шарпе).
Так вот для анонимных типов структурная эквивалентность не поддерживается. Причем это проблема CLR.
Я же предлагаю не объявление нового типа, как кому-то тут показалось, а аннотацию кортежа. Мы же не говорим, что параметры функции — это анонимный тип только на основании того, что у них есть имена? Вот тут та же фигня. Имена всего лишь дополнительная аннотация не вводящая новый тип, но повышающая удобство на практике.

S>И разрешить не только возвращать такие штуки, но и принимать их и объявлять в теле метода.


Это идея здравая. Например, если у нас есть функция типа:
void f(int x, List<int * string> xs)

то было бы не плохо записать ее в более ясном виде:
void f(int x, List<int x, string name> xs)


S>
S>{ r1, r2 } = Func(p1, p2);
S>

S>и

S>
S>{ string ret1, int ret2 } FuncName(string param1, { string p1, int p2 })
S>

S>Причем, результат совместим с типом второго аргумента функции.

1. Зачем тут фигурные скобки? Все равно это не синтаксис анонимных типов.
2. Для соместимости анонимных типов нужна поддержка CLR. Иначе ничего не получится, если функция будет объявлена в одной сборке, а анонимный тип в другой.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[2]: Inline records
От: VladD2 Российская Империя www.nemerle.org
Дата: 10.10.09 15:29
Оценка: 1 (1)
Здравствуйте, samius, Вы писали:

S>Мне же кажется, что надо идти не от туплов к анонимным типам, а от анонимных типов к туплам.


Вам Майкрософт мозг вы...л своими названиями. То что МС (и ты) называешь анонимными типами давным довно называлось записями и являлось разновидностью кортежей с именованными полями. Вся теория реляционных БД на этом построена.

Так вот анонимные типы — это недоразумение возникшее в следствии того, что в МС вместо грамотного проектирования всей системы (CLR и языков) решали частную проблему встраивания запросов в язык. Проблема этого неполноценного решения заключается в том, что в дотнет нет структурной эквивалентности, а без него тип (именно полноценный тип, а не синтаксический сахар, что бы встроен в шарп) создать нельзя.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[2]: Inline records
От: VladD2 Российская Империя www.nemerle.org
Дата: 10.10.09 15:32
Оценка:
Здравствуйте, Nuzhny, Вы писали:

N>В lua функция может возвращать несколько значений. И я не думаю, что это какая-то инновационная идея.


Да пол языков может возвращать множество значений. Разговор был не о том. Речь идет об включении в описание функции имен этих отдельных значений.

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

Прочитай еще раз написанное.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: Inline records
От: samius Япония http://sams-tricks.blogspot.com
Дата: 10.10.09 18:22
Оценка:
Здравствуйте, VladD2, Вы писали:

S>>Допустим, что мы имеем функцию string * int -> string * int, которая принимает "якобы" кортеж (а на самом деле два аргумента через запятую), а возвращает именно кортеж. Проблема в том, что чтобы подать результат функции на ее же вход, потребуется кортеж разделить на части и подать их по-частям.


VD>Не по требуется. Точнее не требуется. Язык "работает" на уровне своих абстракций. В немерле кортеж подходящего типа можно передать в функцию без проблем.

Не знал.
Но в четвертом дотнете есть вполне определенный тип Tuple<,,,>, который в том же цэ-шарпе без проблем не залезет в функцию, если не объявить ее параметры туплом.

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

Только для кортежа? Или ничего не стоит передать Rectangle вместо 4х интов?

S>>Очевидно, что мы не можем записывать одинаково то что физически является разными вещами (вход и выход).


VD>Очевидно, что твоя теория неверна, в следствии не верности предпосылок.

Вообще я полагал что речь именно о способе передачи библиотечного типа а не о встроенной поддержки кортежей языком.

S>>Т.е. если мы оставляем запись string*int для обозначения кортежа, то функция типа string*int->string*int должна как принимать именно кортеж, так и возвращать его.


VD>Она так и делает. Вот так записывается конструктор кортежа:

VD>
("aaa", 12)

VD>а вот так вызов функции:
VD>
f("aaa", 12)

VD>найдите 10 различий.

А как будет выглядеть передача кортежа в TryGetValue(TKey, out TValue)?

S>>Кроме того, мы должны уметь передавать кортежи в функцию, и передача (string, string * int) не должна автоматически преобразоваться в (string * string * int).


VD>Нет никаких "string, string * int" есть описание типа в котом всегда используются "*" для отделения типов, и описание конструктора кортежа в котором всегда используются запятые в качестве разделителей. Но это все условности и ни что не мешает описывать типы так же через запятую.

Когда есть поддержка языка — не мешает. КОгда нет, то речь идет об string, Tuple<string, int>! И это далеко не эквивалентно Tuple<string, string, int>.

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


VD>Ёж и уж видны только тем, кто кроме ООП в своей жизни больше ничего не видел. Практически во всех языках отличных от С++ и его наследников есть такие типы как кортеж и запись, причем кортеж считается записью у которой отсутствуют имена полей. Так что это совершенно нормальная вещь.

Обижаешь, видел. И знаю, что это нормальная вещь. И вот структурная эквивалентность кортежа и записи показалась мне неплохой идеей.

VD>А "с полной совместимостью по типу, невзирая на имена свойств" называется структурной эквивалентностью. Она тоже есть почти во всех языках, даже в С++ (но не в Яве и Шарпе).

Просто не знал названия явления.

VD>Так вот для анонимных типов структурная эквивалентность не поддерживается. Причем это проблема CLR.

Видимо потому, как не предполагался взгляд на анонимный тип как на позиционную структуру.

VD>Я же предлагаю не объявление нового типа, как кому-то тут показалось, а аннотацию кортежа. Мы же не говорим, что параметры функции — это анонимный тип только на основании того, что у них есть имена? Вот тут та же фигня. Имена всего лишь дополнительная аннотация не вводящая новый тип, но повышающая удобство на практике.

А кто предлагал вводить тип?

S>>И разрешить не только возвращать такие штуки, но и принимать их и объявлять в теле метода.


VD>Это идея здравая. Например, если у нас есть функция типа:

VD>
VD>void f(int x, List<int x, string name> xs)
VD>

Приписывание имен к дженерик аргументам — не моя идея, а Undying-а.

S>>
S>>{ r1, r2 } = Func(p1, p2);
S>>

S>>и

S>>
S>>{ string ret1, int ret2 } FuncName(string param1, { string p1, int p2 })
S>>

S>>Причем, результат совместим с типом второго аргумента функции.

VD>1. Зачем тут фигурные скобки? Все равно это не синтаксис анонимных типов.

VD>2. Для соместимости анонимных типов нужна поддержка CLR. Иначе ничего не получится, если функция будет объявлена в одной сборке, а анонимный тип в другой.

Ну вот а я полагал синтаксис анонимных типов как раз. Вместе с их совместимостью и разанонимированием.

Насколько я помню, после выхода C#3.0, разговоры о возможности передавать анонимные типы между сборками велись и фича вроде бы приурочивалась ко смене CLR. Если бы до этого дошло в C#4, то полагаю, их совместимость уже была бы. Но мы почему-то вместо свойств Item1, Item2, Item{K} у анонимных типов получили новые типы Tuple.
Re[3]: Inline records
От: samius Япония http://sams-tricks.blogspot.com
Дата: 10.10.09 19:00
Оценка:
Здравствуйте, VladD2, Вы писали:

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


S>>Мне же кажется, что надо идти не от туплов к анонимным типам, а от анонимных типов к туплам.


VD>Вам Майкрософт мозг вы...л своими названиями. То что МС (и ты) называешь анонимными типами давным довно называлось записями и являлось разновидностью кортежей с именованными полями. Вся теория реляционных БД на этом построена.


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

VD>Так вот анонимные типы — это недоразумение возникшее в следствии того, что в МС вместо грамотного проектирования всей системы (CLR и языков) решали частную проблему встраивания запросов в язык. Проблема этого неполноценного решения заключается в том, что в дотнет нет структурной эквивалентности, а без него тип (именно полноценный тип, а не синтаксический сахар, что бы встроен в шарп) создать нельзя.


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

Ты же предлагаешь для C#-а третью сущность вслед за анонимными типами и туплами (в том виде, в котором они были вытащены из FSharp.Core), а именно то, как оно должно было бы быть, если бы об этом подумали до появления анонимных типов и рискнули бы сменить CLR еще тогда. Это хоть и правильно, но это уже не путь C#. А вот допилка анонимных типов — это все еще вариант (пока, может быть).

Да, в F#-е эти туплы хоть и имеют должную поддержку языка, но вызов метода с передачей кортежа вместо аргументов через запятую (как в немерле) и там не реален. Потому то меня и смутила форма записи типа кортежа со звездой приминительно к немерле (я ожидал от его кортежей чего-то подобного F#-у).
Re: Inline records
От: Lloyd Россия  
Дата: 10.10.09 19:18
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Кроме того можно будет будет использовать следующий синтаксис:

VD>
VD>def x = f();
VD>... = x.var1 + x.var2;
VD>... x.var3
VD>


Если я правильно понимаю, в этом случае одинаковые по сигнатуре (типы входных/выходных параметров) функции не будут совместимы?
Re[2]: Inline records
От: VladD2 Российская Империя www.nemerle.org
Дата: 10.10.09 19:59
Оценка:
Здравствуйте, Lloyd, Вы писали:

L>Если я правильно понимаю, в этом случае одинаковые по сигнатуре (типы входных/выходных параметров) функции не будут совместимы?


Да. Для немерел они и сейчас совместимы, т.е. если функция возвращает кортеж совместимый с параметрами другой функции, то можно вложить вызов первой во второй.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: Inline records
От: Lloyd Россия  
Дата: 10.10.09 20:05
Оценка:
Здравствуйте, VladD2, Вы писали:

L>>Если я правильно понимаю, в этом случае одинаковые по сигнатуре (типы входных/выходных параметров) функции не будут совместимы?


VD>Да. Для немерел они и сейчас совместимы, т.е. если функция возвращает кортеж совместимый с параметрами другой функции, то можно вложить вызов первой во второй.


Кажется, ты не заметил "не" в вопросе.
Re: Inline records
От: thesz Россия http://thesz.livejournal.com
Дата: 10.10.09 20:26
Оценка: 6 (1) -2
Здравствуйте, VladD2, Вы писали:

VD>Идея инспирирована вот этой темой
Автор: IDL
Дата: 05.10.09
, анонимными типами C# и списком аргументов.


VD>Для начала пояснения.


VD>Как рассматриваются кортежи (tuple-ы) в функциональных языках (ФЯ)? Не скажу за все языки (хотя почти уверен, что в других ФЯ все обстоит сходным образом), но в Nemerle кортеж — это не просто структура данных.


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

А то начал за здравие — кортежи в функциональных языках, — а закончил за упокой — в Nemerle так, про другие не знаю.

http://www.haskell.org/ghc/docs/latest/html/libraries/ghc-prim/GHC-Tuple.html

data (,) a b = (,) a b
data (,,) a b c = (,,) a b c
data (,,,) a b c d = (,,,) a b c d
data (,,,,) a b c d e = (,,,,) a b c d e
data (,,,,,) a b c d e f = (,,,,,) a b c d e f
data (,,,,,,) a b c d e f g = (,,,,,,) a b c d e f g
data (,,,,,,,) a b c d e f g h = (,,,,,,,) a b c d e f g h
data (,,,,,,,,) a b c d e f g h i = (,,,,,,,,) a b c d e f g h i
data (,,,,,,,,,) a b c d e f g h i j = (,,,,,,,,,) a b c d e f g h i j
Yours truly, Serguey Zefirov (thesz NA mail TOCHKA ru)
Re[4]: Inline records
От: VladD2 Российская Империя www.nemerle.org
Дата: 10.10.09 23:07
Оценка: +1
Здравствуйте, Lloyd, Вы писали:

L>>>Если я правильно понимаю, в этом случае одинаковые по сигнатуре (типы входных/выходных параметров) функции не будут совместимы?


L>Кажется, ты не заметил "не" в вопросе.


Ты бы расшифровал свой вопрос. А то не ясно что ты вообще имел в виду.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[2]: Inline records
От: VladD2 Российская Империя www.nemerle.org
Дата: 10.10.09 23:12
Оценка:
Здравствуйте, thesz, Вы писали:

T>Ты бы для разнообразия ознакомился бы с состоянием дел в других языках, что ли.


Для разнообразия ознакомился. А ты бы прежде чем вепендриваться с начало бы разобрался в сути вопроса.

T>А то начал за здравие — кортежи в функциональных языках, — а закончил за упокой — в Nemerle так, про другие не знаю.


Ну и за каким фигом ты эту ссылку дал? Тему то читал?

T>http://www.haskell.org/ghc/docs/latest/html/libraries/ghc-prim/GHC-Tuple.html


T>
T>data (,) a b = (,) a b
T>data (,,) a b c = (,,) a b c
T>data (,,,) a b c d = (,,,) a b c d
T>data (,,,,) a b c d e = (,,,,) a b c d e
T>data (,,,,,) a b c d e f = (,,,,,) a b c d e f
T>data (,,,,,,) a b c d e f g = (,,,,,,) a b c d e f g
T>data (,,,,,,,) a b c d e f g h = (,,,,,,,) a b c d e f g h
T>data (,,,,,,,,) a b c d e f g h i = (,,,,,,,,) a b c d e f g h i
T>data (,,,,,,,,,) a b c d e f g h i j = (,,,,,,,,,) a b c d e f g h i j
T>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[4]: Inline records
От: FR  
Дата: 11.10.09 05:24
Оценка: 1 (1)
Здравствуйте, samius, Вы писали:

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


В F# вызов функций с несколькими аргументами это просто сахар для карринга, поэтому никакой "совместимости" и не может быть. Но никто не запрещает (хотя это плохой стиль) использовать вместо функций с несколькими аргументами функцию с одним аргументом кортежом, тогда все будет отлично совместимо.
Re[3]: Inline records
От: FR  
Дата: 11.10.09 05:36
Оценка: 71 (3)
Здравствуйте, VladD2, Вы писали:

VD>Да. Для немерел они и сейчас совместимы, т.е. если функция возвращает кортеж совместимый с параметрами другой функции, то можно вложить вызов первой во второй.


В D тоже самое. Кроме того структуры и классы имеют свойство .tupleof и можно их одним вызовом отправлять в параметры функции при совпадении типов конечно:

struct Tst
{
    int x;
    int y;
}

void tst(int x, int y)
{
}

void main()
{
    Tst t1;
    tst(t1.tupleof);
}
Re[5]: Inline records
От: Lloyd Россия  
Дата: 11.10.09 07:16
Оценка:
Здравствуйте, VladD2, Вы писали:

L>>>>Если я правильно понимаю, в этом случае одинаковые по сигнатуре (типы входных/выходных параметров) функции не будут совместимы?


L>>Кажется, ты не заметил "не" в вопросе.


VD>Ты бы расшифровал свой вопрос. А то не ясно что ты вообще имел в виду.


VD>def x = f();
VD>... = x.var1 + x.var2;
VD>... x.var3


Под несовместимостью я имел в виду следующее: если есть функция g, которая отличается от f только именем возвращаемого параметра, то она не может быть использована в приведенном куске кода.
Re[5]: Inline records
От: samius Япония http://sams-tricks.blogspot.com
Дата: 11.10.09 07:25
Оценка: +1 :)
Здравствуйте, FR, Вы писали:

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

Было бы странно, если бы нельзя было подать кортеж в функцию, принимающую кортеж.
Re[3]: Inline records
От: thesz Россия http://thesz.livejournal.com
Дата: 11.10.09 08:16
Оценка:
Здравствуйте, VladD2, Вы писали:

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


T>>Ты бы для разнообразия ознакомился бы с состоянием дел в других языках, что ли.


VD>Для разнообразия ознакомился.

VD>А ты бы прежде чем вепендриваться с начало бы разобрался в сути вопроса.

Уверяю тебя, я разбираюсь в сути вопроса.

Тем более, что для зависимых типов твои рассуждения про простых смертных ещё менее важны.

T>>А то начал за здравие — кортежи в функциональных языках, — а закончил за упокой — в Nemerle так, про другие не знаю.


VD>Ну и за каким фигом ты эту ссылку дал? Тему то читал?


Затем, что в Хаскеле неверно "Кортеж — это часть дизайна языка." Там верно "кортеж — это удобное сокращение алгебраического типа данных с одним конструктором." Демонстрацией чего и была та ссылка.

Так что твои рассуждения основаны на выборке из одного отсчёта, а потому неверны.
Yours truly, Serguey Zefirov (thesz NA mail TOCHKA ru)
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.