Re[45]: Проблемы организации OR-мапинга
От: VladD2 Российская Империя www.nemerle.org
Дата: 06.05.09 00:19
Оценка: +1
Здравствуйте, vdimas, Вы писали:

V>Динамическое приведение типов в CLR (не преобразование, а именно приведение без изменения значения) — суть рантайм-тест этой "разметки", матч по алгебраическим типам в хаскеле — аналогично.


Ага. Вот только к динамической типизации это отношения не имеет. Ведь все типы известны во время компиляции.
АлгТД — это вид полиморфизма. Эдакое безопасное объедение.

Никто же не называет С++ динамически-типизированным только из того факта, что в нем поддерживаются виртуальные методы которые пиводят к тому, что реальный тип объекта становится известным только во время выполнения?
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[46]: Проблемы организации OR-мапинга
От: vdimas Россия  
Дата: 07.05.09 08:33
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Ага. Вот только к динамической типизации это отношения не имеет. Ведь все типы известны во время компиляции.


Какие еще все? Все, входящие в алг. тип? Дык их несколько в общем случае, а конкретный мы определяем в рантайм.

VD>Никто же не называет С++ динамически-типизированным только из того факта, что в нем поддерживаются виртуальные методы которые пиводят к тому, что реальный тип объекта становится известным только во время выполнения?


В случае виртуальных методов, если я правильно понял о чем ты, мы и не должны динамически определять тип реального объекта, такой подход — следствие правила Лисков.

Тут ведь различие очевидное: при динамическом приведении типа мы должны привести к некоему типу (неважно, матчингом или оператором динамического приведения типа) ДО выполнения операций над типом. В условиях открытой группы типов (так можно назвать все доступные типы) — это признанно плохим тоном в программировании. К сожалению, безопасность такого преобразования в CLR провоцирует подобный подход. С другой стороны, на динамическом приведении типов гораздо проще решаются многие задачи (та же обработка AST), т.к. в этих случаях нам доступен более подходящий данной задаче способ декомпозиции функциональности, в сравнении с размазыванием оной по виртуальным ф-иям многих классов. Отсюда я и считаю, что для тех задач, где сегодня мы используем динамическое приведение типов (даже если оно безопасное с т.з. возможной неверной интерпретации памяти), алгебраические типы будут более удобны, и более безопасны, но уже на уровень выше — в алгоритмическом плане, преодолевая то самое правило Лисков в ввиду закрытости группы (но опять же, только в случае контроля компилятором полноты матчинга, иначе та самая "дыра" остаётся в первозданном виде).
... << RSDN@Home 1.2.0 alpha rev. 786>>
Re[47]: Проблемы организации OR-мапинга
От: VladD2 Российская Империя www.nemerle.org
Дата: 07.05.09 10:11
Оценка: +1
Здравствуйте, vdimas, Вы писали:

V>...Отсюда я и считаю, что для тех задач, где сегодня мы используем динамическое приведение типов (даже если оно безопасное с т.з. возможной неверной интерпретации памяти), алгебраические типы будут более удобны, и более безопасны, но уже на уровень выше — в алгоритмическом плане, преодолевая то самое правило Лисков в ввиду закрытости группы (но опять же, только в случае контроля компилятором полноты матчинга, иначе та самая "дыра" остаётся в первозданном виде).


Я так и не понял какое отношения все эти рассуждения имеют к динамической типизации в стаически-типизированных языках?
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[45]: Проблемы организации OR-мапинга
От: EvilChild Ниоткуда  
Дата: 07.05.09 18:24
Оценка:
В качестве резюме дискуссии, если её ещё кто-то читает:
идём читать The Haskell 98 Report по ссылке и находим 3.13 Case-выражения,
чуть дальше читаем

Case-выражение должно иметь по крайней мере одну альтернативу, и каждая альтернатива должна иметь по крайней мере одно тело.
Каждое тело должно иметь один и тот же тип, и все выражение должно быть того же типа.

