DM> Если где-то можно один вид полиморфизма выразить через другой, первый вид не исчезнет.
он не исчезает, он просто перестает нас интересовать. также как, например, понятие указателя в языках C#/скриптах и т.д. никого не интересует.
DM>Нет, в вопросах теории ЯП нас интересует теория.
если мы хотим, что бы наш ЯП был только в теории, то — да.
если же интересует задача, чтобы ЯП использовался на практике, то кроме теории самого ЯП необходима еще теория:
построения эффективного компилятора, построение эффективного исполнителя, построение эффективной среды программирования, построение эффективного интерпретатора и т.д.
DG>>и кстати ATS должен быть дать понимание, что часть типов это чисто фишка компилятора, а часть переходит и в runtime. DG>>соответственно, каждый реальный язык имеет, как минимум, два набора типов: уровня компиляции и уровня runtime-а.
DM>Не стоит из отдельных примеров практики делать общие правила теории. Вот в Руби и Питоне где "набор типов уровня runtime"? Реальные языки.
как минимум есть типы int, string, массив и т.д.
в динамических языках как раз все типы являются типами runtime-а, и нет типов уровня компиляции
Здравствуйте, FR, Вы писали:
S>>Интересно. Я правильно понимаю, что D как и C++ инстанциирует шаблоны во время компиляции? Т.е. фактически ничто кроме комитета не мешало бы сделать то же самое и в C++?
FR>Угу даже больше, этот самый комитет и зарубил это предложение (Concepts) при принятии нового стандарта.
Точно, я читал о них немного когда их зарубили. Есть надежда, что их в действительности отложили.
А что делать с совместимостью с кодом, который работает без концептов? Оставить фичи темплейтов как есть (аки с небезопасным приведением типов)?
да, так записать можно, но не стоит: при этом дохнет проверка согласованности кода на компиляции, автоматический рефакторинг, intellisence и т.д.
DG>> также нет возможности задать параметры через "или". S>А где есть?
на C++ можно если извратнуться, если использовать аналоги для "или-на-шаблонах" из того же boost-а.
DG>>в частности, на C# нельзя описать следующую конструкцию: DG>>
DG>>T Sum<T>(this IEnumerable<T> items) where T:int/double/string/decimal и т.д.
DG>>
S>Можно использовать subtype полиморфизм и передавать явно сумматор. Можно прийти к решению как с Comparer<T>.Default (Summator<T>.Default.Sum(a, b), где сумматоры для интересующих типов хардкодятся руками). S>Решения есть, согласен что не слишком элегантные. Но ничего принципиально неразрешимого ты не назвал.
они не эквиваленты исходному. что-нибудь да отваливается: или эффективность исполнения, или проверка уровня компиляции, или возможность наращивать уже имеющийся код и т.д.
Здравствуйте, samius, Вы писали:
S>А что делать с совместимостью с кодом, который работает без концептов? Оставить фичи темплейтов как есть (аки с небезопасным приведением типов)?
Ну в D нормльно стыкуется, так же есть оба типа шаблонов, не всегда же жесткий контроль нужен.
Здравствуйте, DarkGray, Вы писали:
DG>да, так записать можно, но не стоит: при этом дохнет проверка согласованности кода на компиляции, автоматический рефакторинг, intellisence и т.д.
Я только опроверг твое утвреждение о том что на C# это сделать нельзя.
S>>Можно использовать subtype полиморфизм и передавать явно сумматор. Можно прийти к решению как с Comparer<T>.Default (Summator<T>.Default.Sum(a, b), где сумматоры для интересующих типов хардкодятся руками). S>>Решения есть, согласен что не слишком элегантные. Но ничего принципиально неразрешимого ты не назвал.
DG>они не эквиваленты исходному.
Если ты про оператор + для дженерика — то, да, неэквивалентны, т.к. придется использовать метод. В остальном — могут быть эквивалентны полностью. DG>что-нибудь да отваливается: или эффективность исполнения, или проверка уровня компиляции, или возможность наращивать уже имеющийся код и т.д.
Эффективность может быть на уровне выполнения оператора + если не использовать виртуальность. Проверено неоднократно.
Проверка уровня компиляции будет.
Возможность наращивать имеющийся код — это что? Если я верно предполагаю о чем ты, то придется заменить + на вызов метода. Да, неудобно. Но это несущественный недостаток, т.к. существует изоморфизм кода (ц) DG
S>Давай разбираться. Под составным отношением ты подразумеваешь композицию отношений?
да
S>Если да, то не очень понятно. Допустим, FoG (o= композиция) определено на SxT (x — декартово произведение). Непонятно, где определены F и G, что их композиция стала определена на SxT.
давай добавим промежуточное множество S-T, тогда F переводит S в S-T, а G из S-T в T.
F1 и G1 тоже преобразуют S в S-T и S-T в T соответственно.
DG>>дальше возьмем изоморфизм M над отношением F G, который переводит отношение F G в F1 G1(и обратно), при этом F1 G1 описывает такое же отношение S в T, как и исходное F G. S>не очень понимаю, о чем речь. Изоморфизм над отношением? Что есть объекты, что есть стрелки?
отношение — это объект
стрелка — это изменение этого отношения.
DG>>У отношения G при переходе к G1 часть свойств остается, а часть пропадает. S>О каких свойствах речь?
теми которыми обладает отношение G.
DG>>и соответственно, утверждается, что те свойства G, которые остаются при преобразовании являются существенными, а которые пропадают — не существенные, потому что с помощью изоморфизма M от них всегда можно избавиться. S>Изоморфизм сохраняет структуру, если что.
странное утверждение, как минимум необходимо зафиксировать структура чего сохраняется.
изоморфизм — это стрелка туда и обратно.
и верно как раз обратное, что то, что сохранилось — это и есть структура.
об этом и речь, что если есть изоморфизм, при котором свойство пропадает, то свойство не является определяющим структуру.
S>давай попроще, например к числам. S>Да, можно множество целых положительных чисел отобразить в множество дробей вида 1/n и они перестанут быть целыми. Что из этого? Исходные целые положительные числа перестали быть целыми? Т.е. ты утверждаешь что "целость" числа это несущественное свойство, потому можно не обращать внимание, целое оно или нет?
в этой задаче нет двух отношений, здесь рассматривается только одно отношение.
DG>>соответственно, я утверждаю, что деление полиморфизма на parametric, subtype и ad-hoc не существенно, потому что есть изоморфизмы, которые переводят одно в другое. S>Вот тут нужен пример, который это подтвердит. Твой исходный не годится, его нельзя отнести к чисто параметрическому. Давай начнем с примера, который чистый ad-hoc (перегрузку функций) переведет в чисто параметрический, который будет соответствовать "written without mention of any specific type" согласно классификации 55-летней давности.
вот только я утверждал, что достаточно "грязного" параметрического (а именно внутри которого можно написать произвольное выражение над типами) полиморфизма, и что соответственно чистый parametric, ad-hoc и subtype не нужны
FR>Таким макаром мы придем к тому что все тьюринг полные языки ничем друг от друга не отличаются.
при такой постановке — да.
поэтому интересует другая постановка задачи:
какой набор примитивов, свойств и т.д. является существенным при сохранении таких свойств кода как:
вычислительная сложность,
предсказуемость,
размер кода,
читабельность человеком
и т.д.
Здравствуйте, DarkGray, Вы писали:
DM>>Хочешь сказать, что для абсолютно любого языка всегда есть "более простой набор примитивов"? Это как минимум не доказано, не очевидно и контринтуитивно.
DG>автомат обладает более простым набором примитивов, не говоря уже про МТ. DG>при этом из тьюринга следует, что любой язык можно преобразовать в автомат.
МТ и др. автоматы — тоже языки, со своими правилами составления программ (грамматикой) и описанным механизмом работы (семантикой). Во что более простое их преобразовывать будешь? И вообще, определи сперва понятие "более простой". Что проще — МТ или лямбда-исчисление?
Здравствуйте, DarkGray, Вы писали:
DG>>>соответственно, каждый реальный язык имеет, как минимум, два набора типов: уровня компиляции и уровня runtime-а. DG>в динамических языках как раз все типы являются типами runtime-а, и нет типов уровня компиляции
Ну вот, а говорил "как минимум, два набора". А ведь в руби и питоне таки есть компиляция — в их байткод.
DG>>да, так записать можно, но не стоит: при этом дохнет проверка согласованности кода на компиляции, автоматический рефакторинг, intellisence и т.д. S>Я только опроверг твое утвреждение о том что на C# это сделать нельзя.
опять двадцатьпять — C# тьюринг полный язык, и сделать на нем можно всё что угодно.
и соответственно, фраза "сделать нельзя" означает, что нельзя сделать без потери каких-то существенных свойств кода, в данном случае, без потери статической проверяемости.
DG>>они не эквиваленты исходному.
если брать решение именно с отдельным сумматором, то отваливается автоматический вывод типов
var items = GetItems();
var s = Sum(items);//вот здесь придется явно указать тип сумматора
S> Возможность наращивать имеющийся код — это что?
кроме + необходимо полиморфность также и других операций: -, * и т.д.
соответственно для удобства обычно делают класс PolyOperation_Double, класс Matrix<T, TSummator> и выносят в библиотеку CoolOperations.
также делается какая-нибудь прикладная библиотека MegaMoving, которая во всю использует Matrix<double, PolyOperation_Double>
дальше вдруг выяснилось при написании библиотеки MySmartAirFly, что необходима еще полиморфная операция возведения в степень. при этом возможности и права изменения библиотеки CoolOperations часто нет, а без этого нельзя добавить эту функцию в PolyOperation_Double, можно лишь сделать PolyOperation_Double_MySmartAirFly отнаследованный от PolyOperation_Double.
в итоге библиотека MySmartAirFly во всю оперирует классом Matrix<double, PolyOperation_Double_MySmartAirFly> и всё вроде не плохо, кроме того, что матрицы из библиотеки MegaMoving нельзя использовать для передачи в функции библиотеки MySmartAirFly без преобразования (и соответствующей потери эффективности кода)
зы
в теории, эта проблема решается через partial(который действует и между библиотеками, а не только внутри) class-ы, которые собираются в один под именем PolyOperation_Double в момент запуска программы.
DM>МТ и др. автоматы — тоже языки, со своими правилами составления программ (грамматикой) и описанным механизмом работы (семантикой). Во что более простое их преобразовывать будешь?
а зачем это надо?
автомат я привел из-за того, что если хочется язык выполнить то все равно его придется тем или иным способом сводить к автомату.
отмечу, что несмотря на то, что языки алгорифмы маркова, лямбда-исчисление и т.д. с математической точки зрения автоматами не являются, исполняются они в любом случае автоматами.
DM> И вообще, определи сперва понятие "более простой". Что проще — МТ или лямбда-исчисление?
с точки зрения комбинирования алгоритмов: лямбда-исчисление проще, чем МТ — большая часть задач комбинирования решается за O(1)
или в более общем виде: есть ЯП, есть ряд требований требуемых от ЯП (часть я из них уже перечислял). для каждого ЯП каждое требование получается с помощью набора алгоритмов, чем меньше вычислительная сложность этих алгоритмов, тем проще ЯП.
как минимум есть еще процессор, а на уровне процессора никаких типов вида unicode-строка или ассоциативный массив — нет.
DM> А ведь в руби и питоне таки есть компиляция — в их байткод.
S> Да, неудобно. Но это несущественный недостаток, т.к. существует изоморфизм кода (ц) DG
тут все упирается в то, что не все морфизмы может выполнить человек за небольшое время.
например, морфизм переопределения символов сам по себе имеет низкую вычислительную сложность, но для человека он обладает высокой вычислительной сложностью (из-за особенности строения памяти человека).
соответственно, в этом и заключается теория создания ЯП:
выделить какие задачи и преобразования умеет делать быстро человек, а какие компьютер.
а дальше скомпоновать ЯП так, чтобы человеку приходилось в основном решать те задачи в которых он быстр, а компьютеру — остальные.
Здравствуйте, DarkGray, Вы писали:
S>>Давай разбираться. Под составным отношением ты подразумеваешь композицию отношений?
DG>да
S>>Если да, то не очень понятно. Допустим, FoG (o= композиция) определено на SxT (x — декартово произведение). Непонятно, где определены F и G, что их композиция стала определена на SxT.
DG>давай добавим промежуточное множество S-T, тогда F переводит S в S-T, а G из S-T в T. DG>F1 и G1 тоже преобразуют S в S-T и S-T в T соответственно.
Отношения ничего не переводят. Если ты говоришь об отношении F, то это тройка (S, S-T, X), где X подмножество SxS-T. Что куда переводится — неясно.
DG>>>дальше возьмем изоморфизм M над отношением F G, который переводит отношение F G в F1 G1(и обратно), при этом F1 G1 описывает такое же отношение S в T, как и исходное F G. S>>не очень понимаю, о чем речь. Изоморфизм над отношением? Что есть объекты, что есть стрелки?
DG>отношение — это объект DG>стрелка — это изменение этого отношения.
DG>>>У отношения G при переходе к G1 часть свойств остается, а часть пропадает. S>>О каких свойствах речь?
DG>теми которыми обладает отношение G.
Ты о каком-то конкретном отношении G?
DG>>>и соответственно, утверждается, что те свойства G, которые остаются при преобразовании являются существенными, а которые пропадают — не существенные, потому что с помощью изоморфизма M от них всегда можно избавиться. S>>Изоморфизм сохраняет структуру, если что.
DG>странное утверждение, как минимум необходимо зафиксировать структура чего сохраняется.
Категории. DG>изоморфизм — это стрелка туда и обратно. DG>и верно как раз обратное, что то, что сохранилось — это и есть структура. DG>об этом и речь, что если есть изоморфизм, при котором свойство пропадает, то свойство не является определяющим структуру.
Как стрелки определишь, такая и будет структура. Что-то ты чем дальше, тем глубже в лес.
S>>давай попроще, например к числам. S>>Да, можно множество целых положительных чисел отобразить в множество дробей вида 1/n и они перестанут быть целыми. Что из этого? Исходные целые положительные числа перестали быть целыми? Т.е. ты утверждаешь что "целость" числа это несущественное свойство, потому можно не обращать внимание, целое оно или нет?
DG>в этой задаче нет двух отношений, здесь рассматривается только одно отношение.
А для чего второе отношение?
S>>Вот тут нужен пример, который это подтвердит. Твой исходный не годится, его нельзя отнести к чисто параметрическому. Давай начнем с примера, который чистый ad-hoc (перегрузку функций) переведет в чисто параметрический, который будет соответствовать "written without mention of any specific type" согласно классификации 55-летней давности.
DG>вот только я утверждал, что достаточно "грязного" параметрического (а именно внутри которого можно написать произвольное выражение над типами) полиморфизма, и что соответственно чистый parametric, ad-hoc и subtype не нужны
Если ты хочешь внутри "грязного" параметрического написать a+b, то я не понимаю, как ты напишешь a+b не задействуя ad-hoc.
DG>>>да, так записать можно, но не стоит: при этом дохнет проверка согласованности кода на компиляции, автоматический рефакторинг, intellisence и т.д. S>>Я только опроверг твое утвреждение о том что на C# это сделать нельзя.
DG>опять двадцатьпять — C# тьюринг полный язык, и сделать на нем можно всё что угодно.
"все что угодно" — это слишком сильно для C# в частности и для тьюринг полноты в общем.
DG>и соответственно, фраза "сделать нельзя" означает, что нельзя сделать без потери каких-то существенных свойств кода, в данном случае, без потери статической проверяемости.
можешь написать диспетчеризацию руками, тогда тебе будет статическая проверяемость. Тут ты найдешь еще какое-то потеряное свойство, которое до сих пор не было в числе упомянутых тобой существенных
DG>>>они не эквиваленты исходному. DG>если брать решение именно с отдельным сумматором, то отваливается автоматический вывод типов
DG>
DG>var items = GetItems();
DG>var s = Sum(items);//вот здесь придется явно указать тип сумматора
DG>
Я же написал что можно не указывать, если пойти по пути Comparer<T>.Default и сделать сумматор для некоторого ограниченного набора типов.
S>> Возможность наращивать имеющийся код — это что?
DG>кроме + необходимо полиморфность также и других операций: -, * и т.д.
они уже полиморфны (ad-hoc).
Интуитивно я понимаю что ты хочешь, но ты настолько небрежно формулируешь свои мысли, что просто немогу удержаться от того что бы поправить.
DG>соответственно для удобства обычно делают класс PolyOperation_Double, класс Matrix<T, TSummator> и выносят в библиотеку CoolOperations.
DG>также делается какая-нибудь прикладная библиотека MegaMoving, которая во всю использует Matrix<double, PolyOperation_Double>
DG>дальше вдруг выяснилось при написании библиотеки MySmartAirFly, что необходима еще полиморфная операция возведения в степень. при этом возможности и права изменения библиотеки CoolOperations часто нет, а без этого нельзя добавить эту функцию в PolyOperation_Double, можно лишь сделать PolyOperation_Double_MySmartAirFly отнаследованный от PolyOperation_Double. DG>в итоге библиотека MySmartAirFly во всю оперирует классом Matrix<double, PolyOperation_Double_MySmartAirFly> и всё вроде не плохо, кроме того, что матрицы из библиотеки MegaMoving нельзя использовать для передачи в функции библиотеки MySmartAirFly без преобразования (и соответствующей потери эффективности кода)
Это проблемы теоретического характера. Матричные операции на С# и эффективность — слова из разных песен. Нужна эффективность в числорубке — сделай ее native.
DG>зы DG>в теории, эта проблема решается через partial(который действует и между библиотеками, а не только внутри) class-ы, которые собираются в один под именем PolyOperation_Double в момент запуска программы.
вижу, ты нашел еще одну категорию полиморфизма в ЯП — через управление набором исходников
Здравствуйте, DarkGray, Вы писали:
S>> Да, неудобно. Но это несущественный недостаток, т.к. существует изоморфизм кода (ц) DG
DG>тут все упирается в то, что не все морфизмы может выполнить человек за небольшое время.
Ты скажи, что за библиотеку ты собрался обобщать на C#? Уверяю тебя, что даже обобщить простенькую библиотеку обработки изображений на C++ может оказаться нетривиальной задачей. Вставить template и скобочки — тривиально, а получить качественный результат — уже нет.
DG>например, морфизм переопределения символов сам по себе имеет низкую вычислительную сложность, но для человека он обладает высокой вычислительной сложностью (из-за особенности строения памяти человека).
этим обычно занимаются не люди.
DG>соответственно, в этом и заключается теория создания ЯП: DG>выделить какие задачи и преобразования умеет делать быстро человек, а какие компьютер. DG>а дальше скомпоновать ЯП так, чтобы человеку приходилось в основном решать те задачи в которых он быстр, а компьютеру — остальные.
Реклама метапрограммирования? Да я не против. Только причем тут полиморфизм? Т.е. кроме того что мы можем написать программу, которая будет писать программу, в отношении полиморфизма ничего не меняется.
DG>>давай добавим промежуточное множество S-T, тогда F переводит S в S-T, а G из S-T в T. DG>>F1 и G1 тоже преобразуют S в S-T и S-T в T соответственно. S>Отношения ничего не переводят. Если ты говоришь об отношении F, то это тройка (S, S-T, X), где X подмножество SxS-T. Что куда переводится — неясно.
набор пар X как раз и определяет какой элемент из множества S переходит в какой элемент множества S-T (и наоборот).
если слово "переходит" не нравится, скажи каким другим одним словом это описывать. имхо, слово "относится" имеет какой-то другой смысл.
DG>>>>дальше возьмем изоморфизм M над отношением F G, который переводит отношение F G в F1 G1(и обратно), при этом F1 G1 описывает такое же отношение S в T, как и исходное F G. S>>>не очень понимаю, о чем речь. Изоморфизм над отношением? Что есть объекты, что есть стрелки?
DG>>отношение — это объект DG>>стрелка — это изменение этого отношения. S>
что не понятно? что такое изменение отношения? изменение набора пар множества X.
DG>>>>У отношения G при переходе к G1 часть свойств остается, а часть пропадает. S>>>О каких свойствах речь?
DG>>теми которыми обладает отношение G. S>Ты о каком-то конкретном отношении G?
в каждой конкретной задаче — оно конкретное, и имеет конкретный набор свойств K1, K2, K3, K4 и т.д.
S>Как стрелки определишь, такая и будет структура. Что-то ты чем дальше, тем глубже в лес.
я не очень понял зачем тебе понадобилась структура категории, когда речь шла про свойства кода, который является отдельными объектами внутри категории.
S>>>давай попроще, например к числам. S>>>Да, можно множество целых положительных чисел отобразить в множество дробей вида 1/n и они перестанут быть целыми. Что из этого? Исходные целые положительные числа перестали быть целыми? Т.е. ты утверждаешь что "целость" числа это несущественное свойство, потому можно не обращать внимание, целое оно или нет?
DG>>в этой задаче нет двух отношений, здесь рассматривается только одно отношение. S>А для чего второе отношение?
потому что сложные штуки становятся видными только на сложных конфигурациях.
с одной стороны: двойственности на одном отношении нет, с другой стороны: реальные задачи из одного отношения редко состоят.
S>Если ты хочешь внутри "грязного" параметрического написать a+b, то я не понимаю, как ты напишешь a+b не задействуя ad-hoc.
допустим вот так:
T Sum<T>(this IEnumerable<T> items)
{
var res = Empty(T);
foreach (var item in items)
{
compile-if(T.operators.contains(+=))
res += item;
else
res = Add(res, item);
}
return res;
}
partial T Add(T item1, T item2)
{
compile-if(T.operators.contains(+))
return item1 + item2;
elsif (T.methods.contains(Add(T)))
return item1.Add(item2);
}
partial T Add(T item1, T item2)
{
compile-if(T is TItem[])
return item1.Concat(item2).ToArray();
}
при этом partial означает, что это один и тот же метод, но разнесенный по коду
DG>>и соответственно, фраза "сделать нельзя" означает, что нельзя сделать без потери каких-то существенных свойств кода, в данном случае, без потери статической проверяемости. S>можешь написать диспетчеризацию руками, тогда тебе будет статическая проверяемость. Тут ты найдешь еще какое-то потеряное свойство, которое до сих пор не было в числе упомянутых тобой существенных
о чем речь?
DG>>>>они не эквиваленты исходному. DG>>если брать решение именно с отдельным сумматором, то отваливается автоматический вывод типов
DG>>
DG>>var items = GetItems();
DG>>var s = Sum(items);//вот здесь придется явно указать тип сумматора
DG>>
S>Я же написал что можно не указывать, если пойти по пути Comparer<T>.Default и сделать сумматор для некоторого ограниченного набора типов.
ты имеешь ввиду сделать?:
public class Summator<T>
{
public readonly static Func<T,T,T> Default = GenerateSummator<T>();
}
это, кстати, интересный подход. здесь, конечно, есть недостатки, но они локализованы в меньшем наборе кода.
и здесь даже можно обойти нерасширяемость, если в GenerateSummator запихнуть обход классов через reflection.
S>Это проблемы теоретического характера. Матричные операции на С# и эффективность — слова из разных песен. Нужна эффективность в
числорубке — сделай ее native.
спорно. например, если числомолотилка есть небольшая часть большего приложения. маршалинг в native может съесть всю эффективность, а писать всё приложение на native съест время разработки и устойчивость приложения.
Здравствуйте, DarkGray, Вы писали:
DG>>>давай добавим промежуточное множество S-T, тогда F переводит S в S-T, а G из S-T в T. DG>>>F1 и G1 тоже преобразуют S в S-T и S-T в T соответственно. S>>Отношения ничего не переводят. Если ты говоришь об отношении F, то это тройка (S, S-T, X), где X подмножество SxS-T. Что куда переводится — неясно.
DG>набор пар X как раз и определяет какой элемент из множества S переходит в какой элемент множества S-T (и наоборот).
Отношение и переходы — это что-то из разных опер. Пример — отношение (<). 0<1, 0<2, 0<3. Так куда переходит 0? DG>если слово "переходит" не нравится, скажи каким другим одним словом это описывать. имхо, слово "относится" имеет какой-то другой смысл.
Я пытаюсь понять, что ты описываешь.
DG>>>>>дальше возьмем изоморфизм M над отношением F G, который переводит отношение F G в F1 G1(и обратно), при этом F1 G1 описывает такое же отношение S в T, как и исходное F G. S>>>>не очень понимаю, о чем речь. Изоморфизм над отношением? Что есть объекты, что есть стрелки?
DG>>>отношение — это объект DG>>>стрелка — это изменение этого отношения. S>>
DG>что не понятно? что такое изменение отношения? изменение набора пар множества X.
Изменение отношения — непонятно. Изменение набора пар — непонятно. Что такое изменение?
Давай ближе к реальности, какие конкретно отношения ты рассматриваешь, и как изменяешь их пары?
DG>>>теми которыми обладает отношение G. S>>Ты о каком-то конкретном отношении G?
DG>в каждой конкретной задаче — оно конкретное, и имеет конкретный набор свойств K1, K2, K3, K4 и т.д.
Допустим, ты взял отношение порядка (<) и изменил набор пар. Ты получил что-то отличное от отношения порядка. И хочешь сказать что что-то нарушенное в отношении порядка оказалось несущественным? К чему вся эта кухня?
S>>Как стрелки определишь, такая и будет структура. Что-то ты чем дальше, тем глубже в лес.
DG>я не очень понял зачем тебе понадобилась структура категории, когда речь шла про свойства кода, который является отдельными объектами внутри категории.
Ты определил свойства кода как отношение? Шизею. Отношение чего к чему?
Допустим есть множество всех кодов C. То что код C1 из C декларативен, это отношение чего с чем? Куда тут стрелка? Что есть композиция отношений?
DG>>>в этой задаче нет двух отношений, здесь рассматривается только одно отношение. S>>А для чего второе отношение?
DG>потому что сложные штуки становятся видными только на сложных конфигурациях. DG>с одной стороны: двойственности на одном отношении нет, с другой стороны: реальные задачи из одного отношения редко состоят.
Нет никаких сложных конфигураций в отношении кода. Есть код. Он есть, он обладает свойствами. Все. Любое преобразование кода дает другой код с другими свойствами. Изменение набора пар свойств кода CxBool приведет лишь к тому, что определение свойств будет испорчено, но не изменит характеристики кода.
S>>Если ты хочешь внутри "грязного" параметрического написать a+b, то я не понимаю, как ты напишешь a+b не задействуя ad-hoc.
DG>допустим вот так: DG>
DG> compile-if(T.operators.contains(+=))
DG> res += item;
DG>
+= здесь уже ad-hoc. Ты от него не избавился. Ты его вовсю используешь.
DG>при этом partial означает, что это один и тот же метод, но разнесенный по коду
Да куда там partial!
+, += — это ad-hoc. Что ты не делай, но сложить два значения без специальных знаний о типе ты не можешь. Положить в контейнер — да. Сложить — нет.
S>Ты скажи, что за библиотеку ты собрался обобщать на C#? Уверяю тебя, что даже обобщить простенькую библиотеку обработки изображений на C++ может оказаться нетривиальной задачей. Вставить template и скобочки — тривиально, а получить качественный результат — уже нет.
Пределы обобщения на C# я знаю.
и C# я использую, в качестве, примера — потому что он достаточно сбалансирован по набору свойств: эффективность, надежность, поддержка IDE, статическая проверка и т.д.