Здравствуйте, VladD2, Вы писали:
VD>Так вот анонимные типы — это недоразумение возникшее в следствии того, что в МС вместо грамотного проектирования всей системы (CLR и языков) решали частную проблему встраивания запросов в язык. Проблема этого неполноценного решения заключается в том, что в дотнет нет структурной эквивалентности, а без него тип (именно полноценный тип, а не синтаксический сахар, что бы встроен в шарп) создать нельзя.
А так ли уж нет возможности вручную эмулировать структурную эквивалентность туплов хотя-бы для Nemerle? Если туплы с именованными свойствами будут наследниками туплов со свойствами безымянными + куча приседаний макросами и в тех и в других что-бы реализовать Equals, все возможные Comparable и приведения для лёгкой конверсии из одного тупла в другой — может прокатит хотя-бы в рамках одной сборки?
Здравствуйте, thesz, Вы писали:
T>Уверяю тебя, я разбираюсь в сути вопроса.
T>Тем более, что для зависимых типов твои рассуждения про простых смертных ещё менее важны.
Ты не здоров? А может ты не трезв? Такое ощущение что нет. Где здесь хоть слово о ЗТ?
T>Затем, что в Хаскеле неверно "Кортеж — это часть дизайна языка." Там верно "кортеж — это удобное сокращение алгебраического типа данных с одним конструктором." Демонстрацией чего и была та ссылка.
Ну, и что? Речь то совершенно не о том. Иди под учи C# тогда с тобой о чем-то можно будет говорить. А пока ты заперт в своем мире хаскеля, ты такой же блаб, как те кто знаком только с миром C#.
T>Так что твои рассуждения основаны на выборке из одного отсчёта, а потому неверны.
Очень советую тебе разобраться в сути вопроса. Разберешься приходи, поговорим. А пока, пока.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, hi_octane, Вы писали:
VD>>Так вот анонимные типы — это недоразумение возникшее в следствии того, что в МС вместо грамотного проектирования всей системы (CLR и языков) решали частную проблему встраивания запросов в язык. Проблема этого неполноценного решения заключается в том, что в дотнет нет структурной эквивалентности, а без него тип (именно полноценный тип, а не синтаксический сахар, что бы встроен в шарп) создать нельзя.
_>А так ли уж нет возможности вручную эмулировать структурную эквивалентность туплов хотя-бы для Nemerle?
Ну, теоретически ничего невозможного нет. Но практического алгоритма я не вижу. К тому же решение для одного языка приведет к большей несовместимости между языками и к потере контроля над типами пересекающими границы сборки.
_>Если туплы с именованными свойствами будут наследниками туплов со свойствами безымянными + куча приседаний макросами и в тех и в других что-бы реализовать Equals, все возможные Comparable и приведения для лёгкой конверсии из одного тупла в другой — может прокатит хотя-бы в рамках одной сборки?
В рамках одной сборки вообще проблем нет.
Если оставить базовым типом кортеж, а поля "приклеить" на уровне системы типов с аннотациями в виде атрибутов, то один язык сможет их контролировать даже за рамками сборки. Но это будет чисто текстуальный контроль.
Кстати, для кортежей это уже в некотором роде есть. Кортежи уже обрабатываются особым образом. Например, в них них есть поля, но в немерле эти поля не видны. Вместо этого используется синтаксис доступа по индексу.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
L>Под несовместимостью я имел в виду следующее: если есть функция g, которая отличается от f только именем возвращаемого параметра, то она не может быть использована в приведенном куске кода.
В смысле у g и f возвращают несколько параметров у которых одинакова структура, но разные имена?
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, FR, Вы писали:
FR>Кроме того структуры и классы имеют свойство .tupleof и можно их одним вызовом отправлять в параметры функции при совпадении типов конечно:...
Полезная фича. В немерле классы могут рассматриваться как кортеж при паттерн-матчинге, но прямого преобрзоавния нет. В прочем написать подобный макрос дело 10 минут.
Кстати, а как при этом дело обстоит с инкапсуляцией? У структур в Ди могут быть не публичные поля?
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
L>>Под несовместимостью я имел в виду следующее: если есть функция g, которая отличается от f только именем возвращаемого параметра, то она не может быть использована в приведенном куске кода.
VD>В смысле у g и f возвращают несколько параметров у которых одинакова структура, но разные имена?
У возвращаемых параметров — типы одинаковые, но различаются имена.
Здравствуйте, VladD2, Вы писали:
VD>Полезная фича. В немерле классы могут рассматриваться как кортеж при паттерн-матчинге, но прямого преобрзоавния нет. В прочем написать подобный макрос дело 10 минут.
На D тоже можно написать (сначала и был вроде шаблонный вариант), но встроенный удобней.
VD>Кстати, а как при этом дело обстоит с инкапсуляцией? У структур в Ди могут быть не публичные поля?
Могут, для структур в кортеж преобразуются все поля независимо от публичности. Вот для классов преобразуются только публичные поля.
Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, thesz, Вы писали:
T>>Уверяю тебя, я разбираюсь в сути вопроса.
T>>Тем более, что для зависимых типов твои рассуждения про простых смертных ещё менее важны. VD>Ты не здоров? А может ты не трезв? Такое ощущение что нет. Где здесь хоть слово о ЗТ?
Видишь ли, эти самые безымянные записи с именованными полями нужны ровно для того, чтобы не перепутать startTime и endTime. Поддержать инвариант startTime <= endTime. Сделать их "типы" "зависящими" от их значений. Зависимыми, иными словами.
Если смотреть на это с такой точки зрения, то всё это обсуждение яйца выеденного не стоит.
T>>Затем, что в Хаскеле неверно "Кортеж — это часть дизайна языка." Там верно "кортеж — это удобное сокращение алгебраического типа данных с одним конструктором." Демонстрацией чего и была та ссылка. VD>Ну, и что? Речь то совершенно не о том. Иди под учи C# тогда с тобой о чем-то можно будет говорить. А пока ты заперт в своем мире хаскеля, ты такой же блаб, как те кто знаком только с миром C#.
В Хаскель не попадают идеи из C#, в отличии от противоположного направления.
Поэтому выгодней учить Хаскель. Что я и делаю.
T>>Так что твои рассуждения основаны на выборке из одного отсчёта, а потому неверны. VD>Очень советую тебе разобраться в сути вопроса. Разберешься приходи, поговорим. А пока, пока.
Вся беда в том, что я разбираюсь на более высоком уровне, чем ты. Вот ты и не можешь понять.
Но ты спрашивай, я объясню.
Yours truly, Serguey Zefirov (thesz NA mail TOCHKA ru)
Здравствуйте, thesz, Вы писали:
T>В Хаскель не попадают идеи из C#, в отличии от противоположного направления. T>Поэтому выгодней учить Хаскель. Что я и делаю.
В C# попадают идеи и из других языков, поэтому выгоднее учить C#, особенно в долгосрочной песпективе
Здравствуйте, gandjustas, Вы писали:
G>Здравствуйте, thesz, Вы писали:
T>>В Хаскель не попадают идеи из C#, в отличии от противоположного направления. T>>Поэтому выгодней учить Хаскель. Что я и делаю. G>В C# попадают идеи и из других языков, поэтому выгоднее учить C#, особенно в долгосрочной песпективе
Да. Но в другие языки эти идеи попадают из того же Хаскеля.
Yours truly, Serguey Zefirov (thesz NA mail TOCHKA ru)
Здравствуйте, thesz, Вы писали:
T>Здравствуйте, gandjustas, Вы писали:
G>>Здравствуйте, thesz, Вы писали:
T>>>В Хаскель не попадают идеи из C#, в отличии от противоположного направления. T>>>Поэтому выгодней учить Хаскель. Что я и делаю. G>>В C# попадают идеи и из других языков, поэтому выгоднее учить C#, особенно в долгосрочной песпективе
T>Да. Но в другие языки эти идеи попадают из того же Хаскеля.
Динамическая типизация (в C# 4) и метапрограммирование (возможно в C# 5+) в хаскеле есть?
Здравствуйте, gandjustas, Вы писали:
G>Здравствуйте, thesz, Вы писали:
T>>>>В Хаскель не попадают идеи из C#, в отличии от противоположного направления. T>>>>Поэтому выгодней учить Хаскель. Что я и делаю. G>>>В C# попадают идеи и из других языков, поэтому выгоднее учить C#, особенно в долгосрочной песпективе T>>Да. Но в другие языки эти идеи попадают из того же Хаскеля. G>Динамическая типизация (в C# 4) и метапрограммирование (возможно в C# 5+) в хаскеле есть?
Да (2003-й, что ли, год, а то и ещё раньше) и Да (2005-й, что ли, год, а то и ещё раньше).
G>А если нет, то таки выгоднее учить C#
Нет, не выгодней.
Yours truly, Serguey Zefirov (thesz NA mail TOCHKA ru)
Здравствуйте, thesz, Вы писали:
T>Видишь ли, эти самые безымянные записи с именованными полями нужны ровно для того, чтобы не перепутать startTime и endTime. Поддержать инвариант startTime <= endTime. Сделать их "типы" "зависящими" от их значений. Зависимыми, иными словами.
Инвариантом здесь и не пахнет. Не надо домысливать.
Все это нужно чтобы помочь человеку. В первую очередь — это возможность доступа к полям по имени. Скажем, если у нас есть некий запрос возвращающий список кортежей, то куда удобнее обращаться к полям кортежей по именам, а не через позиции.
T>Если смотреть на это с такой точки зрения, то всё это обсуждение яйца выеденного не стоит.
Не очень понятно с чего бы это, но на то они и разные точки зрения.
T>В Хаскель не попадают идеи из C#, в отличии от противоположного направления.
Возможно тебя это рассторит, но подовляющему большинству программистов плевать на хаскель и на то что в него попадает.
И плевать, на то что ты не можешь пройти мимо любой темы, посвященной дизайну ЯП, где забыли упомянуть Наскель.
T>Поэтому выгодней учить Хаскель. Что я и делаю.
Ну, учи. Что к другим то приставать? Мне Hasskel без надобнсоти. Что на нем можно сделать? Чистые вычисления меня не интересуют. От иероглифической записи меня не прем (иначе я наверно перся бы от K или J). Мне нужен инструмент позволяющий решать проблемы реального мира. На сегодня по сочетанию факторов (языковые возможности, расширяемость, поддержка ДСЛ-ей, возможность использования огромных мэйнстрим-библиотек) для меня таковым языком является Nemerle. Для подавляющего большинства людей — это, вообще, C# и Java.
В шарпе и немерле есть определенная проблема. Вот ее я и хотел обсудить в этой теме.
T>Вся беда в том, что я разбираюсь на более высоком уровне, чем ты. Вот ты и не можешь понять.
Понуешся ты, несомненно, на более высоком уровне. Остальное сильно сомнительно.
T>Но ты спрашивай, я объясню.
Мне тебя не о чем спрашивать. Твоя позиция почти всегда деструктривно. Потому с тобой просто не интересно разговаривать. Вместо высказывания интересный мыслей ты постоянно выёживашся и потнушся.
Научись воспринимать окружающих как равных. Объяснять свою точку без понтов, воспринимать чужую точку зрения. Тогда с тобой будет интересно вести беседы. А так одно раздражения от общения с тобой получаешь.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, thesz, Вы писали:
T>>Видишь ли, эти самые безымянные записи с именованными полями нужны ровно для того, чтобы не перепутать startTime и endTime. Поддержать инвариант startTime <= endTime. Сделать их "типы" "зависящими" от их значений. Зависимыми, иными словами. VD>Инвариантом здесь и не пахнет. Не надо домысливать. VD>Все это нужно чтобы помочь человеку. В первую очередь — это возможность доступа к полям по имени. Скажем, если у нас есть некий запрос возвращающий список кортежей, то куда удобнее обращаться к полям кортежей по именам, а не через позиции.
Или по сравнению с образцом.
T>>Если смотреть на это с такой точки зрения, то всё это обсуждение яйца выеденного не стоит. VD>Не очень понятно с чего бы это, но на то они и разные точки зрения.
Всё, что ты делаешь (и я делаю, и кто-либо ещё делает в районе проектирования любых ЯП), направлено на уменьшение количества ошибок, допускаемых программистами.
Это единственная разумная точка зрения. "Мы все уменьшаем количество ошибок наших пользователей".
Далее идёт оценка размена — какие ошибки мы уменьшаем, какие увеличиваем. Где мы потратим больше времени, где меньше — второй вариант оценки.
Так вот, с этой точки зрения обсуждение обращения по именами полей безымянных структур выглядит разменом даже не самих пешек, а разменом пыли с тех частей доски, на которых эти пешки стояли.
А вот наличие имён для индикации инвариантов уже более интересно. Про наличие инвариантов и говорить отдельно не стоит, и так понятно, что это круто.
T>>В Хаскель не попадают идеи из C#, в отличии от противоположного направления. VD>Возможно тебя это рассторит, но подовляющему большинству программистов плевать на хаскель и на то что в него попадает. VD>И плевать, на то что ты не можешь пройти мимо любой темы, посвященной дизайну ЯП, где забыли упомянуть Наскель.
Я так думаю, что это их проблемы, не мои.
Это они не знакомы с Хаскелем и потому, начиная говорить о функциональных языках программирования, сворачивают на то, что им известно.
T>>Поэтому выгодней учить Хаскель. Что я и делаю. VD>Ну, учи. Что к другим то приставать?
Я альтруист.
VD>Мне Hasskel без надобнсоти. Что на нем можно сделать? Чистые вычисления меня не интересуют.
А зря.
VD>От иероглифической записи меня не прем (иначе я наверно перся бы от K или J). Мне нужен инструмент позволяющий решать проблемы реального мира.
Это любой ЯП общего назначения.
Интересно, ты не упомянул "наиболее эффективным образом".
T>>Но ты спрашивай, я объясню. VD>Мне тебя не о чем спрашивать. Твоя позиция почти всегда деструктривно. Потому с тобой просто не интересно разговаривать. Вместо высказывания интересный мыслей ты постоянно выёживашся и потнушся. VD>Научись воспринимать окружающих как равных. Объяснять свою точку без понтов, воспринимать чужую точку зрения. Тогда с тобой будет интересно вести беседы. А так одно раздражения от общения с тобой получаешь.
Ух ты!
Это же комплимент.
Поскольку я слышу это от человека, которому последние два параграфа говорят гораздо чаще, чем мне.
Yours truly, Serguey Zefirov (thesz NA mail TOCHKA ru)
Здравствуйте, VladD2, Вы писали:
VD>Все это нужно чтобы помочь человеку. В первую очередь — это возможность доступа к полям по имени. Скажем, если у нас есть некий запрос возвращающий список кортежей, то куда удобнее обращаться к полям кортежей по именам, а не через позиции.
А я вот не понял (это безотносительно вашей дискуссии), зачем там имена. Ведь таплы используются только в случаях, когда эти имена не нужны — там всегда case analysis. А следовательно, в коде эти имена будут присутствовать в разборе. Т.е. мы будем часто писать
Здравствуйте, VladD2, Вы писали:
VD>А почему бы не рассматривать возвращаемое значение функции так же как набор параметров? При этом синтаксис может быть совершенно разрообразным. Например, мы можем объявлять функцию так:
<skipped>
Возвращаемое значение функции — это просто соглашение языка о том, что один из выходных параметров передается как результат.
Гипотетический язык
(string ret1, int ret2) FuncName(string param1, int param2)
{
}
(string ret1) FuncName(string param1, int param2, out int ret2)
{
}
(int ret2) FuncName(string param1, int param2, out string ret1)
{
}
void FuncName(string param1, int param2, out int ret2, out string ret1)
{
}
в сущности эквивалентны. Выбор одного из возвращаемых параметров в качестве результата и остальных — как возвращаемых через аргументы определяется не глубокими идейными соображениями, а просто из удобства. Например, я могу предпочесть второй вариант потому что он мне позволит написать
string s = "Func Name is " + FuncName(аргументы);
а остальные не позволят. Или предпочесть вариант 3, чтобы можно было писать
Здравствуйте, VladD2, Вы писали:
VD>А "с полной совместимостью по типу, невзирая на имена свойств" называется структурной эквивалентностью. Она тоже есть почти во всех языках, даже в С++ (но не в Яве и Шарпе). VD>Так вот для анонимных типов структурная эквивалентность не поддерживается. Причем это проблема CLR. VD>Я же предлагаю не объявление нового типа, как кому-то тут показалось, а аннотацию кортежа. Мы же не говорим, что параметры функции — это анонимный тип только на основании того, что у них есть имена? Вот тут та же фигня. Имена всего лишь дополнительная аннотация не вводящая новый тип, но повышающая удобство на практике.
С какого-то количества элементов в ответе таки да (опыт того же Erlang). Просто примеры не совсем адекватны: пока этих элементов 2-3 — собеседники не видят смысла в подобной "хитрой штуке". На практике же дофига случаев, когда их и 10, и 30. Если их состав определён на этапе компиляции, то рисовать мап на них — нехорошо, лучше пользоваться именованными статическими позициями. По сказанному, я "издалека" поддерживаю эту идею.
S>>Т.е. если мы оставляем запись string*int для обозначения кортежа, то функция типа string*int->string*int должна как принимать именно кортеж, так и возвращать его.
VD>Она так и делает. Вот так записывается конструктор кортежа: VD>
("aaa", 12)
VD>а вот так вызов функции: VD>
f("aaa", 12)
VD>найдите 10 различий.
Полной эта схема будет тогда, когда можно будет где-то отдельно сформировать набор аргументов функции в виде кортежа и затем передать его в функцию. Аналоги — питоновый callable(*args) и эрланговый apply(Fun,Args) (в эрланге передаётся список, а не кортеж, но это тут менее важно). Не знаю, как оно сейчас в Nemerle, но описанного тут — явно недостаточно.
(К слову — тут явно не хватает ещё одного вида скобок для кортежей. Для сравнения, в Erlang — {...}, а в таком оригинальном языке как Рапира (на формирование которого явно повлияли какие-то ранние ФЯ) — <*...*>. В питоне обошлись круглыми скобками и поэтому для кортежа в один элемент используют синтаксический костыль)
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>в сущности эквивалентны.
Дьявол, как всегда — в деталях.
Для дальнейшего я буду использовать шарп, но аналогичные грабли есть и в твоих любимых плюсах.
Сравним следующие две строки:
int a, b;
a = GetSomeInt();
GetSomeInt(out b); // в плюсах был бы соответственно &b
Одинакова ли семантика первой и второй строчки? Нет, неодинакова. а получает значение ровно один раз, а в b происходит неопределённое количество присваиваний.
Это может играть важную роль в тех случаях, когда аргумент в процессе действия GetSomeInt изменяется еще где-то.
И, как следствие, мы имеем разные ограничения на безопасность типов. Для a мы можем применить любой тип, совместимый по присваиванию с int, например — double.
Для b — только сам int. Потому что иначе неясна семантика его использования внутри функции.
Как это относится к кортежам? Да точно так же.
Запись вида
(int a, string b) = GetSomePair();
не может быть эквивалентна записи
GetSomePair(out a, out b);
Просто потому, что иначе вот такие две записи не будут себя вести эквивалентно:
int a = GetSomeInt();
(int a) = GetSomeInt();
А это уже явное противоречие здравому смыслу, с далеко идущими последствиями.
Поэтому в языке нужно будет давать чёткий способ отличать возврат структурированного значения (return (5, "hello") от присваивания out-параметрам.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.