Если сомнения ещё остались, то можно прочесть 3.17 Сопоставление с образцом:

Образцы появляются в лямбда-абстракциях, определениях функций, связываниях с образцом, описаниях списков, do-выражениях и case-выражениях. Тем не менее, первые пять из них в конечном счете транслируются в case-выражения, поэтому достаточно ограничиться определением семантики сопоставления с образцом для case-выражений.

now playing: Dubfire — I Feel Speed (Alternative Mix)
Re[46]: Проблемы организации OR-мапинга
От: vdimas Россия  
Дата: 07.05.09 20:50
Оценка:
Здравствуйте, EvilChild, Вы писали:

EC>В качестве резюме дискуссии, если её ещё кто-то читает:

EC>идём читать The Haskell 98 Report по ссылке и находим 3.13 Case-выражения,
EC>чуть дальше читаем
EC>

EC>Case-выражение должно иметь по крайней мере одну альтернативу, и каждая альтернатива должна иметь по крайней мере одно тело.
EC>Каждое тело должно иметь один и тот же тип, и все выражение должно быть того же типа.


Опять у кого-то кое-где каша.
Каждое тело должно иметь один и тот же тип, т.к. это будет тип всего case-выражения, но этот тип может быть произвольным, не связанным с аргументом case.

Так что не вижу тут никакого резюме, даже не вижу связи с обсуждаемым.
... << RSDN@Home 1.2.0 alpha rev. 786>>
Re[47]: Проблемы организации OR-мапинга
От: EvilChild Ниоткуда  
Дата: 08.05.09 02:57
Оценка: -1
Здравствуйте, vdimas, Вы писали:

EC>>В качестве резюме дискуссии, если её ещё кто-то читает:

EC>>идём читать The Haskell 98 Report по ссылке и находим 3.13 Case-выражения,
EC>>чуть дальше читаем
EC>>

EC>>Case-выражение должно иметь по крайней мере одну альтернативу, и каждая альтернатива должна иметь по крайней мере одно тело.
EC>>Каждое тело должно иметь один и тот же тип, и все выражение должно быть того же типа.


V>Опять у кого-то кое-где каша.

V>Каждое тело должно иметь один и тот же тип, т.к. это будет тип всего case-выражения, но этот тип может быть произвольным, не связанным с аргументом case.

V>Так что не вижу тут никакого резюме, даже не вижу связи с обсуждаемым.


Ок, ваш слив засчитан.
now playing: Dubfire — I Feel Speed (Alternative Mix)
Re[39]: Проблемы организации OR-мапинга
От: artelk  
Дата: 08.05.09 08:32
Оценка:
Здравствуйте, vdimas, Вы писали:

V>Обобщенный тип для алгебраического типа — это не аналог параметризуемого обобщенного типа из С++, это аналог union из того же С++. Это некий bag, куда заворачиваются другие типы, составляющие группу.


V>В общем, типы, входящие в группу, в общем случае не приводимы один к одному, поэтому нужен механизм, чтобы в одном аргументе передавать значения разных типов. Этот механизм — алгебраические типы. Типы заворачиваются в discriminated union.


EC>>Если добавить аргументов конструкторам значений, то с точки зрения типов ничего не изменится.


V>Ты бы сначала добавил.


<...>

EC>>Я не понимаю почему ты не хочешь провести границу между абстракцией и её реализацией.


V>А я не понимаю твоего упорства — всё более чем прозрачно.


V>И как раз об абстракции и говорил в первом утверждении, что полиморфизм по алгебраическим типам — это классика динамической типизации. Могу усилить — это наилучший на сегодня способ использования динамической типизации.


Совсем не обязательно реализовывать алгебраические типы через группировку других типов и т.п.
//data AAA  = X Int Int | Y Int Int Int
public class AAA
{
    private readonly int[] data;

    private enum Discr { X, Y }
    private readonly Discr discr;

    private AAA(Discr discr, int[] data)
    {
        this.data = data;
        this.discr = discr;
    }

    public static AAA CreateX(int a1, int a2)
    {
        return new AAA(Discr.X, new[] { a1, a2 });
    }

    public static AAA CreateY(int a1, int a2, int a3)
    {
        return new AAA(Discr.Y, new[] { a1, a2, a3 });
    }

    private MatchResult<T> matchX<T>(Func<int, int, T> f)
    {
        if (discr != Discr.X)
            return MatchResult<T>.NotMatch;

        return new MatchResult<T>(f(data[0], data[1]));
    }

    private MatchResult<T> matchY<T>(Func<int, int, int, T> f)
    {
        if (discr != Discr.Y)
            return MatchResult<T>.NotMatch;

        return new MatchResult<T>(f(data[0], data[1], data[2]));
    }

    //Принимает параметрами функции для всех возможных вариантов
    public T Match<T>(Func<int, int, T> f_X, Func<int, int, int, T> f_Y)
    {
        var result = matchX(f_X);
        if (result != MatchResult<T>.NotMatch)
            return result.Result;
        return matchY(f_Y).Result;
    }
}

public class MatchResult<T>
{
    public readonly bool IsMatch;
    public readonly T Result;

    public MatchResult(T result)
    {
        IsMatch = true;
        Result = result;
    }

    private MatchResult(){IsMatch = false;}

    public static readonly MatchResult<T> NotMatch = new MatchResult<T>();
}

//case myAAA of
//    | X x y -> x + y
//    | Y a b c -> a + b + c
var myAAA = AAA.CreateY(1, 2, 3);
var res = myAAA.Match((x, y) => x + y,
                      (a, b, c) => a + b + c);
Re[48]: Проблемы организации OR-мапинга
От: vdimas Россия  
Дата: 08.05.09 08:42
Оценка:
Здравствуйте, EvilChild, Вы писали:

V>>Так что не вижу тут никакого резюме, даже не вижу связи с обсуждаемым.


EC>Ок, ваш слив засчитан.



Похоже, ты не понимаешь, почему в ФЯ выражение должно обязательно иметь тип, и почему для тел case этот тип должен быть одинаков, при этом вовсе не обязан быть алгебраическим.
bool2int Bool a = case a of
  True -> 1
  False -> 0
... << RSDN@Home 1.2.0 alpha rev. 786>>
Re[40]: Проблемы организации OR-мапинга
От: vdimas Россия  
Дата: 08.05.09 09:12
Оценка:
Здравствуйте, artelk, Вы писали:

A>Совсем не обязательно реализовывать алгебраические типы через группировку других типов и т.п.


...

В этом примере ты всего лишь разместил по одному адресу значения для случаев X и Y, потому как это оказалось возможным с т.з. системы типов CLR (тип массива не зависит от последней размерности). Если бы зависело, как в С++, то так просто не вышло бы. А в рассматриваемых мною исходниках Хаскеля по одному адресу размещаются значения вообще различных типов, сразу после дискриминатора, такое размещение аналогично union из С/С++. Но в отличии от последнего, язык не предоставляет ср-ва для потенциально неверной реинтерпретации памяти.

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

По остальному:
— приватный конструктор и вмеcто него "статические конструкторы" — абсолютно правильно, однако мы часто делаем их как value type, когда по сценарию их множества хранятся, что оставляет некую "дырочку" в виде конструктора по-умолчанию.
— матч перемудрил, там просто case по дискриминатору надо сделать, безо всяких MatchResult, matchX и matchY.
... << RSDN@Home 1.2.0 alpha rev. 786>>
Re[41]: Проблемы организации OR-мапинга
От: artelk  
Дата: 08.05.09 09:58
Оценка: +1
Здравствуйте, vdimas, Вы писали:

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


A>>Совсем не обязательно реализовывать алгебраические типы через группировку других типов и т.п.


V>...


V>В этом примере ты всего лишь разместил по одному адресу значения для случаев X и Y, потому как это оказалось возможным с т.з. системы типов CLR (тип массива не зависит от последней размерности). Если бы зависело, как в С++, то так просто не вышло бы. А в рассматриваемых мною исходниках Хаскеля по одному адресу размещаются значения вообще различных типов, сразу после дискриминатора, такое размещение аналогично union из С/С++. Но в отличии от последнего, язык не предоставляет ср-ва для потенциально неверной реинтерпретации памяти.


Типы параметров конструкторов X и Y не обязаны быть одинаковыми (Int из примера). В плюсах было бы что-нибудь вроде "char* data = new char[size]" и интерпретацией памати "(int*)(data+2)", правда со всякими выравниваниями пришлось бы бороться, похоже.
Только Хаскель ведь не в C++ транслируется перед компиляцией. Если б транслировался, тогда да, проще всего было бы сделать через union, но это было бы внутренней деталью реализации компилятора, а не чем-то, относящесмя к самому Хаскелю.
Вся интерпретация памяти жестко инкапсулирована. Доступ к полям осуществляется только по матчу — путем передачи лямбд для каждого варианта. Runtime ошибок здесь быть не может вообще.

V>- матч перемудрил, там просто case по дискриминатору надо сделать, безо всяких MatchResult, matchX и matchY.

Ага, можно въинлайнить matchX и matchY в Match и избавиться от MatchResult. Просто хотелось акцентировать на том, что matchX и matchY по отдельности — private методы
Re[49]: Проблемы организации OR-мапинга
От: EvilChild Ниоткуда  
Дата: 08.05.09 11:05
Оценка:
Здравствуйте, vdimas, Вы писали:


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

V>
V>bool2int Bool a = case a of
V>  True -> 1
V>  False -> 0 
V>


Я не понимаю какое отношение то, что ты пишешь имеет к обоснованию динамической типизации паттерн матчинга в хаскеле.
Ты можешь дать ссылку на место в The Haskell 98 report подтверждающее твои слова?
А то надоело слушать отвлечённые рассуждения о том как что-то можно сделать в C++ или поверх CLR.
Re[23]: Проблемы организации OR-мапинга
От: dimgel Россия https://github.com/dimgel
Дата: 18.05.09 13:11
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Но такая фича не поддерживается в дотнете. По этому даже ФЯ реализованные на дотнете не поддерживают записей (по крайней мере в полной мере).


В скале эта фича есть, скала может компилироваться в .NET. Проблема выруливается на этапе компиляции преобразованием (1, "1") в new Tuple2<Int,String> (1, "1"). На данный момент поддерживаются до Tuple22.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[11]: Проблемы организации OR-мапинга
От: dimgel Россия https://github.com/dimgel
Дата: 18.05.09 14:14
Оценка:
Здравствуйте, gandjustas, Вы писали:

A>>Анонимные типы, очень хорошая аналогия, только пользы от них в данном случае никакой нет. Надо уметь возвращать вполне конкретные типы, а какие именно автоматически не вывести.

G>Это решется с помощью метаданных. Причем метаданные могут быть выведены автоматически (следующая версия EF это будет уметь)

Имеется в виду что-то типа следующего?

$ scala
Welcome to Scala version 2.7.4.final (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_13).
Type in expressions to have them evaluated.
Type :help for more information.

scala> case class User(id: Int, firstName: String, lastName: String) {
     | def fullName = firstName + " " + lastName
     | }
defined class User

scala> val tuple = (1, "John", "Brown")
tuple: (Int, java.lang.String, java.lang.String) = (1,John,Brown)

scala> implicit def tuple2user(t: Tuple3[Int, String, String]) = new User(t._1, t._2, t._3)
tuple2user: ((Int, String, String))User

scala> tuple.fullName
res0: java.lang.String = John Brown


Здесь преобразование выполняется не совсем автоматически: явно заданным implicit-методом (вполне, впрочем, простым).
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[24]: Проблемы организации OR-мапинга
От: VladD2 Российская Империя www.nemerle.org
Дата: 18.05.09 15:28
Оценка: 2 (1)
Здравствуйте, dimgel, Вы писали:

VD>>Но такая фича не поддерживается в дотнете. По этому даже ФЯ реализованные на дотнете не поддерживают записей (по крайней мере в полной мере).


D>В скале эта фича есть, скала может компилироваться в .NET. Проблема выруливается на этапе компиляции преобразованием (1, "1") в new Tuple2<Int,String> (1, "1"). На данный момент поддерживаются до Tuple22.


Tuple — это кортеж. Речь же шла о записи — record. Запись это, можно сказать, кортеж с именованными полями.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re: 2IT & VladD2 & gandjustas & MozgC & others
От: Tom Россия http://www.RSDN.ru
Дата: 25.05.09 06:53
Оценка:
Предлагаю продолжить тут http://rsdn.ru/forum/philosophy/3400215.1.aspx
Автор: Tom
Дата: 22.05.09


Очень интересно Ваше мнение на тему сабсоника.
Народная мудрось
всем все никому ничего(с).
Re[2]: 2IT & VladD2 & gandjustas & MozgC & others
От: VladD2 Российская Империя www.nemerle.org
Дата: 26.05.09 11:59
Оценка:
Здравствуйте, Tom, Вы писали:

Tom>Предлагаю продолжить тут http://rsdn.ru/forum/philosophy/3400215.1.aspx
Автор: Tom
Дата: 22.05.09


Tom>Очень интересно Ваше мнение на тему сабсоника.


Какое может быть мнение?
Я этим не пользовался, так что ничего особо сказать не могу.

На первый взгляд выглядит фигней, так как то и дело встречаются строковые константы (стало быть о проверке типов во время компиляции и интеллисенсе речи идти не может).
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: 2IT & VladD2 & gandjustas & MozgC & others
От: Tom Россия http://www.RSDN.ru
Дата: 26.05.09 12:19
Оценка:
Здравствуйте, VladD2, Вы писали:

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


Tom>>Предлагаю продолжить тут http://rsdn.ru/forum/philosophy/3400215.1.aspx
Автор: Tom
Дата: 22.05.09


Tom>>Очень интересно Ваше мнение на тему сабсоника.


VD>Какое может быть мнение?

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

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

Строковые константы там только для того что бы показать что и так можно. Более того, если есть строка (... SET A = 'B'), то сабсоник распарсит такую конструкцию и в итоге передаст 'B' как параметр.
Предлагаю обсуждать в том топике, этот уже нездорово большой
Народная мудрось
всем все никому ничего(с).
Re[4]: 2IT & VladD2 & gandjustas & MozgC & others
От: VladD2 Российская Империя www.nemerle.org
Дата: 26.05.09 12:49
Оценка:
Здравствуйте, Tom, Вы писали:

Tom>Более того, если есть строка (... SET A = 'B'), то сабсоник распарсит такую конструкцию и в итоге передаст 'B' как параметр.

Tom>Предлагаю обсуждать в том топике, этот уже нездорово большой

Когда распарсит?

Из примеров я вижу, что все откладывается на рантайм.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[6]: Проблемы организации OR-мапинга
От: ili Россия  
Дата: 02.06.09 12:10
Оценка:
Здравствуйте, IT, Вы писали:

IT>Кстати, забыл про SQL отдельно от кода. Иногда приложение можно существенно оптимизировать, генерируя и оптимизируя код SQL на клиенте. За примером далеко ходить не надо — это наш сайт и конкретно MainList.aspx. Переписывание кода со статического SQL на Linq2SQL решило проблему, над которой мы бились несколько лет, пытаясь тщетно подкрутить монстрообразный запрос индексами и хинтами.


покажите в образовательных целях что было и что стало, а то пример проскакивает неоднократно, но ненаглядно.
Re[7]: Проблемы организации OR-мапинга
От: IT Россия linq2db.com
Дата: 04.06.09 04:34
Оценка: 38 (1)
Здравствуйте, ili, Вы писали:

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


        [SqlQuery(@"
            WITH Numbered AS
            (
                SELECT TOP (@startRecord + @maxRecords)
                    ROW_NUMBER() OVER (ORDER BY fm.updt DESC) RowNum,
                    fm.mid       ID_Message,
                    fm.subj      Subject,
                    fm.uid       ID_User,
                    fm.usernick  UserNick,
                    fm.nans      AnswerCount,
                    fm.updt      UpdateTime,
                    fm.lastone   LastMessageAuthor,
                    fm.gid       ID_Forum,
                    fg.ref       ForumShortName,
                    (SELECT sum(Rating) FROM   MessageRating WHERE ID_Topic = fm.mid)  Rating,
                    (SELECT Count(*) FROM self WHERE mid = fm.mid AND (dte > COALESCE(fm.last_moderated,0))) SelfCount,
                    fm.dte       [Date]
                FROM forum_tree fm 
                INNER JOIN AllowedReadGroups(@userID,0) fg ON fg.gid = fm.gid
                WHERE fm.tid=0
                    AND ((@nans IS NULL) OR (nans = @nans))
                    AND NOT EXISTS(SELECT 1 FROM forum_filter ff WHERE ff.gid=fm.gid AND uid=@userID)
                ORDER BY fm.updt DESC
            )
            SELECT * FROM Numbered WHERE RowNum BETWEEN @startRecord + 1 AND @startRecord + @maxRecords
            OPTION (MAXDOP 1)")]
        [DataSetTable("Message")]
        public abstract ForumDataSet GetAllPublicTopics(
            int userID,
            [ParamName("nans"), ParamNullValue(-1)] int nAnswers,
            int startRecord, int maxRecords);

        public virtual ICollection GetAllPublicTopicsEx(UserInfo user, IEnumerable<int> allowed, IEnumerable<int> skip, int nAnswers, int startRecord, int maxRecords)
        {
            using (var db = RsdnDataContext.Create())
            {
                var ucread = user.IsAnonym? UserRole.User: user.UserRole;

                var result =
                    from mt in db.MessageTrees
                        join f in db.Forums on mt.ForumID equals f.ForumID
                    where
                        mt.TopicID == 0 &&
                        f.ForumID > 0 &&
                        (f.UserReadLevel >= (short)ucread || allowed.Contains(f.ForumID)) &&
                        !skip.Contains(f.ForumID)
                    orderby mt.UpdatedOn descending
                    select new
                    {
                        ID_Message        = mt.MessageID,
                        Subject           = mt.Subject,
                        ID_User           = mt.UserID,
                        UserNick          = mt.UserNick,
                        AnswerCount       = mt.AnswerNumber,
                        UpdateTime        = mt.UpdatedOn,
                        LastMessageAuthor = mt.LastAnswerBy,
                        ID_Forum          = mt.ForumID,
                        ForumShortName    = f.Alias,
                        UserRole          = f.UserReadLevel,
                        Rating            = (from mr in db.MessageRatings where mr.ID_Topic == mt.MessageID select mr.Rating).Sum()
                    };

                if (nAnswers >= 0)
                    result = from r in result where r.AnswerCount == nAnswers select r;

                result = result.Skip(startRecord).Take(maxRecords);

                return result.ToList();
            }
        }


Первый метод как было, второй как стало.

В 95% работают следующие оптимизации:

— allowed.Contains устраняется,
— пейджинг превращается в TOP,
— проверка AnswerCount не делается.
Если нам не помогут, то мы тоже никого не пощадим.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.