Linq : неудачный маркетинг?
От: 0x7be СССР  
Дата: 16.02.10 20:55
Оценка: +2
Добрый день.

По опыту своих бесед с программистами, не знакомыми с linq, я собрал ряд стереотипных заблуждений и проблем с пониманеим linq, которые у них встречаются. В целом среди них преобладает такое мнение "это убогий SQL в С#, зачем он нужен?". Все попытки объяснить, что linq является воплощением аппарата операций над множествами, который ортогонален языку, и с необходимостью которого никто не спорит, сталкиваются с такой стеной непонимания. Это приводит меня к мысли, что linq подан неудачно. Его SQL-подобный синтаксис вызывает затруднения и у тех кто не знаком с SQL (выглядит больно непривычно) и у тех, кто знаком (не совсем понимают, что SQL делает в языке и сталкиваются с тем, что синтаксис всего лишь похож, а не повторяет SQL). Мое мнение по этому поводу: Linq — хорошая штука, но неудачно подан. Ваши мнения?
Re: Linq : неудачный маркетинг?
От: Temoto  
Дата: 16.02.10 21:11
Оценка: :)
0>По опыту своих бесед с программистами, не знакомыми с linq, я собрал ряд стереотипных заблуждений и проблем с пониманеим linq, которые у них встречаются. В целом среди них преобладает такое мнение "это убогий SQL в С#, зачем он нужен?". Все попытки объяснить, что linq является воплощением аппарата операций над множествами, который ортогонален языку, и с необходимостью которого никто не спорит, сталкиваются с такой стеной непонимания.

Все попытки объяснить обезъянам, что такое дерево, приведут ровно к тому же. Может быть просто не надо с ними это обсуждать?

0> Это приводит меня к мысли, что linq подан неудачно. Его SQL-подобный синтаксис вызывает затруднения и у тех кто не знаком с SQL (выглядит больно непривычно) и у тех, кто знаком (не совсем понимают, что SQL делает в языке и сталкиваются с тем, что синтаксис всего лишь похож, а не повторяет SQL). Мое мнение по этому поводу: Linq — хорошая штука, но неудачно подан. Ваши мнения?


Это такая же мелочь, как лямбда в питоне состоит из одного выражения, стейтменты нельзя вписать. Затруднения — первые пару дней. LINQ — это инструмент для решения определённого класса задач. Если люди пишут код, чтобы решать задачи (а не чтобы поболтать про разные фичи), то они будут его использовать. Инструменты надо использовать, а не подавать.

"Подавать" надо маркетинговые безделушки, типа делегатов или встроенного в IDE списка задач.
Re: Linq : неудачный маркетинг?
От: VladD2 Российская Империя www.nemerle.org
Дата: 16.02.10 21:15
Оценка: +2
Здравствуйте, 0x7be, Вы писали:

0>По опыту своих бесед с программистами, не знакомыми с linq, я собрал ряд стереотипных заблуждений и проблем с пониманеим linq, которые у них встречаются. В целом среди них преобладает такое мнение "это убогий SQL в С#, зачем он нужен?". Все попытки объяснить, что linq является воплощением аппарата операций над множествами, который ортогонален языку, и с необходимостью которого никто не спорит, сталкиваются с такой стеной непонимания. Это приводит меня к мысли, что linq подан неудачно. Его SQL-подобный синтаксис вызывает затруднения и у тех кто не знаком с SQL (выглядит больно непривычно) и у тех, кто знаком (не совсем понимают, что SQL делает в языке и сталкиваются с тем, что синтаксис всего лишь похож, а не повторяет SQL). Мое мнение по этому поводу: Linq — хорошая штука, но неудачно подан. Ваши мнения?


Мое мнение такое... Линк не очень хорош (во многих отношениях), но подан он очень даже хорошо. Это первая, реально успешная попытка преподнести массам функциональное программирование. Другие попытки провалились полностью.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[2]: Linq : неудачный маркетинг?
От: VladD2 Российская Империя www.nemerle.org
Дата: 16.02.10 21:18
Оценка: 1 (1) +2
Здравствуйте, Temoto, Вы писали:

T>Инструменты надо использовать, а не подавать.


T>"Подавать" надо маркетинговые безделушки, типа делегатов или встроенного в IDE списка задач.


Гы. Это даже заблуждением назвать язык не поворачивается. Если бы это было правдой, то мир был бы иным.

К сожалению зомбоящики, пиар и реклама правят миром. И можно придумать просто супер-пупер-опупенную фиговину, но если она не будет красиво завернута, грамотно пропиарена, разжевана и положена в рот массам, она не выживет в этом мире.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: Linq : неудачный маркетинг?
От: Temoto  
Дата: 16.02.10 21:44
Оценка:
T>>Инструменты надо использовать, а не подавать.

T>>"Подавать" надо маркетинговые безделушки, типа делегатов или встроенного в IDE списка задач.


VD>Гы. Это даже заблуждением назвать язык не поворачивается. Если бы это было правдой, то мир был бы иным.


Это правда. Вы давно видели "пиар" редактора (бросайте писать программы через open,write,close)? Тут можно спорить о том, что относится к общепризнанным благам, а что нет.

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


Вы имели в виду иное, но получилось очень точно. Супер-пупер-опупенную фиговину надо подавать, да. Потому что она даже называется сложно, очевидно, что объяснение "зачем она нужна" займёт уйму времени. Простые в использовании вещи, которые просто упрощают жизнь, не требуя ничего взамен, не требуют и рекламы. Например, оптимизации компилятора, вывод типов, лямбды.
Re[2]: Linq : неудачный маркетинг?
От: Temoto  
Дата: 16.02.10 21:45
Оценка:
0>>По опыту своих бесед с программистами, не знакомыми с linq, я собрал ряд стереотипных заблуждений и проблем с пониманеим linq, которые у них встречаются. В целом среди них преобладает такое мнение "это убогий SQL в С#, зачем он нужен?". Все попытки объяснить, что linq является воплощением аппарата операций над множествами, который ортогонален языку, и с необходимостью которого никто не спорит, сталкиваются с такой стеной непонимания. Это приводит меня к мысли, что linq подан неудачно. Его SQL-подобный синтаксис вызывает затруднения и у тех кто не знаком с SQL (выглядит больно непривычно) и у тех, кто знаком (не совсем понимают, что SQL делает в языке и сталкиваются с тем, что синтаксис всего лишь похож, а не повторяет SQL). Мое мнение по этому поводу: Linq — хорошая штука, но неудачно подан. Ваши мнения?

VD>Мое мнение такое... Линк не очень хорош (во многих отношениях), но подан он очень даже хорошо. Это первая, реально успешная попытка преподнести массам функциональное программирование. Другие попытки провалились полностью.


SQL провалился?
Re: Linq : неудачный маркетинг?
От: IT Россия linq2db.com
Дата: 16.02.10 21:50
Оценка:
Здравствуйте, 0x7be, Вы писали:

0>Мое мнение по этому поводу: Linq — хорошая штука, но неудачно подан. Ваши мнения?


Как ни подавай, а чтобы оценить технологию, нужно в ней разобраться. А подавляющее большинство у нас устойчиво путает Linq с query comprehension. Хоть апподавайся — без толку.
Если нам не помогут, то мы тоже никого не пощадим.
Re[2]: Linq : неудачный маркетинг?
От: 0x7be СССР  
Дата: 17.02.10 02:32
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Мое мнение такое... Линк не очень хорош (во многих отношениях), но подан он очень даже хорошо. Это первая, реально успешная попытка преподнести массам функциональное программирование. Другие попытки провалились полностью.

Аргументация мнения или ссылки на конструктивную критику Linq всячески приветствуются.
Мое личное мнение — основной косяк скорее зарыт в идеологии перечислителей.
Re[2]: Linq : неудачный маркетинг?
От: 0x7be СССР  
Дата: 17.02.10 02:35
Оценка:
Здравствуйте, IT, Вы писали:

0>>Мое мнение по этому поводу: Linq — хорошая штука, но неудачно подан. Ваши мнения?

IT>Как ни подавай, а чтобы оценить технологию, нужно в ней разобраться. А подавляющее большинство у нас устойчиво путает Linq с query comprehension. Хоть апподавайся — без толку.
А вот не потому ли путают, что название такое и в синтаксисе совершенно ненужный закос под SQL? Когда на пальцах объясняешь про map, filter, fold и прочие функции — как-то проще понимают. Начинаешь linq расчехлять — упорно с SQL-ем сравнивают.
Re[3]: Linq : неудачный маркетинг?
От: IT Россия linq2db.com
Дата: 17.02.10 03:35
Оценка:
Здравствуйте, 0x7be, Вы писали:

0>А вот не потому ли путают, что название такое и в синтаксисе совершенно ненужный закос под SQL? Когда на пальцах объясняешь про map, filter, fold и прочие функции — как-то проще понимают.


Понимают или делают вид, что понимают?

0>Начинаешь linq расчехлять — упорно с SQL-ем сравнивают.


Я как-то не встречал трудностей у тех, кто одинаково хорошо знаком как с функциональщиной, так и с SQL. Перекосы начинаются, когда знания в SQL есть, а ФП ноль.
Если нам не помогут, то мы тоже никого не пощадим.
Re: Linq : неудачный маркетинг?
От: Mazay Россия  
Дата: 17.02.10 05:11
Оценка: :))) :)))
Здравствуйте, 0x7be, Вы писали:

0>По опыту своих бесед с программистами, не знакомыми с linq, я собрал ряд стереотипных заблуждений и проблем с пониманеим linq, которые у них встречаются. В целом среди них преобладает такое мнение "это убогий SQL в С#, зачем он нужен?". Все попытки объяснить, что linq является воплощением аппарата операций над множествами, который ортогонален языку, и с необходимостью которого никто не спорит, сталкиваются с такой стеной непонимания. Это приводит меня к мысли, что linq подан неудачно. Его SQL-подобный синтаксис вызывает затруднения и у тех кто не знаком с SQL (выглядит больно непривычно) и у тех, кто знаком (не совсем понимают, что SQL делает в языке и сталкиваются с тем, что синтаксис всего лишь похож, а не повторяет SQL). Мое мнение по этому поводу: Linq — хорошая штука, но неудачно подан. Ваши мнения?


Я в промышленном программировании уже 2 года как не появлялся, так что мои представления могут быть несколько устаревшими. Но если взять "типичный" проект с SQL БД, то действительно не очень понятно зачем мне ещё и LINQ. Ведь практически все объекты с которыми я работаю, лежат в БД и оттуда их можно спокойно выдернуть SQL запросом, который отработает на сервере, который всё соптимизирует, закэширует и т. д. Зачем мне самому держать коллекции, к которым потом обращаться через заново изобретенный SQL и не забывать синхронизировать с базой? Нет, конечно иногда приходится, но не так часто, и этого лучше избегать.

"воплощение аппарата операций над множествами, который ортогонален языку" это конечно здорово и где-то он видимо действительно необходим, но не в моём проекте. Вот в проектах, в которых требуется самостоятельно оперировать большими коллекциями в памяти, чуть более сложными чем два массива, там LINQ наверное найдет свое применение, но, как мне представляется, таких проектов немного. Так что маркетинговые усилия на эту фичу не соответсвуют размеру целевой аудитории. Если конечно говорить о LINQ как об инструменте решения конкретных задач, а не о средстве продвижения ФП в массы.
Главное гармония ...
Re[2]: Linq : неудачный маркетинг?
От: IT Россия linq2db.com
Дата: 17.02.10 05:18
Оценка: 1 (1) +6 :))
Здравствуйте, Mazay, Вы писали:

M>Я в промышленном программировании уже 2 года как не появлялся, так что мои представления могут быть несколько устаревшими. Но если взять "типичный" проект с SQL БД, то действительно не очень понятно зачем мне ещё и LINQ. Ведь практически все объекты с которыми я работаю, лежат в БД и оттуда их можно спокойно выдернуть SQL запросом, который отработает на сервере, который всё соптимизирует, закэширует и т. д. Зачем мне самому держать коллекции, к которым потом обращаться через заново изобретенный SQL и не забывать синхронизировать с базой? Нет, конечно иногда приходится, но не так часто, и этого лучше избегать.


Вот! Типичный пример того, о чём я говорил. Люди рассуждают о том, о чём имеют весьма смутное и отдалённое понятие. 0x7be, иди и попробуй теперь это удачно подать
Если нам не помогут, то мы тоже никого не пощадим.
Re[3]: Linq : неудачный маркетинг?
От: Mazay Россия  
Дата: 17.02.10 05:39
Оценка: :)
Здравствуйте, IT, Вы писали:

IT>Вот! Типичный пример того, о чём я говорил. Люди рассуждают о том, о чём имеют весьма смутное и отдалённое понятие. 0x7be, иди и попробуй теперь это удачно подать


О чём я имею "весьма смутное и отдалённое понятие"? О промышленной разработке "типичных" проектов? Не соглашусь. О LINQ? Пожалуй да. Ну дык в том виде в каком её подают я не вижу ей применения для своих задач. Ниже типичный пример использования LINQ. Вот скажите, вам в самом деле часто приходится работать с такими ArrayList'ами? Как правило же все эти данные лежат в БД и дергаются либо тем же SQL, либо HQL.


using System;
using System.Collections;
using System.Linq;

namespace NonGenericLINQ
{
    public class Student
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public int[] Scores { get; set; }
    }

    class Program
    {
        static void Main(string[] args)
        {
            ArrayList arrList = new ArrayList();
            arrList.Add(
                new Student
                    {
                        FirstName = "Svetlana", LastName = "Omelchenko", Scores = new int[] { 98, 92, 81, 60 }
                    });
            arrList.Add(
                new Student
                    {
                        FirstName = "Claire", LastName = "O’Donnell", Scores = new int[] { 75, 84, 91, 39 }
                    });
            arrList.Add(
                new Student
                    {
                        FirstName = "Sven", LastName = "Mortensen", Scores = new int[] { 88, 94, 65, 91 }
                    });
            arrList.Add(
                new Student
                    {
                        FirstName = "Cesar", LastName = "Garcia", Scores = new int[] { 97, 89, 85, 82 }
                    });

            var query = from Student student in arrList
                        where student.Scores[0] > 95
                        select student;

            foreach (Student s in query)
                Console.WriteLine(s.LastName + ": " + s.Scores[0]);

            // Keep the console window open in debug mode.
            Console.WriteLine("Press any key to exit.");
            Console.ReadKey();
        }
    }
}
Главное гармония ...
Re[4]: Linq : неудачный маркетинг?
От: 0x7be СССР  
Дата: 17.02.10 06:36
Оценка:
Здравствуйте, Mazay, Вы писали:

M>О чём я имею "весьма смутное и отдалённое понятие"? О промышленной разработке "типичных" проектов? Не соглашусь. О LINQ? Пожалуй да. Ну дык в том виде в каком её подают я не вижу ей применения для своих задач. Ниже типичный пример использования LINQ. Вот скажите, вам в самом деле часто приходится работать с такими ArrayList'ами? Как правило же все эти данные лежат в БД и дергаются либо тем же SQL, либо HQL.

Вот у меня совсем недавно был свой "пример использования linq" — я писал свой кастомный XML-сериализатор для одного проектика. Итерирование по метаданным, их обработка и так и сяк, отображение самих данных объектов — все это типичные задачи для Linq, и, заметь, с СУБД рядом не лежат.
Re[4]: Linq : неудачный маркетинг?
От: 0x7be СССР  
Дата: 17.02.10 06:38
Оценка:
Здравствуйте, IT, Вы писали:

0>>А вот не потому ли путают, что название такое и в синтаксисе совершенно ненужный закос под SQL? Когда на пальцах объясняешь про map, filter, fold и прочие функции — как-то проще понимают.

IT>Понимают или делают вид, что понимают?
Кто-то делает вид, конечно, но в целом интерес живее.

0>>Начинаешь linq расчехлять — упорно с SQL-ем сравнивают.

IT>Я как-то не встречал трудностей у тех, кто одинаково хорошо знаком как с функциональщиной, так и с SQL. Перекосы начинаются, когда знания в SQL есть, а ФП ноль.
Кстати да, у меня среди собеседников много людей именно с такой картиной кивалифкаций.
Re[3]: Linq : неудачный маркетинг?
От: VladD2 Российская Империя www.nemerle.org
Дата: 17.02.10 07:24
Оценка: 22 (4) +2
Здравствуйте, 0x7be, Вы писали:

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


VD>>Мое мнение такое... Линк не очень хорош (во многих отношениях), но подан он очень даже хорошо. Это первая, реально успешная попытка преподнести массам функциональное программирование. Другие попытки провалились полностью.

0>Аргументация мнения или ссылки на конструктивную критику Linq всячески приветствуются.
0>Мое личное мнение — основной косяк скорее зарыт в идеологии перечислителей.

Это очень большая тема. Не стоит развивать ее в ответвлении другой темы.

В двух словах... у линка есть два вида проблем 1) идеологические, 2) проблемы реализации.

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

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

ЗЫ

В этой ветке спорить не намерен. Интересна тема — открывайте новую.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[2]: Linq : неудачный маркетинг?
От: VladD2 Российская Империя www.nemerle.org
Дата: 17.02.10 07:49
Оценка: +1
Здравствуйте, IT, Вы писали:

IT>Как ни подавай, а чтобы оценить технологию, нужно в ней разобраться. А подавляющее большинство у нас устойчиво путает Linq с query comprehension. Хоть апподавайся — без толку.


Дык в терменологической путаннице виноват МС. Нефига было называть целую груду разной всячины одним именем.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[2]: Linq : неудачный маркетинг?
От: VladD2 Российская Империя www.nemerle.org
Дата: 17.02.10 07:55
Оценка:
Здравствуйте, Mazay, Вы писали:

M>Я в промышленном программировании уже 2 года как не появлялся, так что мои представления могут быть несколько устаревшими. Но если взять "типичный" проект с SQL БД, то действительно не очень понятно зачем мне ещё и LINQ.


Ну, так появись. Или хотя бы почитай что-то прежде чем обсуждать то в чем ты вообще ничего не понимашь.
Твои рассуждения о линке выглядят как полная чушь для тех понимает что это такое.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[4]: Linq : неудачный маркетинг?
От: VladD2 Российская Империя www.nemerle.org
Дата: 17.02.10 07:58
Оценка: +1
Здравствуйте, Mazay, Вы писали:

M>О чём я имею "весьма смутное и отдалённое понятие"?


О LINQ.

Подписываюсь под каждым словом IT.

Несешь полную чушь и еще сейчас спорить начнешь.

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

Господа. Не выставляйте себя на людях ламерами. Изучайте то что пытаетесь обсуждать!
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: Linq : неудачный маркетинг?
От: Mazay Россия  
Дата: 17.02.10 08:05
Оценка: -2
Здравствуйте, VladD2, Вы писали:

M>>Я в промышленном программировании уже 2 года как не появлялся, так что мои представления могут быть несколько устаревшими. Но если взять "типичный" проект с SQL БД, то действительно не очень понятно зачем мне ещё и LINQ.


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

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

Да что ты говоришь?! А то я не понимаю. Если бы я понимал в чём цимес Линк, то наверное не писал бы сюда. Я вообще-то надеялся на диалог с адекватными РСДНерами не на обсирание тобой.
Главное гармония ...
Re[5]: Linq : неудачный маркетинг?
От: Mazay Россия  
Дата: 17.02.10 08:10
Оценка:
Здравствуйте, VladD2, Вы писали:

M>>О чём я имею "весьма смутное и отдалённое понятие"?


VD>О LINQ.


VD>Подписываюсь под каждым словом IT.


VD>Несешь полную чушь и еще сейчас спорить начнешь.


С тобой спорить не буду, ибо полезной информации из спора с тобой круглый ноль, зато оскроблений целая куча.

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


VD>Господа. Не выставляйте себя на людях ламерами. Изучайте то что пытаетесь обсуждать!


Господин, читай посты на которые пытаешься отвечать!
Главное гармония ...
Re[6]: Linq : неудачный маркетинг?
От: Lloyd Россия  
Дата: 17.02.10 08:12
Оценка: +2
Здравствуйте, Mazay, Вы писали:

VD>>Несешь полную чушь и еще сейчас спорить начнешь.


M>С тобой спорить не буду, ибо полезной информации из спора с тобой круглый ноль, зато оскроблений целая куча.


И тем не менее, он прав, вы даже поверхностно не знакомы с LINQ-ом.
Re[5]: Linq : неудачный маркетинг?
От: Mazay Россия  
Дата: 17.02.10 08:16
Оценка:
Здравствуйте, 0x7be, Вы писали:

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


M>>О чём я имею "весьма смутное и отдалённое понятие"? О промышленной разработке "типичных" проектов? Не соглашусь. О LINQ? Пожалуй да. Ну дык в том виде в каком её подают я не вижу ей применения для своих задач. Ниже типичный пример использования LINQ. Вот скажите, вам в самом деле часто приходится работать с такими ArrayList'ами? Как правило же все эти данные лежат в БД и дергаются либо тем же SQL, либо HQL.

0>Вот у меня совсем недавно был свой "пример использования linq" — я писал свой кастомный XML-сериализатор для одного проектика. Итерирование по метаданным, их обработка и так и сяк, отображение самих данных объектов — все это типичные задачи для Linq, и, заметь, с СУБД рядом не лежат.
И получилось сильно проще чем с помощью XPath? Или это рассчет на будущий переезд на СУБД?
Главное гармония ...
Re[6]: Linq : неудачный маркетинг?
От: 0x7be СССР  
Дата: 17.02.10 08:41
Оценка:
Здравствуйте, Mazay, Вы писали:

M>И получилось сильно проще чем с помощью XPath? Или это рассчет на будущий переезд на СУБД?

Хм.
Стояло две задачи:
1. Из графа объектов произвольных классов, отдекорированных правильными атрибутами, построить дерево однотипных Data-Transfer-Object`ов. Основная засада, понятное дело, в разруливании циклических ссылок.
2. Сброс полученного дерева в поток. Сейчас реализован XML, но это, собственно, деталь реализации.
И потом в обратном порядке.

XPath применим только для п.2 при загрузке данные. Маппинг данных из объектов в дерево DTO и обратно не имеет никакого отношения к XML. Там стояла другая задача: рекурсивно обойти граф объектов, вытащить их каждого объекта метаданные по полям/свойствам, сами данные, метаданные, руководящие порядком отображения, и все это благолепие отобразить в дерево. В классе, который этим знанимается из 13 методов 11 — инкапсулированные linq-выражения.

Но это половина истории. Дело в том, что код в подобном виде у меня получился только после двух рефакторингов. Первоначально этот же код был написан в более традиционном духе, с foreach`ами, ручным перекладыванием объектов из коллекции в коллекцию и т.п. Сравнение первоначального варианта и конечного однозначно говорит в пользу реализации на linq, поскольку она получилась короче и прозрачнее (для тех, конечно, кто linq знает).
Re[4]: Linq : неудачный маркетинг?
От: WolfHound  
Дата: 17.02.10 09:00
Оценка:
Здравствуйте, Temoto, Вы писали:

T>Вы имели в виду иное, но получилось очень точно. Супер-пупер-опупенную фиговину надо подавать, да. Потому что она даже называется сложно, очевидно, что объяснение "зачем она нужна" займёт уйму времени. Простые в использовании вещи, которые просто упрощают жизнь, не требуя ничего взамен, не требуют и рекламы. Например, оптимизации компилятора, вывод типов, лямбды.

Если оптимизацию люди еще понимают то вывод типов и лямбды приходится объяснять.
Можешь поискать в форуме .NET там были войны на тему того что var (это такой недоделанный вывод типов) испортит читаемость кода на корню...
А если вывод типов хотябы как у немерле то там народ просто впадает в ступор и не понимает как это может работать.

А что с народом происходит при виде мощьных макросов

А сколько сил понадобится на то чтобы объяснить массам зависимые типы я и представить боюсь. У народа они просто в голове не удерживаются причем даже если объясняешь без матана.
... << RSDN@Home 1.2.0 alpha 4 rev. 1305>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[3]: Linq : неудачный маркетинг?
От: vdimas Россия  
Дата: 17.02.10 11:37
Оценка:
Здравствуйте, Temoto, Вы писали:

T>SQL провалился?


Это скорее декларативное программирование.
Re[4]: Linq : неудачный маркетинг?
От: Temoto  
Дата: 17.02.10 11:46
Оценка:
T>>SQL провалился?

V>Это скорее декларативное программирование.


Да, ваша правда. А вы можете провести чёткую грань между функциональным и декларативным программированием?
Re[2]: Linq : неудачный маркетинг?
От: Dufrenite Дания  
Дата: 17.02.10 14:18
Оценка: +2
Здравствуйте, Mazay, Вы писали:

M>Я в промышленном программировании уже 2 года как не появлялся, так что мои представления могут быть несколько устаревшими. Но если взять "типичный" проект с SQL БД, то действительно не очень понятно зачем мне ещё и LINQ. Ведь практически все объекты с которыми я работаю, лежат в БД и оттуда их можно спокойно выдернуть SQL запросом, который отработает на сервере, который всё соптимизирует, закэширует и т. д. Зачем мне самому держать коллекции, к которым потом обращаться через заново изобретенный SQL и не забывать синхронизировать с базой? Нет, конечно иногда приходится, но не так часто, и этого лучше избегать.


То, что вы хотите сказать вполне разумно, но. Не базой данных единой жив программист. Я не буду строить из себя мега-математика и эксперта по теории множеств, а скажу с точки зрения обычного разработчика. LINQ это мега удобно при работе с коллекциями. Например, там где обычно надо написать несколько вложенных циклов и задействовать несколько промежуточных переменных LINQ позволяет обойтись одним запросом или простой цепочкой вызовов (кому как нравится).
Код получается короче и понятней (проверено). Свободы больше: хочу циклы пишу, хочу запросы. Как проще и понятней получается тот способ и выбираю.

Примерно так. Никакого фанатизма, чистый прагматизм.
Re: Linq : неудачный маркетинг?
От: Wolverrum Ниоткуда  
Дата: 17.02.10 15:06
Оценка:
Здравствуйте, 0x7be, Вы писали:

0>Добрый день.


0>По опыту своих бесед с программистами, не знакомыми с linq, я собрал ряд стереотипных заблуждений и проблем с пониманеим linq, которые у них встречаются. В целом среди них преобладает такое мнение "это убогий SQL в С#, зачем он нужен?". Все попытки объяснить, что linq является воплощением аппарата операций над множествами, который ортогонален языку, и с необходимостью которого никто не спорит, сталкиваются с такой стеной непонимания. Это приводит меня к мысли, что linq подан неудачно. Его SQL-подобный синтаксис вызывает затруднения и у тех кто не знаком с SQL (выглядит больно непривычно) и у тех, кто знаком (не совсем понимают, что SQL делает в языке и сталкиваются с тем, что синтаксис всего лишь похож, а не повторяет SQL). Мое мнение по этому поводу: Linq — хорошая штука, но неудачно подан. Ваши мнения?


А вот встречный вопрос: владея примитивами compose/map/fold/filter/zip/cons я могу прекрасно (и достаточно компактно) решить встающие задачи (в т.ч. и те, что были указаны в топике — про графы, коллецкии и циклы) без применения linq, причем начиная с рамок .net 2.0. Стоит ли мне этот самый linq использовать или даже изучать? В чем профит (м.б., кроме расхода железных ресурсов), так сказать?
Re[4]: Linq : неудачный маркетинг?
От: IT Россия linq2db.com
Дата: 17.02.10 15:28
Оценка:
Здравствуйте, Mazay, Вы писали:

M>О чём я имею "весьма смутное и отдалённое понятие"? О промышленной разработке "типичных" проектов? Не соглашусь. О LINQ? Пожалуй да. Ну дык в том виде в каком её подают я не вижу ей применения для своих задач. Ниже типичный пример использования LINQ. Вот скажите, вам в самом деле часто приходится работать с такими ArrayList'ами? Как правило же все эти данные лежат в БД и дергаются либо тем же SQL, либо HQL.


public class Student
{
    public int    StudentID { get; set; }
    public string FirstName { get; set; }
    public string LastName  { get; set; }

    [Association(ThisKey = "StudentID", OtherKey = "StudentID")]
    public Score[] Scores { get; set; }
}

public class Score
{
    public int StudentID { get; set; }
    public int Value     { get; set; }
}

public class StudentDB : DbManager
{
    public Table<Student> Student { get { return GetTable<Student>(); } }
}

static void Test()
{
    using (var db = new StudentDB())
    {
        var query =
            from Student student in db.Student
            where student.Scores.FirstOrDefault().Value > 95
            select student;

        foreach (Student s in query)
            Console.WriteLine(s.LastName + ": " + s.Scores[0]);
    }
}

Генерируемый SQL (Sybase):

SELECT
    [student].[StudentID],
    [student].[FirstName],
    [student].[LastName]
FROM
    [Student] [student]
WHERE
    (
        SELECT
            [t1].[Value]
        FROM
            [Score] [t1]
        WHERE
            [student].[StudentID] = [t1].[StudentID]
    ) > 95

Ещё вопросы?
Если нам не помогут, то мы тоже никого не пощадим.
Re[5]: Linq : неудачный маркетинг?
От: Lloyd Россия  
Дата: 17.02.10 15:33
Оценка: 58 (1)
Здравствуйте, IT, Вы писали:

IT>Генерируемый SQL (Sybase):


IT>
IT>SELECT
IT>    [student].[StudentID],
IT>    [student].[FirstName],
IT>    [student].[LastName]
IT>FROM
IT>    [Student] [student]
IT>WHERE
IT>    (
IT>        SELECT
IT>            [t1].[Value]
IT>        FROM
IT>            [Score] [t1]
IT>        WHERE
IT>            [student].[StudentID] = [t1].[StudentID]
IT>    ) > 95
IT>

IT>Ещё вопросы?

Без TOP 1?
Re[6]: Linq : неудачный маркетинг?
От: IT Россия linq2db.com
Дата: 17.02.10 15:37
Оценка:
Здравствуйте, Lloyd, Вы писали:

IT>>
IT>>SELECT
IT>>    [student].[StudentID],
IT>>    [student].[FirstName],
IT>>    [student].[LastName]
IT>>FROM
IT>>    [Student] [student]
IT>>WHERE
IT>>    (
IT>>        SELECT
IT>>            [t1].[Value]
IT>>        FROM
IT>>            [Score] [t1]
IT>>        WHERE
IT>>            [student].[StudentID] = [t1].[StudentID]
IT>>    ) > 95
IT>>

IT>>Ещё вопросы?

L>Без TOP 1?


Он в Sybase в подзапросах не поддерживается (будет ошибка сервера). Для вменяемых провайдеров будет, конечно, TOP 1.
Если нам не помогут, то мы тоже никого не пощадим.
Re[7]: Linq : неудачный маркетинг?
От: Lloyd Россия  
Дата: 17.02.10 15:39
Оценка:
Здравствуйте, IT, Вы писали:

L>>Без TOP 1?


IT>Он в Sybase в подзапросах не поддерживается (будет ошибка сервера). Для вменяемых провайдеров будет, конечно, TOP 1.


Гм. А какой результат будет, если записей вернется больше 1-й.
SQL Server вроде как ругается.
Re[7]: Linq : неудачный маркетинг?
От: Lloyd Россия  
Дата: 17.02.10 15:44
Оценка:
Здравствуйте, IT, Вы писали:

L>>Без TOP 1?


IT>Он в Sybase в подзапросах не поддерживается (будет ошибка сервера). Для вменяемых провайдеров будет, конечно, TOP 1.


За что оценка-то? Я баг что-ли нашел?
Re[5]: Linq : неудачный маркетинг?
От: Temoto  
Дата: 17.02.10 15:44
Оценка: 1 (1)
T>>Вы имели в виду иное, но получилось очень точно. Супер-пупер-опупенную фиговину надо подавать, да. Потому что она даже называется сложно, очевидно, что объяснение "зачем она нужна" займёт уйму времени. Простые в использовании вещи, которые просто упрощают жизнь, не требуя ничего взамен, не требуют и рекламы. Например, оптимизации компилятора, вывод типов, лямбды.
WH>Если оптимизацию люди еще понимают то вывод типов и лямбды приходится объяснять.
WH>Можешь поискать в форуме .NET там были войны на тему того что var (это такой недоделанный вывод типов) испортит читаемость кода на корню...

Чёрт знает. Лично я вижу даже убогий var примерно так:
было (забиваем деревянные гвозди руками) "Map <String, ClientInfo> found = (expr)",
стало (взяли в руки киянку) "var found = (expr)".

Т.е. просто бесплатное улучшение жизни. Как это работает объяснять не надо.

Если люди уж и в этом видят проблемы да препятствия и при этом они не тролли, не PHP-шники в душе, то, видимо, вывод типов ещё пока не относится к общепризнанным благам. Увышка.

В любом случае, неблагодарное это дело — объяснять что-то массам. По-моему, пусть лучше 10 человек понимают и используют LINQ, чем тысяча будет ворчать, что это недоSQL и он не нужен.
Re[6]: Linq : неудачный маркетинг?
От: Lloyd Россия  
Дата: 17.02.10 15:46
Оценка: +1
Здравствуйте, Temoto, Вы писали:

T>Чёрт знает. Лично я вижу даже убогий var примерно так:

T>было (забиваем деревянные гвозди руками) "Map <String, ClientInfo> found = (expr)",
T>стало (взяли в руки киянку) "var found = (expr)".

T>Т.е. просто бесплатное улучшение жизни. Как это работает объяснять не надо.


Это улучшения для разработки, но ухудшения для поддержки. А поддержка, как известнно, занимает гораздо больше времени и денег. И где тогда выигрышь?
Re[8]: Linq : неудачный маркетинг?
От: IT Россия linq2db.com
Дата: 17.02.10 15:48
Оценка:
Здравствуйте, Lloyd, Вы писали:

L>Гм. А какой результат будет, если записей вернется больше 1-й.

L>SQL Server вроде как ругается.

Sybase тоже заорёт. Здесь вопрос в принципе заключается не в Linq, а в сервере БД. Если есть способ сгенерировать рабочий SQL для данного запроса для Sybase, то мы можем это сделать.

На самом деле здесь ещё под вопросом сам пример. Может лучше написать так:

var query =
    from Student student in db.Student
    where student.Scores.Max(s => s.Value) > 95
    select student;

Тогда получится вполне рабочий SQL даже для Sybase;

SELECT
    [student].[StudentID],
    [student].[FirstName],
    [student].[LastName]
FROM
    [Student] [student]
WHERE
    (
        SELECT
            Max([t1].[Value])
        FROM
            [Score] [t1]
        WHERE
            [student].[StudentID] = [t1].[StudentID]
    ) > 95
Если нам не помогут, то мы тоже никого не пощадим.
Re[8]: Linq : неудачный маркетинг?
От: IT Россия linq2db.com
Дата: 17.02.10 15:49
Оценка: :)
Здравствуйте, Lloyd, Вы писали:

L>За что оценка-то? Я баг что-ли нашел?


За меткий глаз
Если нам не помогут, то мы тоже никого не пощадим.
Re[7]: Linq : неудачный маркетинг?
От: Temoto  
Дата: 17.02.10 15:50
Оценка:
T>>Чёрт знает. Лично я вижу даже убогий var примерно так:
T>>было (забиваем деревянные гвозди руками) "Map <String, ClientInfo> found = (expr)",
T>>стало (взяли в руки киянку) "var found = (expr)".

T>>Т.е. просто бесплатное улучшение жизни. Как это работает объяснять не надо.


L>Это улучшения для разработки, но ухудшения для поддержки. А поддержка, как известнно, занимает гораздо больше времени и денег. И где тогда выигрышь?


Допустим, что это упрощение разработки, но я продемонстрировал в чём именно улучшение.
Если без демонстрации, то хотя бы объясните в чём ухудшение поддержки?
Re[8]: Linq : неудачный маркетинг?
От: Lloyd Россия  
Дата: 17.02.10 15:51
Оценка: +3
Здравствуйте, Temoto, Вы писали:

L>>Это улучшения для разработки, но ухудшения для поддержки. А поддержка, как известнно, занимает гораздо больше времени и денег. И где тогда выигрышь?


T>Допустим, что это упрощение разработки, но я продемонстрировал в чём именно улучшение.

T>Если без демонстрации, то хотя бы объясните в чём ухудшение поддержки?

Это же очевидно: меньше информации выражено явно => сложнее разбираться.
Re[9]: Linq : неудачный маркетинг?
От: IT Россия linq2db.com
Дата: 17.02.10 15:54
Оценка: +9
Здравствуйте, Lloyd, Вы писали:

T>>Если без демонстрации, то хотя бы объясните в чём ухудшение поддержки?

L>Это же очевидно: меньше информации выражено явно => сложнее разбираться.

Как раз наоборот. Меньше ненужной информации => проще разбираться.
Если нам не помогут, то мы тоже никого не пощадим.
Re[10]: Linq : неудачный маркетинг?
От: Lloyd Россия  
Дата: 17.02.10 15:56
Оценка: +2
Здравствуйте, IT, Вы писали:

L>>Это же очевидно: меньше информации выражено явно => сложнее разбираться.


IT>Как раз наоборот. Меньше ненужной информации => проще разбираться.


Все верно, только тип не является ненужной информацией.
Re[3]: Linq : неудачный маркетинг?
От: IT Россия linq2db.com
Дата: 17.02.10 15:56
Оценка: +1
Здравствуйте, VladD2, Вы писали:

VD>Дык в терменологической путаннице виноват МС. Нефига было называть целую груду разной всячины одним именем.


Возможно. Могли хотя бы 'LINQ to SQL' называть не конкретный провайдер, а всю группу LINQ-провайдеров, поддерживающих SQL.
Если нам не помогут, то мы тоже никого не пощадим.
Re[11]: Linq : неудачный маркетинг?
От: IT Россия linq2db.com
Дата: 17.02.10 15:58
Оценка: +2
Здравствуйте, Lloyd, Вы писали:

L>>>Это же очевидно: меньше информации выражено явно => сложнее разбираться.

IT>>Как раз наоборот. Меньше ненужной информации => проще разбираться.
L>Все верно, только тип не является ненужной информацией.

Вопрос предпочтений. Мне лично в подавляющем большинстве случаев от типа ни холодно, ни жарко.
Если нам не помогут, то мы тоже никого не пощадим.
Re[12]: Linq : неудачный маркетинг?
От: Lloyd Россия  
Дата: 17.02.10 15:59
Оценка:
Здравствуйте, IT, Вы писали:

L>>Все верно, только тип не является ненужной информацией.


IT>Вопрос предпочтений.


О том и речь.
Re[9]: Linq : неудачный маркетинг?
От: Temoto  
Дата: 17.02.10 16:04
Оценка: +1 -1
L>>>Это улучшения для разработки, но ухудшения для поддержки. А поддержка, как известнно, занимает гораздо больше времени и денег. И где тогда выигрышь?

T>>Допустим, что это упрощение разработки, но я продемонстрировал в чём именно улучшение.

T>>Если без демонстрации, то хотя бы объясните в чём ухудшение поддержки?

L>Это же очевидно: меньше информации выражено явно => сложнее разбираться.


Из вашего утверждения можно сделать вывод, что управление памятью, закрытие хэндлов и прочий сахар — всё должно быть строго ручным. Или я что-то неправильно понял?

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

И действительно, каждый явно объявленный тип — это как маленький юнит-тест. Что-то поменяли в другом месте — здесь тип не пропускает. Может помочь (быстрее) поймать некоторые ошибки. Но это уже очень тонкие материи *грамотного* использования инструмента. Иметь инструмент и вовремя использовать (а иногда не использовать) всё-таки лучше, чем не иметь его вовсе.
Re[10]: Linq : неудачный маркетинг?
От: Lloyd Россия  
Дата: 17.02.10 16:09
Оценка: -2
Здравствуйте, Temoto, Вы писали:

L>>Это же очевидно: меньше информации выражено явно => сложнее разбираться.


T>Из вашего утверждения можно сделать вывод, что управление памятью, закрытие хэндлов и прочий сахар — всё должно быть строго ручным. Или я что-то неправильно понял?


Нет, вы неправильно поняли.

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


Вот уже и какие-то промежуточные результаты пошли. Продолжайте в том же духе .
Re[2]: Linq : неудачный маркетинг?
От: 0x7be СССР  
Дата: 17.02.10 16:26
Оценка: +1
Здравствуйте, Wolverrum, Вы писали:

W>А вот встречный вопрос: владея примитивами compose/map/fold/filter/zip/cons я могу прекрасно (и достаточно компактно) решить встающие задачи (в т.ч. и те, что были указаны в топике — про графы, коллецкии и циклы) без применения linq, причем начиная с рамок .net 2.0. Стоит ли мне этот самый linq использовать или даже изучать? В чем профит (м.б., кроме расхода железных ресурсов), так сказать?

Гм. Если есть достойная реализация этих примитивов, то why бы и not? У linq есть то преимущество, что он есть в библиотеке классов фреймворка. Как говорится "лучший танк тот, который есть". У linq есть то преимущество что операции могут быть реализованы неким провайдером, который будет оптимизирован под конкретный источник.

Кстати, если у тебя есть ссылки на другие библиотеки, реализующие эти операции, то я с удовольствием их изучу.
Re[6]: Linq : неудачный маркетинг?
От: VladD2 Российская Империя www.nemerle.org
Дата: 17.02.10 17:21
Оценка:
Здравствуйте, Mazay, Вы писали:

M>С тобой спорить не буду, ибо полезной информации из спора с тобой круглый ноль, зато оскроблений целая куча.


Можно подумать, что с тобой тут кто-то спорить собирался.

M>Господин, читай посты на которые пытаешься отвечать!


Я то читаю. И, в отличии от тебя, понимаю обсуждаемый вопрос. Чего и тебе желаю.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[4]: Linq : неудачный маркетинг?
От: VladD2 Российская Империя www.nemerle.org
Дата: 17.02.10 17:35
Оценка:
Здравствуйте, Mazay, Вы писали:

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

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

M>Да что ты говоришь?! А то я не понимаю.


Уместнее говорить о том, что ты понимаешь. Из твоих слов ясно одно. Про линк ты слышал где-то, что-то слышал, но разобраться в вопрос что это, как работает и для чего нужно так и не удосужился. Цитирую тебя:

оттуда их можно спокойно выдернуть SQL запросом, который отработает на сервере, который всё соптимизирует, закэширует и т. д. Зачем мне самому держать коллекции, к которым потом обращаться через заново изобретенный SQL и не забывать синхронизировать с базой?

Разберем эту цитату...
Начнем с того, что линк бывает разный, но если говорить об взаимодействии с СУБД через LINQ to SQL, LINQ to BLToolkit или даже через LINQ to Entety провайдеры, то никаких коллекций нигде держать не приходится. Линк-провайдер формирует SQL. Этот SQL выполняется на сервере (в СУБД). Обратно возвращаются только результаты запросов. Ничего синхронизировать не нужно. То что возвращенные данные преобразуются в объекты еще не значит, что это какой-то кэш. Если выполнить SQL-запрос, то мы тоже получим некоторые данные. Так вот эти объекты это и есть эти данные, только автоматически помещенные в объекты.

M>Если бы я понимал в чём цимес Линк, то наверное не писал бы сюда.


Да уж. Ну, или писал что-то более похожее на правду. Почти уверен, что и мнение было бы полностью противоположенным.

M> Я вообще-то надеялся на диалог с адекватными РСДНерами не на обсирание тобой.


Ты меня извини, но ты сам себя подставил когда начал нести околесицу по вопросу в котором некомпетентен. Меня просто возмутила та уверенность с которой ты озвучил свои домыслы.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[2]: Linq : неудачный маркетинг?
От: VladD2 Российская Империя www.nemerle.org
Дата: 17.02.10 17:42
Оценка:
Здравствуйте, Wolverrum, Вы писали:

W>А вот встречный вопрос: владея примитивами compose/map/fold/filter/zip/cons я могу прекрасно (и достаточно компактно) решить встающие задачи (в т.ч. и те, что были указаны в топике — про графы, коллецкии и циклы) без применения linq, причем начиная с рамок .net 2.0. Стоит ли мне этот самый linq использовать или даже изучать? В чем профит (м.б., кроме расхода железных ресурсов), так сказать?


Отвечу так. Я в последнее время в основном программирую на Nemerle. В библиотеках этого языка есть все перечисленные методы. Но тем не менее периодически я использую линк, так как шире чем приведенный набор. По сути линк — это завернутый в обертку методов prelud Haskell-я. Думаю, это само по себе объясняет полноту библоитек.

Кроме того многие функции в линке сделаны просто удобнее. Те же функции сортировки куда удобнее нежели те что принимают функции или объекты компараторы.

В общем, это добротно спроектированная библиотека дающая широкий набор примитивов.

ЗЫ

В прочем, в этой теме обсуждался не LINQ to Object, а скорее БД-провайдеры.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[5]: Linq : неудачный маркетинг?
От: D. Mon Великобритания http://thedeemon.livejournal.com
Дата: 17.02.10 17:45
Оценка:
Здравствуйте, Temoto, Вы писали:

T>А вы можете провести чёткую грань между функциональным и декларативным программированием?


Это независимые вещи, с совсем разными определениями.
Функциональное — с использованием первоклассных функций.
Декларативное — с описанием что надо получить, вместо того, как это получать.
Одно не подразумевает другого, хоть и способствует.
Можно писать декларативно, но не функционально (SQL).
Можно писать функционально, но не декларативно (лямбда-исчисление).
Re[6]: Linq : неудачный маркетинг?
От: Temoto  
Дата: 17.02.10 17:47
Оценка:
T>>А вы можете провести чёткую грань между функциональным и декларативным программированием?

DM>Это независимые вещи, с совсем разными определениями.

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

Makes sense, спасибо.
Re[3]: Linq : неудачный маркетинг?
От: VladD2 Российская Империя www.nemerle.org
Дата: 17.02.10 18:06
Оценка:
Здравствуйте, Temoto, Вы писали:

VD>>Мое мнение такое... Линк не очень хорош (во многих отношениях), но подан он очень даже хорошо. Это первая, реально успешная попытка преподнести массам функциональное программирование. Другие попытки провалились полностью.


T>SQL провалился?


SQL — это язык запросов к СУБД. Мы же говорим о программировании на языках общего назначения.

Кстати, если кто-то из читающих эту тему не был в отросли в 90-ые годы прошлого века, то поверьте на слово путь к SQL был очень не простым и многие воспринимали его в штыки или попросту не понимали зачем он нужен. Прошло 10 лет прежде чем программисты стали воспринимать SQL как что-то само собой разумеющееся.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[4]: Linq : неудачный маркетинг?
От: Temoto  
Дата: 17.02.10 18:23
Оценка:
VD>>>Мое мнение такое... Линк не очень хорош (во многих отношениях), но подан он очень даже хорошо. Это первая, реально успешная попытка преподнести массам функциональное программирование. Другие попытки провалились полностью.

T>>SQL провалился?


VD>SQL — это язык запросов к СУБД. Мы же говорим о программировании на языках общего назначения.


На мой взгляд, LINQ (а тема форума именно о нём, а не о прог-нии на языках общего назначения в целом) не менее специфичен (в плане решаемых задач), чем SQL.

Разве это плохо — сказать, что LINQ — вторая после SQL успешная попытка преподнести функциональное/декларативное программирование массам? Это обязательно опровергать?

VD>Кстати, если кто-то из читающих эту тему не был в отросли в 90-ые годы прошлого века, то поверьте на слово путь к SQL был очень не простым и многие воспринимали его в штыки или попросту не понимали зачем он нужен. Прошло 10 лет прежде чем программисты стали воспринимать SQL как что-то само собой разумеющееся.
Re[5]: Linq : неудачный маркетинг?
От: VladD2 Российская Империя www.nemerle.org
Дата: 17.02.10 18:47
Оценка:
Здравствуйте, Temoto, Вы писали:

T>На мой взгляд, LINQ (а тема форума именно о нём, а не о прог-нии на языках общего назначения в целом) не менее специфичен (в плане решаемых задач), чем SQL.


Ну, так это проблема взгляда.
1. Линк — это расширение ЯПОН (языка программирования общего назначения) вводящее в него поддержку ФП.
2. Линк + рекурсия (поддержка которой уже есть в ЯПОН) является достаточным для написания алгоритмов (полон по тюрингу).

T>Разве это плохо — сказать, что LINQ — вторая после SQL успешная попытка преподнести функциональное/декларативное программирование массам? Это обязательно опровергать?


Это не верно. А то что не верно, оно и не плохо, и не хорошо. Главное чего нет в SQL — это возможности формировать функции. Такие расширения есть в разных языках, но они не стандартны и не применимы внутри запросов.

В общем, SQL — это не язык общего назначения. И от того его нельзя рассматривать как пример превнесения ФП в массы.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: Linq : неудачный маркетинг?
От: Al_Shargorodsky Украина  
Дата: 17.02.10 20:46
Оценка: +1
Здравствуйте, VladD2, Вы писали:

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


IT>>Как ни подавай, а чтобы оценить технологию, нужно в ней разобраться. А подавляющее большинство у нас устойчиво путает Linq с query comprehension. Хоть апподавайся — без толку.


VD>Дык в терменологической путаннице виноват МС. Нефига было называть целую груду разной всячины одним именем.


еще, наверное, стоило бы разделять синтаксис и саму бибилиотеку.
вот уже который спор вижу по-поводу LINQ, и всегда упор делается на обработку последовательностей и обсуждение вокруг LINQ-2-провайдер.
Но ведь синтаксис LINQ можно использовать с любым типом, например, отложенное выполнение:

using System;

namespace LinqOperation
{
    internal class Program
    {
        private static void Main()
        {
            var serviceOne = new ServiceOne();
            var serviceTwo = new ServiceTwo();

            var op = from str in serviceOne.Load(42)
                     from ent in serviceTwo.Load("test")
                     select ent.Name + str;

            // this could be transaction scope, for example
            using (var context = new OperationContext())
            {
                Console.WriteLine(op.Execute(context));
            }
        }
    }

    public class OperationContext : IDisposable
    {
        public void Dispose()
        {
        }
    }

    public class NamedEntity
    {
        public string Name { get; set; }
    }

    public class ServiceOne
    {
        public Operation<string> Load(int id)
        {
            return Operation.Create(() => id.ToString());
        }
    }

    public class ServiceTwo
    {
        public Operation<NamedEntity> Load(string name)
        {
            return Operation.Create(() => new NamedEntity { Name = name });
        }
    }

    /// <summary>
    /// Deffered operation.
    /// </summary>
    public class Operation<T>
    {
        internal Func<T> Process { get; set; }

        public T Execute(OperationContext context)
        {
            return Process();
        }
    }

    public static class Operation
    {
        public static Operation<T> Create<T>(Func<T> process)
        {
            return new Operation<T> {Process = process};
        }

        public static Operation<TResult> Select<TSource, TResult>(
            this Operation<TSource> source, Func<TSource, TResult> result)
        {
            return new Operation<TResult>
                   {
                       Process = () => result(source.Process())
                   };
        }

        public static Operation<TResult> SelectMany<TSource, TInner, TResult>(
            this Operation<TSource> source,
            Func<TSource, Operation<TInner>> selecor,
            Func<TSource, TInner, TResult> result)
        {
            return new Operation<TResult>
                   {
                       Process =
                           () =>
                           {
                               var src = source.Process();

                               return result(src, selecor(src).Process());
                           }
                   };
        }
    }
}
Re[9]: Linq : неудачный маркетинг?
От: Dufrenite Дания  
Дата: 17.02.10 21:23
Оценка: 1 (1) +2
Здравствуйте, Lloyd, Вы писали:

L>Это же очевидно: меньше информации выражено явно => сложнее разбираться.


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

Например
Dictionary<string, EntityData> nameToEntityData = new Dictionary<string, EntityData>();

воспринимается хуже чем
var nameToEntityData = new Dictionary<string, EntityData>();
Re[3]: Linq : неудачный маркетинг?
От: Wolverrum Ниоткуда  
Дата: 18.02.10 00:23
Оценка:
Здравствуйте, 0x7be, Вы писали:

0>Кстати, если у тебя есть ссылки на другие библиотеки, реализующие эти операции, то я с удовольствием их изучу.

Есть, разве что, ссылка на свой самопал
Re[5]: Linq : неудачный маркетинг?
От: D. Mon Великобритания http://thedeemon.livejournal.com
Дата: 18.02.10 02:22
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>

VD>оттуда их можно спокойно выдернуть SQL запросом, который отработает на сервере, который всё соптимизирует, закэширует и т. д. Зачем мне самому держать коллекции, к которым потом обращаться через заново изобретенный SQL и не забывать синхронизировать с базой?

VD>Разберем эту цитату...
VD>Начнем с того, что линк бывает разный, но если говорить об взаимодействии с СУБД через LINQ to SQL, LINQ to BLToolkit или даже через LINQ to Entety провайдеры, то никаких коллекций нигде держать не приходится. Линк-провайдер формирует SQL. Этот SQL выполняется на сервере (в СУБД). Обратно возвращаются только результаты запросов. Ничего синхронизировать не нужно. То что возвращенные данные преобразуются в объекты еще не значит, что это какой-то кэш. Если выполнить SQL-запрос, то мы тоже получим некоторые данные. Так вот эти объекты это и есть эти данные, только автоматически помещенные в объекты.

Я так понимаю, вопрос синхронизации с базой возникает, когда мы начинаем эти полученные объекты менять и хотим, чтобы данные менялись в базе. И тут у линка не все гладко.
Re[4]: Linq : неудачный маркетинг?
От: samius Япония http://sams-tricks.blogspot.com
Дата: 18.02.10 05:46
Оценка:
Здравствуйте, Al_Shargorodsky, Вы писали:

A_S>Но ведь синтаксис LINQ можно использовать с любым типом, например, отложенное выполнение:


Нет синтаксиса LINQ, есть:
* Query syntax, который является очень маааленькой и вовсе необязательной частью LINQ-а.
* Query expressions, который является реализацией QS в C#
Другие языки вольны выбирать свой синтаксис QS по усмотрению, либо не использовать его вовсе.
Re[5]: Linq : неудачный маркетинг?
От: Al_Shargorodsky Украина  
Дата: 18.02.10 06:40
Оценка:
Здравствуйте, samius, Вы писали:

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


A_S>>Но ведь синтаксис LINQ можно использовать с любым типом, например, отложенное выполнение:


S>Нет синтаксиса LINQ, есть:

S>* Query syntax, который является очень маааленькой и вовсе необязательной частью LINQ-а.
S>* Query expressions, который является реализацией QS в C#
S>Другие языки вольны выбирать свой синтаксис QS по усмотрению, либо не использовать его вовсе.

согласен. я имел ввиду саму возможность писать в декларативном стиле и ее реализацию, пусть в конкретном языке.
Re[10]: Linq : неудачный маркетинг?
От: Lloyd Россия  
Дата: 18.02.10 08:18
Оценка: 2 (1) +2
Здравствуйте, Dufrenite, Вы писали:

D>Не очевидно. Венгерская нотация, на мой взгляд, ухудшает читаемость программ.


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

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


var customers = GetCustomers()

1. Что не так с названием переменой?
2. Какой тип у customers?

D>Например

D>
D>Dictionary<string, EntityData> nameToEntityData = new Dictionary<string, EntityData>();
D>

D>воспринимается хуже чем
D>
D>var nameToEntityData = new Dictionary<string, EntityData>();
D>


А в приведенном случае информация о типе не теряется, она записана справа от "="
Re[6]: Linq : неудачный маркетинг?
От: WolfHound  
Дата: 18.02.10 08:53
Оценка:
Здравствуйте, D. Mon, Вы писали:

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

А просто не надо так делать.
Нужно взять BLToolkit и использовать DML.
... << RSDN@Home 1.2.0 alpha 4 rev. 1305>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[6]: Linq : неудачный маркетинг?
От: vdimas Россия  
Дата: 18.02.10 10:03
Оценка: +1
Здравствуйте, D. Mon, Вы писали:

Да там не все так однозначно с тех пор, как в SQL появились подзапросы, ссылающиеся на значение полей вышестоящего запроса. Это же "построчное" замыкание, а подзапрос — суть параметризуемый предикат (т.е. ф-ия). Чистейшая, однако, функциональная декомпозиция.
Re[5]: Linq : неудачный маркетинг?
От: vdimas Россия  
Дата: 18.02.10 10:17
Оценка: 8 (2) +1
Здравствуйте, Temoto, Вы писали:

T>Да, ваша правда. А вы можете провести чёткую грань между функциональным и декларативным программированием?


Уже провели рядом, но не до конца. ИМХО, практика оперирования ф-иями как первоклассными объектами дает ф-ому программированию удобную возможность для определения параметризуемых "кирпичиков", дальнейшее использование которых очень смахивает на декларативное программирование. Наверно поэтому декларативное все время пытаются приписать ф-ому подходу, но это не правильно.

На самом деле, декларативность программирования — это сугубо относительное понятие. Любой ЯВУ декларативен по отношению к ассемблеру. Мы сразу говорим printf(2*2) — умножь 2 на 2 и выведи на экран, вместо объяснения, в какие регистры чего ложить и какие инструкции вызывать. При любой "правильной" декомпозиции (не обязательно функциональной), вышестоящие уровни демонстрируют по отношению к нижестоящим то самое декларативное программирование. SQL декларативен по отношению к реляционной алгебре, а по отношению к некоему вышестоящему DAL, с т.з. названия этого форума все-таки отвечает на вопрос "как", а не "что", ибо на вопрос "что" относительно данных во всей иерархии отвечает именно DAL. Собственно, как и сами подробности DAL — это ответ на вопрос "как", который возник после рассмотрения некоего ТЗ на систему (самого верхнего "Что").
Re[11]: Linq : неудачный маркетинг?
От: Jack128  
Дата: 18.02.10 13:08
Оценка: 1 (1)
Здравствуйте, Lloyd, Вы писали:

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


D>>Не очевидно. Венгерская нотация, на мой взгляд, ухудшает читаемость программ.


L>Я вроде не ратовал за венгерскую нотацию, вы меня с кем-то путаете.


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


L>
L>var customers = GetCustomers()
L>

L>1. Что не так с названием переменой?
L>2. Какой тип у customers?

IEnumerable<Customer> ?
Re[12]: Linq : неудачный маркетинг?
От: Lloyd Россия  
Дата: 18.02.10 13:13
Оценка:
Здравствуйте, Jack128, Вы писали:

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


L>>
L>>var customers = GetCustomers()
L>>

L>>1. Что не так с названием переменой?
L>>2. Какой тип у customers?

J>IEnumerable<Customer> ?


С чего ты взял? Почему не Customer[], Collection<Customer>, HashSet<Customer> или List<Customer>?
Re[13]: Linq : неудачный маркетинг?
От: Jack128  
Дата: 18.02.10 13:57
Оценка:
Здравствуйте, Lloyd, Вы писали:

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


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


L>>>
L>>>var customers = GetCustomers()
L>>>

L>>>1. Что не так с названием переменой?
L>>>2. Какой тип у customers?

J>>IEnumerable<Customer> ?


L>С чего ты взял? Почему не Customer[], Collection<Customer>, HashSet<Customer> или List<Customer>?


А какая разница? Тока ближе к практике, пожалуйста.
Re[6]: Linq : неудачный маркетинг?
От: VladD2 Российская Империя www.nemerle.org
Дата: 18.02.10 14:09
Оценка:
Здравствуйте, D. Mon, Вы писали:

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


Ты не верно понимаешь. У лика в общем вообще вопрос изменения БД не оговорен. То как он реализован и реализован ли вообще решает конкретный линк-провайдер. В частности есть такой провайдер BLToolkit (созданный одним из основателей нашего сайта — IT) который решает данную проблему путем предоставления CRUD/DML-операций аналогичных запросам INSERT/DELETE/UPDATE из SQL.

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

Есть пожалуй только один провайдер (для NHibernate) который занимается кэшированием и прочей фигней. Ну, так это потому, что это провайдер к объектному-персистеру который использует идеологию, на мой взгляд, в корне порочную.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[14]: Linq : неудачный маркетинг?
От: Lloyd Россия  
Дата: 18.02.10 14:51
Оценка:
Здравствуйте, Jack128, Вы писали:

J>>>IEnumerable<Customer> ?


L>>С чего ты взял?


Я так понимаю, ответа на вопрос у вас нет?

L>>Почему не Customer[], Collection<Customer>, HashSet<Customer> или List<Customer>?


J>А какая разница? Тока ближе к практике, пожалуйста.


Например, вот в таком коде:
for(int i=0; i < customers.Count(); i++) {
  Consolw.WriteLine("{0}: {1}", i, customers.ElementAt(i).Name);
}

Если customers — IEnumerable, полученный из linq-овского запроса, то на 1000 customer-ах получили 2000 запросов в базу. Если просто лист — то ни одного.
Re[15]: Linq : неудачный маркетинг?
От: IT Россия linq2db.com
Дата: 18.02.10 15:09
Оценка:
Здравствуйте, Lloyd, Вы писали:

L>Если customers — IEnumerable, полученный из linq-овского запроса, то на 1000 customer-ах получили 2000 запросов в базу. Если просто лист — то ни одного.


Это конечно большая проблема! А как ты её решаешь, когда у тебя не List<Customer>, а, например, List<<>f__AnonymousTypef<int,string>>?
Если нам не помогут, то мы тоже никого не пощадим.
Re[16]: Linq : неудачный маркетинг?
От: Lloyd Россия  
Дата: 18.02.10 15:12
Оценка:
Здравствуйте, IT, Вы писали:

L>>Если customers — IEnumerable, полученный из linq-овского запроса, то на 1000 customer-ах получили 2000 запросов в базу. Если просто лист — то ни одного.


IT>Это конечно большая проблема! А как ты её решаешь, когда у тебя не List<Customer>, а, например, List<<>f__AnonymousTypef<int,string>>?


Если ты мне расскажешь, как мне из метода получить List<<>f__AnonymousTypef<int,string>>, я обязательно отвечу на твой вопрос.
Re[17]: Linq : неудачный маркетинг?
От: IT Россия linq2db.com
Дата: 18.02.10 15:18
Оценка:
Здравствуйте, Lloyd, Вы писали:

L>>>Если customers — IEnumerable, полученный из linq-овского запроса, то на 1000 customer-ах получили 2000 запросов в базу. Если просто лист — то ни одного.


IT>>Это конечно большая проблема! А как ты её решаешь, когда у тебя не List<Customer>, а, например, List<<>f__AnonymousTypef<int,string>>?


L>Если ты мне расскажешь, как мне из метода получить List<<>f__AnonymousTypef<int,string>>, я обязательно отвечу на твой вопрос.


var arr  = new[] { new { String = "", Int = 1 } };
var list = arr.ToList();
Если нам не помогут, то мы тоже никого не пощадим.
Re[17]: Linq : неудачный маркетинг?
От: IT Россия linq2db.com
Дата: 18.02.10 15:21
Оценка:
Здравствуйте, Lloyd, Вы писали:

L>>>Если customers — IEnumerable, полученный из linq-овского запроса, то на 1000 customer-ах получили 2000 запросов в базу. Если просто лист — то ни одного.

IT>>Это конечно большая проблема! А как ты её решаешь, когда у тебя не List<Customer>, а, например, List<<>f__AnonymousTypef<int,string>>?
L>Если ты мне расскажешь, как мне из метода получить List<<>f__AnonymousTypef<int,string>>, я обязательно отвечу на твой вопрос.

Могу ещё рассказать, как получить IEnumerable (ты будешь думать о 2000 запросах в базу), а запросов будет ни одного. Рассказывать или ты сам?
Если нам не помогут, то мы тоже никого не пощадим.
Re[18]: Linq : неудачный маркетинг?
От: Lloyd Россия  
Дата: 18.02.10 15:23
Оценка:
Здравствуйте, IT, Вы писали:

L>>Если ты мне расскажешь, как мне из метода получить List<<>f__AnonymousTypef<int,string>>, я обязательно отвечу на твой вопрос.


IT>
IT>var arr  = new[] { new { String = "", Int = 1 } };
IT>var list = arr.ToList();
IT>


Варианты, ToList, ToArray и т.д. не относятся к случаям, когда тип не указан, т.к. тип-таки фигурирует (List, Array).
Кроме того, тип переменных анонимного типа легко выводится из контекста.
Re[18]: Linq : неудачный маркетинг?
От: Lloyd Россия  
Дата: 18.02.10 15:28
Оценка: +1
Здравствуйте, IT, Вы писали:

L>>Если ты мне расскажешь, как мне из метода получить List<<>f__AnonymousTypef<int,string>>, я обязательно отвечу на твой вопрос.


IT>Могу ещё рассказать, как получить IEnumerable (ты будешь думать о 2000 запросах в базу), а запросов будет ни одного. Рассказывать или ты сам?


Нет, не надо.
Я не собираюсь вас убежать в чем либо, у меня есть свои предпочтения в использовании var-а и я им следую. Так же я знаю преимущества и недостатки обоих подходов. Не тратьте свое время на повтороение того, что было уже обсосано не по одному десятку раз.

Удачи.
Re[19]: Linq : неудачный маркетинг?
От: IT Россия linq2db.com
Дата: 18.02.10 15:29
Оценка:
Здравствуйте, Lloyd, Вы писали:

L>>>Если ты мне расскажешь, как мне из метода получить List<<>f__AnonymousTypef<int,string>>, я обязательно отвечу на твой вопрос.

L>Варианты, ToList, ToArray и т.д. не относятся к случаям, когда тип не указан, т.к. тип-таки фигурирует (List, Array).
L>Кроме того, тип переменных анонимного типа легко выводится из контекста.

Ну ты упёртый.

List<T> GetCustomers<T>(T[] arr)
{
    return arr.ToList();
}

var arr  = new[] { new { String = "", Int = 1 } };
var list = GetCustomers(arr);

Теперь в методе GetCustomers меняем тип возвращемого значения на IEnumerable<T> и, 'О, чудо!', получаем IEnumerable, а запросов к базе ни одного!
Если нам не помогут, то мы тоже никого не пощадим.
Re[20]: Linq : неудачный маркетинг?
От: Lloyd Россия  
Дата: 18.02.10 15:33
Оценка: +3
Здравствуйте, IT, Вы писали:

L>>Кроме того, тип переменных анонимного типа легко выводится из контекста.


IT>Ну ты упёртый.


Да ваще, баран полный. Втемяшу себе в голову какую-нить глупость и потом хожу и на потеху публике выставляюсь полным дураком.
Чё с таким говорить, бесполезно же.

IT>Теперь в методе GetCustomers меняем тип возвращемого значения на IEnumerable<T> и, 'О, чудо!', получаем IEnumerable, а запросов к базе ни одного!


Вы правда-правда такие методы пишете или вы просто задались целью опровегнуть мое утверждение про анонимные типы?
Re[21]: Linq : неудачный маркетинг?
От: IT Россия linq2db.com
Дата: 18.02.10 15:38
Оценка: +1
Здравствуйте, Lloyd, Вы писали:

L>Вы правда-правда такие методы пишете или вы просто задались целью опровегнуть мое утверждение про анонимные типы?


Мы пишем разные методы, но никогда при этом не руководствуемся тем, будет ли лучше ставить var перед получением значения из этого метода или полный тип.
Если нам не помогут, то мы тоже никого не пощадим.
Re[22]: Linq : неудачный маркетинг?
От: Lloyd Россия  
Дата: 18.02.10 15:39
Оценка:
Здравствуйте, IT, Вы писали:

L>>Вы правда-правда такие методы пишете или вы просто задались целью опровегнуть мое утверждение про анонимные типы?


IT>Мы пишем разные методы, но никогда при этом не руководствуемся тем, будет ли лучше ставить var перед получением значения из этого метода или полный тип.


И все-таки ответьте на вопрос, пишете ли вы такие методы?
Re[5]: Linq : неудачный маркетинг?
От: Mazay Россия  
Дата: 18.02.10 15:46
Оценка:
Здравствуйте, IT, Вы писали:

M>>О чём я имею "весьма смутное и отдалённое понятие"? О промышленной разработке "типичных" проектов? Не соглашусь. О LINQ? Пожалуй да. Ну дык в том виде в каком её подают я не вижу ей применения для своих задач. Ниже типичный пример использования LINQ. Вот скажите, вам в самом деле часто приходится работать с такими ArrayList'ами? Как правило же все эти данные лежат в БД и дергаются либо тем же SQL, либо HQL.


IT>[c#]

IT>public class Student
IT>{
IT> public int StudentID { get; set; }
...
IT> [Association(ThisKey = "StudentID", OtherKey = "StudentID")]
IT> public Score[] Scores { get; set; }
IT>}
...
IT>Генерируемый SQL (Sybase):

IT>
IT>SELECT
IT>    [student].[StudentID],
IT>    [student].[FirstName],
IT>    [student].[LastName]
IT>FROM
IT>    [Student] [student]
IT>WHERE
...
IT>    ) > 95
IT>

IT>Ещё вопросы?

То есть ЛИНК — это универсальный интерфейс для работы реляционными (БД), иерархическими (XML) данными и стандартными коллекциями в памяти. Так? Он позиционируется как замена XPath, ORM-библиотек, а также как удобная тулза для стандартных коллекций внутри программы на C#. Так? Ну тогда идея действительно масштабная и актуальная. Лишь бы баланс между логической стройностью , простотой и возможностями был приемлемым. Кстати, там под низом полноценный ORM-движок есть или всё просто на уровне запрос/ответ? Я имею ввиду разруливание циклических ссылок, кэширование, пакетное обновление, ленивую загрузку. Датасеты наконец сдохнут?
Главное гармония ...
Re[3]: Linq : неудачный маркетинг?
От: Mazay Россия  
Дата: 18.02.10 15:52
Оценка:
Здравствуйте, Dufrenite, Вы писали:

M>>Я в промышленном программировании уже 2 года как не появлялся, так что мои представления могут быть несколько устаревшими. Но если взять "типичный" проект с SQL БД, то действительно не очень понятно зачем мне ещё и LINQ. Ведь практически все объекты с которыми я работаю, лежат в БД и оттуда их можно спокойно выдернуть SQL запросом, который отработает на сервере, который всё соптимизирует, закэширует и т. д. Зачем мне самому держать коллекции, к которым потом обращаться через заново изобретенный SQL и не забывать синхронизировать с базой? Нет, конечно иногда приходится, но не так часто, и этого лучше избегать.


D>То, что вы хотите сказать вполне разумно, но. Не базой данных единой жив программист. Я не буду строить из себя мега-математика и эксперта по теории множеств, а скажу с точки зрения обычного разработчика. LINQ это мега удобно при работе с коллекциями. Например, там где обычно надо написать несколько вложенных циклов и задействовать несколько промежуточных переменных LINQ позволяет обойтись одним запросом или простой цепочкой вызовов (кому как нравится).

D>Код получается короче и понятней (проверено). Свободы больше: хочу циклы пишу, хочу запросы. Как проще и понятней получается тот способ и выбираю.

Вот меня тоже заинтересовала именно эта фишка. Я в последнее время пишу всякие числодробилки на С/С++ и мне такой инструмен был бы очень кстати. Потому я и удивился, что он появился именно в промышленном программировании (бизнес-приложений), где, насколько я помню, он не особо то нужен был.
Главное гармония ...
Re[23]: Linq : неудачный маркетинг?
От: IT Россия linq2db.com
Дата: 18.02.10 15:53
Оценка:
Здравствуйте, Lloyd, Вы писали:

L>>>Вы правда-правда такие методы пишете или вы просто задались целью опровегнуть мое утверждение про анонимные типы?

IT>>Мы пишем разные методы, но никогда при этом не руководствуемся тем, будет ли лучше ставить var перед получением значения из этого метода или полный тип.
L>И все-таки ответьте на вопрос, пишете ли вы такие методы?

Всякие пишем. Я не вижу никаких проблем в написании методов с таким поведением. А в чём твоя проблема?
Если нам не помогут, то мы тоже никого не пощадим.
Re[6]: Linq : неудачный маркетинг?
От: IT Россия linq2db.com
Дата: 18.02.10 15:58
Оценка:
Здравствуйте, Mazay, Вы писали:

M>То есть ЛИНК — это универсальный интерфейс для работы реляционными (БД), иерархическими (XML) данными и стандартными коллекциями в памяти. Так?


Примерно.

M>Он позиционируется как замена XPath, ORM-библиотек, а также как удобная тулза для стандартных коллекций внутри программы на C#. Так?


Не замена, а скорее дополнение.

M>Ну тогда идея действительно масштабная и актуальная. Лишь бы баланс между логической стройностью , простотой и возможностями был приемлемым. Кстати, там под низом полноценный ORM-движок есть или всё просто на уровне запрос/ответ? Я имею ввиду разруливание циклических ссылок, кэширование, пакетное обновление, ленивую загрузку. Датасеты наконец сдохнут?


Это пример из BLToolkit, а он не позиционируется как тяжёлый ORM с полноценным Entity Service. Но можно взять тот же Entity Framework. В нём всё это есть.
Если нам не помогут, то мы тоже никого не пощадим.
Re[24]: Linq : неудачный маркетинг?
От: Lloyd Россия  
Дата: 18.02.10 15:58
Оценка:
Здравствуйте, IT, Вы писали:

L>>И все-таки ответьте на вопрос, пишете ли вы такие методы?


IT> Всякие пишем. Я не вижу никаких проблем в написании методов с таким поведением.


А можно пример такого метода из жизни?
Re[11]: Linq : неудачный маркетинг?
От: Dufrenite Дания  
Дата: 18.02.10 16:00
Оценка: +1
Здравствуйте, Lloyd, Вы писали:

L>
L>var customers = GetCustomers()
L>

L>1. Что не так с названием переменой?
L>2. Какой тип у customers?

Если используем Visual Studio и надо узнать точный тип, то для этой цели есть контекстная подсказка. Мне лично хватает.
Если IDE нет, то пускаем пулю в лоб, меняем профессию или ищем объявление GetCustomers(). Как то так.
Re[12]: Linq : неудачный маркетинг?
От: Lloyd Россия  
Дата: 18.02.10 16:05
Оценка:
Здравствуйте, Dufrenite, Вы писали:

L>>1. Что не так с названием переменой?

L>>2. Какой тип у customers?

D>Если используем Visual Studio и надо узнать точный тип, то для этой цели есть контекстная подсказка. Мне лично хватает.


В Visual Studio не везде есть подсказка: ее нет в Annotate, нет в diff-ах, stacktrace-ах, логах.

D>Если IDE нет, то пускаем пулю в лоб, меняем профессию или ищем объявление GetCustomers(). Как то так.


Это конечно ваш выбор, но я предпочитаю более гуманный вариант — указывать типы, там где они нужны/возможны.
Re[4]: Linq : неудачный маркетинг?
От: Dufrenite Дания  
Дата: 18.02.10 16:06
Оценка:
Здравствуйте, Mazay, Вы писали:

M>Вот меня тоже заинтересовала именно эта фишка. Я в последнее время пишу всякие числодробилки на С/С++ и мне такой инструмен был бы очень кстати.


Да, мне его тоже в C++ не хватает.

M>Потому я и удивился, что он появился именно в промышленном программировании (бизнес-приложений), где, насколько я помню, он не особо то нужен был.


Я бизнес приложениями не занимаюсь. Использую линк в редакторах игр и DSL компиляторах.
Хотя уверен, что в бизнес приложениях он тоже весьма удобен.
Re[25]: Linq : неудачный маркетинг?
От: IT Россия linq2db.com
Дата: 18.02.10 16:10
Оценка:
Здравствуйте, Lloyd, Вы писали:

IT>> Всякие пишем. Я не вижу никаких проблем в написании методов с таким поведением.

L>А можно пример такого метода из жизни?

Например, есть метод, который получает текстовый поток и дробит его на строки, на выходе IEnumerable<string>. Затем есть второй метод, который каждую строчку преобразует в массив строк, использую символ разделитель. На выходе IEnumrable<string[]>. Следующий метод валидирует данные и преобразует массив в некоторый тип. На выходе IEnumerable<T>. Сигнатура такого метода примерно такая:

IEnumerable<T> ValidateAndConvert<T>(this IEnumerable<string[]>, Func<string[]>,T>);
Если нам не помогут, то мы тоже никого не пощадим.
Re[26]: Linq : неудачный маркетинг?
От: Lloyd Россия  
Дата: 18.02.10 16:21
Оценка:
Здравствуйте, IT, Вы писали:

IT>Например, есть метод, который получает текстовый поток и дробит его на строки, на выходе IEnumerable<string>. Затем есть второй метод, который каждую строчку преобразует в массив строк, использую символ разделитель. На выходе IEnumrable<string[]>. Следующий метод валидирует данные и преобразует массив в некоторый тип. На выходе IEnumerable<T>. Сигнатура такого метода примерно такая:


IT>
IT>IEnumerable<T> ValidateAndConvert<T>(this IEnumerable<string[]>, Func<string[]>,T>);
IT>


Не совсем понимаю, что этот код призван показать. Воткните вызов этого метода в код, приведенный мной выше, и ограбете некорректное поведение. В случае Linq2Sql-я буде еще хуже — он просто начнет по-честному фигачить кучу запросов в базу, тем самым запрятав проблему.
Re[27]: Linq : неудачный маркетинг?
От: IT Россия linq2db.com
Дата: 18.02.10 16:32
Оценка:
Здравствуйте, Lloyd, Вы писали:

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


Не огребём. Этот код не ходит в базу вообще. У тебя какое-то странное понимание IEnumerable. Если это IEnumerable, то он обязательно должен ходить в базу IList, между прочим тоже IEnumerable.
Если нам не помогут, то мы тоже никого не пощадим.
Re: Linq : неудачный маркетинг?
От: Mystic Украина http://mystic2000.newmail.ru
Дата: 18.02.10 16:37
Оценка:
Здравствуйте, 0x7be, Вы писали:

0>Linq — хорошая штука, но неудачно подан. Ваши мнения?


Сравнительно сложен в изучении и понимании при том, что существующие методы решения таких задач всех устраивают.
Re[4]: Linq : неудачный маркетинг?
От: 0x7be СССР  
Дата: 18.02.10 16:51
Оценка:
Здравствуйте, Mazay, Вы писали:

M>Вот меня тоже заинтересовала именно эта фишка. Я в последнее время пишу всякие числодробилки на С/С++ и мне такой инструмен был бы очень кстати. Потому я и удивился, что он появился именно в промышленном программировании (бизнес-приложений), где, насколько я помню, он не особо то нужен был.

В STL есть близкие по духу решения. С поправкой на реалии С++
Re[28]: Linq : неудачный маркетинг?
От: Lloyd Россия  
Дата: 18.02.10 16:52
Оценка: +1
Здравствуйте, IT, Вы писали:

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


IT>Не огребём. Этот код не ходит в базу вообще.


Огребем. Если я понял тебя правильно, ты сцепляешь приведенные методы в цепочку и в конечном итоге у тебя будет происходить чтение stream-а. Если ты "прокрутил" последний enumerable до конца, то стрим у тебя будет спозизионирован на конец. Повторное чтение приведет либо к исключению, либо к пустой коллекции на выходе.

IT>У тебя какое-то странное понимание IEnumerable. Если это IEnumerable, то он обязательно должен ходить в базу


У меня нет такого понимания IEnumerable, не придумывай.
Re[2]: Linq : неудачный маркетинг?
От: 0x7be СССР  
Дата: 18.02.10 17:02
Оценка:
Здравствуйте, Mystic, Вы писали:

M>Сравнительно сложен в изучении и понимании при том, что существующие методы решения таких задач всех устраивают.

Каких задач? Меня интересует твой взгляд.
Re[13]: Linq : неудачный маркетинг?
От: Dufrenite Дания  
Дата: 18.02.10 17:12
Оценка:
Здравствуйте, Lloyd, Вы писали:

L>В Visual Studio не везде есть подсказка: ее нет в Annotate, нет в diff-ах, stacktrace-ах, логах.

L>Это конечно ваш выбор, но я предпочитаю более гуманный вариант — указывать типы, там где они нужны/возможны.

Согласен. Именно поэтому я говорил о контексте. Если из контекста тип переменной не очевиден, то лучше его явно указать.

Если вернуться к изначальному примеру.
Контекст может быть таким:
var customers = GetCustomers();
foreach (var customer in customers)
{
  Output(customer.Name);
}

Здесь не нужен микроскоп чтобы понять, что customers это как минимум IEnumerable<Customer>. В большинстве случаев этого будет достаточно.

Или так:
var customers = GetCustomers();
for (int i = 0; i < customers.Length; ++i)
{
  Output(customers[i].Name);
}

Отсюда очевидно, что customers это массив.

Еще один аргумент: много языков не имеют строгой типизации, однако их активно используют и отказываться не собираются.
Re[14]: Linq : неудачный маркетинг?
От: Lloyd Россия  
Дата: 18.02.10 17:17
Оценка: +1
Здравствуйте, Dufrenite, Вы писали:

D>Согласен. Именно поэтому я говорил о контексте. Если из контекста тип переменной не очевиден, то лучше его явно указать.


D>Если вернуться к изначальному примеру.

D>Контекст может быть таким:

Если вы попытаетесь продумать все контескты, то очень быстро захлебнетесь во множестве вариантов и правила выбора быстро станут очень сложными (а то и противоречивыми). Сложные правила — не работают.
Мое правило — простое и следовательно лучше.
Re[29]: Linq : неудачный маркетинг?
От: Dufrenite Дания  
Дата: 18.02.10 17:19
Оценка:
Здравствуйте, Lloyd, Вы писали:

L>Огребем. Если я понял тебя правильно, ты сцепляешь приведенные методы в цепочку и в конечном итоге у тебя будет происходить чтение stream-а. Если ты "прокрутил" последний enumerable до конца, то стрим у тебя будет спозизионирован на конец. Повторное чтение приведет либо к исключению, либо к пустой коллекции на выходе.


Влезу в ваш диалог. Ленивое поведение в данном случае является потенциально опасным. Лучше в стандарте кодирования явно прописать обязательное приведение результата запроса к коллекции (если в решении не требуется именно ленивость).
Re[5]: Linq : неудачный маркетинг?
От: Dufrenite Дания  
Дата: 18.02.10 17:22
Оценка: +1
Здравствуйте, 0x7be, Вы писали:

0>В STL есть близкие по духу решения. С поправкой на реалии С++


По духу да. Но с точки зрения автоматизации разница колоссальна. Были бы в С++ лямбды и замыкания вопросов бы не было а так
Re[6]: Linq : неудачный маркетинг?
От: 0x7be СССР  
Дата: 18.02.10 17:25
Оценка:
Здравствуйте, Dufrenite, Вы писали:

D>По духу да. Но с точки зрения автоматизации разница колоссальна. Были бы в С++ лямбды и замыкания вопросов бы не было а так

Увы, таков "C++ way" — если программист может сам смоделировать что-то, то не вводить это в язык. Хотя, в новом стандарте анонимные функции будут. И что-то смутно напоминающее лексическое замыкание :
Re[7]: Linq : неудачный маркетинг?
От: VladD2 Российская Империя www.nemerle.org
Дата: 18.02.10 17:53
Оценка: 1 (1) :)))
Здравствуйте, 0x7be, Вы писали:

0>Увы, таков "C++ way" — если программист может сам смоделировать что-то, то не вводить это в язык. Хотя, в новом стандарте анонимные функции будут. И что-то смутно напоминающее лексическое замыкание :


Не. Это называется Lisp way. А C++ way — это если что-то можно сделать через анальное отверстие, то делать именно так. А на предложение изменить язык обяснять, что религия не позволяет.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: Linq : неудачный маркетинг?
От: Mystic Украина http://mystic2000.newmail.ru
Дата: 18.02.10 18:00
Оценка:
Здравствуйте, 0x7be, Вы писали:

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


M>>Сравнительно сложен в изучении и понимании при том, что существующие методы решения таких задач всех устраивают.

0>Каких задач? Меня интересует твой взгляд.

Которые возникают на практике, которые характеризует активное использование foreach и yeild. В большинстве своем такие задачи возникают не часто и изучать что-то новое для их решения нет большого желания. Лучшее враг хорошего.

Например, был мой ответ тут
Автор: Mystic
Дата: 02.09.09
. Код с использованием LINQ выглядит пугающе. Я понимаю также, что мой набросок в ответе вполне можно было бы переписать с использованием LINQ. Но... я не знаю как. Идей также не много. Плюс нет уверенности, что это все хорошо ляжет на абстракцию LINQ. Опасение того, что вот во что-то упрется и не выйдешь.

Другой пример я приводил
Автор: Mystic
Дата: 03.10.09
в ветке про Nemerle. Я тоже понимаю, что мою C# реализацию вполне можно написать на LINQ. Но те же проблемы, плюс меня мой вариант вполне устраивает.
Re[29]: Linq : неудачный маркетинг?
От: IT Россия linq2db.com
Дата: 18.02.10 18:16
Оценка:
Здравствуйте, Lloyd, Вы писали:

IT>>Не огребём. Этот код не ходит в базу вообще.


L>Огребем. Если я понял тебя правильно, ты сцепляешь приведенные методы в цепочку и в конечном итоге у тебя будет происходить чтение stream-а. Если ты "прокрутил" последний enumerable до конца, то стрим у тебя будет спозизионирован на конец. Повторное чтение приведет либо к исключению, либо к пустой коллекции на выходе.


Мы не огнебём. Но не из-за var/не var, стрим может оказаться обыкновенной строкой, но главное, мы не пишем такой код как в твоём примере.

Теперь ты мне, пожалуйста, ответь. Пишешь ли ты такой код, как в твоём примере.
Если нам не помогут, то мы тоже никого не пощадим.
Re[30]: Linq : неудачный маркетинг?
От: Lloyd Россия  
Дата: 18.02.10 18:28
Оценка: :)
Здравствуйте, IT, Вы писали:

L>>Огребем. Если я понял тебя правильно, ты сцепляешь приведенные методы в цепочку и в конечном итоге у тебя будет происходить чтение stream-а. Если ты "прокрутил" последний enumerable до конца, то стрим у тебя будет спозизионирован на конец. Повторное чтение приведет либо к исключению, либо к пустой коллекции на выходе.


IT>Мы не огнебём. Но не из-за var/не var, стрим может оказаться обыкновенной строкой, но главное, мы не пишем такой код как в твоём примере.


Что значит "стрим может оказаться обыкновенной строкой"? Ты говоришь о System.IO.Stream?

IT>Теперь ты мне, пожалуйста, ответь. Пишешь ли ты такой код, как в твоём примере.


Нет, именно так не пишу. Это был код для демонстрации. На практике варианты не такии экстремальные, но давольно часто встречается код типа
if (customers.Any()) {
  grid.DataSource = customers;
  grid.DataBind();
} else {
  // ....
}

В этом коде будет та же самая проблема, что я и писал, только в меньшем масштабе (1 лишний запрос в базу).
Re[8]: Linq : неудачный маркетинг?
От: Dufrenite Дания  
Дата: 18.02.10 18:32
Оценка: :)
Здравствуйте, VladD2, Вы писали:

VD>Не. Это называется Lisp way. А C++ way — это если что-то можно сделать через анальное отверстие, то делать именно так. А на предложение изменить язык обяснять, что религия не позволяет.


Холивар детектед
Но ты все же прав.
Re[15]: Linq : неудачный маркетинг?
От: IT Россия linq2db.com
Дата: 18.02.10 18:44
Оценка: +2
Здравствуйте, Lloyd, Вы писали:

L>Мое правило — простое и следовательно лучше.


Твоё 'простое' решение как минимум содержит много мусора и трудно читается, следовательно оно не лучшее.
Если нам не помогут, то мы тоже никого не пощадим.
Re[16]: Linq : неудачный маркетинг?
От: Lloyd Россия  
Дата: 18.02.10 18:50
Оценка: +1
Здравствуйте, IT, Вы писали:

L>>Мое правило — простое и следовательно лучше.


IT>Твоё 'простое' решение как минимум содержит много мусора и трудно читается, следовательно оно не лучшее.


Нет, в моем правиле нет мусора и оно легко читается.
Re[8]: Linq : неудачный маркетинг?
От: 0x7be СССР  
Дата: 18.02.10 20:44
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Не. Это называется Lisp way. А C++ way — это если что-то можно сделать через анальное отверстие, то делать именно так. А на предложение изменить язык обяснять, что религия не позволяет.

Ты преувеличиваешь Делание через анальное отверстие — это результат комбинации двух идей (что тоже очень С++-но по натуре):
1. Нежелание вводить в язык то, что можно сделать самому.
2. Отсутствие средств по-человечески сделать самому то, чего нет в языке.
Re[4]: Linq : неудачный маркетинг?
От: 0x7be СССР  
Дата: 18.02.10 21:12
Оценка: :)
Здравствуйте, Mystic, Вы писали:

M>Которые возникают на практике, которые характеризует активное использование foreach и yeild. В большинстве своем такие задачи возникают не часто и изучать что-то новое для их решения нет большого желания. Лучшее враг хорошего.

Вот тут я бы с тобой поспорил. Что происходит, при замене конструкций вида foreach на вызов функций linq2objects? Повышается уровень абстракции — ты не просто делаешь foreach, а применяешь к последовательности определенные преобразования, реализация которых скрыта. В чем профит? Появление Plinq дает ответ на этот вопрос.
Re[31]: Linq : неудачный маркетинг?
От: IT Россия linq2db.com
Дата: 18.02.10 22:41
Оценка:
Здравствуйте, Lloyd, Вы писали:

L>Что значит "стрим может оказаться обыкновенной строкой"? Ты говоришь о System.IO.Stream?


Конвертируем байты, заталкиваем в MemoryStream.

L>
L>if (customers.Any()) {
L>  grid.DataSource = customers;
L>  grid.DataBind();
L>} else {
L>  // ....
L>}
L>

L>В этом коде будет та же самая проблема, что я и писал, только в меньшем масштабе (1 лишний запрос в базу).

С баиндингом у нас всегда был разговор особый, так что тут проблем тоже не будет.
Если нам не помогут, то мы тоже никого не пощадим.
Re[17]: Linq : неудачный маркетинг?
От: IT Россия linq2db.com
Дата: 18.02.10 22:42
Оценка:
Здравствуйте, Lloyd, Вы писали:

IT>>Твоё 'простое' решение как минимум содержит много мусора и трудно читается, следовательно оно не лучшее.

L>Нет, в моем правиле нет мусора и оно легко читается.

В твоём правиле куча мусора, за которым не видно логики.
Если нам не помогут, то мы тоже никого не пощадим.
Re[2]: Linq : неудачный маркетинг?
От: IB Австрия http://rsdn.ru
Дата: 18.02.10 23:06
Оценка: 1 (1) +1
Здравствуйте, Mazay, Вы писали:

M> Но если взять "типичный" проект с SQL БД, то действительно не очень понятно зачем мне ещё и LINQ. Ведь практически все объекты с которыми я работаю, лежат в БД и оттуда их можно спокойно выдернуть SQL запросом, который отработает на сервере, который всё соптимизирует, закэширует и т. д.

LINQ — это не про БД.
Нет в природе ни одного проекта больше 10 строчек кода, где не было бы коллекций. Если в коллекции больше двух элементов, то LINQ существенно облегчает жизнь.
Например, вместо того, чтобы писать
            bool isAnySpace = false;
            foreach (var s in "qeqweqweqwe")
            {
                if (s == ' ')
                {
                    isAnySpace = true;
                    break;
                }
            }

Можно написать:
bool isSpace = "qeqweqweqwe".Any(s => s == ' ');

И это все, только часть области применения LINQ. =)
Мы уже победили, просто это еще не так заметно...
Re[12]: Linq : неудачный маркетинг?
От: mrTwister Россия  
Дата: 18.02.10 23:19
Оценка: +1
Здравствуйте, Dufrenite, Вы писали:

D>Если используем Visual Studio и надо узнать точный тип, то для этой цели есть контекстная подсказка. Мне лично хватает.

D>Если IDE нет, то пускаем пулю в лоб, меняем профессию или ищем объявление GetCustomers(). Как то так.

Понятно, то есть другими словами, если нам надо делать code-review, то пускаем пулю в лоб. Так и запишем.
лэт ми спик фром май харт
Re[13]: Linq : неудачный маркетинг?
От: IT Россия linq2db.com
Дата: 18.02.10 23:49
Оценка:
Здравствуйте, mrTwister, Вы писали:

T>Понятно, то есть другими словами, если нам надо делать code-review, то пускаем пулю в лоб. Так и запишем.


А вы code review на бумаге делаете?
Если нам не помогут, то мы тоже никого не пощадим.
Re: Linq : неудачный маркетинг?
От: IB Австрия http://rsdn.ru
Дата: 19.02.10 00:32
Оценка:
Здравствуйте, 0x7be, Вы писали:

0> Ваши мнения?

Сегодня Эрик Мейер начал лекцию со слов "Do you understand LINQ?". очень в тему.. )
Как же он жжет, напалмом просто!!!
И таки да, он показал, что мы нифига не понимаем LINQ ))
Мы уже победили, просто это еще не так заметно...
Re[2]: Linq : неудачный маркетинг?
От: samius Япония http://sams-tricks.blogspot.com
Дата: 19.02.10 04:29
Оценка:
Здравствуйте, IB, Вы писали:

IB>Здравствуйте, 0x7be, Вы писали:


0>> Ваши мнения?

IB>Сегодня Эрик Мейер начал лекцию со слов "Do you understand LINQ?". очень в тему.. )
IB>Как же он жжет, напалмом просто!!!
IB>И таки да, он показал, что мы нифига не понимаем LINQ ))

Можно развернуть тезисы?
Re[3]: Linq : неудачный маркетинг?
От: IB Австрия http://rsdn.ru
Дата: 19.02.10 04:56
Оценка:
Здравствуйте, samius, Вы писали:

S>Можно развернуть тезисы?

Ну, это я просто под впечатлением. Эрик в живую — это круто, на видео он такого эффекта не производит. =)
Выступал он с очередным рассказом про Rx, но в течении первых трех слайдов действительно показал, что линк мы не знаем, на каком-то из видео у него этот эпизод тоже есть, где он рассказывает, что линк — это монады. По ходу лекции рекламировал еще решарпер рекламировал, и утверждал что ни он, ни его команда без него не могут...
Мы уже победили, просто это еще не так заметно...
Re[4]: Linq : неудачный маркетинг?
От: samius Япония http://sams-tricks.blogspot.com
Дата: 19.02.10 05:14
Оценка:
Здравствуйте, IB, Вы писали:

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


S>>Можно развернуть тезисы?

IB>Ну, это я просто под впечатлением. Эрик в живую — это круто, на видео он такого эффекта не производит. =)
IB>Выступал он с очередным рассказом про Rx, но в течении первых трех слайдов действительно показал, что линк мы не знаем, на каком-то из видео у него этот эпизод тоже есть, где он рассказывает, что линк — это монады. По ходу лекции рекламировал еще решарпер рекламировал, и утверждал что ни он, ни его команда без него не могут...

Что линк это монады он неоднократно упоминал в лекциях по хаскелю. А нет ссылки на слайды? Правда я с Rx еще не знаком, только наслышан.
Re[2]: Linq : неудачный маркетинг?
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 19.02.10 05:35
Оценка: +1
Здравствуйте, IB, Вы писали:

IB>Сегодня Эрик Мейер начал лекцию со слов "Do you understand LINQ?".


"Do you think you undenstand LINQ?", если быть точнее.
... << RSDN@Home 1.2.0 alpha 4 rev. 1452 on Windows 7 6.1.7600.0>>
AVK Blog
Re[12]: Linq : неудачный маркетинг?
От: Undying Россия  
Дата: 19.02.10 05:55
Оценка:
Здравствуйте, Jack128, Вы писали:

J>IEnumerable<Customer> ?


А откуда уверенность, что именно Customer, а не ICustomer, к примеру?
Re[14]: Linq : неудачный маркетинг?
От: mrTwister Россия  
Дата: 19.02.10 06:18
Оценка:
Здравствуйте, IT, Вы писали:

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


T>>Понятно, то есть другими словами, если нам надо делать code-review, то пускаем пулю в лоб. Так и запишем.


IT>А вы code review на бумаге делаете?


Нет, в diff-тулах от системы контроля версий. Что показательно даже у TFS там нет никакого интеллисенса, подсказок и навигации по коду.
лэт ми спик фром май харт
Re[5]: Linq : неудачный маркетинг?
От: Al_Shargorodsky Украина  
Дата: 19.02.10 07:11
Оценка:
Здравствуйте, samius, Вы писали:
...
S>Что линк это монады он неоднократно упоминал в лекциях по хаскелю. А нет ссылки на слайды? Правда я с Rx еще не знаком, только наслышан.

Select и SelectMany собственно и есть механизм построения монад + query syntax. я это и пытался сказать выше, просто не очень получилось))
Re[6]: Linq : неудачный маркетинг?
От: samius Япония http://sams-tricks.blogspot.com
Дата: 19.02.10 07:25
Оценка: 17 (3)
Здравствуйте, Al_Shargorodsky, Вы писали:

A_S>Select и SelectMany собственно и есть механизм построения монад + query syntax. я это и пытался сказать выше, просто не очень получилось))


Если что, об этом целый опус у меня в блоге. Можно покритиковать, кстати!
Re[13]: Linq : неудачный маркетинг?
От: Dufrenite Дания  
Дата: 19.02.10 08:20
Оценка:
Здравствуйте, mrTwister, Вы писали:

T>Понятно, то есть другими словами, если нам надо делать code-review, то пускаем пулю в лоб. Так и запишем.


Я понимаю, вашу позицию, но как я писал выше, считаю что тип переменной должен быть без сомнений понятен из имени и контекста использования. Если Вы делаете Code Review и обнаруживаете, что понимание вызывает затруднение, то код просто не принимаете.
Как то так.
Re[2]: Linq : неудачный маркетинг?
От: 0x7be СССР  
Дата: 19.02.10 08:32
Оценка:
Здравствуйте, IB, Вы писали:

IB>Сегодня Эрик Мейер начал лекцию со слов "Do you understand LINQ?". очень в тему.. )

IB>Как же он жжет, напалмом просто!!!
IB>И таки да, он показал, что мы нифига не понимаем LINQ ))
А где можно посмотреть эту лекцию?
Re[14]: Linq : неудачный маркетинг?
От: Dufrenite Дания  
Дата: 19.02.10 08:37
Оценка:
Чтобы не быть голословным приведу конкретный пример.
Получение углов Эйлера из кватерниона:

class Quaternion
{
    // ...
    public EulerAngles Angles
    {
        get
        {
            var zDirection = this.Rotate(new Vector3(0, 0, 1));    // Vector3, т.к. операция, это поворот вектора кватернионом
            var projectedZDirection = new Vector3(zDirection.X, 0, zDirection.Z);    // Vector3, очевидно

            if (projectedZDirection.Length > 0.0001)
            {
                var normalizedProjectedZDirection = projectedZDirection.Normalized;    // Vector3, т.к. нормализованный проецированный вектор
                var yaw = CalculateAngle(normalizedProjectedZDirection.Z, normalizedProjectedZDirection.X);    // float, т.к. Yaq это угол Эйлера.

                var rotationWithoutYaw = Quaternion.RotationY(-yaw) * this;    // Quaternion, т.к. произведение кватернионов, это кватернион
                var zDirectionWithoutYaw = rotationWithoutYaw.Rotate(new Vector3(0, 0, 1));    // И т.д.
                var pitch = CalculateAngle(zDirectionWithoutYaw.Z, -zDirectionWithoutYaw.Y);

                var xDirectionWithoutYaw = rotationWithoutYaw.Rotate(new Vector3(1, 0, 0));
                var roll = CalculateAngle(xDirectionWithoutYaw.X, xDirectionWithoutYaw.Y);

                return new EulerAngles(yaw, pitch, roll);
            }
            else
            {
                var pitch = zDirection.Y > 0 ? -90 : 90;

                var xDirection = this.Rotate(new Vector3(1, 0, 0));
                var normalizedProjectedXDirection = new Vector3(xDirection.X, 0, xDirection.Z).Normalized;
                var yaw = CalculateAngle(normalizedProjectedXDirection.X, normalizedProjectedXDirection.Z);

                var rotationWithoutYawPitch = Quaternion.RotationX(-pitch) * Quaternion.RotationY(-yaw) * this;
                var xDirectionWithoutYawPitch = rotationWithoutYawPitch.Rotate(new Vector3(1, 0, 0));
                var roll = CalculateAngle(xDirectionWithoutYawPitch.X, xDirectionWithoutYawPitch.Y);

                return new EulerAngles(yaw, pitch, roll);
            }
        }
    }
    // ...
}
Re[32]: Linq : неудачный маркетинг?
От: Lloyd Россия  
Дата: 19.02.10 09:26
Оценка:
Здравствуйте, IT, Вы писали:

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


L>>Что значит "стрим может оказаться обыкновенной строкой"? Ты говоришь о System.IO.Stream?


IT>Конвертируем байты, заталкиваем в MemoryStream.


И почему в таком случае не будет проблем после прокручивания внешнего enumerable-а? У стрима position будет на конце и дальнейшая работа с внешним enumerable-ом будет обламываться.

L>>
L>>if (customers.Any()) {
L>>  grid.DataSource = customers;
L>>  grid.DataBind();
L>>} else {
L>>  // ....
L>>}
L>>

L>>В этом коде будет та же самая проблема, что я и писал, только в меньшем масштабе (1 лишний запрос в базу).

IT>С баиндингом у нас всегда был разговор особый, так что тут проблем тоже не будет.


Я рад за вас. Ты задал вопрос, я на него ответил. Пример из реальной жизни. Проблема возникает именно из-за ленивой природы линковских запросов. Использование var скрывает проблему. Не-использование выставляет ее напоказ.
Re[18]: Linq : неудачный маркетинг?
От: Lloyd Россия  
Дата: 19.02.10 09:30
Оценка:
Здравствуйте, IT, Вы писали:

L>>Нет, в моем правиле нет мусора и оно легко читается.


IT>В твоём правиле куча мусора, за которым не видно логики.


В твоём правиле куча мусора, за которым не видно ошибок.

Будем дальше продолжать в том же духе, или перейдем от голословных утверждений хоть к каким-то примерам?
Re[10]: Linq : неудачный маркетинг?
От: igna Россия  
Дата: 19.02.10 10:51
Оценка:
Здравствуйте, Dufrenite, Вы писали:

D>Например

D>Dictionary<string, EntityData> nameToEntityData = new Dictionary<string, EntityData>();


Этот "например" — неправильный "например", надо так:

IDictionary<string, EntityData> nameToEntityData = new Dictionary<string, EntityData>();


Или так:

ICollection<KeyValuePair<string, EntityData>> nameToEntityData = new Dictionary<string, EntityData>();


Или так:

IEnumerable<KeyValuePair<string, EntityData>> nameToEntityData = new Dictionary<string, EntityData>();


В любом из трех случаев явно указано, какими методами пользуется дальнейший код для работы с переменной nameToEntityData, даже указание IDictionary говорит о том, что используются методы отсутствующие в ICollection, иначе программист скорее всего написал бы не IDictionary, а просто Dictionary, то есть как это обычно делают не задумываясь.
Re[11]: Linq : неудачный маркетинг?
От: VladD2 Российская Империя www.nemerle.org
Дата: 19.02.10 11:23
Оценка:
Здравствуйте, igna, Вы писали:

I>В любом из трех случаев явно указано, какими методами пользуется дальнейший код для работы с переменной nameToEntityData


А зачем? Мне достаточно видеть то какие методы используются в реальном коде. А типы пускай выводит компилятор. У него это отлично получается.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[12]: Linq : неудачный маркетинг?
От: igna Россия  
Дата: 19.02.10 11:30
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>А зачем? Мне достаточно видеть то какие методы используются в реальном коде. А типы пускай выводит компилятор. У него это отлично получается.


Затем, что типы не только для эффективности, но и для защиты от некоторых ошибок и более точного документирования.
Re[13]: Linq : неудачный маркетинг?
От: WolfHound  
Дата: 19.02.10 11:38
Оценка:
Здравствуйте, igna, Вы писали:

I>Затем, что типы не только для эффективности, но и для защиты от некоторых ошибок и более точного документирования.

От указания типов локальных переменных никакого толку нет.
Ибо защиту и скорость обеспечивает вывод типов, а документирование нормальные имена переменных.
Это я тебе говорю как человек имеющий опыт работы с языком в котором вывод типов мягко говоря намного сильнее чем var.
... << RSDN@Home 1.2.0 alpha 4 rev. 1305>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[14]: Linq : неудачный маркетинг?
От: igna Россия  
Дата: 19.02.10 11:49
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>Ибо защиту и скорость обеспечивает вывод типов, а документирование нормальные имена переменных.


Какую защиту обеспечит вывод типов от ошибки, когда непреднамеренно используется метод отсутствующий в ICollection?
Re[5]: Linq : неудачный маркетинг?
От: Mystic Украина http://mystic2000.newmail.ru
Дата: 19.02.10 12:01
Оценка:
Здравствуйте, 0x7be, Вы писали:

0>Вот тут я бы с тобой поспорил. Что происходит, при замене конструкций вида foreach на вызов функций linq2objects? Повышается уровень абстракции — ты не просто делаешь foreach, а применяешь к последовательности определенные преобразования, реализация которых скрыта. В чем профит? Появление Plinq дает ответ на этот вопрос.


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

Оптимизация связанная с многопоточностью, обычно либо уровнем выше (например, пул потоков на сервере), либо на уровне качественного изменения алгоритмов, кеширования и т. п. Для качественной оптимизации, данных, которые получает LINQ, может и не хватить. Ну и в таком случае я предпочитаю критические участки писать на чистом С, где все под контролем.

Ну и повышение уровня абстракции также не бесплатно. В свои проектах я нередко с повышением уровня абстракции заходил в тупик, потому что поддерживать становилось все сложнее.
Re[15]: Linq : неудачный маркетинг?
От: WolfHound  
Дата: 19.02.10 12:35
Оценка:
Здравствуйте, igna, Вы писали:

I>Какую защиту обеспечит вывод типов от ошибки, когда непреднамеренно используется метод отсутствующий в ICollection?

Если тип переменной ICollection то будет ошибка компиляции.
Если тип более конкретный то я не вижу почему это проблема.
Попробуй привести пример в котором эта проблема проявляется.
... << RSDN@Home 1.2.0 alpha 4 rev. 1305>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[13]: Linq : неудачный маркетинг?
От: VladD2 Российская Империя www.nemerle.org
Дата: 19.02.10 13:48
Оценка: +1
Здравствуйте, igna, Вы писали:

I>Затем, что типы не только для эффективности, но и для защиты от некоторых ошибок и более точного документирования.


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

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

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

На самом деле если мы не указываем типы внутри методов, то мы оперируем их более абстрактными интерфейсами. В эти интерфейсы входят только те методы, что были применены внутри тела метода. Это позволяет смотреть на код более абстрактно и безболезненно заменять типы на их аналоги.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[16]: Linq : неудачный маркетинг?
От: igna Россия  
Дата: 19.02.10 13:51
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>Если тип переменной ICollection то будет ошибка компиляции.

WH>Если тип более конкретный то я не вижу почему это проблема.
WH>Попробуй привести пример в котором эта проблема проявляется.

Ну вот ты пишешь код работающий только с ICollection и создаешь эту самую ICollection как new Dictionary. Затем случайно используешь метод имеющийся в Dictionary, но отсутствующий в ICollection. В зависимости от того, объявишь ли ты переменную как ICollection или как Dictionary, компилятор схватит тебя за руку или нет. Во втором случае сопровождающий программу возможно получит ненужную проблему, когда несколькими годами позже попытается заменить Dictionary на что-нибудь другое.
Re[15]: Linq : неудачный маркетинг?
От: IT Россия linq2db.com
Дата: 19.02.10 13:59
Оценка:
Здравствуйте, mrTwister, Вы писали:

IT>>А вы code review на бумаге делаете?

T>Нет, в diff-тулах от системы контроля версий. Что показательно даже у TFS там нет никакого интеллисенса, подсказок и навигации по коду.

Круто. Но на бумаге было бы круче.
Если нам не помогут, то мы тоже никого не пощадим.
Re[16]: Linq : неудачный маркетинг?
От: Lloyd Россия  
Дата: 19.02.10 14:02
Оценка: +1
Здравствуйте, IT, Вы писали:

T>>Нет, в diff-тулах от системы контроля версий. Что показательно даже у TFS там нет никакого интеллисенса, подсказок и навигации по коду.


IT>Круто. Но на бумаге было бы круче.


Интересно было бы услышать как ты предлагаешь делать ревью.
Re[33]: Linq : неудачный маркетинг?
От: IT Россия linq2db.com
Дата: 19.02.10 14:04
Оценка:
Здравствуйте, Lloyd, Вы писали:

L>И почему в таком случае не будет проблем после прокручивания внешнего enumerable-а? У стрима position будет на конце и дальнейшая работа с внешним enumerable-ом будет обламываться.


Если будет обламываться, то это очень хорошо. Тебе же вроде как не нравится нежелательное поведение, а не обломы.

IT>>С баиндингом у нас всегда был разговор особый, так что тут проблем тоже не будет.


L>Я рад за вас. Ты задал вопрос, я на него ответил. Пример из реальной жизни.


Только твой пример как-то часто меняются.

L>Проблема возникает именно из-за ленивой природы линковских запросов. Использование var скрывает проблему. Не-использование выставляет ее напоказ.


Такие скрытия в нашей жизни происходят постоянно. Вот тебе, например, типичные скрытия:

myObj.Foo().Bar();

Какой тип возвращает Foo? Или ты тоже в таких случаях всегда заводишь локальную переменную, чтобы не дай бог не ошибиться?
Если нам не помогут, то мы тоже никого не пощадим.
Re[19]: Linq : неудачный маркетинг?
От: IT Россия linq2db.com
Дата: 19.02.10 14:08
Оценка:
Здравствуйте, Lloyd, Вы писали:

LL>>>Нет, в моем правиле нет мусора и оно легко читается.

IT>>В твоём правиле куча мусора, за которым не видно логики.
L>В твоём правиле куча мусора, за которым не видно ошибок.

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

L>Будем дальше продолжать в том же духе, или перейдем от голословных утверждений хоть к каким-то примерам?


С примерами у тебя пока туговато. Сначала ты приводишь теоретический пример, где проблема в каждой итерации и делаешь далеко идущие выводы. Потом в качестве практического подтверждения приводишь какой-то левый пример с баиндингом, где проблема уже не в каждой итерации. Мне как-то продолжать в таком ключе продолжать не очень интересно.
Если нам не помогут, то мы тоже никого не пощадим.
Re[14]: Linq : неудачный маркетинг?
От: igna Россия  
Дата: 19.02.10 14:08
Оценка:
Здравствуйте, VladD2, Вы писали:

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


Не находишь, что это напоминает шаблоны C++?
Re[34]: Linq : неудачный маркетинг?
От: Lloyd Россия  
Дата: 19.02.10 14:13
Оценка:
Здравствуйте, IT, Вы писали:

L>>И почему в таком случае не будет проблем после прокручивания внешнего enumerable-а? У стрима position будет на конце и дальнейшая работа с внешним enumerable-ом будет обламываться.


IT>Если будет обламываться, то это очень хорошо.


Двумя сообщениями выше было:

Мы не огнебём.

Я недоумевае.

IT>Тебе же вроде как не нравится нежелательное поведение, а не обломы.


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

L>>Проблема возникает именно из-за ленивой природы линковских запросов. Использование var скрывает проблему. Не-использование выставляет ее напоказ.


IT>Такие скрытия в нашей жизни происходят постоянно.


И что из того? Это сразу нивелирвует проблему в ноль что-ли?

IT>Вот тебе, например, типичные скрытия:


IT>
IT>myObj.Foo().Bar();
IT>

IT>Какой тип возвращает Foo? Или ты тоже в таких случаях всегда заводишь локальную переменную, чтобы не дай бог не ошибиться?

Пример некорректен. Здесь не будет промежуточной переменной ни в товем ни в моем случае.
Re[20]: Linq : неудачный маркетинг?
От: Lloyd Россия  
Дата: 19.02.10 14:15
Оценка:
Здравствуйте, IT, Вы писали:

IT>>>В твоём правиле куча мусора, за которым не видно логики.

L>>В твоём правиле куча мусора, за которым не видно ошибок.

IT>Покажи мусор в коде с var, которого нет в коде с явным указанием типов.


Покажи мусор в коде без var.

L>>Будем дальше продолжать в том же духе, или перейдем от голословных утверждений хоть к каким-то примерам?


IT>С примерами у тебя пока туговато. Сначала ты приводишь теоретический пример, где проблема в каждой итерации и делаешь далеко идущие выводы. Потом в качестве практического подтверждения приводишь какой-то левый пример с баиндингом, где проблема уже не в каждой итерации.


Да, с примерами у меня огромная проблема. Зато у вас с ними все хорошо — нет примеров, нет проблемы.
Re[15]: Linq : неудачный маркетинг?
От: IT Россия linq2db.com
Дата: 19.02.10 14:19
Оценка:
Здравствуйте, igna, Вы писали:

WH>>Ибо защиту и скорость обеспечивает вывод типов, а документирование нормальные имена переменных.

I>Какую защиту обеспечит вывод типов от ошибки, когда непреднамеренно используется метод отсутствующий в ICollection?

Что значит непреднамеренно?
Если нам не помогут, то мы тоже никого не пощадим.
Re[17]: Linq : неудачный маркетинг?
От: IT Россия linq2db.com
Дата: 19.02.10 14:23
Оценка:
Здравствуйте, Lloyd, Вы писали:

T>>>Нет, в diff-тулах от системы контроля версий. Что показательно даже у TFS там нет никакого интеллисенса, подсказок и навигации по коду.

IT>>Круто. Но на бумаге было бы круче.
L>Интересно было бы услышать как ты предлагаешь делать ревью.

Для начала следует определиться понимаем ли мы одно и тоже под термином code review.
Если нам не помогут, то мы тоже никого не пощадим.
Re[35]: Linq : неудачный маркетинг?
От: IT Россия linq2db.com
Дата: 19.02.10 14:29
Оценка:
Здравствуйте, Lloyd, Вы писали:

IT>>Вот тебе, например, типичные скрытия:


IT>>
IT>>myObj.Foo().Bar();
IT>>

IT>>Какой тип возвращает Foo? Или ты тоже в таких случаях всегда заводишь локальную переменную, чтобы не дай бог не ошибиться?

L>Пример некорректен. Здесь не будет промежуточной переменной ни в товем ни в моем случае.


Здесь будет таже проблема, о которой ты говоришь.
Если нам не помогут, то мы тоже никого не пощадим.
Re[18]: Linq : неудачный маркетинг?
От: Lloyd Россия  
Дата: 19.02.10 14:30
Оценка:
Здравствуйте, IT, Вы писали:

IT>>>Круто. Но на бумаге было бы круче.

L>>Интересно было бы услышать как ты предлагаешь делать ревью.

IT>Для начала следует определиться понимаем ли мы одно и тоже под термином code review.


Во всех командах, где мне доводилось работать, под "code review" понималась регулярная проверка кода, измененного за определенный промежуток времени. Для этого тех. лид просматривал дифы, внесенные его коллегами за последние день-два-три.
Re[21]: Linq : неудачный маркетинг?
От: IT Россия linq2db.com
Дата: 19.02.10 14:31
Оценка:
Здравствуйте, Lloyd, Вы писали:

IT>>Покажи мусор в коде с var, которого нет в коде с явным указанием типов.

L>Покажи мусор в коде без var.

IEnumerable<Customer> customers = GetCustomers();
^^^^^^^^^^^^^^^^^^^^^ <- мусор здесь


IT>>С примерами у тебя пока туговато. Сначала ты приводишь теоретический пример, где проблема в каждой итерации и делаешь далеко идущие выводы. Потом в качестве практического подтверждения приводишь какой-то левый пример с баиндингом, где проблема уже не в каждой итерации.


L>Да, с примерами у меня огромная проблема. Зато у вас с ними все хорошо — нет примеров, нет проблемы.


У тебя проблема не только с примерами, но ещё и с памятью.
Если нам не помогут, то мы тоже никого не пощадим.
Re[36]: Linq : неудачный маркетинг?
От: Lloyd Россия  
Дата: 19.02.10 14:33
Оценка:
Здравствуйте, IT, Вы писали:

L>>Пример некорректен. Здесь не будет промежуточной переменной ни в товем ни в моем случае.


IT>Здесь будет таже проблема, о которой ты говоришь.


Абсолютно верно. И как это относится к наличию аннотации типа у переменной?
Или тот факт, что проблема не может быть решена глобально, означает, что ее не стоит решать даже там, где это возможно?
Re[16]: Linq : неудачный маркетинг?
От: igna Россия  
Дата: 19.02.10 14:34
Оценка:
Здравствуйте, IT, Вы писали:

IT>Что значит непреднамеренно?


Unattended.
Re[22]: Linq : неудачный маркетинг?
От: Lloyd Россия  
Дата: 19.02.10 14:35
Оценка:
Здравствуйте, IT, Вы писали:

IT>>>Покажи мусор в коде с var, которого нет в коде с явным указанием типов.

L>>Покажи мусор в коде без var.

IT>
IT>IEnumerable<Customer> customers = GetCustomers();
IT>^^^^^^^^^^^^^^^^^^^^^ <- мусор здесь
IT>


Это не мусор, это аннотация типа, которая часто при ревью позволяет увидеть потенциальные проблемы.

L>>Да, с примерами у меня огромная проблема. Зато у вас с ними все хорошо — нет примеров, нет проблемы.


IT>У тебя проблема не только с примерами, но ещё и с памятью.


Да, старею. совсем плохой стал.
Тебя не затруднит мне немощному еще раз привести тот мега-пример, который ты якобы приводил? Ну пожалуйтса.
Re[15]: Linq : неудачный маркетинг?
От: VladD2 Российская Империя www.nemerle.org
Дата: 19.02.10 14:43
Оценка:
Здравствуйте, igna, Вы писали:

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


I>Не находишь, что это напоминает шаблоны C++?


Нет.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[16]: Linq : неудачный маркетинг?
От: igna Россия  
Дата: 19.02.10 14:54
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Нет.


В чем же две большие разницы? Твое "если мы не указываем типы внутри методов, то мы оперируем их более абстрактными интерфейсами. В эти интерфейсы входят только те методы, что были применены внутри тела метода" вполне относится и к шаблонам функций C++:

template <class T>
void f(T const& t)
{
    // оперируем "более абстрактным интерфейсам" t,
    //   в который входят только те функции,
    //     что были применены внутри f
}
Re[17]: Linq : неудачный маркетинг?
От: WolfHound  
Дата: 19.02.10 14:55
Оценка:
Здравствуйте, igna, Вы писали:

I>Ну вот ты пишешь код работающий только с ICollection

Что это за задача такая что нужно писать код работающий только с ICollection?

I>и создаешь эту самую ICollection как new Dictionary. Затем случайно используешь метод имеющийся в Dictionary, но отсутствующий в ICollection. В зависимости от того, объявишь ли ты переменную как ICollection или как Dictionary, компилятор схватит тебя за руку или нет. Во втором случае сопровождающий программу возможно получит ненужную проблему, когда несколькими годами позже попытается заменить Dictionary на что-нибудь другое.

Слишком много если чтобы об этом думать.
В любом случае замена словаря на что-то другое это само по себе не слабое изменение алгоритма.
А менять алгоритм не включая мозг это само по себе глупо.
... << RSDN@Home 1.2.0 alpha 4 rev. 1305>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[17]: Linq : неудачный маркетинг?
От: VladD2 Российская Империя www.nemerle.org
Дата: 19.02.10 15:15
Оценка:
Здравствуйте, igna, Вы писали:

I>Ну вот ты пишешь код работающий только с ICollection и создаешь эту самую ICollection как new Dictionary. Затем случайно используешь метод имеющийся в Dictionary, но отсутствующий в ICollection. В зависимости от того, объявишь ли ты переменную как ICollection или как Dictionary, компилятор схватит тебя за руку или нет. Во втором случае сопровождающий программу возможно получит ненужную проблему, когда несколькими годами позже попытается заменить Dictionary на что-нибудь другое.


У тебя извращенная (перевернутая) логика. Я пишу код реализующий алгоритм, а не "код работающий только с ICollection".

Ограничения на тип коллекции обычно накладываются неким публичным интерфейсом или неким полем в некой структуре. Но тогда компилятор сам остановит тебя от использования более широкого типа.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[18]: Linq : неудачный маркетинг?
От: igna Россия  
Дата: 19.02.10 15:15
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>Что это за задача такая что нужно писать код работающий только с ICollection?


Хрен ее знает, тебе конкретика нужна? Посмотри примеры в MSDN, где сплошь и рядом создаваемый FileStream присваивается переменной того же типа, хотя переменная эта вполне могла бы иметь тип Stream.
Re[23]: Linq : неудачный маркетинг?
От: VladD2 Российская Империя www.nemerle.org
Дата: 19.02.10 15:20
Оценка:
Здравствуйте, Lloyd, Вы писали:

IT>>
IT>>IEnumerable<Customer> customers = GetCustomers();
IT>>^^^^^^^^^^^^^^^^^^^^^ <- мусор здесь
IT>>


L>Это не мусор, это аннотация типа, которая часто при ревью позволяет увидеть потенциальные проблемы.


Если проблема видна только с аннотациями тиов локальных переменных, то код является помойкой и ждать что-то хорошее от него я бы не стал.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[19]: Linq : неудачный маркетинг?
От: WolfHound  
Дата: 19.02.10 15:21
Оценка:
Здравствуйте, igna, Вы писали:

WH>>Что это за задача такая что нужно писать код работающий только с ICollection?

I>Хрен ее знает, тебе конкретика нужна? Посмотри примеры в MSDN, где сплошь и рядом создаваемый FileStream присваивается переменной того же типа, хотя переменная эта вполне могла бы иметь тип Stream.
А в чем проблема то?
Какая разница какие типы используются внутри метода?
... << RSDN@Home 1.2.0 alpha 4 rev. 1305>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[19]: Linq : неудачный маркетинг?
От: IT Россия linq2db.com
Дата: 19.02.10 15:23
Оценка:
Здравствуйте, Lloyd, Вы писали:

IT>>Для начала следует определиться понимаем ли мы одно и тоже под термином code review.

L>Во всех командах, где мне доводилось работать, под "code review" понималась регулярная проверка кода, измененного за определенный промежуток времени. Для этого тех. лид просматривал дифы, внесенные его коллегами за последние день-два-три.

Во всех командах, где мне доводилось работать, под 'code review' понимался переодический критический разбор кода, на предмет анализа дизайна, применения паттернов, следования соглашениям.
Если нам не помогут, то мы тоже никого не пощадим.
Re[24]: Linq : неудачный маркетинг?
От: Lloyd Россия  
Дата: 19.02.10 15:23
Оценка:
Здравствуйте, VladD2, Вы писали:

L>>Это не мусор, это аннотация типа, которая часто при ревью позволяет увидеть потенциальные проблемы.


VD>Если проблема видна только с аннотациями тиов локальных переменных, то код является помойкой и ждать что-то хорошее от него я бы не стал.


Я уже приводил код:
var customers = GetCustomers();
if (customers.Any()) {
  grid.DataSource = customers;
  grid.DataBind();
} else {
  // ...
}


Видна проблема?
Re[20]: Linq : неудачный маркетинг?
От: Lloyd Россия  
Дата: 19.02.10 15:25
Оценка:
Здравствуйте, IT, Вы писали:

L>>Во всех командах, где мне доводилось работать, под "code review" понималась регулярная проверка кода, измененного за определенный промежуток времени. Для этого тех. лид просматривал дифы, внесенные его коллегами за последние день-два-три.


IT>Во всех командах, где мне доводилось работать, под 'code review' понимался переодический критический разбор кода, на предмет анализа дизайна, применения паттернов, следования соглашениям.


И? Значит в твоем варианте отсутствие аннотаций может быть и подойдет, но в моем-то — нет.
Re[37]: Linq : неудачный маркетинг?
От: IT Россия linq2db.com
Дата: 19.02.10 15:25
Оценка:
Здравствуйте, Lloyd, Вы писали:

IT>>Здесь будет таже проблема, о которой ты говоришь.


L>Абсолютно верно. И как это относится к наличию аннотации типа у переменной?

L>Или тот факт, что проблема не может быть решена глобально, означает, что ее не стоит решать даже там, где это возможно?

Она может быть решена глобально. Просто не используй цепочки вызовов, заводи под каждое возвращаемое значение свою переменную. Лишний мусор же для тебя фигня.
Если нам не помогут, то мы тоже никого не пощадим.
Re[17]: Linq : неудачный маркетинг?
От: VladD2 Российская Империя www.nemerle.org
Дата: 19.02.10 15:26
Оценка:
Здравствуйте, igna, Вы писали:

VD>>Нет.


I>В чем же две большие разницы?


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

Я вообще нахожу тут мало общего. В одном случае нет публичного интерфейса, в другом вывода типов.

I>
I>template <class T>
I>void f(T const& t)
I>{
I>    // оперируем "более абстрактным интерфейсам" t,
I>    //   в который входят только те функции,
I>    //     что были применены внутри f
I>}
I>


Разница в том, что в случае вывода типов типы будут проверены при компиляции и стало быть ошибок типов быть не может. А в случае С++ типы при разборе шаблона не проверяются вообще.
Тут уж скорее была бы уместна аналогия с выводом типов в ML-подобных языках (ОКамл, Хаскель).
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[20]: Linq : неудачный маркетинг?
От: igna Россия  
Дата: 19.02.10 15:27
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>Какая разница какие типы используются внутри метода?


Самодокументирование. Используя Stream stream = new FileStream, я сообщаю, что не использую в дальнейшем методов специфичных для FileStream.
Re[19]: Linq : неудачный маркетинг?
От: VladD2 Российская Империя www.nemerle.org
Дата: 19.02.10 15:27
Оценка:
Здравствуйте, igna, Вы писали:

I>Хрен ее знает, тебе конкретика нужна? Посмотри примеры в MSDN, где сплошь и рядом создаваемый FileStream присваивается переменной того же типа, хотя переменная эта вполне могла бы иметь тип Stream.


Это как раз говорит о том, что программистам по сути по фигу какой там тип у этой переменной.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[38]: Linq : неудачный маркетинг?
От: Lloyd Россия  
Дата: 19.02.10 15:28
Оценка:
Здравствуйте, IT, Вы писали:

IT>>>Здесь будет таже проблема, о которой ты говоришь.


L>>Абсолютно верно. И как это относится к наличию аннотации типа у переменной?

L>>Или тот факт, что проблема не может быть решена глобально, означает, что ее не стоит решать даже там, где это возможно?

IT>Она может быть решена глобально.


Нет, она не может быть решена гловально. т.к. есть еще анонимные типы.

IT>Просто не используй цепочки вызовов, заводи под каждое возвращаемое значение свою переменную. Лишний мусор же для тебя фигня.


Там где это критично, там я завожу. В общем случае, заведение доп. переменной порождает лишний "шум" и это перевешивает достоинства наличия аннотации.
Re[17]: Linq : неудачный маркетинг?
От: IT Россия linq2db.com
Дата: 19.02.10 15:28
Оценка:
Здравствуйте, igna, Вы писали:

IT>>Что значит непреднамеренно?


I>Unattended.


Оставленный без присмотра, что-ли?

Может unintended?
Если нам не помогут, то мы тоже никого не пощадим.
Re[25]: Linq : неудачный маркетинг?
От: VladD2 Российская Империя www.nemerle.org
Дата: 19.02.10 15:30
Оценка:
Здравствуйте, Lloyd, Вы писали:

L>Я уже приводил код:

L>
L>var customers = GetCustomers();
L>if (customers.Any()) {
L>  grid.DataSource = customers;
L>  grid.DataBind();
L>} else {
L>  // ...
L>}
L>


L>Видна проблема?


Дык ее здесь и нет. Если она внутри DataSource или DataBind(), то там ее и нужно устранять.

Есть такое простое правило нельзя принимать тип более общий чем требуется. Если оно нарушается, то можно долго искать ошибки там где их нет.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[23]: Linq : неудачный маркетинг?
От: IT Россия linq2db.com
Дата: 19.02.10 15:30
Оценка:
Здравствуйте, Lloyd, Вы писали:

IT>>>>Покажи мусор в коде с var, которого нет в коде с явным указанием типов.

L>>>Покажи мусор в коде без var.

IT>>
IT>>IEnumerable<Customer> customers = GetCustomers();
IT>>^^^^^^^^^^^^^^^^^^^^^ <- мусор здесь
IT>>


L>Это не мусор, это аннотация типа, которая часто при ревью позволяет увидеть потенциальные проблемы.


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

IT>>У тебя проблема не только с примерами, но ещё и с памятью.


L>Да, старею. совсем плохой стал.

L>Тебя не затруднит мне немощному еще раз привести тот мега-пример, который ты якобы приводил? Ну пожалуйтса.

Я тоже старею. Уже на лишние телодвижения не хватает сил.
Если нам не помогут, то мы тоже никого не пощадим.
Re[21]: Linq : неудачный маркетинг?
От: IT Россия linq2db.com
Дата: 19.02.10 15:33
Оценка: +1
Здравствуйте, Lloyd, Вы писали:

IT>>Во всех командах, где мне доводилось работать, под 'code review' понимался переодический критический разбор кода, на предмет анализа дизайна, применения паттернов, следования соглашениям.


L>И? Значит в твоем варианте отсутствие аннотаций может быть и подойдет, но в моем-то — нет.


Видимо так. Если задача бэбиситить девелоперов и каждые три дня проверять всё, что они понаписали, то наверное лучше использовать аннотации. Да и вообще, что-нибудь попроще.
Если нам не помогут, то мы тоже никого не пощадим.
Re[26]: Linq : неудачный маркетинг?
От: Lloyd Россия  
Дата: 19.02.10 15:34
Оценка:
Здравствуйте, VladD2, Вы писали:

L>>Я уже приводил код:

L>>
L>>var customers = GetCustomers();
L>>if (customers.Any()) {
L>>  grid.DataSource = customers;
L>>  grid.DataBind();
L>>} else {
L>>  // ...
L>>}
L>>


L>>Видна проблема?


VD>Дык ее здесь и нет.


Она здесь есть.

VD>Если она внутри DataSource или DataBind(), то там ее и нужно устранять.


Хорошо, пример попроще:
var customers = GetCustomers();
if (customers.Any()) {
  Console.WriteLine(customers.First().Name);
}

Только не говори, что проблема в Console.WriteLine.

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


Где это правило тут нарушается?
Re[39]: Linq : неудачный маркетинг?
От: VladD2 Российская Империя www.nemerle.org
Дата: 19.02.10 15:34
Оценка:
Здравствуйте, Lloyd, Вы писали:

L>В общем случае, заведение доп. переменной порождает лишний "шум" и это перевешивает достоинства наличия аннотации.


Шум ты создаешь описявая явно типы там где в этом нет смысла.

А переменная дает имя значению. Иногда это очень даже способствует чтению кода. А уж для отладки — это полезно всегда и без каких либо условий.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[18]: Linq : неудачный маркетинг?
От: igna Россия  
Дата: 19.02.10 15:35
Оценка: -2 :)
Здравствуйте, IT, Вы писали:

IT>Может unintended?


таблетку номер 16
Re[24]: Linq : неудачный маркетинг?
От: Lloyd Россия  
Дата: 19.02.10 15:36
Оценка:
Здравствуйте, IT, Вы писали:

IT>>>
IT>>>IEnumerable<Customer> customers = GetCustomers();
IT>>>^^^^^^^^^^^^^^^^^^^^^ <- мусор здесь
IT>>>


L>>Это не мусор, это аннотация типа, которая часто при ревью позволяет увидеть потенциальные проблемы.


IT>Это никому не нужный мусор, который некоторые выдают за возможность увидеть потенциальные проблемы.


Это не мусор, это аннотация типа, которая часто при ревью позволяет увидеть потенциальные проблемы.

Продолжим дальше сию увлекательную беседу?

IT>>>У тебя проблема не только с примерами, но ещё и с памятью.


L>>Да, старею. совсем плохой стал.

L>>Тебя не затруднит мне немощному еще раз привести тот мега-пример, который ты якобы приводил? Ну пожалуйтса.

IT>Я тоже старею. Уже на лишние телодвижения не хватает сил.


У тебя, видимо процесс старения зашел гораздо дальше — появляются воспомнинания о том, чего не было. Эх. мне б такое, жизнь стала бы куда интереснее.
Re[27]: Linq : неудачный маркетинг?
От: VladD2 Российская Империя www.nemerle.org
Дата: 19.02.10 15:39
Оценка:
Здравствуйте, Lloyd, Вы писали:

L>Хорошо, пример попроще:

L>
L>var customers = GetCustomers();
L>if (customers.Any()) {
L>  Console.WriteLine(customers.First().Name);
L>}
L>

L>Только не говори, что проблема в Console.WriteLine.

А какая здесь проблема то? Какой-то урод написал кривую коллекцию?

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


L>Где это правило тут нарушается?


А где тут проблема? Два раза энумератор запросили что ли?
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[22]: Linq : неудачный маркетинг?
От: Lloyd Россия  
Дата: 19.02.10 15:39
Оценка: +1
Здравствуйте, IT, Вы писали:

L>>И? Значит в твоем варианте отсутствие аннотаций может быть и подойдет, но в моем-то — нет.


IT>Видимо так. Если задача бэбиситить девелоперов и каждые три дня проверять всё, что они понаписали, то наверное лучше использовать аннотации.


Бэбиситить можно не только девелоперов, но и себя самого. Особенно умиляет смотреть на свой же код 2-3-летней давности.

IT>Да и вообще, что-нибудь попроще.


Угу. В управдомы пора.
Re[40]: Linq : неудачный маркетинг?
От: Lloyd Россия  
Дата: 19.02.10 15:42
Оценка:
Здравствуйте, VladD2, Вы писали:

L>>В общем случае, заведение доп. переменной порождает лишний "шум" и это перевешивает достоинства наличия аннотации.


VD>Шум ты создаешь описявая явно типы там где в этом нет смысла.


"там где в этом нет смысла" аннотацию типов писать нет смысла. Вы правы, кэп.

VD>А переменная дает имя значению. Иногда это очень даже способствует чтению кода.


А иногда — нет.

VD>А уж для отладки — это полезно всегда и без каких либо условий.
Re[18]: Linq : неудачный маркетинг?
От: igna Россия  
Дата: 19.02.10 15:43
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Я вообще нахожу тут мало общего. В одном случае нет публичного интерфейса, в другом вывода типов.


И фиг с ним. Тем не менее твое "если мы не указываем типы внутри методов, то мы оперируем их более абстрактными интерфейсами. В эти интерфейсы входят только те методы, что были применены внутри тела метода" вполне относится и к шаблонам функций C++.

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


Так ведь и в случае использования шаблонов C++ "типы будут проверены при компиляции и стало быть ошибок типов быть не может".

VD>А в случае С++ типы при разборе шаблона не проверяются вообще.


Ну при инстанцировании проверяются. Хрен с редькой...
Re[27]: Linq : неудачный маркетинг?
От: IT Россия linq2db.com
Дата: 19.02.10 15:43
Оценка: -1
Здравствуйте, Lloyd, Вы писали:

L>Хорошо, пример попроще:

L>
L>var customers = GetCustomers();
L>if (customers.Any()) {
L>  Console.WriteLine(customers.First().Name);
L>}
L>

L>Только не говори, что проблема в Console.WriteLine.

Эту кривульку лучше переписать так:

var customer = GetCustomers().FirstOrDefault();
if (customer != null)
  Console.WriteLine(customer.Name);

И проблем не будет.
Если нам не помогут, то мы тоже никого не пощадим.
Re[9]: Linq : неудачный маркетинг?
От: VladD2 Российская Империя www.nemerle.org
Дата: 19.02.10 15:45
Оценка:
Здравствуйте, 0x7be, Вы писали:

VD>>Не. Это называется Lisp way. А C++ way — это если что-то можно сделать через анальное отверстие, то делать именно так. А на предложение изменить язык обяснять, что религия не позволяет.

0>Ты преувеличиваешь Делание через анальное отверстие — это результат комбинации двух идей (что тоже очень С++-но по натуре):
0>1. Нежелание вводить в язык то, что можно сделать самому.
0>2. Отсутствие средств по-человечески сделать самому то, чего нет в языке.
0>

ОК. Согласен с этим определением. Но результат то тот же — все через зад.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[28]: Linq : неудачный маркетинг?
От: Lloyd Россия  
Дата: 19.02.10 15:45
Оценка:
Здравствуйте, VladD2, Вы писали:

L>>Хорошо, пример попроще:

L>>
L>>var customers = GetCustomers();
L>>if (customers.Any()) {
L>>  Console.WriteLine(customers.First().Name);
L>>}
L>>

L>>Только не говори, что проблема в Console.WriteLine.

VD>А какая здесь проблема то? Какой-то урод написал кривую коллекцию?


Любой linq-провайдер такие коллекции отдает на раз. Предлагаешь отказаться от linq-а для доступа к базам данных?

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


L>>Где это правило тут нарушается?


Так правило нарушается или нет?

VD>А где тут проблема? Два раза энумератор запросили что ли?


Да.
Re[5]: Linq : неудачный маркетинг?
От: VladD2 Российская Империя www.nemerle.org
Дата: 19.02.10 15:47
Оценка:
Здравствуйте, 0x7be, Вы писали:

0>Вот тут я бы с тобой поспорил. Что происходит, при замене конструкций вида foreach на вызов функций linq2objects? Повышается уровень абстракции — ты не просто делаешь foreach, а применяешь к последовательности определенные преобразования, реализация которых скрыта. В чем профит? Появление Plinq дает ответ на этот вопрос.


Фиг бы со всеми Plinq — ками. Главный профит в том, что код пишется на более высокоуровневых абстракциях. Их проще распознавать в коде, а значит проще понять что делает сам код. А Plinq и т.п. — это уже следствие.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[20]: Linq : неудачный маркетинг?
От: igna Россия  
Дата: 19.02.10 15:48
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Это как раз говорит о том, что программистам по сути по фигу какой там тип у этой переменной.


Программисты в большей свой части лет так дцать использовали контейнеры of Objects, кастили доставаемые из них объекты перед использованием и не видели в этом никакой проблемы. Ну по фигу им было и по сути.
Re[28]: Linq : неудачный маркетинг?
От: Lloyd Россия  
Дата: 19.02.10 15:48
Оценка: -1
Здравствуйте, IT, Вы писали:

IT>Эту кривульку лучше переписать так:


А как писать кривульку с DataSource-ом. Ты вроде говорил, что "у вас" эта проблема как-то решается. Как?

IT>
IT>var customer = GetCustomers().FirstOrDefault();
IT>if (customer != null)
IT>  Console.WriteLine(customer.Name);
IT>

IT>И проблем не будет.

Код читается хуже + лишняя переменная. Хотя, на вкус и цвет...
Re[41]: Linq : неудачный маркетинг?
От: VladD2 Российская Империя www.nemerle.org
Дата: 19.02.10 15:51
Оценка:
Здравствуйте, Lloyd, Вы писали:

VD>>Шум ты создаешь описявая явно типы там где в этом нет смысла.


L>"там где в этом нет смысла" аннотацию типов писать нет смысла. Вы правы, кэп.


Ну, вот и консенсус. Осталось только определиться с тем где этот смысл появляется.

VD>>А переменная дает имя значению. Иногда это очень даже способствует чтению кода.


L>А иногда — нет.


Несомненно. В этом мире вообще редко встречаются правила работающие во всех без исключения случаях.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[42]: Linq : неудачный маркетинг?
От: Lloyd Россия  
Дата: 19.02.10 15:52
Оценка:
Здравствуйте, VladD2, Вы писали:

L>>"там где в этом нет смысла" аннотацию типов писать нет смысла. Вы правы, кэп.


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


Ну, я думаю, мое мнение по этому поводу достаточно очевидно.
Re[19]: Linq : неудачный маркетинг?
От: VladD2 Российская Империя www.nemerle.org
Дата: 19.02.10 16:03
Оценка:
Здравствуйте, igna, Вы писали:

VD>>Я вообще нахожу тут мало общего. В одном случае нет публичного интерфейса, в другом вывода типов.


I>И фиг с ним.


А, ну, тогда общее есть со всеми видами полиморфизма. Например, с перегрузкой методов по имени.
Есть смысл в такой общности?

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


Естественно. Только от этого между шаблонами и выводом типов связи не появляется. Несомненно и то, и то виды полиморфизма.

I>Так ведь и в случае использования шаблонов C++ "типы будут проверены при компиляции и стало быть ошибок типов быть не может".


Не будут. Шаблоны или не компилируются вовсе или компилируются в некие АСТ-макросы. Проблема в том, что раскрываются эти макросы в совершенно другое время и в совершенно другом месте.

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

VD>>А в случае С++ типы при разборе шаблона не проверяются вообще.


I>Ну при инстанцировании проверяются. Хрен с редькой...


Дык она может быть выполнена через 20 лет после того как код шаблона будет написан и признан корректным. А через эти 20 лет в шаблон передадут параметр который приведет к непредсказуемому результату. При чем найти источник проблем будет крайне не просто.

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

По моему, различий куда больше чем сходств.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[29]: Linq : неудачный маркетинг?
От: VladD2 Российская Империя www.nemerle.org
Дата: 19.02.10 16:08
Оценка: -2
Здравствуйте, Lloyd, Вы писали:

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


L>Так правило нарушается или нет?


Нет.

VD>>А где тут проблема? Два раза энумератор запросили что ли?


L>Да.


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

Человек обычно прекрасно понимает в каких условиях работает программа, с какими данными и какие требования предъявляются к производительности. И тут одно из двух. Или человек идиот и он будет раз за разом порождать не эффективные решения, или он адекватен и 99% кода будет приемлемого качества, а остальное придется искать с помощью профайлера. Подложить саломку на все случаи жизни невозможно.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[21]: Linq : неудачный маркетинг?
От: VladD2 Российская Империя www.nemerle.org
Дата: 19.02.10 16:10
Оценка: -1
Здравствуйте, igna, Вы писали:

I>Программисты в большей свой части лет так дцать использовали контейнеры of Objects, кастили доставаемые из них объекты перед использованием и не видели в этом никакой проблемы. Ну по фигу им было и по сути.


Я почему-то жил в другом мире. Ну, по фигу, так по фигу. Это их проблемы. Многие пишут на Питоне и Руби и не видят в этом проблем, хотя там почти любое вычисление — это "ксты".
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[29]: Linq : неудачный маркетинг?
От: IT Россия linq2db.com
Дата: 19.02.10 16:10
Оценка: :))
Здравствуйте, Lloyd, Вы писали:

IT>>Эту кривульку лучше переписать так:


L>А как писать кривульку с DataSource-ом. Ты вроде говорил, что "у вас" эта проблема как-то решается. Как?


Ты про баиндинг? У нас для баиндинга используются специальные продвинутые списки. Так что по любому перекладывать.

var customer = GetCustomers().FirstOrDefault();

if (customer != null)
    Console.WriteLine(customer.Name);


L>Код читается хуже



А теперь?

L>+ лишняя переменная. Хотя, на вкус и цвет...


Переменных абсолютно столько же. И правда у кого-то что-то с памятью.
Если нам не помогут, то мы тоже никого не пощадим.
Re[43]: Linq : неудачный маркетинг?
От: VladD2 Российская Империя www.nemerle.org
Дата: 19.02.10 16:11
Оценка: -1
Здравствуйте, Lloyd, Вы писали:

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


L>Ну, я думаю, мое мнение по этому поводу достаточно очевидно.


Ну, да. Очевидно не верное .
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[30]: Linq : неудачный маркетинг?
От: IT Россия linq2db.com
Дата: 19.02.10 16:14
Оценка: -4
Здравствуйте, VladD2, Вы писали:

VD>Или человек идиот и он будет раз за разом порождать не эффективные решения, или...


Судя по тому, что они у себя бэбиситят девелоперов, первое.
Если нам не помогут, то мы тоже никого не пощадим.
Re[30]: Linq : неудачный маркетинг?
От: Lloyd Россия  
Дата: 19.02.10 16:17
Оценка: +1
Здравствуйте, VladD2, Вы писали:

VD>А это не проблема даже если энумератор на самом деле каждый раз лезет в БД. Ведь раз человек написал код таким образом, то производительность доступа к коллекции его не волнует. Иначе он просто не стал бы так писать код.


Ты никогда не ошибался? Тебя в реале не Чаком Норрисом зовут случаем?

VD>Человек обычно прекрасно понимает в каких условиях работает программа, с какими данными и какие требования предъявляются к производительности. И тут одно из двух. Или человек идиот и он будет раз за разом порождать не эффективные решения, или он адекватен и 99% кода будет приемлемого качества, а остальное придется искать с помощью профайлера. Подложить саломку на все случаи жизни невозможно.


Т.е. var — для тех, кто в 99% случаев не ошибается? Ну я-то явно к этой категории не отношусь.
Re[21]: Linq : неудачный маркетинг?
От: WolfHound  
Дата: 19.02.10 16:24
Оценка:
Здравствуйте, igna, Вы писали:

I>Программисты в большей свой части лет так дцать использовали контейнеры of Objects, кастили доставаемые из них объекты перед использованием и не видели в этом никакой проблемы. Ну по фигу им было и по сути.

Подмена понятий.
Статическая и динамическая типизция это резные вещи.
... << RSDN@Home 1.2.0 alpha 4 rev. 1305>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[21]: Linq : неудачный маркетинг?
От: WolfHound  
Дата: 19.02.10 16:24
Оценка: +2
Здравствуйте, igna, Вы писали:

I>Самодокументирование. Используя Stream stream = new FileStream, я сообщаю, что не использую в дальнейшем методов специфичных для FileStream.

А смысл?
Данное "самодокументирование" не делает алгоритм ни проще ни понятнее.
А то что не делает код понятнее мусор который делает код сложнее.
... << RSDN@Home 1.2.0 alpha 4 rev. 1305>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[30]: Linq : неудачный маркетинг?
От: Lloyd Россия  
Дата: 19.02.10 16:27
Оценка:
Здравствуйте, IT, Вы писали:

IT>>>Эту кривульку лучше переписать так:


L>>А как писать кривульку с DataSource-ом. Ты вроде говорил, что "у вас" эта проблема как-то решается. Как?


IT>Ты про баиндинг? У нас для баиндинга используются специальные продвинутые списки. Так что по любому перекладывать.


И как вы защититесь от того, что кто-то не воспользуется вашим продвинутым списком, а задействует напрямую linq-коллекцию?
Или опять будешь сказочки рассказывать про то, что у вас никто никогда не ошибается?

IT>
IT>var customer = GetCustomers().FirstOrDefault();

IT>if (customer != null)
IT>    Console.WriteLine(customer.Name);
IT>


L>>Код читается хуже


IT>

IT>А теперь?

Совсем плохо. Не скомпилится даже.

L>>+ лишняя переменная. Хотя, на вкус и цвет...


IT>Переменных абсолютно столько же.


А какого лешего ты убрал customers? Там может ниже код размером с пол-"Войны и Мира", где в каждой строчке customers — по пять раз.
Re[44]: Linq : неудачный маркетинг?
От: Lloyd Россия  
Дата: 19.02.10 16:30
Оценка: :)
Здравствуйте, VladD2, Вы писали:

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


L>>Ну, я думаю, мое мнение по этому поводу достаточно очевидно.


VD>Ну, да. Очевидно не верное .


Конечно, неверное. У меня специализация такая — создаю проблемы там где их не было, а где были — усугубляю.
Без проблем жизнь скушна.
Re[31]: Linq : неудачный маркетинг?
От: IT Россия linq2db.com
Дата: 19.02.10 16:34
Оценка:
Здравствуйте, Lloyd, Вы писали:

L>И как вы защититесь от того, что кто-то не воспользуется вашим продвинутым списком, а задействует напрямую linq-коллекцию?


Кто именно воспользуется?

L>Или опять будешь сказочки рассказывать про то, что у вас никто никогда не ошибается?


Постоянно ошибаться — это наша профессия. Я вот, например, в предыдущем предложении слово 'ошибаться' сначала без мягкого знака написал. Но потом исправился и в релиз этот текст пошёл без этой ошибки.

IT>>
IT>>var customer = GetCustomers().FirstOrDefault();

IT>>if (customer != null)
IT>>    Console.WriteLine(customer.Name);
IT>>


L>>>Код читается хуже


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

L>Совсем плохо. Не скомпилится даже.


А ты попробуй. Кстати, если предыдущий код по-твоему компилировался, то в этом я добавил всего лишь одну пробельную строчку

IT>>Переменных абсолютно столько же.

L>А какого лешего ты убрал customers? Там может ниже код размером с пол-"Войны и Мира", где в каждой строчке customers — по пять раз.

А зачем в этом коде этот мусор. Или ты переменные создаёшь на про запас?
Если нам не помогут, то мы тоже никого не пощадим.
Re[22]: Linq : неудачный маркетинг?
От: igna Россия  
Дата: 19.02.10 16:36
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>А то что не делает код понятнее мусор который делает код сложнее.


Сравниваем:

    Stream stream = new FileStream(...

    FileStream stream = new FileStream(...

    var stream = new FileStream(...


Кто тут сложнее?
Re[22]: Linq : неудачный маркетинг?
От: igna Россия  
Дата: 19.02.10 16:42
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>Статическая и динамическая типизция это резные вещи.


Согласен, кастинг доставаемых объектов еще и неэффективен и гораздо хуже чем использование FileStream там, где достаточно Stream. Тем не менее последнее тоже нехорошо.
Re[23]: Linq : неудачный маркетинг?
От: WolfHound  
Дата: 19.02.10 16:46
Оценка:
Здравствуйте, igna, Вы писали:

I>
I>    Stream stream = new FileStream(...
I>    FileStream stream = new FileStream(...
I>    var stream = new FileStream(...
I>

I>Кто тут сложнее?
Первые два конечно.
И особенно очевидно это будет если имя типа будет длиннее да еще и с параметрами.
Например так:
    Dictionary<MySuperPuperType, MyHyperMegaType> dictionary = new Dictionary<MySuperPuperType, MyHyperMegaType>();
    var dictionary = new Dictionary<MySuperPuperType, MyHyperMegaType>();

а теперь немерле:
    def dictionary = Dictionary();

Ну как?

Единственное место где анотации типов полезны это публичный интерфейс.
Внутри методов они безполезны и как следствие вредны.
... << RSDN@Home 1.2.0 alpha 4 rev. 1305>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[23]: Linq : неудачный маркетинг?
От: IT Россия linq2db.com
Дата: 19.02.10 16:49
Оценка:
Здравствуйте, igna, Вы писали:

I>Согласен, кастинг доставаемых объектов еще и неэффективен и гораздо хуже чем использование FileStream там, где достаточно Stream. Тем не менее последнее тоже нехорошо.


Смахивает на паранойку, приобретённую тяжёлых и изнурительных боях
Если нам не помогут, то мы тоже никого не пощадим.
Re[32]: Linq : неудачный маркетинг?
От: Lloyd Россия  
Дата: 19.02.10 16:50
Оценка:
Здравствуйте, IT, Вы писали:

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


L>>И как вы защититесь от того, что кто-то не воспользуется вашим продвинутым списком, а задействует напрямую linq-коллекцию?


IT>Кто именно воспользуется?


Любой твой коллега или ты сам.

L>>Или опять будешь сказочки рассказывать про то, что у вас никто никогда не ошибается?


IT>Постоянно ошибаться — это наша профессия. Я вот, например, в предыдущем предложении слово 'ошибаться' сначала без мягкого знака написал. Но потом исправился и в релиз этот текст пошёл без этой ошибки.


И? Это к чему было написано? Как отследит тот факт, что использовалась не та коллекция?


IT>>>
IT>>>var customer = GetCustomers().FirstOrDefault();

IT>>>if (customer != null)
IT>>>    Console.WriteLine(customer.Name);
IT>>>


L>>>>Код читается хуже


IT>Ну понятно. Оно, конечно, Any, большинству девелоперов, за которыми надо каждые три дня код проверять, понятнее будет.


Any — звучит естественно для любого человека.

L>>Совсем плохо. Не скомпилится даже.


IT>А ты попробуй. Кстати, если предыдущий код по-твоему компилировался, то в этом я добавил всего лишь одну пробельную строчку


Ну не знаюю по-моему между
var customers = GetCustomers();
if (customers.Any()) {
  Console.WriteLine(customers.First().Name);
}

и
var customer = GetCustomers().FirstOrDefault();

if (customer != null)
    Console.WriteLine(customer.Name);

различий все-таки больше, чем "одна пробельная строка".

IT>>>Переменных абсолютно столько же.

L>>А какого лешего ты убрал customers? Там может ниже код размером с пол-"Войны и Мира", где в каждой строчке customers — по пять раз.

IT>А зачем в этом коде этот мусор. Или ты переменные создаёшь на про запас?


Конечно, а ты разве нет? Вау.
Что же ты будешь делать, когда они закончатся?
Re[23]: Linq : неудачный маркетинг?
От: WolfHound  
Дата: 19.02.10 16:51
Оценка:
Здравствуйте, igna, Вы писали:

WH>>Статическая и динамическая типизция это резные вещи.

I>Согласен, кастинг доставаемых объектов еще и неэффективен и гораздо хуже чем использование FileStream там, где достаточно Stream. Тем не менее последнее тоже нехорошо.
Хватит демагогию разводить.
Ты берешь не относящаяся к теме утверждение с котором не поспоришь, проводишь не корректные ассоциации и на их основе "доказываешь" свое ложное утверждение.
Такими методами со мной спорить бесполезно.
... << RSDN@Home 1.2.0 alpha 4 rev. 1305>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[33]: Linq : неудачный маркетинг?
От: olegkr  
Дата: 19.02.10 17:01
Оценка: +1
Здравствуйте, Lloyd, Вы писали:

L>>>И как вы защититесь от того, что кто-то не воспользуется вашим продвинутым списком, а задействует напрямую linq-коллекцию?

IT>>Кто именно воспользуется?
L>Любой твой коллега или ты сам.

Страшно жить, когда от коллег и себя защищаться приходится.
Re[24]: Linq : неудачный маркетинг?
От: igna Россия  
Дата: 19.02.10 17:29
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>Ты берешь не относящаяся к теме утверждение с котором не поспоришь, проводишь не корректные ассоциации и на их основе "доказываешь" свое ложное утверждение.


Ну уж нет. Дело было так: я привел пример использования коллекций of Objects программистами в ответ на VladD2-овское "программистам по сути по фигу какой там тип у этой переменной". То есть в смысле, что мне по сути по фигу, по фигу ли по сути неким программистам, какой там тип у этой переменной. И независимо от мнения пофигных программистов полагаю, что в MSDN корректнее было написать Stream stream = new FileStream или, если уж на то пошло, var stream = new FileStream, но не FileStream stream = new FileStream создавая впечатление будто тут и вправду используются некие методы FileStream отсутствующие в Stream. Если тип указан, он должен быть выбран так, чтобы давать как можно меньше возможностей программисту, в идеале — только те, что используются.
Re[6]: Linq : неудачный маркетинг?
От: 0x7be СССР  
Дата: 19.02.10 17:48
Оценка:
Здравствуйте, VladD2, Вы писали:

0>>Вот тут я бы с тобой поспорил. Что происходит, при замене конструкций вида foreach на вызов функций linq2objects? Повышается уровень абстракции — ты не просто делаешь foreach, а применяешь к последовательности определенные преобразования, реализация которых скрыта. В чем профит? Появление Plinq дает ответ на этот вопрос.

VD>Фиг бы со всеми Plinq — ками. Главный профит в том, что код пишется на более высокоуровневых абстракциях. Их проще распознавать в коде, а значит проще понять что делает сам код. А Plinq и т.п. — это уже следствие.
Я с тобой согласен на 100%. Даже на 250%. Но мне часто встречаются собеседники не согласные с этим утверждением, так что я не рискую применять этот аргумент Вот и в этом топике мой один собеседник выразился в том духе, что повышение абстракции делает программу менее поддерживаемой. Я даже запнулся ответить.
Re[25]: Linq : неудачный маркетинг?
От: Dufrenite Дания  
Дата: 19.02.10 18:01
Оценка:
Здравствуйте, igna, Вы писали:

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


Полезное правило. Но там где нет неявного приведения к базовому типу (подавляющее большинство случаев), использование вывода типа вполне оправдано.
Re[6]: Linq : неудачный маркетинг?
От: 0x7be СССР  
Дата: 19.02.10 18:01
Оценка:
Здравствуйте, Mystic, Вы писали:

M>Профит еще в тех же ленивых вычислениях, когда можно просто описать все действия, а сам LINQ уже выполнит только необходимое. Но все это не кажется чем-то уж крайне необходимым и полезным.

Где как. Во время отладки это вообще ОЧЕНЬ неудобно. И при обработке небольших коллекций особой роли не играет. А если речь идет о чем-то тяжелом, что еще не просто берется из памяти, а генерируется и вычитывается откуда-то, то ленивость может стать хорошим методом оптимизации.

M>Оптимизация связанная с многопоточностью, обычно либо уровнем выше (например, пул потоков на сервере), либо на уровне качественного изменения алгоритмов, кеширования и т. п. Для качественной оптимизации, данных, которые получает LINQ, может и не хватить. Ну и в таком случае я предпочитаю критические участки писать на чистом С, где все под контролем.

Не соглашусь. Пулы потоков, всякие "Task manager`ы", "Scheduler`ы" и прочие "тяжеловесные" решения, организующие параллельные вычисления, достаточно неуклюжи. Они хороши для организации архитектуры прогаммы, сервера, там, какого-нибудь, но неудобны при написании вычислительных алгоритмов. Очень хочется чего-то более простого и органичного.

Идея переписать на "чистом С" критические участки мне тоже не нравится. При таком раскладе придется самому "с нуля" писать инфраструктуру для распараллеливания, что, по-сути, есть велосипед. К тому же хочется максимально отделить спецификацию алгоритма от тонкостей реализации параллелизма, что бы можно было заменять инфраструктуру параллелизма без переписывания вычислительного кода.

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

Вообще-то странно, я всегда думал, что поддерживаемость программы прямо пропорциональна высоте абстракций, на которых она построена. При условии, конечно, что абстракции выбраны правильно
Re[25]: Linq : неудачный маркетинг?
От: VladD2 Российская Империя www.nemerle.org
Дата: 19.02.10 18:44
Оценка: +2
Здравствуйте, igna, Вы писали:

WH>>Ты берешь не относящаяся к теме утверждение с котором не поспоришь, проводишь не корректные ассоциации и на их основе "доказываешь" свое ложное утверждение.


I>Ну уж нет. Дело было так: я привел пример использования коллекций of Objects программистами в ответ на VladD2-овское "программистам по сути по фигу какой там тип у этой переменной".


Если бы ты не вырывал фразу из контекста, то было бы очевидно, что по фигу только при том условии, что у объекта есть необходимые методы.

Я пишу:

def keyToValMap = Dectionary();
...
keyToValMap["key1"] = 123;
...
keyToValMap["key2"] = 65;
...
when (keyToValMap.Contains("key2"))
  doSomeWork();


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


I>...полагаю, что в MSDN корректнее было написать Stream stream = new FileStream или, если уж на то пошло, var stream = new FileStream, но не FileStream stream = new FileStream


Когда этот пример писали в шарпе просто не было еще var. А то как там они написали Stream или FileStream по сути не очень важно. Ведь разбирается другой вопрос. Хотя конечно примеры в журналах и документации становятся образцами для подражания. Вот только причем тут эта дискуссия? Она ведь не о журналах? Она о реальном коде. А в реальном коде я бы предпочел var. И мне плевать, что гда-то там есть базовый тип. Если мне станет это важно, я могу просто воспользоваться явным приведением типов.

I>создавая впечатление будто тут и вправду используются некие методы FileStream отсутствующие в Stream. Если тип указан, он должен быть выбран так, чтобы давать как можно меньше возможностей программисту, в идеале — только те, что используются.


Это зависит от задачи. Если задача скопировать два файла, то нет смысла выбирать минимальную абстракцию. Если ты пишешь метод в сигнатуре которого присутствует входной параметр, то таки да, лучше выбрать минимально допустимую абстракцию.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[7]: Linq : неудачный маркетинг?
От: VladD2 Российская Империя www.nemerle.org
Дата: 19.02.10 18:46
Оценка:
Здравствуйте, 0x7be, Вы писали:

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


Забавно. Я всегда считал наоборот. В прочем тут нужно смотреть на то, что вкладывается в понятие "абстракция". Можно ссылочку?
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[8]: Linq : неудачный маркетинг?
От: WolfHound  
Дата: 19.02.10 19:00
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Забавно. Я всегда считал наоборот. В прочем тут нужно смотреть на то, что вкладывается в понятие "абстракция". Можно ссылочку?

Re[5]: Linq : неудачный маркетинг?
Автор: Mystic
Дата: 19.02.10
... << RSDN@Home 1.2.0 alpha 4 rev. 1305>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[8]: Linq : неудачный маркетинг?
От: 0x7be СССР  
Дата: 19.02.10 19:04
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Забавно. Я всегда считал наоборот. В прочем тут нужно смотреть на то, что вкладывается в понятие "абстракция". Можно ссылочку?

здесь
Автор: Mystic
Дата: 19.02.10
Re[3]: Linq : неудачный маркетинг?
От: IB Австрия http://rsdn.ru
Дата: 19.02.10 19:21
Оценка:
Здравствуйте, 0x7be, Вы писали:

0>А где можно посмотреть эту лекцию?

Боюсь, что нигде, помоему записи вообще не было, но если и велась, то скорее всего она будет под NDA.
Мы уже победили, просто это еще не так заметно...
Re[7]: Linq : неудачный маркетинг?
От: Al_Shargorodsky Украина  
Дата: 19.02.10 19:54
Оценка:
Здравствуйте, samius, Вы писали:

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


A_S>>Select и SelectMany собственно и есть механизм построения монад + query syntax. я это и пытался сказать выше, просто не очень получилось))


S>Если что, об этом целый опус у меня в блоге. Можно покритиковать, кстати!


вот бы этот опус да превратить в статью на rsdn. нлядишь, и споров бы поубавилось)))
Re[31]: Linq : неудачный маркетинг?
От: mrTwister Россия  
Дата: 19.02.10 20:17
Оценка:
Здравствуйте, IT, Вы писали:

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


VD>>Или человек идиот и он будет раз за разом порождать не эффективные решения, или...


IT>Судя по тому, что они у себя бэбиситят девелоперов, первое.


Прежде чем демонстрировать тут свое непонимание термина code review и его целей, лучше бы разобрался. Дак вот, важнейшая цель code review — это поиск багов путем вычитки посторонним человеком кода. Таким способом у нас находятся и исправляются большое количество багов еще до того, как они попадут к тестерам (причем бывают такие хитрые баги, что тестеры бы могли их и не найти). Чтобы этот механизм эффективно работал надо как можно более точно представлять, какой именно код в данном месте выполняется и чем он (код) строже и однозначней, тем лучше. Здесь нет проблемы "понять алгоритм", поскольку алгоритмы, как правило, очень простые (мы же не гугл).

А по поводу бебиситерства. У стартима Чаков Норрисов, видимо, даже тесторов нет и код сразу идет в продакшен. Ибо Чаку Норрису не нужны тестеры-бебиситтеры, которые ищут ошибки Чака Норриса. Ибо Чак Норрис никогда не ошибается.
лэт ми спик фром май харт
Re[5]: Linq : неудачный маркетинг?
От: 0x7be СССР  
Дата: 19.02.10 20:26
Оценка:
Здравствуйте, samius, Вы писали:

S>Что линк это монады он неоднократно упоминал в лекциях по хаскелю. А нет ссылки на слайды? Правда я с Rx еще не знаком, только наслышан.

Если в разговоре с теми программистами, о которых я говорил в стартовом сообщении, упомянуть слово "монада", то беседа тут же прекратится
Re[26]: Linq : неудачный маркетинг?
От: mrTwister Россия  
Дата: 19.02.10 20:35
Оценка: +1 -1 :))
Здравствуйте, VladD2, Вы писали:

VD>
VD>def keyToValMap = Dectionary();
VD>...
VD>keyToValMap["key1"] = 123;
VD>...
VD>keyToValMap["key2"] = 65;
VD>...
VD>when (keyToValMap.Contains("key2"))
VD>  doSomeWork();
VD>


А что сделает keyToValMap при обращении по несуществующему ключу: сгенерирует исключение, или вернет null? Если бы там было написано Dictionary<Key,Value>, то у меня такой вопрос бы не возник.
лэт ми спик фром май харт
Re[8]: Linq : неудачный маркетинг?
От: samius Япония http://sams-tricks.blogspot.com
Дата: 19.02.10 20:47
Оценка:
Здравствуйте, Al_Shargorodsky, Вы писали:

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


S>>Если что, об этом целый опус у меня в блоге. Можно покритиковать, кстати!


A_S>вот бы этот опус да превратить в статью на rsdn. нлядишь, и споров бы поубавилось)))


Думал об этом, но мне кажется что для статьи нужен куда более глубокий и серьезный материал. Причем монады уже подавались в статьях rsdn, да так что тягаться с ними сложно.
Re[6]: Linq : неудачный маркетинг?
От: samius Япония http://sams-tricks.blogspot.com
Дата: 19.02.10 20:53
Оценка: :)))
Здравствуйте, 0x7be, Вы писали:

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


S>>Что линк это монады он неоднократно упоминал в лекциях по хаскелю. А нет ссылки на слайды? Правда я с Rx еще не знаком, только наслышан.

0>Если в разговоре с теми программистами, о которых я говорил в стартовом сообщении, упомянуть слово "монада", то беседа тут же прекратится

А в общественном транспорте при упоминания этого слова и побить могут
Re[9]: Linq : неудачный маркетинг?
От: 0x7be СССР  
Дата: 19.02.10 20:57
Оценка:
Здравствуйте, samius, Вы писали:

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

Я посмотрел твою статью. Подумай ой не вот в таком разрезе, что это ты не монады там подаешь, а linq под новым углом разворачиваешь. Я с монадами знаком, но мне было внове то, что ты там пишешь.
Re[7]: Linq : неудачный маркетинг?
От: 0x7be СССР  
Дата: 19.02.10 20:59
Оценка:
Здравствуйте, samius, Вы писали:

0>>Если в разговоре с теми программистами, о которых я говорил в стартовом сообщении, упомянуть слово "монада", то беседа тут же прекратится

S>А в общественном транспорте при упоминания этого слова и побить могут
Шутки шутками, а факт на лицо — есть определенные сообщества программистов, сильно замкнутые на себе и консервативные в своих традициях.
Re[10]: Linq : неудачный маркетинг?
От: samius Япония http://sams-tricks.blogspot.com
Дата: 19.02.10 21:05
Оценка:
Здравствуйте, 0x7be, Вы писали:

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


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

0>Я посмотрел твою статью. Подумай ой не вот в таком разрезе, что это ты не монады там подаешь, а linq под новым углом разворачиваешь. Я с монадами знаком, но мне было внове то, что ты там пишешь.

Подумаю в этом ракурсе, но ничего обещать по поводу статьи не буду.
Re[8]: Linq : неудачный маркетинг?
От: samius Япония http://sams-tricks.blogspot.com
Дата: 19.02.10 21:10
Оценка:
Здравствуйте, 0x7be, Вы писали:

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


0>>>Если в разговоре с теми программистами, о которых я говорил в стартовом сообщении, упомянуть слово "монада", то беседа тут же прекратится

S>>А в общественном транспорте при упоминания этого слова и побить могут
0>Шутки шутками, а факт на лицо — есть определенные сообщества программистов, сильно замкнутые на себе и консервативные в своих традициях.

8 лет проработал в такой конторе. Там не то что монада, указатель для многих вдиковинку.
Re[32]: Linq : неудачный маркетинг?
От: IT Россия linq2db.com
Дата: 19.02.10 21:25
Оценка:
Здравствуйте, mrTwister, Вы писали:

IT>>Судя по тому, что они у себя бэбиситят девелоперов, первое.


T>Прежде чем демонстрировать тут свое непонимание термина code review и его целей, лучше бы разобрался. Дак вот, важнейшая цель code review — это поиск багов путем вычитки посторонним человеком кода.


Отладка в diff'е? Это круто!

T>Таким способом у нас находятся и исправляются большое количество багов еще до того, как они попадут к тестерам (причем бывают такие хитрые баги, что тестеры бы могли их и не найти). Чтобы этот механизм эффективно работал надо как можно более точно представлять, какой именно код в данном месте выполняется и чем он (код) строже и однозначней, тем лучше. Здесь нет проблемы "понять алгоритм", поскольку алгоритмы, как правило, очень простые (мы же не гугл).


Знаешь почему я этому не верю? Потому что за три дня я могу столько нафигачить/нарефакторить кода, что твой тим лид месяц будет разбираться, а за три дня, больше ничего не делая кроме ревью, он только названия файлов успеет прочитать.

T>А по поводу бебиситерства. У стартима Чаков Норрисов, видимо, даже тесторов нет и код сразу идет в продакшен. Ибо Чаку Норрису не нужны тестеры-бебиситтеры, которые ищут ошибки Чака Норриса. Ибо Чак Норрис никогда не ошибается.


У Чаков Норрисов в командах прежде всего нет недоверия к коллегам. Возможно, потому что они не берут в команду тех, кому нельзя доверить самостоятельную работу. Чаки Норрисы привыкли доверять команде и, в свою очередь, нести полную ответственность за свой код. Причём, если команду Чаков Норрисов разбавить до определённой степени бэбиками, которых нужно ситить, то в результате придётся уже ситить и самих Чакиков Норрисиков.
Если нам не помогут, то мы тоже никого не пощадим.
Re[8]: Linq : неудачный маркетинг?
От: IT Россия linq2db.com
Дата: 19.02.10 21:27
Оценка:
Здравствуйте, 0x7be, Вы писали:

0>Шутки шутками, а факт на лицо — есть определенные сообщества программистов, сильно замкнутые на себе и консервативные в своих традициях.


Клуб первых парней на деревне?
Если нам не помогут, то мы тоже никого не пощадим.
Re[9]: Linq : неудачный маркетинг?
От: 0x7be СССР  
Дата: 19.02.10 21:30
Оценка:
Здравствуйте, IT, Вы писали:

0>>Шутки шутками, а факт на лицо — есть определенные сообщества программистов, сильно замкнутые на себе и консервативные в своих традициях.

IT>Клуб первых парней на деревне?
Можно и так сказать. Их принцип можно суммировать фразой: "мы вот так уже привыкли".
Re[33]: Linq : неудачный маркетинг?
От: Lloyd Россия  
Дата: 19.02.10 21:35
Оценка: +1
Здравствуйте, IT, Вы писали:

T>>Прежде чем демонстрировать тут свое непонимание термина code review и его целей, лучше бы разобрался. Дак вот, важнейшая цель code review — это поиск багов путем вычитки посторонним человеком кода.


IT>Отладка в diff'е? Это круто!


При чем тут отладка. Баги находятся и банальным ревью тоже.

T>>Таким способом у нас находятся и исправляются большое количество багов еще до того, как они попадут к тестерам (причем бывают такие хитрые баги, что тестеры бы могли их и не найти). Чтобы этот механизм эффективно работал надо как можно более точно представлять, какой именно код в данном месте выполняется и чем он (код) строже и однозначней, тем лучше. Здесь нет проблемы "понять алгоритм", поскольку алгоритмы, как правило, очень простые (мы же не гугл).


IT>Знаешь почему я этому не верю? Потому что за три дня я могу столько нафигачить/нарефакторить кода, что твой тим лид месяц будет разбираться, а за три дня, больше ничего не делая кроме ревью, он только названия файлов успеет прочитать.


Не, точно Чак Норис.

T>>А по поводу бебиситерства. У стартима Чаков Норрисов, видимо, даже тесторов нет и код сразу идет в продакшен. Ибо Чаку Норрису не нужны тестеры-бебиситтеры, которые ищут ошибки Чака Норриса. Ибо Чак Норрис никогда не ошибается.


IT>У Чаков Норрисов в командах прежде всего нет недоверия к коллегам. Возможно, потому что они не берут в команду тех, кому нельзя доверить самостоятельную работу. Чаки Норрисы привыкли доверять команде и, в свою очередь, нести полную ответственность за свой код. Причём, если команду Чаков Норрисов разбавить до определённой степени бэбиками, которых нужно ситить, то в результате придётся уже ситить и самих Чакиков Норрисиков.


Бла-бла-бла.
Доверие тут совершенно непричем, у человека, плотно занимающимся каким-то куском кода банально глаз замыливается. Неужели у тебя ни разу такого не было, когда допускаешь совершенно тупые ошибки, не смотря на весь опыт?
Re[33]: Linq : неудачный маркетинг?
От: mrTwister Россия  
Дата: 19.02.10 21:36
Оценка:
Здравствуйте, IT, Вы писали:

T>>Прежде чем демонстрировать тут свое непонимание термина code review и его целей, лучше бы разобрался. Дак вот, важнейшая цель code review — это поиск багов путем вычитки посторонним человеком кода.


IT>Отладка в diff'е? Это круто!


При чем тут отладка?

IT>Знаешь почему я этому не верю? Потому что за три дня я могу столько нафигачить/нарефакторить кода, что твой тим лид месяц будет разбираться, а за три дня, больше ничего не делая кроме ревью, он только названия файлов успеет прочитать.


Страшно подумать, сколько кода ты в год генерируешь, наверное гигабайты исходников. Почему-то анекдот вспомнился про то, как один хвастался своим сумасшедшим скоропечатанием вслепую.
Для информации:

There are many examples of where it is claimed that adopting code reviews improved a software development project. Capers Jones ongoing analysis of over 12,000 software development projects showed that the latent defect discovery rate of formal inspection is in the 60-65% range. For informal inspection, the figure is less than 50%. The latent defect discovery rate for most forms of testing is about 30%.

http://en.wikipedia.org/wiki/Code_review

T>>А по поводу бебиситерства. У стартима Чаков Норрисов, видимо, даже тесторов нет и код сразу идет в продакшен. Ибо Чаку Норрису не нужны тестеры-бебиситтеры, которые ищут ошибки Чака Норриса. Ибо Чак Норрис никогда не ошибается.


IT>У Чаков Норрисов в командах прежде всего нет недоверия к коллегам. Возможно, потому что они не берут в команду тех, кому нельзя доверить самостоятельную работу. Чаки Норрисы привыкли доверять команде и, в свою очередь, нести полную ответственность за свой код. Причём, если команду Чаков Норрисов разбавить до определённой степени бэбиками, которых нужно ситить, то в результате придётся уже ситить и самих Чакиков Норрисиков.


У вас тестеры есть?
лэт ми спик фром май харт
Re[34]: Linq : неудачный маркетинг?
От: IT Россия linq2db.com
Дата: 19.02.10 21:44
Оценка: :)
Здравствуйте, Lloyd, Вы писали:

IT>>Отладка в diff'е? Это круто!

L>При чем тут отладка. Баги находятся и банальным ревью тоже.

Находятся, не спорю. Ровно пол процента.

IT>>Знаешь почему я этому не верю? Потому что за три дня я могу столько нафигачить/нарефакторить кода, что твой тим лид месяц будет разбираться, а за три дня, больше ничего не делая кроме ревью, он только названия файлов успеет прочитать.


L>Не, точно Чак Норис.


Чак ни Чак, но любого тим лида кодом завалю легко, если понадобится. Из дифов хрен выползет.

L>Бла-бла-бла.

L>Доверие тут совершенно непричем, у человека, плотно занимающимся каким-то куском кода банально глаз замыливается. Неужели у тебя ни разу такого не было, когда допускаешь совершенно тупые ошибки, не смотря на весь опыт?

А вы поменьше дифы разглядывайте и типов аннотируйте, больше сил на недопускание совершенно тупых ошибок останется.
Если нам не помогут, то мы тоже никого не пощадим.
Re[34]: Linq : неудачный маркетинг?
От: IT Россия linq2db.com
Дата: 19.02.10 21:50
Оценка:
Здравствуйте, mrTwister, Вы писали:

T>>>Прежде чем демонстрировать тут свое непонимание термина code review и его целей, лучше бы разобрался. Дак вот, важнейшая цель code review — это поиск багов путем вычитки посторонним человеком кода.

IT>>Отладка в diff'е? Это круто!
T>При чем тут отладка?

http://en.wikipedia.org/wiki/Debugging

IT>>Знаешь почему я этому не верю? Потому что за три дня я могу столько нафигачить/нарефакторить кода, что твой тим лид месяц будет разбираться, а за три дня, больше ничего не делая кроме ревью, он только названия файлов успеет прочитать.


T>Страшно подумать, сколько кода ты в год генерируешь, наверное гигабайты исходников. Почему-то анекдот вспомнился про то, как один хвастался своим сумасшедшим скоропечатанием вслепую.


Не хвастался, а хвасталась.

T>http://en.wikipedia.org/wiki/Code_review

http://en.wiktionary.org/wiki/code_review

IT>>У Чаков Норрисов в командах прежде всего нет недоверия к коллегам. Возможно, потому что они не берут в команду тех, кому нельзя доверить самостоятельную работу. Чаки Норрисы привыкли доверять команде и, в свою очередь, нести полную ответственность за свой код. Причём, если команду Чаков Норрисов разбавить до определённой степени бэбиками, которых нужно ситить, то в результате придётся уже ситить и самих Чакиков Норрисиков.


T>У вас тестеры есть?


На текущем проекте? Выделенные? Нет. Впрочем, это исключительно специфика нашего тима.
Если нам не помогут, то мы тоже никого не пощадим.
Re[35]: Linq : неудачный маркетинг?
От: Lloyd Россия  
Дата: 19.02.10 21:50
Оценка:
Здравствуйте, IT, Вы писали:

IT>>>Отладка в diff'е? Это круто!

L>>При чем тут отладка. Баги находятся и банальным ревью тоже.

IT>Находятся, не спорю. Ровно пол процента.


Ссылочку на исследования подкинешь или это частное мнение Чака?

IT>>>Знаешь почему я этому не верю? Потому что за три дня я могу столько нафигачить/нарефакторить кода, что твой тим лид месяц будет разбираться, а за три дня, больше ничего не делая кроме ревью, он только названия файлов успеет прочитать.


L>>Не, точно Чак Норис.


IT>Чак ни Чак, но любого тим лида кодом завалю легко, если понадобится. Из дифов хрен выползет.


Я рад за вас, если все действительно так, как вы это тут описываете. Но все-таки средние цифры продуктивности программиста вполне позволяют лидам делать ревью.

L>>Бла-бла-бла.

L>>Доверие тут совершенно непричем, у человека, плотно занимающимся каким-то куском кода банально глаз замыливается. Неужели у тебя ни разу такого не было, когда допускаешь совершенно тупые ошибки, не смотря на весь опыт?

IT>А вы поменьше дифы разглядывайте и типов аннотируйте, больше сил на недопускание совершенно тупых ошибок останется.


Ответы ты видимо тоже не считаешь нужным "разглядывать"? Это был вопрос, если ты не понял.
Re[35]: Linq : неудачный маркетинг?
От: Lloyd Россия  
Дата: 19.02.10 21:53
Оценка:
Здравствуйте, IT, Вы писали:

IT>>>Отладка в diff'е? Это круто!

T>>При чем тут отладка?

IT>http://en.wikipedia.org/wiki/Debugging


Похоже, все-таки не читаешь ответы. Вопрос был "при чем тут отладка", а не "что это такое".
Re[36]: Linq : неудачный маркетинг?
От: IT Россия linq2db.com
Дата: 19.02.10 21:56
Оценка: -1
Здравствуйте, Lloyd, Вы писали:

IT>>>>Отладка в diff'е? Это круто!

L>>>При чем тут отладка. Баги находятся и банальным ревью тоже.
IT>>Находятся, не спорю. Ровно пол процента.
L>Ссылочку на исследования подкинешь или это частное мнение Чака?

Это элементарная логика, дружок. Ты наверное думаешь, что отладчик придумали для сравнения различных версий исходных файлов, а diff для отладки? Так вот всё совсем наоборот.

IT>>Чак ни Чак, но любого тим лида кодом завалю легко, если понадобится. Из дифов хрен выползет.

L>Я рад за вас, если все действительно так, как вы это тут описываете. Но все-таки средние цифры продуктивности программиста вполне позволяют лидам делать ревью.

Понятное дело, замусоривание кода аннотациями никак не способствует продуктивности программиста.

IT>>А вы поменьше дифы разглядывайте и типов аннотируйте, больше сил на недопускание совершенно тупых ошибок останется.

L>Ответы ты видимо тоже не считаешь нужным "разглядывать"? Это был вопрос, если ты не понял.

Я понял. Это был ответ-совет.
Если нам не помогут, то мы тоже никого не пощадим.
Re[35]: Linq : неудачный маркетинг?
От: mrTwister Россия  
Дата: 19.02.10 21:57
Оценка:
Здравствуйте, IT, Вы писали:


T>>>>Прежде чем демонстрировать тут свое непонимание термина code review и его целей, лучше бы разобрался. Дак вот, важнейшая цель code review — это поиск багов путем вычитки посторонним человеком кода.

IT>>>Отладка в diff'е? Это круто!
T>>При чем тут отладка?

IT>http://en.wikipedia.org/wiki/Debugging


У вас тестеры тоже в дебаггере работают?

IT>>>Знаешь почему я этому не верю? Потому что за три дня я могу столько нафигачить/нарефакторить кода, что твой тим лид месяц будет разбираться, а за три дня, больше ничего не делая кроме ревью, он только названия файлов успеет прочитать.


T>>Страшно подумать, сколько кода ты в год генерируешь, наверное гигабайты исходников. Почему-то анекдот вспомнился про то, как один хвастался своим сумасшедшим скоропечатанием вслепую.


IT>Не хвастался, а хвасталась.


Совсем другое дело!

T>>http://en.wikipedia.org/wiki/Code_review

IT>http://en.wiktionary.org/wiki/code_review

И?

T>>У вас тестеры есть?


IT>На текущем проекте? Выделенные? Нет. Впрочем, это исключительно специфика нашего тима.


Не увиливай. Твой код кто-нибудь кроме тебя тестирует, перед тем, как он попадает в продакшен? Или твой код в продакшен не попадает? Если так, то вопросов больше не имею
лэт ми спик фром май харт
Re[23]: Linq : неудачный маркетинг?
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 19.02.10 21:59
Оценка: +1
Здравствуйте, Lloyd, Вы писали:

L> Особенно умиляет смотреть на свой же код 2-3-летней давности.


Со временем это проходит.
... << RSDN@Home 1.2.0 alpha 4 rev. 1458 on Windows 7 6.1.7600.0>>
AVK Blog
Re[11]: Linq : неудачный маркетинг?
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 19.02.10 21:59
Оценка: +1
Здравствуйте, igna, Вы писали:

I>Этот "например" — неправильный "например", надо так:


I>
I>IDictionary<string, EntityData> nameToEntityData = new Dictionary<string, EntityData>();
I>


Вот как раз этот пример — неправильный. Толку обобщать тип для локальных переменных никакого, один вред. Насколько я еще не забыл CS, в контрактах надо указывать максимально общий тип, а в локальных переменных наоборот, максимально точный.
... << RSDN@Home 1.2.0 alpha 4 rev. 1458 on Windows 7 6.1.7600.0>>
AVK Blog
Re[37]: Linq : неудачный маркетинг?
От: Lloyd Россия  
Дата: 19.02.10 22:25
Оценка:
Здравствуйте, IT, Вы писали:

L>>>>При чем тут отладка. Баги находятся и банальным ревью тоже.

IT>>>Находятся, не спорю. Ровно пол процента.
L>>Ссылочку на исследования подкинешь или это частное мнение Чака?

IT>Это элементарная логика, дружок.


Ты меня в свои дружки не записывай. Мне такие друзья ни к чему.

IT>Ты наверное думаешь, что отладчик придумали для сравнения различных версий исходных файлов, а diff для отладки? Так вот всё совсем наоборот.


Бред какой-то. Празднование пятницы в полном разгаре?
Или ты намекаешь, что codereview не способствует нахождению ошибок?

IT>>>Чак ни Чак, но любого тим лида кодом завалю легко, если понадобится. Из дифов хрен выползет.

L>>Я рад за вас, если все действительно так, как вы это тут описываете. Но все-таки средние цифры продуктивности программиста вполне позволяют лидам делать ревью.

IT>Понятное дело, замусоривание кода аннотациями никак не способствует продуктивности программиста.


Замусоривание — не способствует, спорить не буду. Но только аннотирование к замусориванию имеет такое же отношение codereview к отладчику.

IT>>>А вы поменьше дифы разглядывайте и типов аннотируйте, больше сил на недопускание совершенно тупых ошибок останется.

L>>Ответы ты видимо тоже не считаешь нужным "разглядывать"? Это был вопрос, если ты не понял.

IT>Я понял. Это был ответ-совет.


А я не понял. На всякий случай, повторю вопрос, раз с первого раза не прошло:

Неужели у тебя ни разу такого не было, когда допускаешь совершенно тупые ошибки, не смотря на весь опыт?

Re[27]: Linq : неудачный маркетинг?
От: rameel https://github.com/rsdn/CodeJam
Дата: 19.02.10 22:25
Оценка:
Здравствуйте, mrTwister, Вы писали:

T>А что сделает keyToValMap при обращении по несуществующему ключу: сгенерирует исключение, или вернет null? Если бы там было написано Dictionary<Key,Value>, то у меня такой вопрос бы не возник.


Я так понимаю, что если бы там было написано скажем ActionsDictionary, то таких вопросов бы тоже не возникло?
... << RSDN@Home 1.2.0 alpha 4 rev. 1325>>
Re[24]: Linq : неудачный маркетинг?
От: Lloyd Россия  
Дата: 19.02.10 22:27
Оценка: +1
Здравствуйте, AndrewVK, Вы писали:

L>> Особенно умиляет смотреть на свой же код 2-3-летней давности.


AVK>Со временем это проходит.


Со временем все проходит.
Re[28]: Linq : неудачный маркетинг?
От: mrTwister Россия  
Дата: 19.02.10 22:33
Оценка: +1
Здравствуйте, rameel, Вы писали:

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


T>>А что сделает keyToValMap при обращении по несуществующему ключу: сгенерирует исключение, или вернет null? Если бы там было написано Dictionary<Key,Value>, то у меня такой вопрос бы не возник.


R>Я так понимаю, что если бы там было написано скажем ActionsDictionary, то таких вопросов бы тоже не возникло?


Если бы я знал, что такое ActionsDictionary, то нет. Предвидя вопрос, сразу даю на него ответ: методов гораздо больше, чем типов.
лэт ми спик фром май харт
Re[6]: Linq : неудачный маркетинг?
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 20.02.10 04:41
Оценка:
Здравствуйте, Mystic, Вы писали:

M>Ну и в таком случае я предпочитаю критические участки писать на чистом С, где все под контролем.


Упомянутый уже здесь Эрик Мейер, когда рассказывал про некоторые применения Rx, говорил, что он недостаточно умен, чтобы написать аналогичное без линка. И я ему почму то верю.
... << RSDN@Home 1.2.0 alpha 4 rev. 1458 on Windows 7 6.1.7600.0>>
AVK Blog
Re[22]: Linq : неудачный маркетинг?
От: igna Россия  
Дата: 20.02.10 07:48
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Я почему-то жил в другом мире.


Как же, а C# 1.0?
Re[24]: Linq : неудачный маркетинг?
От: igna Россия  
Дата: 20.02.10 07:54
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>а теперь немерле:

WH>    def dictionary = Dictionary();

WH>Ну как?

Интересно. А если написать:

    def stream = FileStream();


и использовать затем только методы Stream, какого типа окажется stream, Stream или FileStream?
Re[12]: Linq : неудачный маркетинг?
От: igna Россия  
Дата: 20.02.10 07:58
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Толку обобщать тип для локальных переменных никакого, один вред.


Какой?

AVK>Насколько я еще не забыл CS, в контрактах надо указывать максимально общий тип, а в локальных переменных наоборот, максимально точный.


Зачем?
Re: Linq : неудачный маркетинг?
От: minorlogic Украина  
Дата: 20.02.10 11:17
Оценка:
Добавлю еще одно , когда я краем уха слышал про LINQ (я не работаю с С решетка), я для себя сделал вывод что это механизм мапинга объектов, в БД в первую очередь.
... << RSDN@Home 1.2.0 alpha 4 rev. 1237>>
Ищу работу, 3D, SLAM, computer graphics/vision.
Re[17]: Linq : неудачный маркетинг?
От: fmiracle  
Дата: 20.02.10 11:37
Оценка:
Здравствуйте, igna, Вы писали:

I>Ну вот ты пишешь код работающий только с ICollection и создаешь эту самую ICollection как new Dictionary. Затем случайно используешь метод имеющийся в Dictionary, но отсутствующий в ICollection. В зависимости от того, объявишь ли ты переменную как ICollection или как Dictionary, компилятор схватит тебя за руку или нет. Во втором случае сопровождающий программу возможно получит ненужную проблему, когда несколькими годами позже попытается заменить Dictionary на что-нибудь другое.


Это, кажется, что-то из сферы написания ПО для АЭС. На практике как-то ни разу не видел, чтобы кто-то хотел ограничивать локальные переменные или даже приватные методы.

Ограничение по интерфейсу публичных/защищенных члоенов класса разумно и понятно. Ограниение возможностей локальных переменных уже смахивает на паранойю.
... << RSDN@Home 1.2.0 alpha 4 rev. 1237>>
Re[25]: Linq : неудачный маркетинг?
От: WolfHound  
Дата: 20.02.10 12:02
Оценка:
Здравствуйте, igna, Вы писали:

I>Интересно. А если написать:

I>
I>    def stream = FileStream();
I>

I>и использовать затем только методы Stream, какого типа окажется stream, Stream или FileStream?
Конечно FileStream. Ведь тип указан явно.
И в моем прмере тип был указан явно. Компилятор только параметры генерика вывел.
... << RSDN@Home 1.2.0 alpha 4 rev. 1305>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[27]: Linq : неудачный маркетинг?
От: WolfHound  
Дата: 20.02.10 12:02
Оценка: -2
Здравствуйте, mrTwister, Вы писали:

T>А что сделает keyToValMap при обращении по несуществующему ключу: сгенерирует исключение, или вернет null? Если бы там было написано Dictionary<Key,Value>, то у меня такой вопрос бы не возник.

А может тебе стоит для начала изучить стандартную библиотеку .NET?
... << RSDN@Home 1.2.0 alpha 4 rev. 1305>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[36]: Linq : неудачный маркетинг?
От: WolfHound  
Дата: 20.02.10 12:12
Оценка:
Здравствуйте, mrTwister, Вы писали:

T>Не увиливай. Твой код кто-нибудь кроме тебя тестирует, перед тем, как он попадает в продакшен? Или твой код в продакшен не попадает? Если так, то вопросов больше не имею

Его код попадает в такое колличество продакшенов...
... << RSDN@Home 1.2.0 alpha 4 rev. 1305>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[2]: Linq : неудачный маркетинг?
От: 0x7be СССР  
Дата: 20.02.10 12:33
Оценка: +1
Здравствуйте, minorlogic, Вы писали:

M>Добавлю еще одно , когда я краем уха слышал про LINQ (я не работаю с С решетка), я для себя сделал вывод что это механизм мапинга объектов, в БД в первую очередь.

Этот факт хорошо ложится в мою гипотезу
Re[37]: Linq : неудачный маркетинг?
От: Lloyd Россия  
Дата: 20.02.10 12:40
Оценка: :)
Здравствуйте, WolfHound, Вы писали:

T>>Не увиливай. Твой код кто-нибудь кроме тебя тестирует, перед тем, как он попадает в продакшен? Или твой код в продакшен не попадает? Если так, то вопросов больше не имею

WH>Его код попадает в такое колличество продакшенов...

Ссылок на success stories не замечено. Активности в гуглгрупс нет. Количество скачиваний в районе нескольких сотен за полтора года. Ссылок в гугле находится в 2 раза меньше, чем на Nemerle.
Как вы определили, что этот код используется в большом кол-ве продакшенов?
Re[28]: Linq : неудачный маркетинг?
От: Lloyd Россия  
Дата: 20.02.10 12:42
Оценка: +1
Здравствуйте, WolfHound, Вы писали:

T>>А что сделает keyToValMap при обращении по несуществующему ключу: сгенерирует исключение, или вернет null? Если бы там было написано Dictionary<Key,Value>, то у меня такой вопрос бы не возник.

WH>А может тебе стоит для начала изучить стандартную библиотеку .NET?

А что не так в его вопросе? У Нashtable-а и Dictionary — разное поведение при чтении несуществующего элемента.
Re[29]: Linq : неудачный маркетинг?
От: WolfHound  
Дата: 20.02.10 13:09
Оценка:
Здравствуйте, Lloyd, Вы писали:

L>А что не так в его вопросе? У Нashtable-а и Dictionary — разное поведение при чтении несуществующего элемента.

Вот именно это и нет так. Там было написано Dictionary, а не Нashtable.
... << RSDN@Home 1.2.0 alpha 4 rev. 1305>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[28]: Linq : неудачный маркетинг?
От: mrTwister Россия  
Дата: 20.02.10 13:42
Оценка: :)
Здравствуйте, WolfHound, Вы писали:

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


T>>А что сделает keyToValMap при обращении по несуществующему ключу: сгенерирует исключение, или вернет null? Если бы там было написано Dictionary<Key,Value>, то у меня такой вопрос бы не возник.

WH>А может тебе стоит для начала изучить стандартную библиотеку .NET?

Я её знаю.
лэт ми спик фром май харт
Re[30]: Linq : неудачный маркетинг?
От: mrTwister Россия  
Дата: 20.02.10 14:00
Оценка:
Здравствуйте, WolfHound, Вы писали:

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


L>>А что не так в его вопросе? У Нashtable-а и Dictionary — разное поведение при чтении несуществующего элемента.

WH>Вот именно это и нет так. Там было написано Dictionary, а не Нashtable.

Там написан какой-то "def keyToValMap = Dectionary();" без типов-аргументов, что больше похоже на вызов метода c неграмотным именем и уж совсем не похоже на использование класса Dictionary<Key,Value>
лэт ми спик фром май харт
Re[31]: Linq : неудачный маркетинг?
От: WolfHound  
Дата: 20.02.10 15:34
Оценка:
Здравствуйте, mrTwister, Вы писали:

T>Там написан какой-то "def keyToValMap = Dectionary();" без типов-аргументов, что больше похоже на вызов метода c неграмотным именем и уж совсем не похоже на использование класса Dictionary<Key,Value>

А теперь попробуй ответить чем вызов конструктора отличается от вызова метода?
Меня кстати всегда интересовало нафига в C# ключевое слово new ибо оно нафиг не упало.
... << RSDN@Home 1.2.0 alpha 4 rev. 1305>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[32]: Linq : неудачный маркетинг?
От: Cyberax Марс  
Дата: 20.02.10 15:43
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>А теперь попробуй ответить чем вызов конструктора отличается от вызова метода?

WH>Меня кстати всегда интересовало нафига в C# ключевое слово new ибо оно нафиг не упало.
class SomeClass
{
     public boolean Dictionary()
     {
          return true;
     }
 
....
          var dict = Dictionary();
....
}

Что будет Dictionary() в этом примере?

Потому пусть new лучше остаётся.
Sapienti sat!
Re[33]: Linq : неудачный маркетинг?
От: WolfHound  
Дата: 20.02.10 16:08
Оценка:
Здравствуйте, Cyberax, Вы писали:

C>Что будет Dictionary() в этом примере?

C>Потому пусть new лучше остаётся.
Ни разу подобных проблем небыло.
А даже если кто-то такой метод и заведет то стандартные методы разрешения подобных конфликтов никто не отменял... всегда можно обратиться по полному имени.
... << RSDN@Home 1.2.0 alpha 4 rev. 1305>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[13]: Linq : неудачный маркетинг?
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 20.02.10 16:56
Оценка:
Здравствуйте, igna, Вы писали:

AVK>>Толку обобщать тип для локальных переменных никакого, один вред.


I>Какой?


Отсутствие возможности воспользоваться максимально полным контрактом.

I>Зачем?


Это обеспечивает максимальную гибкость и надежность кода. Есть, ЕМНИП, довольно строгое доказательство сего на основе LSP.

А теперь встречный вопрос — а зачем обобщать тип локальной переменной?
... << RSDN@Home 1.2.0 alpha 4 rev. 1458 on Windows 7 6.1.7600.0>>
AVK Blog
Re[2]: Жуткий оффтопик
От: Кэр  
Дата: 20.02.10 17:39
Оценка:
Здравствуйте, IB, Вы писали:

Иван, а ты еще в Редмонде? Я буду во вторник-среду там (остальное время в Ванкувере). Можно пересечься, пообщаться В частности, мне интересно, что вам там Эрик Мейер рассказывал. Кто там еще из rsdn тусовки есть?

email: alex.klimov at hotmail.com
Re[30]: Linq : неудачный маркетинг?
От: Lloyd Россия  
Дата: 20.02.10 18:18
Оценка:
Здравствуйте, WolfHound, Вы писали:

L>>А что не так в его вопросе? У Нashtable-а и Dictionary — разное поведение при чтении несуществующего элемента.

WH>Вот именно это и нет так. Там было написано Dictionary, а не Нashtable.

Там было написано вообще keyValueMap, а какой там именно map — непонятно. И в зависимости от типа поведение у похожих методов будет разным.
Re[31]: Linq : неудачный маркетинг?
От: WolfHound  
Дата: 20.02.10 19:02
Оценка:
Здравствуйте, Lloyd, Вы писали:

WH>>Вот именно это и нет так. Там было написано Dictionary, а не Нashtable.

L>Там было написано вообще keyValueMap, а какой там именно map — непонятно. И в зависимости от типа поведение у похожих методов будет разным.
Там было написано:
def keyToValMap = Dictionary();

Конструктор явно задает тип.
... << RSDN@Home 1.2.0 alpha 4 rev. 1305>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[32]: Linq : неудачный маркетинг?
От: mrTwister Россия  
Дата: 20.02.10 19:15
Оценка:
Здравствуйте, WolfHound, Вы писали:

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


WH>>>Вот именно это и нет так. Там было написано Dictionary, а не Нashtable.

L>>Там было написано вообще keyValueMap, а какой там именно map — непонятно. И в зависимости от типа поведение у похожих методов будет разным.
WH>Там было написано:
WH>
WH>def keyToValMap = Dictionary();
WH>

WH>Конструктор явно задает тип.

Вообще-то там был загадочный Dectionary() и что это конструктор ниоткуда не следует. Можно, конечно, предположить, что это generic-класс "System.Collections.Generic.Dictionary<TKey,TValue>", но куда в этом случае подевались типы-аргументы?
лэт ми спик фром май харт
Re[32]: Linq : неудачный маркетинг?
От: mrTwister Россия  
Дата: 20.02.10 19:19
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>А теперь попробуй ответить чем вызов конструктора отличается от вызова метода?

WH>Меня кстати всегда интересовало нафига в C# ключевое слово new ибо оно нафиг не упало.

Тем, что при использовании виден класс, чей метод (конструктор) вызывается. В обсуждаемом варианте можно предположить, что это метод текущего класса (что я и сделал).
лэт ми спик фром май харт
Re[33]: Linq : неудачный маркетинг?
От: WolfHound  
Дата: 20.02.10 19:53
Оценка:
Здравствуйте, mrTwister, Вы писали:

T>Вообще-то там был загадочный Dectionary()

Докапывание до опечаток. Как мелко... что совсем сказать нечего?

T>и что это конструктор ниоткуда не следует. Можно, конечно, предположить, что это generic-класс "System.Collections.Generic.Dictionary<TKey,TValue>", но куда в этом случае подевались типы-аргументы?

Если знать что язык на котором написан этот код прекрасно выводит типы из использования то очевидно куда они делись.
... << RSDN@Home 1.2.0 alpha 4 rev. 1305>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[33]: Linq : неудачный маркетинг?
От: WolfHound  
Дата: 20.02.10 19:53
Оценка:
Здравствуйте, mrTwister, Вы писали:

T>Тем, что при использовании виден класс, чей метод (конструктор) вызывается. В обсуждаемом варианте можно предположить, что это метод текущего класса (что я и сделал).

Признайся хотя бы самому себе что ты это сделал не по тому что не понял что там создается словарь, а по тому что хочешь переспорить.

Как человек имеющий опыт разработки на немерле кода с весьма нетривиальной логикой (включая поиск и исправление ошибок в самом компиляторе) могу сказать что отсутствие new и вывод типов ни разу не создали проблем с пониманием того что происходит.
... << RSDN@Home 1.2.0 alpha 4 rev. 1305>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[33]: Linq : неудачный маркетинг?
От: Lloyd Россия  
Дата: 20.02.10 19:54
Оценка:
Здравствуйте, mrTwister, Вы писали:

WH>>Конструктор явно задает тип.


T>Вообще-то там был загадочный Dectionary() и что это конструктор ниоткуда не следует. Можно, конечно, предположить, что это generic-класс "System.Collections.Generic.Dictionary<TKey,TValue>", но куда в этом случае подевались типы-аргументы?


Подозреваю, система вывода типа Nemerle в состоянии вывести тип для этого случая.
Re[34]: Linq : неудачный маркетинг?
От: mrTwister Россия  
Дата: 20.02.10 20:06
Оценка: :)
Здравствуйте, WolfHound, Вы писали:

T>>Вообще-то там был загадочный Dectionary()

WH>Докапывание до опечаток. Как мелко... что совсем сказать нечего?

Это не докапывание до опечаток, поиск ошибок в коде в процессе проведения code-review (который мы сейчас и обсуждаем). Собственно для этого code review и проводят.

WH>Если знать что язык на котором написан этот код прекрасно выводит типы из использования то очевидно куда они делись.


А, ну тогда предлагаю еще поубирать в коде разный мусор и сделать код более совершенным:

def keyToValMap = Dectionary();
...
keyToValMap[Foo()] = Bar();


Теперь враг точно не пройдет!
лэт ми спик фром май харт
Re[34]: Linq : неудачный маркетинг?
От: mrTwister Россия  
Дата: 20.02.10 20:12
Оценка: +1
Здравствуйте, WolfHound, Вы писали:

WH>Как человек имеющий опыт разработки на немерле кода с весьма нетривиальной логикой (включая поиск и исправление ошибок в самом компиляторе) могу сказать что отсутствие new и вывод типов ни разу не создали проблем с пониманием того что происходит.


Это стандартный аргумент. Его регулярно произносят в холиварах любители линукса, виндовса, С++, скриптовых языков, языков со статической и динамической типизацией и прочее.
лэт ми спик фром май харт
Re[35]: Linq : неудачный маркетинг?
От: WolfHound  
Дата: 20.02.10 20:36
Оценка:
Здравствуйте, mrTwister, Вы писали:

T>Это не докапывание до опечаток, поиск ошибок в коде в процессе проведения code-review (который мы сейчас и обсуждаем). Собственно для этого code review и проводят.

Это именно докапывание до опечаток.
Ибо в реальной жизни такие "ошибки" ловит компилятор.

T>А, ну тогда предлагаю еще поубирать в коде разный мусор и сделать код более совершенным:

хъ
T>Теперь враг точно не пройдет!
А какие проблемы?
... << RSDN@Home 1.2.0 alpha 4 rev. 1305>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[35]: Linq : неудачный маркетинг?
От: WolfHound  
Дата: 20.02.10 20:36
Оценка:
Здравствуйте, mrTwister, Вы писали:

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

Нет.
В данном случае я прекрасно знаю и работал с обоими подходими. Как следствие могу сравнивать.
А ты как и те "любители" к которым ты опелируешь только один.
... << RSDN@Home 1.2.0 alpha 4 rev. 1305>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[3]: Жуткий оффтопик
От: IB Австрия http://rsdn.ru
Дата: 20.02.10 21:26
Оценка:
Здравствуйте, Кэр, Вы писали:

Кэр>Иван, а ты еще в Редмонде?

Уже нет, мы сейчас с AVK и Голлумом в джерси, в гостях у IT =)
Мы уже победили, просто это еще не так заметно...
Re[36]: Linq : неудачный маркетинг?
От: mrTwister Россия  
Дата: 20.02.10 21:26
Оценка:
Здравствуйте, WolfHound, Вы писали:

T>>Теперь враг точно не пройдет!

WH>А какие проблемы?

var size = keyToValMap["size"];
if(CheckSomething(size))
{
    size *= 2;
}
var buffer = new byte[size];
лэт ми спик фром май харт
Re[36]: Linq : неудачный маркетинг?
От: mrTwister Россия  
Дата: 20.02.10 21:27
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>В данном случае я прекрасно знаю и работал с обоими подходими.

Это ещё один стандартный аргумент в холиварах.
лэт ми спик фром май харт
Re[37]: Linq : неудачный маркетинг?
От: WolfHound  
Дата: 20.02.10 21:34
Оценка:
Здравствуйте, mrTwister, Вы писали:

T>>>Теперь враг точно не пройдет!

WH>>А какие проблемы?
T>
T>var size = keyToValMap["size"];
T>if(CheckSomething(size))
T>{
T>    size *= 2;
T>}
T>var buffer = new byte[size]; 
T>

А где проблемы то?
... << RSDN@Home 1.2.0 alpha 4 rev. 1305>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[37]: Linq : неудачный маркетинг?
От: WolfHound  
Дата: 20.02.10 21:34
Оценка:
Здравствуйте, mrTwister, Вы писали:

WH>>В данном случае я прекрасно знаю и работал с обоими подходими.

T>Это ещё один стандартный аргумент в холиварах.
Ты конечно можешь и дальше отвергать факты этой фразой но факты от этого не перестанут быть фактами ...
... << RSDN@Home 1.2.0 alpha 4 rev. 1305>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[38]: Linq : неудачный маркетинг?
От: mrTwister Россия  
Дата: 20.02.10 21:38
Оценка:
Здравствуйте, WolfHound, Вы писали:


T>>>>Теперь враг точно не пройдет!

WH>>>А какие проблемы?
T>>
T>>var size = keyToValMap["size"];
T>>if(CheckSomething(size))
T>>{
T>>    size *= 2;
T>>}
T>>var buffer = new byte[size]; 
T>>

WH>А где проблемы то?

Вот, ты проблем не видишь. А если мы запишем туже программу так, то увидишь?

byte size = keyToValMap["size"];
if(CheckSomething(size))
{
    size *= 2;
}
var buffer = new byte[size];
лэт ми спик фром май харт
Re[38]: Linq : неудачный маркетинг?
От: mrTwister Россия  
Дата: 20.02.10 21:40
Оценка: +1
Здравствуйте, WolfHound, Вы писали:

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


WH>>>В данном случае я прекрасно знаю и работал с обоими подходими.

T>>Это ещё один стандартный аргумент в холиварах.
WH>Ты конечно можешь и дальше отвергать факты этой фразой но факты от этого не перестанут быть фактами ...

Факт заключается в том, что это твое личное мнение (что обсуждаемый синтаксис тебе не мешает). Дак вот, факт наличия у тебя такого личного мнения я не отрицаю.
лэт ми спик фром май харт
Re[39]: Linq : неудачный маркетинг?
От: WolfHound  
Дата: 20.02.10 21:49
Оценка:
Здравствуйте, mrTwister, Вы писали:

T>Вот, ты проблем не видишь. А если мы запишем туже программу так, то увидишь?

        def keyToValMap = SCG.Dictionary();
        keyToValMap["asd"] = 1 : byte;//говорим компилятору что 1 у нас имеет тип byte.
        def size = keyToValMap["asd"];
        def arr = array(size); // expected int, got byte- in value reference: System.Byte is not a subtype of System.Int32 [simple require]

Я ее и без указания типов увижу...
Я же говорю ты не работал с языками в которых вывод типов есть.
... << RSDN@Home 1.2.0 alpha 4 rev. 1305>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[40]: Linq : неудачный маркетинг?
От: mrTwister Россия  
Дата: 20.02.10 22:09
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>Я ее и без указания типов увижу...

WH>Я же говорю ты не работал с языками в которых вывод типов есть.
Offtop: неужели в Nemerle размер массива можно указывать только в Int32? В любом случае, к выводу типов это не имеет никакого отношения.

Но тем неменее, если вернуться с небес на землю (в смысле к C#), то вышеуказанный пример наглядно демонстрирует, как использование var помешало сделать ошибку очевидной.
лэт ми спик фром май харт
Re[4]: Жуткий оффтопик
От: Кэр  
Дата: 21.02.10 00:18
Оценка:
Здравствуйте, IB, Вы писали:

IB>Здравствуйте, Кэр, Вы писали:


Кэр>>Иван, а ты еще в Редмонде?

IB>Уже нет, мы сейчас с AVK и Голлумом в джерси, в гостях у IT =)

Ых Ну ладно — стучитесь в следующий раз если что
Re[41]: Linq : неудачный маркетинг?
От: samius Япония http://sams-tricks.blogspot.com
Дата: 21.02.10 07:17
Оценка:
Здравствуйте, mrTwister, Вы писали:

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


WH>>Я ее и без указания типов увижу...

WH>>Я же говорю ты не работал с языками в которых вывод типов есть.
T>Offtop: неужели в Nemerle размер массива можно указывать только в Int32? В любом случае, к выводу типов это не имеет никакого отношения.

T>Но тем неменее, если вернуться с небес на землю (в смысле к C#), то вышеуказанный пример наглядно демонстрирует, как использование var помешало сделать ошибку очевидной.


Если сравнивать C# с языками с более мощным выводом типов, то оказывается что проблема не в var, а в неявном приведении типов в C#.
Re[14]: Linq : неудачный маркетинг?
От: igna Россия  
Дата: 21.02.10 07:27
Оценка: -1
Здравствуйте, AndrewVK, Вы писали:

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


Ну что это за аргумент? Почему он относится к локальным переменным и не относится к параметрам?

AVK>Это обеспечивает максимальную гибкость и надежность кода. Есть, ЕМНИП, довольно строгое доказательство сего на основе LSP.


А вдруг все же ТИП? Ссылку давай.

AVK>А теперь встречный вопрос — а зачем обобщать тип локальной переменной?


Затем же, зачем обобщают тип параметра. Различие только количественное.
Re[26]: Linq : неудачный маркетинг?
От: igna Россия  
Дата: 21.02.10 07:31
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>Конечно FileStream. ... Компилятор только параметры генерика вывел.


Никакой "конечности" тут нет, компилятор точно также мог вывести наиболее общий достаточный тип.
Re[42]: Linq : неудачный маркетинг?
От: igna Россия  
Дата: 21.02.10 07:39
Оценка:
Здравствуйте, samius, Вы писали:

S>Если сравнивать C# с языками с более мощным выводом типов, то оказывается что проблема не в var, а в неявном приведении типов в C#.


То есть хотя и не использование вывода типов вообще, но все же использование вывода типов в C# может привести к проблемам?
Re[27]: Linq : неудачный маркетинг?
От: samius Япония http://sams-tricks.blogspot.com
Дата: 21.02.10 08:01
Оценка:
Здравствуйте, igna, Вы писали:

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


WH>>Конечно FileStream. ... Компилятор только параметры генерика вывел.


I>Никакой "конечности" тут нет, компилятор точно также мог вывести наиболее общий достаточный тип.


Зачем может понадобится компилятору мухлевать с явно указанным типом локальной переменной?
Re[43]: Linq : неудачный маркетинг?
От: samius Япония http://sams-tricks.blogspot.com
Дата: 21.02.10 08:21
Оценка: 5 (2) +2
Здравствуйте, igna, Вы писали:

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


S>>Если сравнивать C# с языками с более мощным выводом типов, то оказывается что проблема не в var, а в неявном приведении типов в C#.


I>То есть хотя и не использование вывода типов вообще, но все же использование вывода типов в C# может привести к проблемам?


Да, я считаю что именно неявное преобразование типов в C# делает вывод типов в нем менее предсказуемым чем в Nemerle и F#.

Выше был приведен пример когда переполненный byte мог уйти в длину массива. Но шутка может быть еще хуже:

var size = keyToValMap["size"];
var sizeDiv2 = size / 2;
Console.WriteLine(Math.Sqrt(sizeDiv2));

Смотря на этот код без подсказок среды мы не можем предсказать, какой тип хранится в size. Мы его можем поделить на 2 (а хрен знает, это целая 2 или с плавающей точкой) и можем подать в метод, который принимает double.

Языки без неявного приведения типов не стерпят это безобразие. Потому — да, в C#-е вывод типов проблемнее.
Re[28]: Linq : неудачный маркетинг?
От: igna Россия  
Дата: 21.02.10 09:03
Оценка: +1
Здравствуйте, samius, Вы писали:

S>Зачем может понадобится компилятору мухлевать с явно указанным типом локальной переменной?


Затем чтобы IDE показывало тип Stream читающему программу и последнему было бы без просмотра дальнейшего кода ясно, что методы специфичные для FileStream не используются.
Re[7]: Linq : неудачный маркетинг?
От: Mystic Украина http://mystic2000.newmail.ru
Дата: 21.02.10 10:15
Оценка:
Здравствуйте, 0x7be, Вы писали:

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


M>>Оптимизация связанная с многопоточностью, обычно либо уровнем выше (например, пул потоков на сервере), либо на уровне качественного изменения алгоритмов, кеширования и т. п. Для качественной оптимизации, данных, которые получает LINQ, может и не хватить. Ну и в таком случае я предпочитаю критические участки писать на чистом С, где все под контролем.

0>Не соглашусь. Пулы потоков, всякие "Task manager`ы", "Scheduler`ы" и прочие "тяжеловесные" решения, организующие параллельные вычисления, достаточно неуклюжи. Они хороши для организации архитектуры прогаммы, сервера, там, какого-нибудь, но неудобны при написании вычислительных алгоритмов. Очень хочется чего-то более простого и органичного.

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

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



0>Идея переписать на "чистом С" критические участки мне тоже не нравится. При таком раскладе придется самому "с нуля" писать инфраструктуру для распараллеливания, что, по-сути, есть велосипед. К тому же хочется максимально отделить спецификацию алгоритма от тонкостей реализации параллелизма, что бы можно было заменять инфраструктуру параллелизма без переписывания вычислительного кода.


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

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

0>Вообще-то странно, я всегда думал, что поддерживаемость программы прямо пропорциональна высоте абстракций, на которых она построена. При условии, конечно, что абстракции выбраны правильно

Вот большая проблема как раз в правильном выборе. Возникают "дыры", с которыми потом усиленно борешься.
Re[7]: Linq : неудачный маркетинг?
От: Mystic Украина http://mystic2000.newmail.ru
Дата: 21.02.10 10:17
Оценка:
Здравствуйте, AndrewVK, Вы писали:

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


M>>Ну и в таком случае я предпочитаю критические участки писать на чистом С, где все под контролем.


AVK>Упомянутый уже здесь Эрик Мейер, когда рассказывал про некоторые применения Rx, говорил, что он недостаточно умен, чтобы написать аналогичное без линка. И я ему почму то верю.


Так тут все просто: не будет хватать моего ума, будут возникать проблемы, буду смотреть в сторону того, как их решать. А если проблем нет и пока не предвидится?
Re[29]: Linq : неудачный маркетинг?
От: samius Япония http://sams-tricks.blogspot.com
Дата: 21.02.10 17:18
Оценка:
Здравствуйте, igna, Вы писали:

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


S>>Зачем может понадобится компилятору мухлевать с явно указанным типом локальной переменной?


I>Затем чтобы IDE показывало тип Stream читающему программу и последнему было бы без просмотра дальнейшего кода ясно, что методы специфичные для FileStream не используются.


И что это даст читающему программу в отношени локальной переменной?
Re[8]: Linq : неудачный маркетинг?
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 21.02.10 17:35
Оценка:
Здравствуйте, Mystic, Вы писали:

M>Так тут все просто: не будет хватать моего ума, будут возникать проблемы, буду смотреть в сторону того, как их решать. А если проблем нет и пока не предвидится?


Если проблем нет, то, с большой вероятностью, это означает что ты их пока не видишь
... << RSDN@Home 1.2.0 alpha 4 rev. 1458 on Windows 7 6.1.7600.0>>
AVK Blog
Re[30]: Linq : неудачный маркетинг?
От: igna Россия  
Дата: 21.02.10 20:58
Оценка:
Здравствуйте, samius, Вы писали:

S>И что это даст читающему программу в отношени локальной переменной?


Отсутствие необходимости просматривать дальнейший код, чтобы убедиться в том, что методы специфичные для FileStream не используются.

Каков вопрос, таков и ответ.
Re[31]: Linq : неудачный маркетинг?
От: samius Япония http://sams-tricks.blogspot.com
Дата: 21.02.10 21:07
Оценка:
Здравствуйте, igna, Вы писали:

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


S>>И что это даст читающему программу в отношени локальной переменной?


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


И что же даст знание о том что специфичные методы не используются для локальной переменной?
Re[34]: Linq : неудачный маркетинг?
От: Lloyd Россия  
Дата: 21.02.10 22:04
Оценка:
Здравствуйте, olegkr, Вы писали:

IT>>>Кто именно воспользуется?

L>>Любой твой коллега или ты сам.

O>Страшно жить, когда от коллег и себя защищаться приходится.


Правильно, тормоза придумали трусы.
Re: вопрос к специалистам
От: Pavel Dvorkin Россия  
Дата: 22.02.10 03:04
Оценка: 1 (1)
Здравствуйте, 0x7be, Вы писали:

Почитал этот тред и все нелестные высказывания в адрес тех, кто LinQ как следует не знает, а делает выводы.
Я его тоже не знаю, и, чтобы не получить в свой адрес нелестные высказывания, выводы делать не буду.

У меня вопрос к тем, кто считает, что он LinQ знает.

Сформулируйте, когда LinQ стоит применять и когда его применение нецелесообразно.
With best regards
Pavel Dvorkin
Re[32]: Linq : неудачный маркетинг?
От: igna Россия  
Дата: 22.02.10 07:36
Оценка:
Здравствуйте, samius, Вы писали:

S>И что же даст знание о том что специфичные методы не используются для локальной переменной?


Например понимание того, что можно заменить FileStream на какой-либо другой Stream без модификации дальнейшего кода.
Re[33]: Linq : неудачный маркетинг?
От: samius Япония http://sams-tricks.blogspot.com
Дата: 22.02.10 08:34
Оценка: +2 -1 :)
Здравствуйте, igna, Вы писали:

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


S>>И что же даст знание о том что специфичные методы не используются для локальной переменной?


I>Например понимание того, что можно заменить FileStream на какой-либо другой Stream без модификации дальнейшего кода.


Если нужно такое понимание, то следует сделать Extract Method с параметром типа Stream.
Re[9]: Linq : неудачный маркетинг?
От: Mystic Украина http://mystic2000.newmail.ru
Дата: 22.02.10 08:38
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Если проблем нет, то, с большой вероятностью, это означает что ты их пока не видишь


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

Конечно, на кое-что закладываешь еще в самом начале, не надо понимать все утрировано
Re[2]: вопрос к специалистам
От: Dufrenite Дания  
Дата: 22.02.10 08:42
Оценка: 5 (2) +1
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Сформулируйте, когда LinQ стоит применять и когда его применение нецелесообразно.


Linq to XML — стоит применять почти всегда, так как это, на мой взгляд, наиболее удобная объектная модель для работы с XML.

Linq to objects — применять в тех случаях, когда улучшается читаемость кода, то есть в подавляющем большинстве. Противопоказания такие же как и при применении цикла foreach — если надо выжимать такты, то не использовать.

Linq to SQL — ничего сказать не могу, так как не работаю постоянно с БД.
Re[2]: вопрос к специалистам
От: samius Япония http://sams-tricks.blogspot.com
Дата: 22.02.10 09:08
Оценка: 19 (2)
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Сформулируйте, когда LinQ стоит применять и когда его применение нецелесообразно.


Во-первых, следует уточнить о котором из LINQ-ов речь. Ответить за целесообразность применения всех провайдеров зараз нельзя.

Отвечу за LINQ 2 Objects.
Вообще это высокоурвневый инструмент и к нему применимы обычные соображения применения высокоуровневых инструментов. Т.е. каждый решает за себя в контексте целей. Например, проверка числа на простоту средствами LINQ-а будет весьма наглядна и декларативна, но это будет не лучшее решение в аспекте производительности. Применять ли в данном случае LINQ — следует решать исходя из целей. Если стоит цель написать легкоподдерживаемый и наглядный код, то да, LINQ целесообразен. Если стоит цель выжать производительность до такта, то ответ — нет.

(по поводу целесообразности можно провести аналогию с другим высокоуровневым инструментом — двоичной сериализацией. Да, сериализация действительно медленная и не такая компактная как хотелось бы и иногда имеет смысл от нее отказываться, но .NET Remoting без нее бы не состоялся, либо был бы сплошным геморроем. Без сериализации целый класс приложений был бы значительно более трудоемким в разработке)
Re[2]: вопрос к специалистам
От: 0x7be СССР  
Дата: 22.02.10 09:41
Оценка: -1
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Сформулируйте, когда LinQ стоит применять и когда его применение нецелесообразно.

По поводу Linq to XML и Linq to objects предыдущие ораторы очень хорошо сказали, мне добавить нечего.
Что касается Linq to Sql — мой опыт общения с ним говорит, что его можно применять в небольших приложениях.
При этом ни в коем случае не внедрять бизнес-логику в сгенерированные классы через механизм частичных классов, хотя так кое-где советуют.
Re[3]: вопрос к специалистам
От: Pavel Dvorkin Россия  
Дата: 22.02.10 10:05
Оценка:
Здравствуйте, samius, Вы писали:

S>Вообще это высокоурвневый инструмент и к нему применимы обычные соображения применения высокоуровневых инструментов. Т.е. каждый решает за себя в контексте целей. Например, проверка числа на простоту средствами LINQ-а будет весьма наглядна и декларативна, но это будет не лучшее решение в аспекте производительности. Применять ли в данном случае LINQ — следует решать исходя из целей. Если стоит цель написать легкоподдерживаемый и наглядный код, то да, LINQ целесообразен. Если стоит цель выжать производительность до такта, то ответ — нет.


Переформулирую вопрос немного иначе. К каким структурам данных его стоит применять ? У меня некоторое ощущение (можеТ , я не прав), что он "ложится" на "линейные контейнеры" (термин очень неточный, я имею в виду нечто такое, что более или менее линейно перечислимо, и дело даже не в том, что перечислимо, а в том, что это перечисление именно то, что нужно в этой задаче). А вот насколько он применим к нелинейным конструкциям ? Например, алгоритмы работы с деревьями, графами ?
With best regards
Pavel Dvorkin
Re[34]: Linq : неудачный маркетинг?
От: igna Россия  
Дата: 22.02.10 10:19
Оценка:
Здравствуйте, samius, Вы писали:

S>Если нужно такое понимание, то следует сделать Extract Method с параметром типа Stream.


Понимание того, что делаешь, нужно всегда, а выделять метод на каждое открытие файла, при последующем использовании которого не используются специфические для FileStream методы — overkill. Или ты имеешь ввиду один универсальный CreateFileStreamAsStream?

Кроме того внутри вновь созданного метода получим ту же ситуацию, что имели: чтобы узнать, что при использовании созданного FileStream используются только методы Stream, нужно будет просмотреть код. Так зачем тогда?
Re[25]: Linq : неудачный маркетинг?
От: Wolverrum Ниоткуда  
Дата: 22.02.10 10:20
Оценка:
Здравствуйте, igna, Вы писали:

[... cut ...]

Тут еще точно linq обсуждается?
Re[8]: Linq : неудачный маркетинг?
От: 0x7be СССР  
Дата: 22.02.10 10:20
Оценка:
Здравствуйте, Mystic, Вы писали:

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

А что делать сессии, если у нее алгоритм обработки запроса частично последовательный, а частично параллельный?
Самой обращаться к пулу потоков и ручками в этих потоках запускать свои куски?

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

Запустить несколько генераторов в отдельных потоках, отрезав каждому по ломтику задачи?

M>Вообще, потребность в оптимизации вычислительных алгоритмов возникает не часто. И первый шаг в такой оптимиации происходит на алгоритмическом уровне: вместо того, чтобы выполнять циклы быстро и параллельно, мы избавляемся от циклов, строим заранее таблицы для часто повторяющихс вычислений и т. д. и т. п.


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


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

M>Вот большая проблема как раз в правильном выборе. Возникают "дыры", с которыми потом усиленно борешься.

Это скорее к вопросу о том, как правильно проектировать программу. Нельзя отказываться абстрагирования только потому, что это при неправильном применении заводит в тупик.
Re[4]: вопрос к специалистам
От: samius Япония http://sams-tricks.blogspot.com
Дата: 22.02.10 10:25
Оценка: 1 (1) +1
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Переформулирую вопрос немного иначе. К каким структурам данных его стоит применять ? У меня некоторое ощущение (можеТ , я не прав), что он "ложится" на "линейные контейнеры" (термин очень неточный, я имею в виду нечто такое, что более или менее линейно перечислимо, и дело даже не в том, что перечислимо, а в том, что это перечисление именно то, что нужно в этой задаче). А вот насколько он применим к нелинейным конструкциям ? Например, алгоритмы работы с деревьями, графами ?


Применим. Причем применим не только к структурам данных аки списки деревья и графы. Он применим к асинхронным вычислениям, к реактивным вычислениям, к синтаксическому разбору и т.п.
Re[5]: вопрос к специалистам
От: 0x7be СССР  
Дата: 22.02.10 10:28
Оценка:
Здравствуйте, samius, Вы писали:

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

Кстати, о синтаксическом разборе. Есть такие примеры?
Re[35]: Linq : неудачный маркетинг?
От: samius Япония http://sams-tricks.blogspot.com
Дата: 22.02.10 10:33
Оценка:
Здравствуйте, igna, Вы писали:

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


S>>Если нужно такое понимание, то следует сделать Extract Method с параметром типа Stream.


I>Понимание того, что делаешь, нужно всегда, а выделять метод на каждое открытие файла, при последующем использовании которого не используются специфические для FileStream методы — overkill. Или ты имеешь ввиду один универсальный CreateFileStreamAsStream?


Повышение абстракции помогает тестированию, например. Когда я пишу метод чтения либо записи чего-то в файл/из файла, я сразу думаю, а как я его буду тестировать. Работать с MemoryStream-ом в тестах удобнее, чем с файлами, потому я для начала создам метод, работающий с абстракцией стрима, потом сделаю метод, создающий файл-стрим и делегирующий более абстрактному методу, который работает со стримом.

I>Кроме того внутри вновь созданного метода получим ту же ситуацию, что имели: чтобы узнать, что при использовании созданного FileStream используются только методы Stream, нужно будет просмотреть код. Так зачем тогда?


Можно будет посмотреть только на сигнатуру метода и убедиться что внутри нет даункаста.
Re[5]: вопрос к специалистам
От: Pavel Dvorkin Россия  
Дата: 22.02.10 10:37
Оценка:
Здравствуйте, samius, Вы писали:

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


Можно пример функции, скажем, нахождения минимального элемента в двоичном дереве ? Или классическую SearchAndInsert в несбалансированном двоичном дереве поиска ?
With best regards
Pavel Dvorkin
Re[6]: вопрос к специалистам
От: samius Япония http://sams-tricks.blogspot.com
Дата: 22.02.10 11:19
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

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


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


PD>Можно пример функции, скажем, нахождения минимального элемента в двоичном дереве ?

Можно пойти двумя путями: сведение пути по дереву к последовательности и применения стандартных методов для IEnumerable<T>, либо написание своей обвязки для типа Node<T>.

Вот первый вариант:

    class Node<T>
    {
        public T Value { get; set; }
        public Node<T> Left { get; set; }
        public Node<T> Right { get; set; }
    }

    class Program
    {
        static IEnumerable<T> Walk<T>(T root, Func<T, IEnumerable<T>> next)
        {
            yield return root;

            var q = from node in next(root)
                    from n in Walk(node, next)
                    select n;
            foreach (var node in q)
            {
                yield return node;
            }
        }
        static void Main()
        {
            Node<int> root = new Node<int>
                             {
                                 Value = 3,
                                 Left = new Node<int> 
                                 { 
                                     Value = 2,
                                     Left = new Node<int> { Value = 1 }
                                 },
                                 Right = new Node<int> { Value = 4 }
                             };

            var minNode = Walk(
                root, 
                n => n.Left != null? new[] {n.Left} : new Node<int>[]{})
                .Last();
            Console.WriteLine(minNode.Value);
        }
    }

Метод Walk может показаться громоздким для решения этой задачи, но вообще у него офигительный реюз, он сгодится не только здесь, а например и для выпрямления в последовательность дерева каталогов и вообще деревьев. Вообще не понимаю, почему нет аналога в Enumerable.

Второй способ опущу.

PD>Или классическую SearchAndInsert в несбалансированном двоичном дереве поиска ?

Insert — это не запрос. Здесь нужно либо модификация существующего дерева, либо построение нового дерева. LINQ тут не совсем по назначению, хоть и присобачить его можно.
Re[6]: вопрос к специалистам
От: samius Япония http://sams-tricks.blogspot.com
Дата: 22.02.10 11:23
Оценка: 12 (1)
Здравствуйте, 0x7be, Вы писали:

0>Кстати, о синтаксическом разборе. Есть такие примеры?


http://www.gotdotnet.ru/blogs/bezzus/1215/
Re[7]: вопрос к специалистам
От: Pavel Dvorkin Россия  
Дата: 22.02.10 11:46
Оценка:
Здравствуйте, samius, Вы писали:

PD>>Можно пример функции, скажем, нахождения минимального элемента в двоичном дереве ?

S>Можно пойти двумя путями: сведение пути по дереву к последовательности и применения стандартных методов для IEnumerable<T>, либо написание своей обвязки для типа Node<T>.

S>Вот первый вариант:




S> foreach (var node in q)

S> {
S> yield return node;
S> }

Может, я не так понимаю, но ИМХО ты здесь еще один контейнер создал, q. Пусть временный, но создал.


S> var minNode = Walk(

S> root,
S> n => n.Left != null? new[] {n.Left} : new Node<int>[]{})
S> .Last();

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

S>Метод Walk может показаться громоздким для решения этой задачи, но вообще у него офигительный реюз, он сгодится не только здесь, а например и для выпрямления в последовательность дерева каталогов и вообще деревьев. Вообще не понимаю, почему нет аналога в Enumerable.


Я не спорю, но ты решил иную задачу Реюз-то реюз, но... как бы объяснить без ссылок на производительность. Попробую так. Вот есть алгоритмы сортировки. И все договорились — отсортировать надо исходный массив без дополнительной памяти O(N). Иными словами, решения с еще одним массивом не рассматриваются. А для обхода деревьев не рассматриваются алгоритмы, которые копируют элементы деревьев — куда бы то ни было.

Такое можно ?

S>Insert — это не запрос. Здесь нужно либо модификация существующего дерева, либо построение нового дерева.


Зачем же новое ? Но это к слову.
А вот что не к слову — здесь не чистый запрос, да.
Но вначале чистый запрос — есть ли элемент. Если не SearchAndInsert, а просто Search — это уж точно запрос. И если ты собираешься его реализовать чем-то вроде выкладывания как в прошлом примере и поиском там — извини, но что это за алгоритм поиска в двоичном дереве, который требует его выкладывания в последовательность ? На кой мне черт такое дерево ? Мне log(N) подайте и без копирования!
А во вторых, тут очень показательный момент. Без Linq SearchAndInsert отличается от Search 2 строчками (либо return nul, либо return new node(...)) А так получится, что допустим, предполагал я , что вставки не понадобятся, написал на LinQ, а они потом понадобились, и что теперь ?
With best regards
Pavel Dvorkin
Re[8]: вопрос к специалистам
От: Dufrenite Дания  
Дата: 22.02.10 11:53
Оценка: +2
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Может, я не так понимаю, но ИМХО ты здесь еще один контейнер создал, q. Пусть временный, но создал.


Здесь q, это запрос, а не контейнер.

Все остальные рассуждения на изначально неверном предположении.
Re[9]: вопрос к специалистам
От: Pavel Dvorkin Россия  
Дата: 22.02.10 12:07
Оценка:
Здравствуйте, Dufrenite, Вы писали:

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


Допустим, я не прав, но ... какая-то еще структура создается в памяти или или нет ? Запросом, контейнером, чертом лысым — но да или нет ? Потому что я не понимаю, как можно Last делать в дереве — ну нет там Last. А сами элементы копируются или нет ? Если нет — то как это все же работает ? Лежат они как попало в памяти, а тут вдруг оказались выложенными в линию. Одно из двух — либо в памяти создан контейнер со ссылками на них, либо их скопировали в другой контейнер и там они подряд лежат.

Не согласен ? Тогда объясни, что там под спудом. Что там делается, какие данные и куда создаются или копируются.
With best regards
Pavel Dvorkin
Re[36]: Linq : неудачный маркетинг?
От: igna Россия  
Дата: 22.02.10 12:15
Оценка:
Здравствуйте, samius, Вы писали:

I>>Кроме того внутри вновь созданного метода получим ту же ситуацию, что имели: чтобы узнать, что при использовании созданного FileStream используются только методы Stream, нужно будет просмотреть код. Так зачем тогда?


S>Можно будет посмотреть только на сигнатуру метода и убедиться что внутри нет даункаста.


"Внутри вновь созданного метода" у тебя переменная и так будет типа FileStream, какой даункаст?
Re[10]: вопрос к специалистам
От: Dufrenite Дания  
Дата: 22.02.10 12:33
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Допустим, я не прав, но ... какая-то еще структура создается в памяти или или нет ? Запросом, контейнером, чертом лысым — но да или нет ?


Создается, безусловно. Что создается конкретно можно увидеть декомпилировав код.

PD>Потому что я не понимаю, как можно Last делать в дереве — ну нет там Last.


Last, это extension-метод IEnumerable<T> — результата запроса.

PD>А сами элементы копируются или нет ?


Только как возвращаемое значение свойства IEnumerator<T>.Current.

PD>Если нет — то как это все же работает ? Лежат они как попало в памяти, а тут вдруг оказались выложенными в линию. Одно из двух — либо в памяти создан контейнер со ссылками на них, либо их скопировали в другой контейнер и там они подряд лежат.


PD>Не согласен ? Тогда объясни, что там под спудом. Что там делается, какие данные и куда создаются или копируются.


Там все намного проще. Надеюсь с концепцией итераторов знакомы? Так вот енумератор, это такой продвинутый, генерируемый компилятором (или написанный вручную) итератор.
В данном случае q, это фактически объект, реализующий интерфейс IEnumerable<T>, в котором есть метод, возвращающий итератор.
Re[11]: вопрос к специалистам
От: Pavel Dvorkin Россия  
Дата: 22.02.10 12:48
Оценка:
Здравствуйте, Dufrenite, Вы писали:

D>Создается, безусловно. Что создается конкретно можно увидеть декомпилировав код.


Так я и жду от знающих LinQ объяснения, что именно там создается.


PD>>Потому что я не понимаю, как можно Last делать в дереве — ну нет там Last.


D>Last, это extension-метод IEnumerable<T> — результата запроса.


Все это замечательно, но вопрос совсем не в этом.

PD>>А сами элементы копируются или нет ?


D>Только как возвращаемое значение свойства IEnumerator<T>.Current.


И не в этом.

PD>>Если нет — то как это все же работает ? Лежат они как попало в памяти, а тут вдруг оказались выложенными в линию. Одно из двух — либо в памяти создан контейнер со ссылками на них, либо их скопировали в другой контейнер и там они подряд лежат.


PD>>Не согласен ? Тогда объясни, что там под спудом. Что там делается, какие данные и куда создаются или копируются.


D>Там все намного проще. Надеюсь с концепцией итераторов знакомы? Так вот енумератор, это такой продвинутый, генерируемый компилятором (или написанный вручную) итератор.


Замечательно. Давай отвлечемся от итераторов, энумераторов и т.д. Не надо мне объяснять, что это такое. Меня другое интересует.

Есть дерево. У него есть узлы. В узлах есть поле данных. Узлы лежат в куче в произвольном порядке. Поля ссылок узлов показывают на другие узлы (или равны nul)

Что там LinQ делает, какие там запросы и т.д. — об этом я сейчас не спрашиваю.

Мой вопрос достаточно четкий.

В алгоритме, представленнос samius, какие и в каком объеме промежуточные данные создаются в куче ? Хоть в результате создания контейнера, хоть в результате исполнения запроса, хоть итератором, хоть трансформатором ? Какие и в каком объеме ?

Или по крайней мере оцени их порядок. Сколько их — O(N), O(log(N), O(1) ?

Вот и все. Если можешь ответить — жду.
With best regards
Pavel Dvorkin
Re[12]: вопрос к специалистам
От: Lloyd Россия  
Дата: 22.02.10 13:06
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Мой вопрос достаточно четкий.


PD>В алгоритме, представленнос samius, какие и в каком объеме промежуточные данные создаются в куче ? Хоть в результате создания контейнера, хоть в результате исполнения запроса, хоть итератором, хоть трансформатором ? Какие и в каком объеме ?


Никаких промежуточных данных не создается, в том-то и фан. Linq-запросы — это по сути способ комбинирования энумераторов.
Re[13]: вопрос к специалистам
От: Pavel Dvorkin Россия  
Дата: 22.02.10 13:16
Оценка:
Здравствуйте, Lloyd, Вы писали:

L>Никаких промежуточных данных не создается, в том-то и фан. Linq-запросы — это по сути способ комбинирования энумераторов.


Ладно, пусть. Но вот сказано — Last. Что там реально делается, когда выполняется этот Last ? Ведь нельзя же в дереве выполнить Last физически, потому что нет в дереве информации, позволяющей пройти его таким способом. Да и Last нет вообще.
Список можно и массив можно. Сделал энумератор , а он внутри себя имеет способ перехода к следующемму элементу (t=t.next или i++), а дерево нельзя и граф нельзя. Чудес-то не бывает.

Если не согласен — тогда объясни, как это делается. Ну вот есть запрос, или комбинация энумераторов, или что хочешь. Что там в конечном счете делается в этом дереве, как этот минимальный элемент находится ? Бог с ним, с линком, но какие действия там процессор выполняет ? Он же линк выполнять не может!

И еще вопрос, если можешь ответить. Императивный алгоритм обхода дерева, естественно, O(N) и однопроходной. Здесь что ?
With best regards
Pavel Dvorkin
Re[12]: вопрос к специалистам
От: Dufrenite Дания  
Дата: 22.02.10 13:18
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Или по крайней мере оцени их порядок. Сколько их — O(N), O(log(N), O(1) ?

PD>Вот и все. Если можешь ответить — жду.

Очевидно, O(log(N)).
По лишним веткам не ходим.
Re[14]: вопрос к специалистам
От: Dufrenite Дания  
Дата: 22.02.10 13:22
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Список можно и массив можно. Сделал энумератор , а он внутри себя имеет способ перехода к следующемму элементу (t=t.next или i++), а дерево нельзя и граф нельзя. Чудес-то не бывает.


Это не чудеса. И даже не новое изобретение. Поинтересуйтесь на досуге, как работает итератор std::map.
Re[13]: возвращаю задачу специалистам обратно
От: Pavel Dvorkin Россия  
Дата: 22.02.10 13:25
Оценка:
Здравствуйте, Dufrenite, Вы писали:

D>Очевидно, O(log(N)).

D>По лишним веткам не ходим.

А, черт! Понял.

Видимо, samius решил , что я прошу алгоритм поиска минимального элемента в двоичном дереве поиска. Там действительно проще, и намного — есть путь, его можно в виде набора итераторов представить. А я имел в виду произвольное двоичное дерево, то есть полный разветвляющийся обход. В нем лучше O(N) не может быть никак.
Да, должен был я на этом акцентировать внимание. То-то я удивился с этим его Left, но списал на свое незнание LinQ Но вина моя небольшая — я же не написал, что это дерево поиска, так что и оснований предполагать не было.


Жду от специалистов решения задачи — заново.
With best regards
Pavel Dvorkin
Re[15]: вопрос к специалистам
От: Pavel Dvorkin Россия  
Дата: 22.02.10 13:48
Оценка:
Здравствуйте, Dufrenite, Вы писали:


D>Это не чудеса. И даже не новое изобретение. Поинтересуйтесь на досуге, как работает итератор std::map.


Поинтересовался. Честно говоря, до сих пор лишь предполагал, как он устроен.

Начнем с этого

iterator operator++(int)
{ // postincrement
iterator _Tmp = *this;
++*this;
return (_Tmp);
}

Далее через промежуточные методы (опущены) придем к

void _Inc()
{ // move to node with next larger value


Внутри него есть

while (!_Isnil(_Pnode = _Parent(_Ptr))
&& _Ptr == _Right(_Pnode))
_Ptr = _Pnode; // ==> parent while right subtree

В общем, все как обычно. Для map это вполне нормально — реализация на базе дерева, как еще возьмешь ключи.

Но я-то имел в виду не дерево поиска. Собственно говоря, меня интересует, как реализуется разветвляющийся алгоритм.
With best regards
Pavel Dvorkin
Re[14]: вопрос к специалистам
От: Lloyd Россия  
Дата: 22.02.10 14:15
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

L>>Никаких промежуточных данных не создается, в том-то и фан. Linq-запросы — это по сути способ комбинирования энумераторов.


PD>Ладно, пусть. Но вот сказано — Last. Что там реально делается, когда выполняется этот Last ? Ведь нельзя же в дереве выполнить Last физически, потому что нет в дереве информации, позволяющей пройти его таким способом. Да и Last нет вообще.

PD>Список можно и массив можно. Сделал энумератор , а он внутри себя имеет способ перехода к следующемму элементу (t=t.next или i++), а дерево нельзя и граф нельзя. Чудес-то не бывает.

Бывают разные варианты обхода дерева. Который реализуешь, так и будет обходиться.

PD>Если не согласен — тогда объясни, как это делается. Ну вот есть запрос, или комбинация энумераторов, или что хочешь. Что там в конечном счете делается в этом дереве, как этот минимальный элемент находится ? Бог с ним, с линком, но какие действия там процессор выполняет ? Он же линк выполнять не может!


Ты концепцию итератора понимаешь? Значит и как линк работает понимаешь.

PD>И еще вопрос, если можешь ответить. Императивный алгоритм обхода дерева, естественно, O(N) и однопроходной. Здесь что ?


Ровно то же самое.
Re[14]: возвращаю задачу специалистам обратно
От: Dufrenite Дания  
Дата: 22.02.10 14:25
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Жду от специалистов решения задачи — заново.


Эта задача совсем тривиальна:

        class Node
        {
            public int Value;
            public Node Right;
            public Node Left;
        }

        static IEnumerable<int> Values(Node root)
        {
            if (!ReferenceEquals(root, null))
            {
                yield return root.Value;
                var childValues = Values(root.Left).Concat(Values(root.Right));
                foreach (var value in childValues)
                {
                    yield return value;
                }
            }
        }

        static int Min(Node root)
        {
            return Values(root).Aggregate(int.MaxValue, (min, value) => value < min ? value : min);
        }

        static void Main(string[] args)
        {
            var root = new Node
                {
                    Value = 3,
                    Left = new Node
                        {
                            Value = 2,
                            Left = new Node { Value = 1 }
                        },
                    Right = new Node { Value = 4 }
                };

            Console.WriteLine(Min(root));
        }
Re[15]: возвращаю задачу специалистам обратно
От: Dufrenite Дания  
Дата: 22.02.10 14:45
Оценка:
Здравствуйте, Dufrenite, Вы писали:

Маленькое дополнение. При таком обходе скорее всего сложность Aggregate() будет не 0(N), а O(N * log(N)).

Но это издержки приведения дерева к линейному виду.
Если отказаться от приведения к линейному виду функцией Values(), а искать минимальный элемент прямо при обходе дерева, то алгоритм будет гарантировано линейным.
Re[35]: Linq : неудачный маркетинг?
От: olegkr  
Дата: 22.02.10 15:40
Оценка: :))
Здравствуйте, Lloyd, Вы писали:

L>Правильно, тормоза придумали трусы.

Тормозов я отсеиваю на собеседовании.
Re[36]: Linq : неудачный маркетинг?
От: Lloyd Россия  
Дата: 22.02.10 16:04
Оценка:
Здравствуйте, olegkr, Вы писали:

L>>Правильно, тормоза придумали трусы.

O>Тормозов я отсеиваю на собеседовании.

О да, детка.
Re[16]: возвращаю задачу специалистам обратно
От: Lloyd Россия  
Дата: 22.02.10 16:07
Оценка:
Здравствуйте, Dufrenite, Вы писали:

D>Маленькое дополнение. При таком обходе скорее всего сложность Aggregate() будет не 0(N), а O(N * log(N)).


D>Но это издержки приведения дерева к линейному виду.


А откуда "* log(N)" берется?
Re[17]: возвращаю задачу специалистам обратно
От: Dufrenite Дания  
Дата: 22.02.10 16:52
Оценка: 11 (1) +1
Здравствуйте, Lloyd, Вы писали:

L>А откуда "* log(N)" берется?


Здесь тонкий момент, я сам не сразу заметил.
Фактически, енумератор, возвращающий листовой элемент, представляет собой связный список енумераторов (это можно увидеть декомпилировав код), длиной с глубину просмотра, а это log(N). Поэтому, при перемещении к следующему элементу, приходится проходить весь список енумераторов.
Отсюда и получаем N * log(N).
Re[15]: Linq : неудачный маркетинг?
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 22.02.10 18:23
Оценка:
Здравствуйте, igna, Вы писали:

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


I>Ну что это за аргумент?


Отличный аргумент.

I> Почему он относится к локальным переменным и не относится к параметрам?


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

AVK>>А теперь встречный вопрос — а зачем обобщать тип локальной переменной?


I>Затем же, зачем обобщают тип параметра.


Параметр — часть контракта, локальная переменная — нет. Так что не катит.
... << RSDN@Home 1.2.0 alpha 4 rev. 1458 on Windows 7 6.1.7600.0>>
AVK Blog
Re[8]: вопрос к специалистам
От: samius Япония http://sams-tricks.blogspot.com
Дата: 22.02.10 19:41
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

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



S>> foreach (var node in q)

S>> {
S>> yield return node;
S>> }

PD>Может, я не так понимаю, но ИМХО ты здесь еще один контейнер создал, q. Пусть временный, но создал.


Нет, в широком понимании контейнер здесь я не создавал. q — это запрос, который возвращает элементы из существующего дерева, не копируя и не выстраивая их в новую структуру. Разверну его:
        static IEnumerable<T> Walk<T>(T root, Func<T, IEnumerable<T>> next)
        {
            yield return root;

            //var q = from node in next(root)
            //        from n in Walk(node, next)
            //        select n;
            //foreach (var node in q)
            //{
            //    yield return node;
            //}

            foreach(var node in next(root))
            {
                foreach (var n in Walk(node, next))
                {
                    yield return n;
                }
            }
        }

Надеюсь, что так понятнее.


S>> var minNode = Walk(

S>> root,
S>> n => n.Left != null? new[] {n.Left} : new Node<int>[]{})
S>> .Last();

Вот здесь внимательный читатель найдет по новому контейнеру (пустому либо с одним элементом) на пройденный узел.

PD>И вот это мне совсем не по душе. Задача — найти минимальный элемент в дереве, а не выложить его куда-то упорядоченным и взять последний элемент. Задача нахождения минимального элемента в дереве алгоритмически не требует ни одного копирования элементов.


Минимальный — да, копирования элементов — нет. Дело в том, что я предположил что двоичное дерево есть BST и прошел от корня по левым поддеревьям. А если BST, то искать в нем минимальный элемент можно лишь полным перебором.

PD>Я не спорю, но ты решил иную задачу Реюз-то реюз, но... как бы объяснить без ссылок на производительность. Попробую так. Вот есть алгоритмы сортировки. И все договорились — отсортировать надо исходный массив без дополнительной памяти O(N). Иными словами, решения с еще одним массивом не рассматриваются. А для обхода деревьев не рассматриваются алгоритмы, которые копируют элементы деревьев — куда бы то ни было.

PD>Такое можно ?

Во-первыйх, не вижу никаких оговорок по дополнительной памяти:

Можно пример функции, скажем, нахождения минимального элемента в двоичном дереве ?

Во-вторых, новые контейнеры создаются только для того чтобы содержать единичные элементы и выкидываются сразу после того как по ним завершится обход. Эти контейнеры нужны для обхода стандартными методами линка, так что они скорее технологические чем алгоритмические. Всегда можно от одноэлементных и пустых массивов перейти к одноэлементным оберткам вроде
IEnumerable<T> Wrap(T value)
{
   if(EqualityComparer<T>.Equals(value, default(T)))
       yield return value;
}

Это можно назвать контейнером весьма условно.
Однако да, глубина рекурсии будет соответствовать глубине дерева.

S>>Insert — это не запрос. Здесь нужно либо модификация существующего дерева, либо построение нового дерева.


PD>Зачем же новое ? Но это к слову.

PD>А вот что не к слову — здесь не чистый запрос, да.
PD>Но вначале чистый запрос — есть ли элемент. Если не SearchAndInsert, а просто Search — это уж точно запрос. И если ты собираешься его реализовать чем-то вроде выкладывания как в прошлом примере и поиском там — извини, но что это за алгоритм поиска в двоичном дереве, который требует его выкладывания в последовательность ? На кой мне черт такое дерево ? Мне log(N) подайте и без копирования!

Итак, чистый запрос на наличие элемента в BST получается из моего примера лишь небольшим изменением метода-селектора. В этом случае нужно будет выбирать не левое поддерево, а то, что ближе к искомому элементу.
Алгоритм не требует копирования или создания новых контейнеров. Его сложность в худшем случае будет соответствовать высоте дерева. log(N) — это только для сбалансированных деревьев.

PD>А во вторых, тут очень показательный момент. Без Linq SearchAndInsert отличается от Search 2 строчками (либо return nul, либо return new node(...)) А так получится, что допустим, предполагал я , что вставки не понадобятся, написал на LinQ, а они потом понадобились, и что теперь ?


Тут варианты:
а) Дерево модифицируемое. Тогда мы поиском находим узел для вставки и потом отдельным методом модифицируем дерево.
б) Дерево иммутабельное. В этом случае придется написать 8 строчек вставки с нуля.
Ведь формально обход и обновление — разные вещи.
Re[37]: Linq : неудачный маркетинг?
От: samius Япония http://sams-tricks.blogspot.com
Дата: 22.02.10 19:47
Оценка:
Здравствуйте, igna, Вы писали:

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


I>>>Кроме того внутри вновь созданного метода получим ту же ситуацию, что имели: чтобы узнать, что при использовании созданного FileStream используются только методы Stream, нужно будет просмотреть код. Так зачем тогда?


S>>Можно будет посмотреть только на сигнатуру метода и убедиться что внутри нет даункаста.


I>"Внутри вновь созданного метода" у тебя переменная и так будет типа FileStream, какой даункаст?

У вновь созданного метода будет параметр типа Stream. Соответственно для того чтобы использовать его как FileStream, нужен будет даункаст.
Re[10]: вопрос к специалистам
От: samius Япония http://sams-tricks.blogspot.com
Дата: 22.02.10 19:49
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

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


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


PD>Допустим, я не прав, но ... какая-то еще структура создается в памяти или или нет ? Запросом, контейнером, чертом лысым — но да или нет ? Потому что я не понимаю, как можно Last делать в дереве — ну нет там Last. А сами элементы копируются или нет ? Если нет — то как это все же работает ? Лежат они как попало в памяти, а тут вдруг оказались выложенными в линию. Одно из двух — либо в памяти создан контейнер со ссылками на них, либо их скопировали в другой контейнер и там они подряд лежат.


PD>Не согласен ? Тогда объясни, что там под спудом. Что там делается, какие данные и куда создаются или копируются.


Предполагалось что дерево BST. Создаются IEnumerable-ы и IEnumerator-ы по одному на шаг. Шагов в худшем случае по глубине дерева.
Re[12]: вопрос к специалистам
От: samius Япония http://sams-tricks.blogspot.com
Дата: 22.02.10 19:51
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>В алгоритме, представленнос samius, какие и в каком объеме промежуточные данные создаются в куче ? Хоть в результате создания контейнера, хоть в результате исполнения запроса, хоть итератором, хоть трансформатором ? Какие и в каком объеме ?

IEnumerable-ы и IEnumerator-ы по одному за шаг.

PD>Или по крайней мере оцени их порядок. Сколько их — O(N), O(log(N), O(1) ?

Выделил
Re[14]: вопрос к специалистам
От: samius Япония http://sams-tricks.blogspot.com
Дата: 22.02.10 19:53
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Ладно, пусть. Но вот сказано — Last. Что там реально делается, когда выполняется этот Last ? Ведь нельзя же в дереве выполнить Last физически, потому что нет в дереве информации, позволяющей пройти его таким способом. Да и Last нет вообще.

PD>Список можно и массив можно. Сделал энумератор , а он внутри себя имеет способ перехода к следующемму элементу (t=t.next или i++), а дерево нельзя и граф нельзя. Чудес-то не бывает.

Те енумераторы имеют в себе только узел, от которого они идут + способ перехода. Но способ перехода памяти не просит.

PD>Если не согласен — тогда объясни, как это делается. Ну вот есть запрос, или комбинация энумераторов, или что хочешь. Что там в конечном счете делается в этом дереве, как этот минимальный элемент находится ? Бог с ним, с линком, но какие действия там процессор выполняет ? Он же линк выполнять не может!


PD>И еще вопрос, если можешь ответить. Императивный алгоритм обхода дерева, естественно, O(N) и однопроходной. Здесь что ?


Здесь был O(log N), обход по BST.
Re[14]: возвращаю задачу специалистам обратно
От: samius Япония http://sams-tricks.blogspot.com
Дата: 22.02.10 19:56
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

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


D>>Очевидно, O(log(N)).

D>>По лишним веткам не ходим.

PD>А, черт! Понял.


PD>Видимо, samius решил , что я прошу алгоритм поиска минимального элемента в двоичном дереве поиска. Там действительно проще, и намного — есть путь, его можно в виде набора итераторов представить. А я имел в виду произвольное двоичное дерево, то есть полный разветвляющийся обход. В нем лучше O(N) не может быть никак.

Да, я действительно решил что речь о BST

PD>Да, должен был я на этом акцентировать внимание. То-то я удивился с этим его Left, но списал на свое незнание LinQ Но вина моя небольшая — я же не написал, что это дерево поиска, так что и оснований предполагать не было.


PD>Жду от специалистов решения задачи — заново.


Заново не потребуется. Изменение будет лишь в селекторе, правда он станет немного сложнее. Оставлю в качестве упражнения.
Re[2]: вопрос к специалистам
От: VladD2 Российская Империя www.nemerle.org
Дата: 23.02.10 00:20
Оценка: +1
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>У меня вопрос к тем, кто считает, что он LinQ знает.


Вот это хороший подход. Одобряю!

PD>Сформулируйте, когда LinQ стоит применять и когда его применение нецелесообразно.


Введение: LINQ — это общее название используемое для весьма разных вещей. Посему я буду говорить о LINQ to Object, LINQ to DB (последнего не существует — это некий собирательный образ подразумевающий использование LINQ-провайдеров предоставляющий доступ к удаленным данным) и синтаксическом расширении (синтаксисе запросов).

LINQ to Object следует использовать в проектах на дотнет-языках для обработки списков. То есть, буквально, заменяя тонны циклов и невнятного кода на весьма компактный и легко читаемый код использующий LINQ-функции всшего порядка (т.п. функции параметризуемые функциями позволяющие уточнить или задать действия).

LINQ to Object не следует применять в редких случаях когда очень важна производительность, так как циклы все же несколько эффективнее LINQ to Object, и они лучше оптимизируеютя.

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

LINQ to DB имеет смысл использовать там где требуется создавать приложения плотно общающиеся с БД или другими внешними источниками информации для которых есть качественные LINQ-провайдеры.

LINQ to DB может быть заменен неким другим решением обеспечивающим такой же или более высокий уровень, например, собственный DSL-движок напрямую генерирующий SQL.

Синтаксическое расширение можно использовать, а можно не использовать. От этого мало что зависит. Некоторый код выигрывает от применения синтаксиса, некоторый — нет. Обычно мелкие "запросы" выгоднее писать в виде прямого использования функций высшего порядка предоставляемых LINQ-ом, а большие "запросы" лучше выглядят с использованием синтаксиса.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[9]: Linq : неудачный маркетинг?
От: Mystic Украина http://mystic2000.newmail.ru
Дата: 23.02.10 08:08
Оценка:
Здравствуйте, 0x7be, Вы писали:

0>А что делать сессии, если у нее алгоритм обработки запроса частично последовательный, а частично параллельный?

0>Самой обращаться к пулу потоков и ручками в этих потоках запускать свои куски?

Мы получили достаточно специфическую задачу.

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


0>Запустить несколько генераторов в отдельных потоках, отрезав каждому по ломтику задачи?


Если честно, то в шахматах будет даже модификация алгоритма перебора alpha-beta, облегчающая многопоточность. В однопоточном случае мы рассматриваем первый ход 1. e2-e4 (и белые выигрывают! Раузер) и вычисляем коэффициенты отсечения alpha и beta, которые затем используются при анализе второго хода 1. d2-d4 (и белые выигрывают! Боголюбов). В двухпоточном случае 1. e2-e4 и 1. d2-d4 будут анализировать одновременно, а результаты alpha и beta будуи применяться уже к третьему ходу. Есть еще эвристика ходов-киллеров, которые меняют порядок перебора в продолжении 1.d2-d4 после анализа 1. e2-e4. Уже этот пример может показать всякие тонкости, которые могут возникнуть в практической жизни.

int Position.AlphaBeta(int color, int depth, int alpha, int beta)
{
  if (depth == 0) return Evaluate(color);

  // В этом цикле запустить параллельное выполнение AlphaBeta в цикле мы не можем,
  // так как формально значение alpha может измениться
  
  foreach (move in GenerateAllMoves())
  {
    if (alpha >= beta) break;

    DoMove(move); // Второй ньюанс: быстрее выполняется do/undo, чем создание новой позиции
    int temp = -AlphaBeta(Toggle(color), depth-1, -beta, -alpha);
    UndoMove(move);

    if (tmp > alpha) alpha = tmp;
  }

  return alpha;
}


0>Сложно сказать. В принципе, сейчас я тоже к параллелизму прихожу как к крайнему средству. Но это происходит не в последнюю очередь потому, что средства распараллеливания сейчас очень неуклюжи. Их применение обфусцирует предметный алгоритм. Однако многоядерность твердой поступью входит в нашу жизнь, появляются новые средства обеспечения параллельных вычислений, так что приоритеты оптимизации меняются. По-этому я активно интересуюсь прогрессом в этой области.


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

На сегодня мы не часто упираемся в вычислительную мощь процессора. Если брать игры, и особенно, математические расчеты, то зачастую это большое колиество однотипных действий. Поэтому тут развитие может пойти в сторону параллельных процессоров (NVIDIA CUDA — неграфические вычисления на графических процессорах и Часть 2 — Примеры внедрения NVIDIA CUDA. А это уже специальное программирование. В случае серверов опять же чаще всего проблема в том, чтобы распараллелить работу многих пользователей, а вычислений для конкретного пользователя не так уж и много. Остаются еще задачи типа шахмат, но там свои приколы, затрудняющие общий подход. Так что средства вроде PLINQ и ФЯ, применительно к многопоточной оптимизации, по моему мнению, помогут решить некоторый узкий круг задач, а в остальном просто видоизменят проблему: вместо того, чтобы параллелить вычисления самому, мы будем думать о том, каким образом донести до компилятора идею о том, как лучше параллелить, где это можно а где нельзя, где можно отойти от алгоритма и как.
Re[10]: Linq : неудачный маркетинг?
От: 0x7be СССР  
Дата: 23.02.10 10:58
Оценка:
Здравствуйте, Mystic, Вы писали:

0>>А что делать сессии, если у нее алгоритм обработки запроса частично последовательный, а частично параллельный?

0>>Самой обращаться к пулу потоков и ручками в этих потоках запускать свои куски?
M>Мы получили достаточно специфическую задачу.
Ну да. Многопоточный сервер — это тоже задача, обладающая своей спецификой

M>Есть правило крутого поворота: крутой поворот в жизни происходит или намного раньше, или намного позже ожидаемого срока и ведет обычно в совсем неожидаемом направлении.

+1

M>На сегодня мы не часто...

[skip]
M>...где можно отойти от алгоритма и как.
Я согласен с такой точкой зрения. Предлагаю некоторую сумму, как итоговый консенсус: "больше средств для параллелизма, хороших и разных". Я не выступал за PLINQ и подобные ему средства, как за панацею. Безусловно, у них своя ниша, так же как и у "серверо-ориентированных" и у GPU и MAPI и прочих.
Re[16]: Linq : неудачный маркетинг?
От: igna Россия  
Дата: 23.02.10 14:50
Оценка:
Здравствуйте, AndrewVK, Вы писали:

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


А можно все же посмотреть то самое "довольно строгое доказательство на основе LSP"?
Re[38]: Linq : неудачный маркетинг?
От: igna Россия  
Дата: 23.02.10 15:01
Оценка:
Здравствуйте, samius, Вы писали:

S>У вновь созданного метода будет параметр типа Stream. Соответственно для того чтобы использовать его как FileStream, нужен будет даункаст.


Вот ты чего. Хорошо, это решает вопрос, только во-первых решение это является пальбой из пушки по воробьям, если других причин для выделения метода нет, а во-вторых оно может оказаться не вполне тривиальным, если нужно передавать в выделяемый метод несколько локальных переменных.
Re[39]: Linq : неудачный маркетинг?
От: samius Япония http://sams-tricks.blogspot.com
Дата: 23.02.10 15:16
Оценка:
Здравствуйте, igna, Вы писали:

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


S>>У вновь созданного метода будет параметр типа Stream. Соответственно для того чтобы использовать его как FileStream, нужен будет даункаст.


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


Если есть возможность абстрагироваться от FileStream-а при записи в файл (а это можно сделать в 98% случаев), то это следует сделать, и перегруженный метод для записи в стрим должен быть. Пусть он будет приватным, но именно он будет содержать основную логику и локальные переменные тоже. Метод, создающий непосредственно FileStream будет лишь делегировать и не должен содержать никакой логики и локальных переменных кроме самого стрима.

По поводу причин — выделение абстракции для тестирования — довольно уважительная причина для Extract method рефакторинга.
Re: Linq : неудачный маркетинг?
От: mukhomor  
Дата: 23.02.10 15:54
Оценка:
Здравствуйте, 0x7be, Вы писали:

0>Добрый день.


0>По опыту своих бесед с программистами, не знакомыми с linq, я собрал ряд стереотипных заблуждений и проблем с пониманеим linq, которые у них встречаются. В целом среди них преобладает такое мнение "это убогий SQL в С#, зачем он нужен?". Все попытки объяснить, что linq является воплощением аппарата операций над множествами, который ортогонален языку, и с необходимостью которого никто не спорит, сталкиваются с такой стеной непонимания. Это приводит меня к мысли, что linq подан неудачно. Его SQL-подобный синтаксис вызывает затруднения и у тех кто не знаком с SQL (выглядит больно непривычно) и у тех, кто знаком (не совсем понимают, что SQL делает в языке и сталкиваются с тем, что синтаксис всего лишь похож, а не повторяет SQL). Мое мнение по этому поводу: Linq — хорошая штука, но неудачно подан. Ваши мнения?


А мне больше понравились новшества, которые появились из-за LINQ. Вот их бы совершенствовать, а LINQ как LINQ — есть и хорошо.
Re[15]: возвращаю задачу специалистам обратно
От: igna Россия  
Дата: 23.02.10 17:03
Оценка:
Здравствуйте, samius, Вы писали:

S>Оставлю в качестве упражнения.


Оставь. Только когда поупражняешься, не забудь запостить результат.
Re[2]: Linq : неудачный маркетинг?
От: 0x7be СССР  
Дата: 23.02.10 17:37
Оценка:
Здравствуйте, mukhomor, Вы писали:

M>А мне больше понравились новшества, которые появились из-за LINQ. Вот их бы совершенствовать, а LINQ как LINQ — есть и хорошо.

Какие именно новшества ты имеешь в виду?
Re[16]: возвращаю задачу специалистам обратно
От: samius Япония http://sams-tricks.blogspot.com
Дата: 23.02.10 17:59
Оценка:
Здравствуйте, igna, Вы писали:

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


S>>Оставлю в качестве упражнения.


I>Оставь. Только когда поупражняешься, не забудь запостить результат.


Полагаю что любой, кому интересен результат, сможет получить его самостоятельно.
Re[3]: Linq : неудачный маркетинг?
От: mukhomor  
Дата: 23.02.10 21:27
Оценка: 1 (1)
Здравствуйте, 0x7be, Вы писали:

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


M>>А мне больше понравились новшества, которые появились из-за LINQ. Вот их бы совершенствовать, а LINQ как LINQ — есть и хорошо.

0>Какие именно новшества ты имеешь в виду?

Расширяющие методы, лямбда-выражения, анонимные типы. На мой взгляд, это добавляет некоторое изящество в код. Что касается самого LINQ, то, опять-таки, на мой взгляд, он немного меняет мировозрение в отношении работы с данными. Может поэтому сразу и не прижился. Нужно попривыкнуть.
Re[17]: Linq : неудачный маркетинг?
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 23.02.10 22:21
Оценка:
Здравствуйте, igna, Вы писали:

I>А можно все же посмотреть то самое "довольно строгое доказательство на основе LSP"?


Ссылки под рукой нет.
... << RSDN@Home 1.2.0 alpha 4 rev. 1458 on Windows 7 6.1.7600.0>>
AVK Blog
Re[15]: возвращаю задачу специалистам обратно
От: Pavel Dvorkin Россия  
Дата: 24.02.10 03:49
Оценка:
Здравствуйте, samius, Вы писали:


S>Заново не потребуется. Изменение будет лишь в селекторе, правда он станет немного сложнее. Оставлю в качестве упражнения.


И все же, если не очень сложно — напиши. Моих знаний LinQ для решения этого упражнения не хватает
Я не могу одно понять. В BST фактически поиск минимального элемента есть работа не с деревом, а со списком из .Left. Это понятно, и твой итератор тоже. Но в просто дереве идея .Last ИМХО попросту не работает, поскольку тут Last нет. Отсортировать и взять Last — такое не надо. А иначе что ?
With best regards
Pavel Dvorkin
Re[15]: возвращаю задачу специалистам обратно
От: Pavel Dvorkin Россия  
Дата: 24.02.10 04:24
Оценка:
Здравствуйте, Dufrenite, Вы писали:

D>Здравствуйте, Pavel Dvorkin, Вы писали:


PD>>Жду от специалистов решения задачи — заново.


D>Эта задача совсем тривиальна:


Может, я что-то не понимаю, но

D>[c#]

D> class Node
D> {
D> public int Value;
D> public Node Right;
D> public Node Left;
D> }

D> static IEnumerable<int> Values(Node root)

D> {
D> if (!ReferenceEquals(root, null))
D> {
D> yield return root.Value;
D> var childValues = Values(root.Left).Concat(Values(root.Right));


Enumerable.Concat<(Of <(TSource>)>) — метод
Объект IEnumerable<(Of <(T>)>), содержащий объединенные элементы двух входных последовательностей.

Я правильно понял, что здесь создается новый объект, содержащий элементы двух последовательностей ? Не итератор или что-то еще, а именно объект ?

Если да — это не решение. Задача должна быть решена без создания новых "массовых "объектов. Иными словами, на памяти O(1). Алгоритм это позволяет.

Если я неправильно понял — объясни, пожалуйста.

Для справки — императивный алгоритм. Сорри, С++ (привычнее




#include "stdafx.h"
#include "algorithm"

struct TreeElem{
    int Value;
    TreeElem* Left, *Right;
    TreeElem(int _Value, TreeElem* _Left, TreeElem* _Right) : 
      Value(_Value), Left(_Left),Right(_Right) {}
};

int MinElem(TreeElem* pElement)
{
  int temp = pElement->Value;
  if(pElement->Left)
      temp = std::min(temp,MinElem(pElement->Left));
  if(pElement->Right)
      temp = std::min(temp,MinElem(pElement->Right));
  return temp;
}



int _tmain(int argc, _TCHAR* argv[])
{
    TreeElem* t1 = new TreeElem(1, NULL, NULL);
    TreeElem* t2 = new TreeElem(2,t1, NULL);
    TreeElem* t3 = new TreeElem(4,NULL, NULL);
    TreeElem* root = new TreeElem(3,t2,t3);
    int m = MinElem(root);
    // уничтожение опущено
    return 0;
}
With best regards
Pavel Dvorkin
Re[3]: вопрос к специалистам
От: Pavel Dvorkin Россия  
Дата: 24.02.10 05:01
Оценка:
Здравствуйте, VladD2, Вы писали:


VD>LINQ to Object следует использовать в проектах на дотнет-языках для обработки списков. То есть, буквально, заменяя тонны циклов и невнятного кода на весьма компактный и легко читаемый код использующий LINQ-функции всшего порядка (т.п. функции параметризуемые функциями позволяющие уточнить или задать действия).


Спасибо. Вот именно это я и хотел узнать — выделено выше. У меня было то же ощущение — что LinQ (как и его духовный предок SQL) предназначен для обработки линейных структур (в общем понимании этого слова). Для структур нелинейного характера (деревья, графы и т.д.) он, как мне кажется, не слишком подходит. Хотя samius и Dufrenite пытаются меня убедить в обратном. Почитай эту часть дискуссии, она еще не кончена, можешь там высказаться.

И второе, это уже вопрос. Если речь идет о запросе — ладно. А если не о запросе ? Я, может, ошибаюсь опять, но вроде бы LinQ — это функциональное программирование. А оно позиционируется как альтернатива императивному. Если альтернатива — будьте добры обеспечить мне возможность сделать все, что я там могу сделать, иначе что же это за альтернатива! А если это только добавление — тогда уж так и будем говорить.

VD>LINQ to Object не следует применять в редких случаях когда очень важна производительность, так как циклы все же несколько эффективнее LINQ to Object, и они лучше оптимизируеютя.


Ну это я давно знаю.
With best regards
Pavel Dvorkin
Re[16]: возвращаю задачу специалистам обратно
От: samius Япония http://sams-tricks.blogspot.com
Дата: 24.02.10 05:33
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

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



S>>Заново не потребуется. Изменение будет лишь в селекторе, правда он станет немного сложнее. Оставлю в качестве упражнения.


PD>И все же, если не очень сложно — напиши. Моих знаний LinQ для решения этого упражнения не хватает

PD>Я не могу одно понять. В BST фактически поиск минимального элемента есть работа не с деревом, а со списком из .Left. Это понятно, и твой итератор тоже. Но в просто дереве идея .Last ИМХО попросту не работает, поскольку тут Last нет. Отсортировать и взять Last — такое не надо. А иначе что ?

Пройти по всему дереву (а не по Left) и взять минимальный элемент.

Проход по всему дереву от прохода по .Left отличается лишь селектором.
Вместо
n => n.Left != null? new[] {n.Left} : new Node<int>[]{}

или
        public static IEnumerable<Node<T>> NextLeft<T>(this Node<T> root)
        {
            if (root.Left != null)
                yield return root.Left;
        }

указываем селектор такой

        public static IEnumerable<Node<T>> SubNodes<T>(this Node<T> root)
        {
            return root.NextLeft().Concat(root.NextRight());
        }

Тогда поиск минимума будет
var min = Walk(root, SubNodes).Select(n => n.Value).Min();

Вообще Dufrenite написал верный алгоритм. Но он написал новую функцию обхода значений элемента, в то время как я заюзал ФВП Walk лишь изменив селектор.
Re[17]: возвращаю задачу специалистам обратно
От: Pavel Dvorkin Россия  
Дата: 24.02.10 06:11
Оценка:
Здравствуйте, samius, Вы писали:

S> return root.NextLeft().Concat(root.NextRight());


Вопрос задан здесь (по Concat)

http://www.rsdn.ru/forum/philosophy/3714968.1.aspx
Автор: Pavel Dvorkin
Дата: 24.02.10



S>Вообще Dufrenite написал верный алгоритм. Но он написал новую функцию обхода значений элемента, в то время как я заюзал ФВП Walk лишь изменив селектор.


В сущности, меня вот что интересует.

Императивный алгоритм приведен там же. Он имеет O(N) по времени (больше просто незачем), однопроходной, копирование чего бы то ни было отсутствует (кроме, впрочем, адресов возврата в стеке — рекурсия!) и O(1) по дополнительной памяти (опять же не учитывая место в стеке)

Какова зависимость твоего алгоритма от времени ?
Сколько проходов ?
Копируются данные или нет ? Создается ли какой-то дополнительный контейнер какого бы то ни было вида (хоть из одних ссылок на элементы дерева) или нет ?
Объем дополнительной памяти как функция от N ?
With best regards
Pavel Dvorkin
Re[16]: возвращаю задачу специалистам обратно
От: samius Япония http://sams-tricks.blogspot.com
Дата: 24.02.10 06:12
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

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


PD>Enumerable.Concat<(Of <(TSource>)>) — метод

PD>Объект IEnumerable<(Of <(T>)>), содержащий объединенные элементы двух входных последовательностей.

PD>Я правильно понял, что здесь создается новый объект, содержащий элементы двух последовательностей ? Не итератор или что-то еще, а именно объект ?


Да, это объект-итератор, котрый пройдет по элементам двух последовательностей, но он не содержит их элементов, а только лишь умеет ходить по ним аки итератор из STL.

PD>Если да — это не решение. Задача должна быть решена без создания новых "массовых "объектов. Иными словами, на памяти O(1). Алгоритм это позволяет.

Ниже прикинем

PD>Если я неправильно понял — объясни, пожалуйста.

Правильно

PD>Для справки — императивный алгоритм. Сорри, С++ (привычнее


PD>
PD>int MinElem(TreeElem* pElement)
PD>{
PD>  int temp = pElement->Value;
PD>  if(pElement->Left)
PD>      temp = std::min(temp,MinElem(pElement->Left));
PD>  if(pElement->Right)
PD>      temp = std::min(temp,MinElem(pElement->Right));
PD>  return temp;
PD>}
PD>


Этот алгоритм не может работать на памяти O(1), т.к. он юзает рекурсию, которая не приводима к хвостовой оптимизации. В точности ему потребуется память соразмерная высоте дерева, т.е. O(log N) в среднем и O(N) в худшем случае. Разница лишь в том, что этот вариант работает лишь на стэке, а вариант с объектами-итераторами просит еще и выделений в куче. Впрочем, возможно переписать реализацию IEnumerable в структурах и итераторы лягут полностью на стэк (потребуется немного другая форма метода Walk с двумя дженерик параметрами).

Самое важное отличие от реализации с функцией высшего порядка в том, что для MaxElem, SearchElem и т.п. придется писать новый метод обхода дерева каждый раз. В то время как обход дерева через ФВП Walk позволяет привести его к линейному виду и применить стандартный набор LINQ методов для работы с последовательностями.

Открою секрет, LINQ здесь используется только как набор высокоуровневых методов Select + Min из нэймспейса System.Linq. Т.е. сказать что обойти дерево можно на LINQ = немного слукавить. Более уместно здесь сказать что выделение паттерна обхода дерева в высокоуровневый метод высшего порядка позволяет свести задачу обхода дерева к обходу последовательности и применить Min из LINQ-а.

Полагаю что этот же подход можно реализовать в итераторах на C++ (к сожалению, STL не помню, а boost не знаю).
Re[18]: возвращаю задачу специалистам обратно
От: samius Япония http://sams-tricks.blogspot.com
Дата: 24.02.10 06:22
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

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


S>> return root.NextLeft().Concat(root.NextRight());


PD>Вопрос задан здесь (по Concat)


PD>http://www.rsdn.ru/forum/philosophy/3714968.1.aspx
Автор: Pavel Dvorkin
Дата: 24.02.10


Уже ответил


S>>Вообще Dufrenite написал верный алгоритм. Но он написал новую функцию обхода значений элемента, в то время как я заюзал ФВП Walk лишь изменив селектор.


PD>В сущности, меня вот что интересует.


PD>Императивный алгоритм приведен там же. Он имеет O(N) по времени (больше просто незачем), однопроходной, копирование чего бы то ни было отсутствует (кроме, впрочем, адресов возврата в стеке — рекурсия!) и O(1) по дополнительной памяти (опять же не учитывая место в стеке)


PD>Какова зависимость твоего алгоритма от времени ?

Такая же

PD>Сколько проходов ?

1

PD>Копируются данные или нет ? Создается ли какой-то дополнительный контейнер какого бы то ни было вида (хоть из одних ссылок на элементы дерева) или нет ?

Я итератор не считаю контейнером, потому — нет.

PD>Объем дополнительной памяти как функция от N ?

Учитывая стек и созданные итераторы — по высоте дерева (log N при сбалансированном дереве и N в худшем случае).
Re[17]: возвращаю задачу специалистам обратно
От: Pavel Dvorkin Россия  
Дата: 24.02.10 06:34
Оценка:
Здравствуйте, samius, Вы писали:

PD>>Я правильно понял, что здесь создается новый объект, содержащий элементы двух последовательностей ? Не итератор или что-то еще, а именно объект ?


S>Да, это объект-итератор, котрый пройдет по элементам двух последовательностей, но он не содержит их элементов, а только лишь умеет ходить по ним аки итератор из STL.


Гм. Итератор map из STL — это нечто иное, там BST. Это раз. А во-вторых, там цикл

http://www.rsdn.ru/forum/philosophy/3713716.1.aspx
Автор: Pavel Dvorkin
Дата: 22.02.10


при каждом ++. Это ни к чему здесь.

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


S>Этот алгоритм не может работать на памяти O(1), т.к. он юзает рекурсию, которая не приводима к хвостовой оптимизации. В точности ему потребуется память соразмерная высоте дерева, т.е. O(log N) в среднем и O(N) в худшем случае.


Не совсем верно. Память, соразмерная высоте дерева, понадобится, само собой, но не из элементов дерева, а только из указателей (ссылок). Тут то же самое, что в QuickSort. Кстати, если дерево сбалансированное, то точно O(log N).


>Разница лишь в том, что этот вариант работает лишь на стэке, а вариант с объектами-итераторами просит еще и выделений в куче. Впрочем, возможно переписать реализацию IEnumerable в структурах и итераторы лягут полностью на стэк (потребуется немного другая форма метода Walk с двумя дженерик параметрами).


Резюмирую. Ты утверждаешь, что твой LinQ-вариант при его "ассемблерной" реализации делает обход дерева, создавая при этом не более чем log(N) элементов размером не более 4(8), не копируя данные и не проходя их дважды ? Иными словами, он логически эквивалентен императивному ?

S>Самое важное отличие от реализации с функцией высшего порядка в том, что для MaxElem, SearchElem и т.п. придется писать новый метод обхода дерева каждый раз. В то время как обход дерева через ФВП Walk позволяет привести его к линейному виду и применить стандартный набор LINQ методов для работы с последовательностями.

S>Открою секрет, LINQ здесь используется только как набор высокоуровневых методов Select + Min из нэймспейса System.Linq. Т.е. сказать что обойти дерево можно на LINQ = немного слукавить. Более уместно здесь сказать что выделение паттерна обхода дерева в высокоуровневый метод высшего порядка позволяет свести задачу обхода дерева к обходу последовательности и применить Min из LINQ-а.

Так создается тут последовательность или нет ? Физически она есть или нет ? Что-то я уж совсем запутался.
With best regards
Pavel Dvorkin
Re[19]: возвращаю задачу специалистам обратно
От: Pavel Dvorkin Россия  
Дата: 24.02.10 06:37
Оценка:
Здравствуйте, samius, Вы писали:


S>Уже ответил


И я тоже. Перенесем дискуссию туда, иначе у нас обход дерева будет
With best regards
Pavel Dvorkin
Re[18]: возвращаю задачу специалистам обратно
От: samius Япония http://sams-tricks.blogspot.com
Дата: 24.02.10 06:59
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

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


PD>>>Я правильно понял, что здесь создается новый объект, содержащий элементы двух последовательностей ? Не итератор или что-то еще, а именно объект ?


S>>Да, это объект-итератор, котрый пройдет по элементам двух последовательностей, но он не содержит их элементов, а только лишь умеет ходить по ним аки итератор из STL.


PD>Гм. Итератор map из STL — это нечто иное, там BST. Это раз. А во-вторых, там цикл

Итератор map из STL — действительно нечто другое.

PD>Но дело не в этом. Я никак не могу понять, каким образом можно итерировать по дереву, не создав промежуточных структур, причем массовых. Ну хорошо, элементы не копируются. Но пройти дерево — надо или стек заводить, или рекурсию, других способов вроде нет. В любом случае это дополнительная память. Что именно здесь делается ?

Используется стек, как и в случае MinElem.
И немного используется куча для создания последовательности (об этом ниже).

S>>Этот алгоритм не может работать на памяти O(1), т.к. он юзает рекурсию, которая не приводима к хвостовой оптимизации. В точности ему потребуется память соразмерная высоте дерева, т.е. O(log N) в среднем и O(N) в худшем случае.


PD>Не совсем верно. Память, соразмерная высоте дерева, понадобится, само собой, но не из элементов дерева, а только из указателей (ссылок). Тут то же самое, что в QuickSort. Кстати, если дерево сбалансированное, то точно O(log N).

Про сбалансированное дерево мы не говорили, потому я все время оговариваюсь что мерию O(x) в высоте дерева.
Элементы дерева я не копирую, потому память под элементы дерева мне не нужна.

>>Разница лишь в том, что этот вариант работает лишь на стэке, а вариант с объектами-итераторами просит еще и выделений в куче. Впрочем, возможно переписать реализацию IEnumerable в структурах и итераторы лягут полностью на стэк (потребуется немного другая форма метода Walk с двумя дженерик параметрами).


PD>Резюмирую. Ты утверждаешь, что твой LinQ-вариант при его "ассемблерной" реализации делает обход дерева, создавая при этом не более чем log(N) элементов размером не более 4(8),

Элементы он не создает. Создаются лишь итераторы, которые при необходимости можно расположить в стеке. Размер итератора вот только побольше 4х байт, но абсолютно точно не зависит ни от размера дерева ни от размера элемента дерева, т.е. O(C).

PD>не копируя данные и не проходя их дважды ?

да, не копируя и не проходя их дважды

PD>Иными словами, он логически эквивалентен императивному ?

Абсолютно логически эквивалентен и устроен по тому же принципу — ПВГ. Только лишь абстрагирован от выбора следующего шага, так что я могу его параметризовать способом обхода (по левым детям, по правым, по n-ым, по всем, через 1 и как угодно)

PD>Так создается тут последовательность или нет ? Физически она есть или нет ? Что-то я уж совсем запутался.


Последовательность как контейнер НЕ создается. Последовательность как способ обхода — создается.
Мы можем по ней пройти через foreach — в этом случае это лишь проход с помощью итератора, мы можем ее фильтровать, преобразовывать, группировать и т.п. Но лишь когда мы сделаем new List<Node>(seq), вот тогда создастся новый контейнер список, который вберет в себя последовательность.

var array = new int[]{1, 2, 3} — контейнер и последовательность.
array.Where(n => n % 2 == 0) — последовательность но не контейнер. Да, она занимает место в памяти как объект, имеющий размер O(C), и при этом не содержит ни одного элемента из массива в своей памяти. Но мы можем итерировать через эту последовтельность и в ней будет 1 элемент. Так что она "содержит" элементы не содержа их физически.
Re[16]: возвращаю задачу специалистам обратно
От: 0x7be СССР  
Дата: 24.02.10 07:09
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:


D>> var childValues = Values(root.Left).Concat(Values(root.Right));

PD>Я правильно понял, что здесь создается новый объект, содержащий элементы двух последовательностей ? Не итератор или что-то еще, а именно объект ?
Нет. Здесь создается именно итератор. Какой-либо коллекции, содержащей объекты дерева или ссылки на них, не создается.

Как выглядит простейшая реализация Concat?

public IEnumerable<T> Concat<T>(this IEnumerable<T> first, IEnumerable<T> second)
{
  foreach(var i in first) yield return i;
  foreach(var i in second) yield return i;
}


Никакой новой коллекции не создается, итератор просто выдает сначала элементы одной последовательности, а потом — второй. У пользователя итератора есть полная иллюзия, что он работает с одной коллекцией, содержащей элементы обоих операндов. На самом деле он неявно опрашивает обе коллекции.
Re[18]: возвращаю задачу специалистам обратно
От: samius Япония http://sams-tricks.blogspot.com
Дата: 24.02.10 07:10
Оценка:
Здравствуйте, Dufrenite, Вы писали:

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


L>>А откуда "* log(N)" берется?


D>Здесь тонкий момент, я сам не сразу заметил.

D>Фактически, енумератор, возвращающий листовой элемент, представляет собой связный список енумераторов (это можно увидеть декомпилировав код), длиной с глубину просмотра, а это log(N). Поэтому, при перемещении к следующему элементу, приходится проходить весь список енумераторов.
D>Отсюда и получаем N * log(N).

Енумераторы действительно выстраиваются в цепочку, и длина этой цепочки соответствует высоте дерва.
Однако, справедливо считать что сложность ПВГ O(N), хотя глубина рекурсии там тоже будет соответствовать высоте дерева. Предлагаю не учитывать стоимость вызова по цепочке енумераторов в алгоритмической оценке потому как его вклад будет соразмерен рекурсивному вызову, который не учитывается.
Re[19]: возвращаю задачу специалистам обратно
От: Pavel Dvorkin Россия  
Дата: 24.02.10 07:49
Оценка:
Здравствуйте, samius, Вы писали:



S>Элементы дерева я не копирую, потому память под элементы дерева мне не нужна.


OK, с этим ясно.

S>Элементы он не создает. Создаются лишь итераторы, которые при необходимости можно расположить в стеке. Размер итератора вот только побольше 4х байт, но абсолютно точно не зависит ни от размера дерева ни от размера элемента дерева, т.е. O(C).


Вот это я все же не понимаю. Ладно, оставим LinQ в покое. Проитерируй мне это несчастное дерево императивным путем.

Я-то, грешный, прошел его рекурсией. Мне не надо извне его уметь следующий элемент получить, я это только внутри него самого делаю. И итератора там нет. Я вообще понятие "следующий" явно не использую. А вот попроси ты меня

root = BuildTree();
tree_iterator te = tree_iterator(root);
for(t = te.begin; t!=t.end; t++)

написать, и все будет хуже. Это не список и не массив, тут позицией или индексом не обойдешься. Тут мне придется внутри этого итератора стек хранить, да как бы не что-то еще. Скорее всего придется еще поле Parent добавить, иначе как к нему возвращаться ?


PD>>не копируя данные и не проходя их дважды ?

S>да, не копируя и не проходя их дважды

PD>>Иными словами, он логически эквивалентен императивному ?

S>Абсолютно логически эквивалентен и устроен по тому же принципу — ПВГ. Только лишь абстрагирован от выбора следующего шага, так что я могу его параметризовать способом обхода (по левым детям, по правым, по n-ым, по всем, через 1 и как угодно)

PD>>Так создается тут последовательность или нет ? Физически она есть или нет ? Что-то я уж совсем запутался.


S>Последовательность как контейнер НЕ создается. Последовательность как способ обхода — создается.


Вот это я и не понимаю. Можно создать последовательность как способ обхода для массива — i++. Для списка p=p.next. Тут никакие дополнительные структуры не требуются. А в дереве это не получится. Так что твоя последовательность как способ обхода есть по сути дела некая управляющая структура над эти деревом. И как тут может быть O(C) — не понимаю, если в императивном O(log N). К примеру, я мог бы обойти это дерево как написал и выложить все указатели в массив. После этого пройти итератором будет несложно, но это не решение.


S>Мы можем по ней пройти через foreach


Вот-вот. each что ? Управляющий элемент для каждого элемента дерева ?

>- в этом случае это лишь проход с помощью итератора, мы можем ее фильтровать, преобразовывать, группировать и т.п. Но лишь когда мы сделаем new List<Node>(seq), вот тогда создастся новый контейнер список, который вберет в себя последовательность.


S>var array = new int[]{1, 2, 3} — контейнер и последовательность.

S>array.Where(n => n % 2 == 0) — последовательность но не контейнер. Да, она занимает место в памяти как объект, имеющий размер O(C), и при этом не содержит ни одного элемента из массива в своей памяти. Но мы можем итерировать через эту последовтельность и в ней будет 1 элемент. Так что она "содержит" элементы не содержа их физически.


Это все слова. Да, я понял, что Where тут не контейнер. Отлично. Но начнешь итерировать — будет там ++ где-то внутри какого-то регистра или индекса, и не надо никаких новых байт для этого. Но в дереве же такое невозможно!
With best regards
Pavel Dvorkin
Re[20]: возвращаю задачу специалистам обратно
От: samius Япония http://sams-tricks.blogspot.com
Дата: 24.02.10 08:21
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

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


S>>Элементы он не создает. Создаются лишь итераторы, которые при необходимости можно расположить в стеке. Размер итератора вот только побольше 4х байт, но абсолютно точно не зависит ни от размера дерева ни от размера элемента дерева, т.е. O(C).


PD>Вот это я все же не понимаю. Ладно, оставим LinQ в покое.

Да это не LINQ вовсе. Из LINQ-а там только Concat, который легко реализуется на yield return, который в свою очередь генерирует код конечного автомата для реализации IEnumerator<T>.

PD>Проитерируй мне это несчастное дерево императивным путем.

Да легко. Вместо yield return будет callback и всего лишь.
        static void Walk<T>(Node<T> root, Action<Node<T>> callback)
        {
            callback(root);

            if (root.Left != null)
                Walk(root.Left, callback);
            if (root.Right != null)
                Walk(root.Right, callback);
        }

Здесь я слил специфичный для Node<T> селектор с обходом в единое целое чтобы полностью избавиться от IEnumerable. Алгоритм остался идентичным, только стал более низкоуровневый.

PD>Я-то, грешный, прошел его рекурсией. Мне не надо извне его уметь следующий элемент получить, я это только внутри него самого делаю. И итератора там нет. Я вообще понятие "следующий" явно не использую. А вот попроси ты меня


PD>root = BuildTree();

PD>tree_iterator te = tree_iterator(root);
PD>for(t = te.begin; t!=t.end; t++)

PD>написать, и все будет хуже. Это не список и не массив, тут позицией или индексом не обойдешься. Тут мне придется внутри этого итератора стек хранить, да как бы не что-то еще. Скорее всего придется еще поле Parent добавить, иначе как к нему возвращаться ?

В случае C# (достаточно 2.0) это все на раз-два реализуется с помощью yield return. Стэк перетекает в цепочку связанных перечислителей, Parent не нужен. Можно было бы и на C# 1.0, но пришлось бы вместо yield return реализовывать IEnumerator вручную.

S>>Последовательность как контейнер НЕ создается. Последовательность как способ обхода — создается.


PD>Вот это я и не понимаю. Можно создать последовательность как способ обхода для массива — i++. Для списка p=p.next. Тут никакие дополнительные структуры не требуются.

IEnumerator/IEnumerable — высокоуровневая абстракция над i++ и p=p.next

PD>А в дереве это не получится.

Получится в виде комбинации перечислителей.

PD>Так что твоя последовательность как способ обхода есть по сути дела некая управляющая структура над эти деревом. И как тут может быть O(C) — не понимаю, если в императивном O(log N).

Каждый из перечислителей занимает O(C) места. Но их комбинация будет O(log N). Т.е. ровно как и в императиве. Просто стек перерождается в другую структуру, которая полностью ему соответствует с тем лишь отличием, что будет работать отложенно, а не сразу.

PD>К примеру, я мог бы обойти это дерево как написал и выложить все указатели в массив. После этого пройти итератором будет несложно, но это не решение.

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

S>>Мы можем по ней пройти через foreach


PD>Вот-вот. each что ? Управляющий элемент для каждого элемента дерева ?

Each — это подузлы. Но управляющая структура все-же создается при прохождении в foreach. См. IEnumerable/IEnumerator.

PD>Это все слова. Да, я понял, что Where тут не контейнер. Отлично. Но начнешь итерировать — будет там ++ где-то внутри какого-то регистра или индекса, и не надо никаких новых байт для этого. Но в дереве же такое невозможно!


В дереве во время итерации по внешней последовательности, полученной в результате Walk метода, будут создаваться новые итераторы по мере погружения в дерево.
Если виртуально собрать все итераторы, созданные и собранные сборщиком во время обхода дерева, то да, их структура повторит дерево полностью. Однако в каждый конкретный момент активны только те итераторы, которые выстроены вдоль текущего пути в дереве. Структура активных энумераторов будет абсолютно соответствовать стэку в императивном подходе, который в каждый момент времени хранит лишь узлы вдоль текущего пути, а за все время проходит дерево целиком.
Re[21]: возвращаю задачу специалистам обратно
От: Pavel Dvorkin Россия  
Дата: 24.02.10 08:46
Оценка:
Здравствуйте, samius, Вы писали:
S>В дереве во время итерации по внешней последовательности, полученной в результате Walk метода, будут создаваться новые итераторы по мере погружения в дерево.
S>Если виртуально собрать все итераторы, созданные и собранные сборщиком во время обхода дерева, то да, их структура повторит дерево полностью. Однако в каждый конкретный момент активны только те итераторы, которые выстроены вдоль текущего пути в дереве. Структура активных энумераторов будет абсолютно соответствовать стэку в императивном подходе, который в каждый момент времени хранит лишь узлы вдоль текущего пути, а за все время проходит дерево целиком.

В общем, если я тебя правильно понял, ты утверждаешь следующее. В ходе прохода по дереву при погружении будут создаваться новые экземпляры некоего класса под названием "итератор" (и уничтожались бы они тоже при подъеме, если бы мы не в .NET, а в C++ были). Логически набор этих экземпляров эквивалентен стеку в классическом алгоритме. Правильно ?

Остается один вопрос — а что это такое в данном случае — итератор ? Нет, я не спрашиваю, что такое итератор вообще, я хочу понять. что он есть в данном конкретном случае. Все же эффективнее стека найти структуру данных сложно.
With best regards
Pavel Dvorkin
Re[22]: возвращаю задачу специалистам обратно
От: samius Япония http://sams-tricks.blogspot.com
Дата: 24.02.10 09:02
Оценка: 18 (1)
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>В общем, если я тебя правильно понял, ты утверждаешь следующее. В ходе прохода по дереву при погружении будут создаваться новые экземпляры некоего класса под названием "итератор" (и уничтожались бы они тоже при подъеме, если бы мы не в .NET, а в C++ были). Логически набор этих экземпляров эквивалентен стеку в классическом алгоритме. Правильно ?


Да, правильно и очень лаконично.

PD>Остается один вопрос — а что это такое в данном случае — итератор ? Нет, я не спрашиваю, что такое итератор вообще, я хочу понять. что он есть в данном конкретном случае.

В данном конкретном случае итератор (точнее их комбинирование) есть мост от дерева к методам, работающим с итераторами.

PD>Все же эффективнее стека найти структуру данных сложно.

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

Но в случае дерева — соглашусь. Реализация на стеке будет эффективнее чем на комбинировании итераторов (хоть и алгоритмически эквивалентна). Зато приведение дерева к последовательности позволяет задействовать весь арсенал методов LINQ-а (выборка/маппирование, фильтрация, группировка, упорядочивание, склеивание, теоретико-множественные операции Intersect+Union+Except и т.п.).
Re[23]: возвращаю задачу специалистам обратно
От: Pavel Dvorkin Россия  
Дата: 24.02.10 09:19
Оценка:
Здравствуйте, samius, Вы писали:


PD>>Остается один вопрос — а что это такое в данном случае — итератор ? Нет, я не спрашиваю, что такое итератор вообще, я хочу понять. что он есть в данном конкретном случае.

S>В данном конкретном случае итератор (точнее их комбинирование) есть мост от дерева к методам, работающим с итераторами.

Не то. Я имел в виду, что он реально содержит. Ссылки на Left-Right или что-то еще ?

Кстати, дурацкий вопрос. А не существует ли компиляции с LinQ на императивный код ? . Я не прошу эффективно это сделать и не для productive. Пусть хоть псевдокод. Просто хочется понять, что же там делается. Я посмотрел ассемблер — там не скоро разберешься, сплошные call.

PD>>Все же эффективнее стека найти структуру данных сложно.

S>В общем случае я не могу согласиться с таким утверждением, все зависит от задачи. Например, факториал можно посчитать с помощью стека (callstack), а можно с помощью аккумулятора.

Я неточно выразился. Я хотел сказать, что структуру данных "стек" заменить на более простую данных нелегко. Массив разве что. А ты привел пример, когда "массовую" структуру данных можно вообще выкинуть.


S>Но в случае дерева — соглашусь. Реализация на стеке будет эффективнее чем на комбинировании итераторов (хоть и алгоритмически эквивалентна). Зато приведение дерева к последовательности позволяет задействовать весь арсенал методов LINQ-а (выборка/маппирование, фильтрация, группировка, упорядочивание, склеивание, теоретико-множественные операции Intersect+Union+Except и т.п.).


Спасибо за дискуссию.
With best regards
Pavel Dvorkin
Re[24]: возвращаю задачу специалистам обратно
От: samius Япония http://sams-tricks.blogspot.com
Дата: 24.02.10 09:51
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

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


S>>В данном конкретном случае итератор (точнее их комбинирование) есть мост от дерева к методам, работающим с итераторами.


PD>Не то. Я имел в виду, что он реально содержит. Ссылки на Left-Right или что-то еще ?

Итератор содержит физическую ссылку на узел дерева, потом во время работы щупает наличие Left/Right узлов и возвращает их (но хранит только один узел).

PD>Кстати, дурацкий вопрос. А не существует ли компиляции с LinQ на императивный код ? . Я не прошу эффективно это сделать и не для productive. Пусть хоть псевдокод.

Не думаю. У LINQ чисто функциональная природа.

PD>Просто хочется понять, что же там делается. Я посмотрел ассемблер — там не скоро разберешься, сплошные call.

Начать понимание лучше всего с интерфейсов IEnumerable/IEnumerator и ручной их реализации для примитивных коллекций типа ArrayList. Reflector поможет. Потом разобраться с конструкцией yield return и генерацией компилятором соответствующего конечного автомата в реализации IEnumerator<T>. MSDN + прототип на C# + Рефлектор.
После этого станет прозрачно устройство LINQ через Рефлектор.

PD>Спасибо за дискуссию.


Спасибо за оценку!
Re[4]: вопрос к специалистам
От: VladD2 Российская Империя www.nemerle.org
Дата: 24.02.10 13:07
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Спасибо. Вот именно это я и хотел узнать — выделено выше. У меня было то же ощущение — что LinQ (как и его духовный предок SQL) предназначен для обработки линейных структур (в общем понимании этого слова).


Очень советую по ближе познакомиться с Лиспом. Там все типы данных — списки. И при этом есть и хэш-таблицы, и деревья.

PD>Для структур нелинейного характера (деревья, графы и т.д.) он, как мне кажется, не слишком подходит.


Любое дерево в конечном итоге — это набор элементов. Рано или поздно тебе понадобиться обработать их все. И тут линк будет к стати.

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

PD>Хотя samius и Dufrenite пытаются меня убедить в обратном. Почитай эту часть дискуссии, она еще не кончена, можешь там высказаться.


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

PD>И второе, это уже вопрос. Если речь идет о запросе — ладно. А если не о запросе ? Я, может, ошибаюсь опять, но вроде бы LinQ — это функциональное программирование. А оно позиционируется как альтернатива императивному. Если альтернатива — будьте добры обеспечить мне возможность сделать все, что я там могу сделать, иначе что же это за альтернатива! А если это только добавление — тогда уж так и будем говорить.


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

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

Линк — это в первую очередь библиотека таких фукнций высшего порядка. Они в основно предназначены для работы со последовательностями (т.е. наборами данных). Но деревья и хэш-таблицы — это тоже разновидность последовательности. Кроме того сам подход принятый в ФП позволяет точно так же создавать свои "мелкие алгоритмы". Это позволяет делать код более высокоуровневым и не содержащим дублирование мелких элементов.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[5]: вопрос к специалистам
От: Pavel Dvorkin Россия  
Дата: 24.02.10 13:24
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Очень советую по ближе познакомиться с Лиспом. Там все типы данных — списки. И при этом есть и хэш-таблицы, и деревья.


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

PD>>Для структур нелинейного характера (деревья, графы и т.д.) он, как мне кажется, не слишком подходит.


VD>Любое дерево в конечном итоге — это набор элементов. Рано или поздно тебе понадобиться обработать их все. И тут линк будет к стати.


Мне совсем не обязательно нужно обработать их все. Даже банальный Search в BST просматривает только Log N. Впрочем, его мы уже обсудили, там вообще проход по списку, а не по дереву. Но и в других случаях обработка всех не нужна. Впрочем, это не так важно.


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


Да нет у меня насчет LinQ никаких убеждений, кроме того, что это в несколько раз медленнее. Но это я здесь не обсуждал.

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


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


А все же, можешь что-то сказать насчет SearchAndInsert в BST ? То есть вроде как запрос, но в самый интересный момент он превращается во вставку, тут же, по ходу действия, а потом опять в запрос (при отсутствии вставить и вернуть) ? Вариант с, как ты пишешь, "вводить новые копируя в них информацию из старых и меняя нужные подэлементы", тут вроде как не проходит.

VD>По сути все преимущества ФП которые дает линк — это приемущества вызванные использованием функций высшего порядка. Другими словами — это возможность более детальной декомпозиции кода путем вынесения мелких алгоритмов в отдельные функции и настройки их с помощью лямбд (т.е. еще более мелких функций передаваемых в качестве параметров).


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

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


ИМХО все же дерево — это дерево, а не последовательность. Линейный и разветвленные структуры — это все же не одно и то же, принципиально. Так следующим шагом ты и граф в последовательность превратишь Конечно, я говорю о самой структуре, а не о результате ее сериализации.
With best regards
Pavel Dvorkin
Re[19]: возвращаю задачу специалистам обратно
От: Dufrenite Дания  
Дата: 24.02.10 15:33
Оценка:
Здравствуйте, samius, Вы писали:

S>Однако, справедливо считать что сложность ПВГ O(N), хотя глубина рекурсии там тоже будет соответствовать высоте дерева. Предлагаю не учитывать стоимость вызова по цепочке енумераторов в алгоритмической оценке потому как его вклад будет соразмерен рекурсивному вызову, который не учитывается.


Мы можем учитывать или не учитывать проход по цепочке енумераторов, но я больше чем уверен, что время выполнения алгоритма будет расти по закону N * log(N), так как наиболее существенным в данном случае является вызов метода MoveNext(), а количество этих вызовов растет как раз по этому закону.

Этот факт как раз подтверждает тезис о том, что за удобство частенько приходится чем-то расплачиваться.
Re[18]: возвращаю задачу специалистам обратно
От: Dufrenite Дания  
Дата: 24.02.10 15:43
Оценка: 18 (1)
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Но дело не в этом. Я никак не могу понять, каким образом можно итерировать по дереву, не создав промежуточных структур, причем массовых. Ну хорошо, элементы не копируются. Но пройти дерево — надо или стек заводить, или рекурсию, других способов вроде нет. В любом случае это дополнительная память. Что именно здесь делается ?


Для понимания того, что происходит в высокоуровневом коде удобно использовать Рефлектор.
Вот декомпилированный код класса, возвращаемого функцией Values():

[CompilerGenerated]
private sealed class <Values>d__0 : IEnumerable<int>, IEnumerable, IEnumerator<int>, IEnumerator, IDisposable
{
    // Fields
    private int <>1__state;
    private int <>2__current;
    public Program.Node <>3__root;
    public IEnumerator<int> <>7__wrap3;
    private int <>l__initialThreadId;
    public IEnumerable<int> <childValues>5__1;
    public int <value>5__2;
    public Program.Node root;

    // Methods
    [DebuggerHidden]
    public <Values>d__0(int <>1__state)
    {
        this.<>1__state = <>1__state;
        this.<>l__initialThreadId = Thread.CurrentThread.ManagedThreadId;
    }

    private void <>m__Finally4()
    {
        this.<>1__state = -1;
        if (this.<>7__wrap3 != null)
        {
            this.<>7__wrap3.Dispose();
        }
    }

    private bool MoveNext()
    {
        try
        {
            switch (this.<>1__state)
            {
                case 0:
                    this.<>1__state = -1;
                    if (object.ReferenceEquals(this.root, null))
                    {
                        break;
                    }
                    this.<>2__current = this.root.Value;
                    this.<>1__state = 1;
                    return true;

                case 1:
                    this.<>1__state = -1;
                    this.<childValues>5__1 = Program.Values(this.root.Left).Concat<int>(Program.Values(this.root.Right));
                    this.<>7__wrap3 = this.<childValues>5__1.GetEnumerator();
                    this.<>1__state = 2;
                    while (this.<>7__wrap3.MoveNext())
                    {
                        this.<value>5__2 = this.<>7__wrap3.Current;
                        this.<>2__current = this.<value>5__2;
                        this.<>1__state = 3;
                        return true;
                    Label_00DE:
                        this.<>1__state = 2;
                    }
                    this.<>m__Finally4();
                    break;

                case 3:
                    goto Label_00DE;
            }
            return false;
        }
        fault
        {
            this.System.IDisposable.Dispose();
        }
    }

    [DebuggerHidden]
    IEnumerator<int> IEnumerable<int>.GetEnumerator()
    {
        Program.<Values>d__0 d__;
        if ((Thread.CurrentThread.ManagedThreadId == this.<>l__initialThreadId) && (this.<>1__state == -2))
        {
            this.<>1__state = 0;
            d__ = this;
        }
        else
        {
            d__ = new Program.<Values>d__0(0);
        }
        d__.root = this.<>3__root;
        return d__;
    }

    [DebuggerHidden]
    IEnumerator IEnumerable.GetEnumerator()
    {
        return this.System.Collections.Generic.IEnumerable<System.Int32>.GetEnumerator();
    }

    [DebuggerHidden]
    void IEnumerator.Reset()
    {
        throw new NotSupportedException();
    }

    void IDisposable.Dispose()
    {
        switch (this.<>1__state)
        {
            case 2:
            case 3:
                break;

            default:
                break;
                try
                {
                }
                finally
                {
                    this.<>m__Finally4();
                }
                break;
        }
    }

    // Properties
    int IEnumerator<int>.Current
    {
        [DebuggerHidden]
        get
        {
            return this.<>2__current;
        }
    }

    object IEnumerator.Current
    {
        [DebuggerHidden]
        get
        {
            return this.<>2__current;
        }
    }
}


Из этого кода видно, что енумератор содержит поле <>7__wrap3, которое фактически является ссылкой на енумератор следующего уровня. Получается, действительно, некая разновидность стека.
Re[6]: вопрос к специалистам
От: VladD2 Российская Империя www.nemerle.org
Дата: 24.02.10 16:39
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Мне совсем не обязательно нужно обработать их все.


Это вопрос взглядов на алгоритмы.

PD>Даже банальный Search в BST просматривает только Log N. Впрочем, его мы уже обсудили, там вообще проход по списку, а не по дереву. Но и в других случаях обработка всех не нужна. Впрочем, это не так важно.


Дык, а что нужно? Обычно нужно найти некоторые элементы отвечающие критерию. Для этого можно воспользоваться теми же методами Where или First. Ну, а чтобы они не делали полный перебор написать специализированную версию использующую поиск по ключу.

PD>А все же, можешь что-то сказать насчет SearchAndInsert в BST ?


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

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

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

PD> То есть вроде как запрос, но в самый интересный момент он превращается во вставку, тут же, по ходу действия, а потом опять в запрос (при отсутствии вставить и вернуть) ? Вариант с, как ты пишешь, "вводить новые копируя в них информацию из старых и меняя нужные подэлементы", тут вроде как не проходит.


Тут никаких запросов нет. Это вообще какой-то изврат — тандем двух методов. Причем методов (по всей видимости) работающих с отдельными элементами. А тут линк не к чему. Линк он нужен чтобы не возиться с отдельными элементами, а работать с их группами.

PD>Хм... Ну ладно. Хотя вроде как выносить мелкие алгоритмы в отдельные функции мы и так умели давно. И даже передавать им в качестве параметров иные функции, хоть и не лямбды.


Ну, значит ты давно пользовался ФП не подозревая об этом. Хотя более правдоподобным выглядит предположение о том, что ты преувеличиваешь.

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

PD>ИМХО все же дерево — это дерево, а не последовательность. Линейный и разветвленные структуры — это все же не одно и то же, принципиально. Так следующим шагом ты и граф в последовательность превратишь Конечно, я говорю о самой структуре, а не о результате ее сериализации.


Ну, ты уж как-то давай сам решай. Или ты задаешь вопросы и получаешь ответы, или ты уже сам все решил, но тогда не стоит задавать вопросы.

Твое ИМПХО базируется на старых привычках. У меня было тоже самое, но я сумел перестроиться. Попробуй и ты. Не выйдет, значит и дальше ничего в линке не будешь видеть. В принципе не проблема. На циклах тоже можно программировать. Несколько медленнее конечно, но не смертельно.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[20]: возвращаю задачу специалистам обратно
От: samius Япония http://sams-tricks.blogspot.com
Дата: 24.02.10 18:08
Оценка: +2
Здравствуйте, Dufrenite, Вы писали:

D>Мы можем учитывать или не учитывать проход по цепочке енумераторов, но я больше чем уверен, что время выполнения алгоритма будет расти по закону N * log(N), так как наиболее существенным в данном случае является вызов метода MoveNext(), а количество этих вызовов растет как раз по этому закону.


Возможно так и будет при ОЧЕНЬ большой глубине дерева порядка от нескольких миллионов элементов. А в таком случае имеет смысл задуматься а стоит ли вообще использовать LINQ, если время выполнения существенно...

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

В программировании довольно часто приходится расплачиваться производительностью за удобство и наоборот. Но гораздо лучше когда высокоуровневые средства есть под рукой, чем их нет. Тогда есть выбор, использовать их или нет в зависимости от ситуации.
Re[21]: возвращаю задачу специалистам обратно
От: Dufrenite Дания  
Дата: 24.02.10 21:09
Оценка:
Здравствуйте, samius, Вы писали:

S>А в таком случае имеет смысл задуматься а стоит ли вообще использовать LINQ, если время выполнения существенно...


В большинстве случаев такая сложность вполне приемлема. Например, если в последовательности преобразований есть сортировка, то сложность будет N * log(N).

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


Полностью поддерживаю.
Re[7]: вопрос к специалистам
От: Pavel Dvorkin Россия  
Дата: 25.02.10 07:11
Оценка:
Здравствуйте, VladD2, Вы писали:

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


PD>>Мне совсем не обязательно нужно обработать их все.


VD>Это вопрос взглядов на алгоритмы.


Я бы так сказал — это вопрос алгоритма. Поиск в BST, например, этого совсем не требует.


PD>>А все же, можешь что-то сказать насчет SearchAndInsert в BST ?


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


Хм... Ну а доведись тебе все же ее писать (алгоритм-то стандартный, школьный, можно сказать) — что напишешь ?

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


В общем-то верно. Добавляется одна запись. Но тогда ФП не есть замена императивному коду, а только дополнение. Так ?

Вот смотри. Мы тут с samius и Dufrenite пообсуждали деревья, и решение для всякого поиска они предложили на LinQ. Теперь представь себе, что есть у меня BST. Откуда взялось — не важно, но в данный момент сформировано окончательно и изменениям не подлежит (это мне так кажется). Я беру их код с поиском на LinQ и вставляю к себе. Все на ура. И тут выясняется, что я кое-что не учел, и если поиск неудачен, то надо этот ненайденный ключ вставить в BST. Что делать-то ? Выбросить весь код и переписать в императивном стиле ?

VD>Когда кто-то использует функциональный стиль, то он вместо возни с одним элементов отчирает их группу и вдет работу с ней. При этом отобранная группа обычно помещается в новую коллекцию.


Влад, я думаю, не стоит опять начинать дискуссию насчет объемов данных и осмысленности копирования, мы это уже не раз обсуждали, без толку. Но хочу отметить, что в моем примере чуть выше это просто не пройдет. Ну не предлагаешь же ты скопировать все BST ради вставки одного элемента — это же чепуха совсем получится! Да и как это сделать — все равно же вставлять придется ?

PD>> То есть вроде как запрос, но в самый интересный момент он превращается во вставку, тут же, по ходу действия, а потом опять в запрос (при отсутствии вставить и вернуть) ? Вариант с, как ты пишешь, "вводить новые копируя в них информацию из старых и меняя нужные подэлементы", тут вроде как не проходит.


VD>Тут никаких запросов нет. Это вообще какой-то изврат — тандем двух методов.


Побойся бога! Это один из классических алгоритмов! Более того, никакого другого способа строить BST я не знаю, его просто нет.

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


Вот это я так и понимаю. Но мой вопрос остается. Сформулирую его точно.
Мне надо работать с BST. Делать BST буду сам

class TreeElem {
int key;
TreeElem Left, Right;
}

Операция, в сущности одна — SearchAndInsert. Иногда только Search, то есть вместо вставки вернуть null, если не найдено.

LinQ не пойдет ? Да или нет ?

PD>>Хм... Ну ладно. Хотя вроде как выносить мелкие алгоритмы в отдельные функции мы и так умели давно. И даже передавать им в качестве параметров иные функции, хоть и не лямбды.


VD>Ну, значит ты давно пользовался ФП не подозревая об этом. Хотя более правдоподобным выглядит предположение о том, что ты преувеличиваешь.


Что я преувеличиваю ? Вспомни нелюбимый тобой Win32, там функций с callback параметрами полным-полно. А это даже не С++, а чистый С.

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


Ну не знаю. Может, мы о разных вещах говорим.

PD>>ИМХО все же дерево — это дерево, а не последовательность. Линейный и разветвленные структуры — это все же не одно и то же, принципиально. Так следующим шагом ты и граф в последовательность превратишь Конечно, я говорю о самой структуре, а не о результате ее сериализации.


VD>Ну, ты уж как-то давай сам решай. Или ты задаешь вопросы и получаешь ответы, или ты уже сам все решил, но тогда не стоит задавать вопросы.


Опять ты на свой тон сбиваешься. Я не задаю вопросы и не получаю ответы, я веду дискуссию, и в ней могу высказать свое мнение, тем более, что здесь речь идет не о LinQ, которого я не знаю, а о структурах данных — разделе, где у меня есть некоторые основания высказывать свое мнение

VD>Твое ИМПХО базируется на старых привычках.


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

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


Да никакой проблемы нет. Для моих задач LinQ совершенно неуместен, и я его использовать не буду, там скорость критична. Мне просто интересно, с чего вы все так на него набросились при всех его недостатках. Вот и пытаюсь разобраться, что он может, а что нет. Из чисто познавательских целей.
With best regards
Pavel Dvorkin
Re[8]: вопрос к специалистам
От: samius Япония http://sams-tricks.blogspot.com
Дата: 25.02.10 08:15
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>В общем-то верно. Добавляется одна запись. Но тогда ФП не есть замена императивному коду, а только дополнение. Так ?

Не замена, не дополнение, а альтернатива.

PD>Вот смотри. Мы тут с samius и Dufrenite пообсуждали деревья, и решение для всякого поиска они предложили на LinQ. Теперь представь себе, что есть у меня BST. Откуда взялось — не важно, но в данный момент сформировано окончательно и изменениям не подлежит (это мне так кажется). Я беру их код с поиском на LinQ и вставляю к себе. Все на ура. И тут выясняется, что я кое-что не учел, и если поиск неудачен, то надо этот ненайденный ключ вставить в BST. Что делать-то ? Выбросить весь код и переписать в императивном стиле ?

Нет, написать новых 10 строчек кода для вставки.

VD>>Когда кто-то использует функциональный стиль, то он вместо возни с одним элементов отчирает их группу и вдет работу с ней. При этом отобранная группа обычно помещается в новую коллекцию.


PD>Влад, я думаю, не стоит опять начинать дискуссию насчет объемов данных и осмысленности копирования, мы это уже не раз обсуждали, без толку. Но хочу отметить, что в моем примере чуть выше это просто не пройдет. Ну не предлагаешь же ты скопировать все BST ради вставки одного элемента — это же чепуха совсем получится! Да и как это сделать — все равно же вставлять придется ?

Не нужно копировать ВСЕ BST ради вставки одного элемента. Кол-во вновь созданных элементов при любом "изменении" не превышает высоту дерева (изменение в ковычках потому как дерево не меняется). И вставлять придется не в существующее дерево, а в новое дерево, которое будет в основном состоять из старых элементов.
Вот код, совместимый с предыдущими примерами:
        static Node<T> Insert<T>(this Node<T> tree, T value)
        {
            if(tree == null)
                return new Node<T>(value, null, null);
            var eq = Comparer<T>.Default.Compare(tree.Value, value);
            if (eq == 0)
                return tree;
            return eq > 0
               ? new Node<T>(tree.Value, Insert(tree.Left, value), tree.Right)
               : new Node<T>(tree.Value, tree.Left, Insert(tree.Right, value));
        }



PD>>> То есть вроде как запрос, но в самый интересный момент он превращается во вставку, тут же, по ходу действия, а потом опять в запрос (при отсутствии вставить и вернуть) ? Вариант с, как ты пишешь, "вводить новые копируя в них информацию из старых и меняя нужные подэлементы", тут вроде как не проходит.


VD>>Тут никаких запросов нет. Это вообще какой-то изврат — тандем двух методов.


PD>Побойся бога! Это один из классических алгоритмов! Более того, никакого другого способа строить BST я не знаю, его просто нет.

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

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


PD>Вот это я так и понимаю. Но мой вопрос остается. Сформулирую его точно.

PD>Мне надо работать с BST. Делать BST буду сам

PD>class TreeElem {

PD> int key;
PD> TreeElem Left, Right;
PD>}

PD>Операция, в сущности одна — SearchAndInsert. Иногда только Search, то есть вместо вставки вернуть null, если не найдено.


PD>LinQ не пойдет ? Да или нет ?


Для модификации данных использовать LINQ однозначно зло! Но если дерево мутабельное, то можно сделать следующим образом: SearchAndInsert вызывает поиск узла с value и если его нет, то чтобы вернул узел, куда будем вставлять новый. Это делается линком. После того как узел получен, SearhAndInsert делает небольшой анализ и либо возвращает его, либо создает новый узел и модифицирует существующий. Т.е. мы не модифицируем Search->SearchAndInsert, а делегируем SearhAndInsert=>SearchForInsert.

Пойдет? И LINQ замешан и Insert есть, причем даже императивный/модифицирующий.

PD>Если речь идет о дереве — то оно базируется все же на концепциях структур данных, которые опять же ИМХО ни от чего не зависят, ибо базис.


Павел! Без обид, у Вас базис не полный. Изучите функциональные подходы для работы со структурами данных.
Re[9]: вопрос к специалистам
От: Pavel Dvorkin Россия  
Дата: 25.02.10 08:44
Оценка:
Здравствуйте, samius, Вы писали:

S>Здравствуйте, Pavel Dvorkin, Вы писали:


PD>>В общем-то верно. Добавляется одна запись. Но тогда ФП не есть замена императивному коду, а только дополнение. Так ?

S>Не замена, не дополнение, а альтернатива.

А в чем разница между заменой и альтернативой в данном контексте ? ИМХО если альтернатива — то можно на нее полностью перейти (заменить), ну а если дополнение — перейти можно в части того, где это дополнение работает.

S>Не нужно копировать ВСЕ BST ради вставки одного элемента. Кол-во вновь созданных элементов при любом "изменении" не превышает высоту дерева (изменение в ковычках потому как дерево не меняется). И вставлять придется не в существующее дерево, а в новое дерево, которое будет в основном состоять из старых элементов.


Ну нет, такое мне не надо. За каким богом мне дублировать эту массовую структуру при каждой SearchAndInsert. Я его и BST ценю за log N,


S>Вот код, совместимый с предыдущими примерами:


S>[c#]

S> static Node<T> Insert<T>(this Node<T> tree, T value)
S> {
S> if(tree == null)
S> return new Node<T>(value, null, null);

Это понятно.

S> var eq = Comparer<T>.Default.Compare(tree.Value, value);

S> if (eq == 0)
S> return tree;

И это тоже.

S> return eq > 0

S> ? new Node<T>(tree.Value, Insert(tree.Left, value), tree.Right)
S> : new Node<T>(tree.Value, tree.Left, Insert(tree.Right, value));

А вот это нет. Почему не

return eq > 0
? Insert(tree.Left, value) : Insert(tree.Right, value));


S>Для модификации данных использовать LINQ однозначно зло! Но если дерево мутабельное, то можно сделать следующим образом: SearchAndInsert вызывает поиск узла с value и если его нет, то чтобы вернул узел, куда будем вставлять новый. Это делается линком. После того как узел получен, SearhAndInsert делает небольшой анализ и либо возвращает его, либо создает новый узел и модифицирует существующий. Т.е. мы не модифицируем Search->SearchAndInsert, а делегируем SearhAndInsert=>SearchForInsert.


S>Пойдет? И LINQ замешан и Insert есть, причем даже императивный/модифицирующий.


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


PD>>Если речь идет о дереве — то оно базируется все же на концепциях структур данных, которые опять же ИМХО ни от чего не зависят, ибо базис.


S>Павел! Без обид, у Вас базис не полный.


А у кого он полный ?


>Изучите функциональные подходы для работы со структурами данных.


Извини, но разве функциональный подход что-то может изменить в структурах данных ?. Я же не об алгоритмах говорю.

Влад утверждает, что дерево — это последовательность. Если речь идет о пути поиска минимума или просто поиске в BST — согласен, это последовательность. Но если речь идет о просто дереве, то, разумееется, можно в нем придумать способы последовательного обхода, но называть дерево последовательной структурой...
With best regards
Pavel Dvorkin
Re[10]: вопрос к специалистам
От: samius Япония http://sams-tricks.blogspot.com
Дата: 25.02.10 08:59
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

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


PD>А в чем разница между заменой и альтернативой в данном контексте ? ИМХО если альтернатива — то можно на нее полностью перейти (заменить), ну а если дополнение — перейти можно в части того, где это дополнение работает.


В моем понимании замена — это значит выкинуть старое и применить новое. А альтернатива — это когда можно выбирать.

PD>Ну нет, такое мне не надо. За каким богом мне дублировать эту массовую структуру при каждой SearchAndInsert. Я его и BST ценю за log N,

log N справедливо и для ФП подхода.

S>> return eq > 0

S>> ? new Node<T>(tree.Value, Insert(tree.Left, value), tree.Right)
S>> : new Node<T>(tree.Value, tree.Left, Insert(tree.Right, value));

PD>А вот это нет. Почему не


PD> return eq > 0

PD> ? Insert(tree.Left, value) : Insert(tree.Right, value));
Потому что узлы не модифицируемые и на каждом этапе нужно создать новый.

S>>Пойдет? И LINQ замешан и Insert есть, причем даже императивный/модифицирующий.


PD>Вполне. Правда, он должен вернуть не только узел, куда вставлять, но еще и куда (Left-Right).

Проще вернуть один узел и проанализировать его, ведь вставлять может не потребоваться. А если потребуется, то после анализа будет ясно, в какую сторону.

>>Изучите функциональные подходы для работы со структурами данных.


PD>Извини, но разве функциональный подход что-то может изменить в структурах данных ?. Я же не об алгоритмах говорю.

Что есть структура данных без способов работы с ней?

PD>Влад утверждает, что дерево — это последовательность. Если речь идет о пути поиска минимума или просто поиске в BST — согласен, это последовательность. Но если речь идет о просто дереве, то, разумееется, можно в нем придумать способы последовательного обхода, но называть дерево последовательной структурой...


Более чем уверен что Влад утверждал о последовательности именно как о способе обхода дерева.
Re[11]: вопрос к специалистам
От: Pavel Dvorkin Россия  
Дата: 25.02.10 09:32
Оценка:
Здравствуйте, samius, Вы писали:


S>В моем понимании замена — это значит выкинуть старое и применить новое. А альтернатива — это когда можно выбирать.


Ну ладно, не будем спорить о дефинициях

PD>>Ну нет, такое мне не надо. За каким богом мне дублировать эту массовую структуру при каждой SearchAndInsert. Я его и BST ценю за log N,

S>log N справедливо и для ФП подхода.

S>>> return eq > 0

S>>> ? new Node<T>(tree.Value, Insert(tree.Left, value), tree.Right)
S>>> : new Node<T>(tree.Value, tree.Left, Insert(tree.Right, value));

PD>>А вот это нет. Почему не


PD>> return eq > 0

PD>> ? Insert(tree.Left, value) : Insert(tree.Right, value));
S>Потому что узлы не модифицируемые и на каждом этапе нужно создать новый.

Вот! Именно об этом я и говорю. Код, который ты написал, по сути ничем не отличается от моего — в плане алгоритма. Но я не создаю ничего, кроме одного new элемента и модификации одного указателя (на него). А ты пересоздал зачем-то элементы. Не слишком дорогая плата ? Тем более. что мою рекурсивную SearchAndInsert ты все равно переписал, и даже она длинее (в байтах текста кода)

S>>>Пойдет? И LINQ замешан и Insert есть, причем даже императивный/модифицирующий.


PD>>Вполне. Правда, он должен вернуть не только узел, куда вставлять, но еще и куда (Left-Right).

S>Проще вернуть один узел и проанализировать его, ведь вставлять может не потребоваться. А если потребуется, то после анализа будет ясно, в какую сторону.

Согласен. Хотя мне алгоритм со вставкой по ходу действия кажется логичнее и яснее.

PD>>Извини, но разве функциональный подход что-то может изменить в структурах данных ?. Я же не об алгоритмах говорю.

S>Что есть структура данных без способов работы с ней?

Хм... Все же структура первична, а алгоритмы ИМХО вторичны. Структура данных двоичное дерево есть структура, в которой у каждого элемента не более дух потомков. И это все. Пока все. Это разветвленная структура. Как обходить, к примеру, это дерево — это другой вопрос, кстати, и способов аж 4 есть.

PD>>Влад утверждает, что дерево — это последовательность. Если речь идет о пути поиска минимума или просто поиске в BST — согласен, это последовательность. Но если речь идет о просто дереве, то, разумееется, можно в нем придумать способы последовательного обхода, но называть дерево последовательной структурой...


S>Более чем уверен что Влад утверждал о последовательности именно как о способе обхода дерева.


А это бога ради. В конце концов ваша любимая сериализация и есть в конечном счете обход произвольной структуры с выкладыванием в линию. Но это не значит, что произвольная структура есть последовательность.
With best regards
Pavel Dvorkin
Re[12]: вопрос к специалистам
От: samius Япония http://sams-tricks.blogspot.com
Дата: 25.02.10 09:53
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

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


S>>Потому что узлы не модифицируемые и на каждом этапе нужно создать новый.


PD>Вот! Именно об этом я и говорю. Код, который ты написал, по сути ничем не отличается от моего — в плане алгоритма. Но я не создаю ничего, кроме одного new элемента и модификации одного указателя (на него). А ты пересоздал зачем-то элементы. Не слишком дорогая плата ?

Нет, у иммутабельных структур есть серьезные преимущества, которые часто окупают накладные расходы. А создание элементов в дотнете дешевая операция.

PD>Тем более. что мою рекурсивную SearchAndInsert ты все равно переписал, и даже она длинее (в байтах текста кода)


Если речь об этом

А вот это нет. Почему не

return eq > 0
? Insert(tree.Left, value) : Insert(tree.Right, value));

, то оно не работает.

PD>Согласен. Хотя мне алгоритм со вставкой по ходу действия кажется логичнее и яснее.

Только императивщикам.

S>>Что есть структура данных без способов работы с ней?


PD>Хм... Все же структура первична, а алгоритмы ИМХО вторичны. Структура данных двоичное дерево есть структура, в которой у каждого элемента не более дух потомков. И это все. Пока все. Это разветвленная структура. Как обходить, к примеру, это дерево — это другой вопрос, кстати, и способов аж 4 есть.


Кто-то недавно говорил что знает только один способ вставки элемента в BST

S>>Более чем уверен что Влад утверждал о последовательности именно как о способе обхода дерева.


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

Очевидно что не значит. Но если мы можем применить к ней методы работы с последовательностями, то почему нет? Зачем выдумывать методы работы со структурой когда можно использовать готовые?
Вот я с помощью метода Walk могу ходить по вложенным директориям, по двоичному дереву, по связному графу (даже с циклами) особо не напрягаясь. Следовательно я ко всему этому могу применять LINQ левой пяткой если речь не идет о выжимании тактов и битов. А для моей работы такты и биты не актуальны в 90% случаев.
Re[13]: вопрос к специалистам
От: Pavel Dvorkin Россия  
Дата: 25.02.10 10:03
Оценка:
Здравствуйте, samius, Вы писали:

S>Нет, у иммутабельных структур есть серьезные преимущества, которые часто окупают накладные расходы. А создание элементов в дотнете дешевая операция.


Хоть дешевая, хоть нет, а лишнее пложить незачем.

PD>>Тем более. что мою рекурсивную SearchAndInsert ты все равно переписал, и даже она длинее (в байтах текста кода)



PD>>Согласен. Хотя мне алгоритм со вставкой по ходу действия кажется логичнее и яснее.

S>Только императивщикам.



S>>>Что есть структура данных без способов работы с ней?


PD>>Хм... Все же структура первична, а алгоритмы ИМХО вторичны. Структура данных двоичное дерево есть структура, в которой у каждого элемента не более дух потомков. И это все. Пока все. Это разветвленная структура. Как обходить, к примеру, это дерево — это другой вопрос, кстати, и способов аж 4 есть.


S>Кто-то недавно говорил что знает только один способ вставки элемента в BST


Я говорил. И что ? Вставка в BST делается одни способом, а способов обхода двоичного дерева (не BST) таки 4 . Что тут не так ?

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

S>Очевидно что не значит. Но если мы можем применить к ней методы работы с последовательностями, то почему нет? Зачем выдумывать методы работы со структурой когда можно использовать готовые?

Что мы можем применить ? Методы обхода произвольной структуры ? Бога ради, в конце концов любая структура есть граф, и его можно обойти, и, обходить придется последовательно, потому что иначе мы не умеем (без потоков), у нас в конце концов процессор последовательно работает . Но делать из этого выводы что все есть последовательность — это уж слишком.

S>Вот я с помощью метода Walk могу ходить по вложенным директориям, по двоичному дереву, по связному графу (даже с циклами) особо не напрягаясь. Следовательно я ко всему этому могу применять LINQ левой пяткой если речь не идет о выжимании тактов и битов. А для моей работы такты и биты не актуальны в 90% случаев.


В общем, я с этим могу согласиться. У меня наоборот все, поэтому он мне и не нужен.

И все же какое-то чувство неудовлетворенности у меня. Да, тебе легче работать (левой пяткой , быстрее, да, все понимаю. Но когда я вижу код, который мог бы (а машинном исполнениии) быит намного лучше — мне это не по душе...
With best regards
Pavel Dvorkin
Re[14]: вопрос к специалистам
От: samius Япония http://sams-tricks.blogspot.com
Дата: 25.02.10 10:12
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

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


S>>Нет, у иммутабельных структур есть серьезные преимущества, которые часто окупают накладные расходы. А создание элементов в дотнете дешевая операция.


PD>Хоть дешевая, хоть нет, а лишнее пложить незачем.

Не лишнее, оно окупает бонусы иммутабельности.

S>>Кто-то недавно говорил что знает только один способ вставки элемента в BST


PD>Я говорил. И что ? Вставка в BST делается одни способом, а способов обхода двоичного дерева (не BST) таки 4 . Что тут не так ?

Вставка есть как минимум изменяющая исходное дерево и неизменяющая.

PD>Что мы можем применить ? Методы обхода произвольной структуры ? Бога ради, в конце концов любая структура есть граф, и его можно обойти, и, обходить придется последовательно, потому что иначе мы не умеем (без потоков), у нас в конце концов процессор последовательно работает . Но делать из этого выводы что все есть последовательность — это уж слишком.

Не все есть последовательность, а ко всему применимы методы работы с последовательностями.

PD>И все же какое-то чувство неудовлетворенности у меня. Да, тебе легче работать (левой пяткой , быстрее, да, все понимаю. Но когда я вижу код, который мог бы (а машинном исполнениии) быит намного лучше — мне это не по душе...


А мне не по душе когда я вижу избыточный и дублирующийся код, думая о том парне, кому придется его поддерживать.
Re[18]: возвращаю задачу специалистам обратно
От: vdimas Россия  
Дата: 25.02.10 10:15
Оценка:
Здравствуйте, Dufrenite, Вы писали:


D>Фактически, енумератор, возвращающий листовой элемент, представляет собой связный список енумераторов (это можно увидеть декомпилировав код), длиной с глубину просмотра, а это log(N). Поэтому, при перемещении к следующему элементу, приходится проходить весь список енумераторов.

D>Отсюда и получаем N * log(N).

Угу, хотел добавить, что при любой рекурсии итераторов динамически создается их цепочка длиной в глубину рекурсии (обсуждали это здесь еще в 2005-м году), и затраты на переход к след. элементу зависят от длины цепочки.
Re[15]: вопрос к специалистам
От: Pavel Dvorkin Россия  
Дата: 25.02.10 10:26
Оценка:
Здравствуйте, samius, Вы писали:


PD>>Хоть дешевая, хоть нет, а лишнее пложить незачем.

S>Не лишнее, оно окупает бонусы иммутабельности.

Тут не договоримся.

S>>>Кто-то недавно говорил что знает только один способ вставки элемента в BST


PD>>Я говорил. И что ? Вставка в BST делается одни способом, а способов обхода двоичного дерева (не BST) таки 4 . Что тут не так ?

S>Вставка есть как минимум изменяющая исходное дерево и неизменяющая.

Вставка куда бы то ни было не может не изменять. Если не согласен — как тогда вообще изменить-то ?


PD>>Что мы можем применить ? Методы обхода произвольной структуры ? Бога ради, в конце концов любая структура есть граф, и его можно обойти, и, обходить придется последовательно, потому что иначе мы не умеем (без потоков), у нас в конце концов процессор последовательно работает . Но делать из этого выводы что все есть последовательность — это уж слишком.

S>Не все есть последовательность, а ко всему применимы методы работы с последовательностями.

Теоретически (абстрактно) совершенно безупречное рассуждение. Они даже не только в мире ИТ применимы.

PD>>И все же какое-то чувство неудовлетворенности у меня. Да, тебе легче работать (левой пяткой , быстрее, да, все понимаю. Но когда я вижу код, который мог бы (а машинном исполнениии) быит намного лучше — мне это не по душе...


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


А мне не по душе, когда я вижу код, который мог бы работать быстрее, думая о том парне, которому придется с этой программой работать
With best regards
Pavel Dvorkin
Re[16]: вопрос к специалистам
От: samius Япония http://sams-tricks.blogspot.com
Дата: 25.02.10 10:38
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

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


S>>Вставка есть как минимум изменяющая исходное дерево и неизменяющая.


PD>Вставка куда бы то ни было не может не изменять. Если не согласен — как тогда вообще изменить-то ?

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

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


PD>А мне не по душе, когда я вижу код, который мог бы работать быстрее, думая о том парне, которому придется с этой программой работать

В моем случае перень не заметит разницы даже с секундомером.
Re[17]: вопрос к специалистам
От: Pavel Dvorkin Россия  
Дата: 25.02.10 10:59
Оценка:
Здравствуйте, samius, Вы писали:

S>Здравствуйте, Pavel Dvorkin, Вы писали:


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


S>>>Вставка есть как минимум изменяющая исходное дерево и неизменяющая.


PD>>Вставка куда бы то ни было не может не изменять. Если не согласен — как тогда вообще изменить-то ?

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

Это уже игра в слова. Вставка в моем понимании и есть — взять дерево, добавить элемент и получить новое дерево (пусть мне кто-то скажет, что это прежнее дерево!). Но при этом не меняется истинный root, не меняются никакие ссылки (кроме точенчного изменения в месте вставки) и ничего не копируется — ни данные, ни управляющая информация). Изменения по памяти — O(1). На то оно и дерево. А иначе я могу и упорядоченный массив взять, и он многое из того, что дерево позволяет (Log N поиск хотя бы), да только вставка в нем O(1) не пройдет ни по памяти, ни по времени. И именно за эти свойтсва я ту или иную структуру применяю или отвергаю в данной ситуации.

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


PD>>А мне не по душе, когда я вижу код, который мог бы работать быстрее, думая о том парне, которому придется с этой программой работать

S>В моем случае перень не заметит разницы даже с секундомером.

Значит, для твоих задач это действительно не важно.
With best regards
Pavel Dvorkin
Re[17]: задача для LinQ
От: Pavel Dvorkin Россия  
Дата: 25.02.10 11:03
Оценка:
Здравствуйте, samius, Вы писали:

http://www.rsdn.ru/forum/dotnet/3715037.1.aspx
Автор: hooky-mars
Дата: 24.02.10


Честно говоря, Аверченко вспоминается

«Жасминовые тирсы наших первых мэнад примахались быстро…»
Мне отчасти до боли сделалось жаль наш бестолковый русский народ, а отчасти было досадно: ничего нельзя поручить русскому человеку… Дали ему в руки жасминовый тирс, а он обрадовался, и ну — махать им, пока примахал этот инструмент окончательно.

http://ru.wikisource.org/wiki/%D0%90%D0%BF%D0%BE%D0%BB%D0%BB%D0%BE%D0%BD_(%D0%90%D0%B2%D0%B5%D1%80%D1%87%D0%B5%D0%BD%D0%BA%D0%BE)
With best regards
Pavel Dvorkin
Re[18]: вопрос к специалистам
От: samius Япония http://sams-tricks.blogspot.com
Дата: 25.02.10 11:09
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

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


S>>Здравствуйте, Pavel Dvorkin, Вы писали:


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


S>>>>Вставка есть как минимум изменяющая исходное дерево и неизменяющая.


PD>>>Вставка куда бы то ни было не может не изменять. Если не согласен — как тогда вообще изменить-то ?

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

PD>Это уже игра в слова. Вставка в моем понимании и есть — взять дерево, добавить элемент и получить новое дерево (пусть мне кто-то скажет, что это прежнее дерево!). Но при этом не меняется истинный root, не меняются никакие ссылки (кроме точенчного изменения в месте вставки) и ничего не копируется — ни данные, ни управляющая информация).

Это побочный эффект императивной вставки.

PD>Изменения по памяти — O(1). На то оно и дерево. А иначе я могу и упорядоченный массив взять, и он многое из того, что дерево позволяет (Log N поиск хотя бы), да только вставка в нем O(1) не пройдет ни по памяти, ни по времени. И именно за эти свойтсва я ту или иную структуру применяю или отвергаю в данной ситуации.

А я по другим свойствам. Но об алгоритмических оценках помню.

S>>В моем случае перень не заметит разницы даже с секундомером.


PD>Значит, для твоих задач это действительно не важно.

действительно.
Re[18]: задача для LinQ
От: samius Япония http://sams-tricks.blogspot.com
Дата: 25.02.10 11:16
Оценка: +1
Здравствуйте, Pavel Dvorkin, Вы писали:

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


PD>http://www.rsdn.ru/forum/dotnet/3715037.1.aspx
Автор: hooky-mars
Дата: 24.02.10


PD>Честно говоря, Аверченко вспоминается


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

Другое дело, если человек из опыта ничего не вынесет полезного...
Re[19]: вопрос к специалистам
От: Pavel Dvorkin Россия  
Дата: 25.02.10 11:17
Оценка:
Здравствуйте, samius, Вы писали:

PD>>Это уже игра в слова. Вставка в моем понимании и есть — взять дерево, добавить элемент и получить новое дерево (пусть мне кто-то скажет, что это прежнее дерево!). Но при этом не меняется истинный root, не меняются никакие ссылки (кроме точенчного изменения в месте вставки) и ничего не копируется — ни данные, ни управляющая информация).

S>Это побочный эффект императивной вставки.

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

PD>>Изменения по памяти — O(1). На то оно и дерево. А иначе я могу и упорядоченный массив взять, и он многое из того, что дерево позволяет (Log N поиск хотя бы), да только вставка в нем O(1) не пройдет ни по памяти, ни по времени. И именно за эти свойтсва я ту или иную структуру применяю или отвергаю в данной ситуации.


S>А я по другим свойствам. Но об алгоритмических оценках помню.


Вот именно. Они, вообще-то, не должны ни от языка, ни от среды ни от императивное vs функциональное зависеть не должны. Они таковы в силу природы вещей. Хотя испоритить их (структуры данных) неудачным алгоритмом или средой исполнения можно .
With best regards
Pavel Dvorkin
Re[20]: вопрос к специалистам
От: samius Япония http://sams-tricks.blogspot.com
Дата: 25.02.10 11:19
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

S>>А я по другим свойствам. Но об алгоритмических оценках помню.


PD>Вот именно. Они, вообще-то, не должны ни от языка, ни от среды ни от императивное vs функциональное зависеть не должны. Они таковы в силу природы вещей. Хотя испоритить их (структуры данных) неудачным алгоритмом или средой исполнения можно .


Т.е. ФП испортило структуры данных? Или ФП это неудачное исполнение?
Re[21]: вопрос к специалистам
От: Pavel Dvorkin Россия  
Дата: 25.02.10 11:25
Оценка: -2
Здравствуйте, samius, Вы писали:

S>Здравствуйте, Pavel Dvorkin, Вы писали:


S>>>А я по другим свойствам. Но об алгоритмических оценках помню.


PD>>Вот именно. Они, вообще-то, не должны ни от языка, ни от среды ни от императивное vs функциональное зависеть не должны. Они таковы в силу природы вещей. Хотя испоритить их (структуры данных) неудачным алгоритмом или средой исполнения можно .


S>Т.е. ФП испортило структуры данных? Или ФП это неудачное исполнение?


Не исключаю. Впрочем, не будучи знатоком ФП, выводы делать не буду. Возможно, некая иная реализация имела бы иные свойства в этом плане. В частности LinQ явно унаследован от SQL. А если бы унаследовались от некоего языка для работы с иерархическим данными ? Возможно такое ФП ? (хотя бы в принципе, полезность не обсуждаю)
With best regards
Pavel Dvorkin
Re[22]: вопрос к специалистам
От: samius Япония http://sams-tricks.blogspot.com
Дата: 25.02.10 11:39
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

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


S>>Т.е. ФП испортило структуры данных? Или ФП это неудачное исполнение?


PD>Не исключаю. Впрочем, не будучи знатоком ФП, выводы делать не буду. Возможно, некая иная реализация имела бы иные свойства в этом плане. В частности LinQ явно унаследован от SQL. А если бы унаследовались от некоего языка для работы с иерархическим данными ?

LINQ растет из Haskell-а, а у того с иерархическими данными все впорядке. К SQL LINQ имеет отношение лишь схожим QuerySyntax в реализации C#.

PD> Возможно такое ФП ? (хотя бы в принципе, полезность не обсуждаю)

Возможно ли что в ФП будут другие методы работы с неизменяемыми структурами? Исключено.
А как только ФП начинает использовать изменяемые структуры, то получается гибрид императива с ФП, что уже нельзя отнести к ФП.

Нет понятия "абсолютно быстрый код", но есть понятие "достаточно быстрый код за такую-то цену".
Да, императивный код быстрее (намного ли?). Но он начинает сливать при распараллеливании, т.к. сам себя ждет для того чтобы эксклюзивно изменить состояние.
У всего своя цена.
Re[23]: вопрос к специалистам
От: Pavel Dvorkin Россия  
Дата: 25.02.10 11:57
Оценка:
Здравствуйте, samius, Вы писали:

S>LINQ растет из Haskell-а, а у того с иерархическими данными все впорядке. К SQL LINQ имеет отношение лишь схожим QuerySyntax в реализации C#.


Я вот эту реализацию и имел в виду. Но возможны же другие ?

PD>> Возможно такое ФП ? (хотя бы в принципе, полезность не обсуждаю)

S>Возможно ли что в ФП будут другие методы работы с неизменяемыми структурами? Исключено.
S>А как только ФП начинает использовать изменяемые структуры, то получается гибрид императива с ФП, что уже нельзя отнести к ФП.

Гм...

S>Нет понятия "абсолютно быстрый код", но есть понятие "достаточно быстрый код за такую-то цену".


Ну это уже другая тема, давай не будем.

S>Да, императивный код быстрее (намного ли?).


Намного. В 4-6 раз на простом тесте.

http://rsdn.ru/forum/dotnet/3528765.1.aspx
Автор: Pavel Dvorkin
Дата: 07.09.09


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


Что значит сам себя ? Ждет один поток сигнала от другого. И без ожидания написать многопоточный код , вообще-то, нельзя, просто в силу наличия общих модифицируемых данных. А если ты хочешь сказать, что можно от них избавиться, перейдя к иммутабельным данным, то это применимо очень и очень не всегда. Для дерева ты это сделаешь, проиграв в быстродействии, ладно. А для файла на диске ? Его-то не сдублируешь и копию не сделаешь.

S>У всего своя цена.


Это уж точно.
With best regards
Pavel Dvorkin
Re[24]: вопрос к специалистам
От: samius Япония http://sams-tricks.blogspot.com
Дата: 25.02.10 12:13
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

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


S>>LINQ растет из Haskell-а, а у того с иерархическими данными все впорядке. К SQL LINQ имеет отношение лишь схожим QuerySyntax в реализации C#.


PD>Я вот эту реализацию и имел в виду. Но возможны же другие ?

Реализации QuerySyntax? Да. Они есть и меньше смахивают на SQL и только.

S>>Да, императивный код быстрее (намного ли?).


PD>Намного. В 4-6 раз на простом тесте.


PD>http://rsdn.ru/forum/dotnet/3528765.1.aspx
Автор: Pavel Dvorkin
Дата: 07.09.09


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

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


PD>Что значит сам себя ? Ждет один поток сигнала от другого. И без ожидания написать многопоточный код , вообще-то, нельзя, просто в силу наличия общих модифицируемых данных.

Вот в силу наличия этих данных императив и сливает за счет ожидания.

PD>А если ты хочешь сказать, что можно от них избавиться, перейдя к иммутабельным данным, то это применимо очень и очень не всегда. Для дерева ты это сделаешь, проиграв в быстродействии, ладно. А для файла на диске ? Его-то не сдублируешь и копию не сделаешь.

Разве нельзя сделать копию файла?
Дык причем тут файл-то, если речь идет о распараллеливании? Обычно когда распараллеливают, имеют цель выполнить быстрее счет, а не записать быстрее в файл. Обращение к диску это не CPU-емкие операции.
Re[25]: вопрос к специалистам
От: Pavel Dvorkin Россия  
Дата: 25.02.10 13:01
Оценка:
Здравствуйте, samius, Вы писали:

S>Реализации QuerySyntax? Да. Они есть и меньше смахивают на SQL и только.


OK

S>>>Да, императивный код быстрее (намного ли?).


PD>>Намного. В 4-6 раз на простом тесте.


PD>>http://rsdn.ru/forum/dotnet/3528765.1.aspx
Автор: Pavel Dvorkin
Дата: 07.09.09


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


Надо будет сравнить на дереве в десяток тысяч элементов

PD>>Что значит сам себя ? Ждет один поток сигнала от другого. И без ожидания написать многопоточный код , вообще-то, нельзя, просто в силу наличия общих модифицируемых данных.

S>Вот в силу наличия этих данных императив и сливает за счет ожидания.

Я чего-то не понял. Кто мне мешает в императиве иметь неизменяемые данные и не ждать ? Просто это редкий случай.

PD>>А если ты хочешь сказать, что можно от них избавиться, перейдя к иммутабельным данным, то это применимо очень и очень не всегда. Для дерева ты это сделаешь, проиграв в быстродействии, ладно. А для файла на диске ? Его-то не сдублируешь и копию не сделаешь.

S>Разве нельзя сделать копию файла?

А нельзя, допустим. Вот у меня модифицируется разными потоками файл размером в 1 Гб. Что, копию на каждое изменение байта будем делать ?

S>Дык причем тут файл-то, если речь идет о распараллеливании? Обычно когда распараллеливают, имеют цель выполнить быстрее счет, а не записать быстрее в файл. Обращение к диску это не CPU-емкие операции.


Ну тут ты меня просто удивил. Почитай иные форумы, там сплошь и рядом задача распараллеливания с записью в файл. Разные потоки , например, независимо ведут операции, а писать надо в один и тот же файл. А операции счета я и так могу вести независимо и ничего не ждать, если они не работают с общими данными.
With best regards
Pavel Dvorkin
Re[26]: вопрос к специалистам
От: samius Япония http://sams-tricks.blogspot.com
Дата: 25.02.10 13:26
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

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


PD>>>Что значит сам себя ? Ждет один поток сигнала от другого. И без ожидания написать многопоточный код , вообще-то, нельзя, просто в силу наличия общих модифицируемых данных.

S>>Вот в силу наличия этих данных императив и сливает за счет ожидания.

PD>Я чего-то не понял. Кто мне мешает в императиве иметь неизменяемые данные и не ждать ? Просто это редкий случай.

Вот-вот.

PD>>>А если ты хочешь сказать, что можно от них избавиться, перейдя к иммутабельным данным, то это применимо очень и очень не всегда. Для дерева ты это сделаешь, проиграв в быстродействии, ладно. А для файла на диске ? Его-то не сдублируешь и копию не сделаешь.

S>>Разве нельзя сделать копию файла?

PD>А нельзя, допустим. Вот у меня модифицируется разными потоками файл размером в 1 Гб. Что, копию на каждое изменение байта будем делать ?


По поводу файлов у ФП отдельная философия. Любой ввод-вывод относится к взаимодействию с "внешним миром" где чистота не требуется. Так что на каждое изменение копирования файла не будет, если специально этим не озадачиться.

S>>Дык причем тут файл-то, если речь идет о распараллеливании? Обычно когда распараллеливают, имеют цель выполнить быстрее счет, а не записать быстрее в файл. Обращение к диску это не CPU-емкие операции.


PD>Ну тут ты меня просто удивил. Почитай иные форумы, там сплошь и рядом задача распараллеливания с записью в файл. Разные потоки , например, независимо ведут операции, а писать надо в один и тот же файл. А операции счета я и так могу вести независимо и ничего не ждать, если они не работают с общими данными.

С файлами у ФП дела обстоят не хуже чем в императивном мире.
Re[27]: вопрос к специалистам
От: Pavel Dvorkin Россия  
Дата: 25.02.10 14:14
Оценка:
Здравствуйте, samius, Вы писали:

PD>>Я чего-то не понял. Кто мне мешает в императиве иметь неизменяемые данные и не ждать ? Просто это редкий случай.

S>Вот-вот.

Но я могу сделать это. Просто не надо. И неудобно к тому же.

S>По поводу файлов у ФП отдельная философия. Любой ввод-вывод относится к взаимодействию с "внешним миром" где чистота не требуется. Так что на каждое изменение копирования файла не будет, если специально этим не озадачиться.


Надеюсь, что не будет

S>С файлами у ФП дела обстоят не хуже чем в императивном мире.


Ладно, ИМХО пора заканчивать

With best regards
Pavel Dvorkin
Re[26]: вопрос к специалистам
От: samius Япония http://sams-tricks.blogspot.com
Дата: 25.02.10 14:26
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Надо будет сравнить на дереве в десяток тысяч элементов


    class Node<T>
    {
        public Node(T value, Node<T> left, Node<T> right)
        {
            Value = value;
            Left = left;
            Right = right;
        }
        public T Value { get; set; }
        public Node<T> Left { get; set; }
        public Node<T> Right { get; set; }
    }

    static class Program
    {
        static Node<T> Insert<T>(this Node<T> tree, T value)
        {
            if(tree == null)
                return new Node<T>(value, null, null);
            var eq = Comparer<T>.Default.Compare(tree.Value, value);
            if (eq == 0)
                return tree;
            return eq > 0
               ? new Node<T>(tree.Value, Insert(tree.Left, value), tree.Right)
               : new Node<T>(tree.Value, tree.Left, Insert(tree.Right, value));
        }

        static bool SearchAndInsert<T>(this Node<T> tree, T value)
        {
            if (tree == null)
                throw new ArgumentNullException("tree");

            var eq = Comparer<T>.Default.Compare(tree.Value, value);
            if (eq == 0)
                return true;

            if(eq > 0)
            {
                if(tree.Left != null)
                    SearchAndInsert(tree.Left, value);
                else
                    tree.Left = new Node<T>(value, null, null);
            }
            else
            {
                if (tree.Right != null)
                    SearchAndInsert(tree.Right, value);
                else
                    tree.Right = new Node<T>(value, null, null);
            }
            return false;
        }

        static Node<T> BuildTree<T>(IEnumerable<T> data)
        {
            return data.Aggregate(default(Node<T>), Insert);
        }

        static Node<T> BuildTreeM<T>(IEnumerable<T> data)
        {
            var iter = data.GetEnumerator();
            if(!iter.MoveNext())
            {
                throw new ArgumentException();
            }
            var result = new Node<T>(iter.Current, null, null);
            while (iter.MoveNext())
                SearchAndInsert(result, iter.Current);
            return result;
        }

        static void Main()
        {
            var buffer = Enumerable.Range(0, 1000000).ToArray();
            var rnd = new Random();
            for(int i = 0; i < buffer.Length; i++)
            {
                int j = rnd.Next(buffer.Length);
                var tmp = buffer[i];
                buffer[i] = buffer[j];
                buffer[j] = tmp;
            }

            Test(() => BuildTree(buffer), "Immutable insert");
            Test(() => BuildTreeM(buffer), "SearchAndReplace");

            Console.ReadKey();
        }

        static void Test(Action action, string name)
        {
            Console.WriteLine();
            Console.WriteLine(name);
            var sw = Stopwatch.StartNew();
            action();
            Console.WriteLine(sw.Elapsed);
        }
    }


Immutable insert
00:00:04.4543060

SearchAndReplace
00:00:01.4691780


При том что иммутабельное заполнение дерева в 3 и более раз короче, оно во столько же раз проигрывает по производительности императивному на миллионе вставок.
Можно сказать паритет
Re[28]: вопрос к специалистам
От: samius Япония http://sams-tricks.blogspot.com
Дата: 25.02.10 14:28
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Ладно, ИМХО пора заканчивать


PD>


Не возражаю
Re[8]: вопрос к специалистам
От: VladD2 Российская Империя www.nemerle.org
Дата: 25.02.10 18:12
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

VD>>Это вопрос взглядов на алгоритмы.


PD>Я бы так сказал — это вопрос алгоритма. Поиск в BST, например, этого совсем не требует.


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

PD>Хм... Ну а доведись тебе все же ее писать (алгоритм-то стандартный, школьный, можно сказать) — что напишешь ?


Доведись мне ее писать (а мне доводилось и не раз) я бы такой метод не добавил. Для справки в том же Dictionary<K, V> для оптимизации паттерна "поиск и вставка элемента если он не найден" используется пара методов TryGetValue и Add. Действия тоже императивные, но тем не менее обледенения двух действий в одно не происходит.

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


PD>В общем-то верно. Добавляется одна запись. Но тогда ФП не есть замена императивному коду, а только дополнение. Так ?


Не так. ФП — это альтернативный стиль. Он может быть не всегда эффективным, но за то почти всегда дает заметный выигрышь в объеме и понятности кода.

Пойми простую истину. Твоя мысль действует на более низком уровне нежели мысль того кто пишет функциональный код. Ты думаешь как вставить один элемент в процессе перебора других и возможно еще каких-то там условиях. А функциональное мышление подразумевает мыслить только об исходном наборе данных и преобразованном. В нем нет место одной записи. Там (как и в современных базах данных) мышление ведется на уровне наборов данных (назовем их резалт-сетами).

PD>Вот смотри. Мы тут с samius и Dufrenite пообсуждали деревья, и решение для всякого поиска они предложили на LinQ. Теперь представь себе, что есть у меня BST. Откуда взялось — не важно, но в данный момент сформировано окончательно и изменениям не подлежит (это мне так кажется). Я беру их код с поиском на LinQ и вставляю к себе. Все на ура. И тут выясняется, что я кое-что не учел, и если поиск неудачен, то надо этот ненайденный ключ вставить в BST. Что делать-то ?


PD> Выбросить весь код и переписать в императивном стиле ?


Одно из двух. Или ты просто вставишь нужный элемент в императивном стиле (смешав его с функцональным кодом), или будешь мыслить в терминах преобразования коллекций где не нужно вставлять элементы в старую коллекцию, так как результат каждой операции — это новая коллекция.

Вот смотри. В Map.n находится реализация функционального Map-а (ассоциативного массива построенного на базе дерева). А вот пример его использования:
    def sm = Map ();
    assert (sm.IsEmpty && sm.Count == 0);

    def sm = sm.Add ("raz", seed);
    def sm = sm.Add ("dwa", 2 * seed);
    def sm = sm.Add ("trzy", 3 * seed);
    assert (!sm.IsEmpty && sm.Count == 3);

    sm.Iter (fun (k, v) { printf ("No to %s: %i\n", k, v) });

    // moved from testsuite/positive/map.n:
    def map = Map ();
    def map = map.Add (1,"1");
    def map = map.Add (2,"2");
    def map = map.Add (3, "2");
    def map = map.Remove (3);
    def map = map.Add (3, "4");
    map.Iter (fun (elem, str) {printf ("%d %s\n", elem, str)});
    printf ("size : %d\n", map.Count);
    when (! map.Contains (3))
      printf ("wrong member\n");
    def map = map.Remove (3);
    match (map.Find (3)) {
    | Some => printf ("wrong get\n")
    | None => printf ("ok\n")
    };
    printf ("size : %d\n", map.Count);
    def map = map.Add (4, "3");
    def map = map.Replace (4, "4");
    printf ("size : %d\n", map.Count);
    map.Iter (fun (elem, str) {printf ("%d %s\n", elem, str)});
    match (map.Partition ( fun (x, _) { x>2 })) {
      (ymap, nmap) =>
        printf ("1st part :\n");
        ymap.Iter (fun (elem, str) {printf ("%d %s\n", elem, str)});
        printf ("2nd part :\n");
        nmap.Iter (fun (elem, str) {printf ("%d %s\n", elem, str)})
    }


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

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


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

PD>Ну не предлагаешь же ты скопировать все BST ради вставки одного элемента — это же чепуха совсем получится! Да и как это сделать — все равно же вставлять придется ?


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

PD>Побойся бога! Это один из классических алгоритмов!


Точнее будет сказать — доисторических.

PD>Более того, никакого другого способа строить BST я не знаю, его просто нет.


BST — это вообще что?

PD>Вот это я так и понимаю. Но мой вопрос остается. Сформулирую его точно.

PD>Мне надо работать с BST. Делать BST буду сам

PD>class TreeElem {

PD> int key;
PD> TreeElem Left, Right;
PD>}

PD>Операция, в сущности одна — SearchAndInsert. Иногда только Search, то есть вместо вставки вернуть null, если не найдено.


PD>LinQ не пойдет ? Да или нет ?


Как ты сам уже говорил. Повторяться тут бессмысленно. Не хочешь понимать, не понимай.

PD>>>Хм... Ну ладно. Хотя вроде как выносить мелкие алгоритмы в отдельные функции мы и так умели давно. И даже передавать им в качестве параметров иные функции, хоть и не лямбды.


VD>>Ну, значит ты давно пользовался ФП не подозревая об этом. Хотя более правдоподобным выглядит предположение о том, что ты преувеличиваешь.


PD>Что я преувеличиваю ? Вспомни нелюбимый тобой Win32, там функций с callback параметрами полным-полно. А это даже не С++, а чистый С.


Вот это и преувеличиваешь. Колбэки имеют примерно столько же общего с ФВП, как ассемблер с ООП.
Ну, и твоя настойчивость в вопросе возни с отдельными элементами четко показывает, что абстрагировать мелкие операции ты не умеешь и каждый раз программируешь их на самом нижнем (снова и снова).

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


PD>Ну не знаю.


Так познакомься. Там делов то.

PD>Может, мы о разных вещах говорим.


Ага, о разных. Ознакомься.

PD>>>ИМХО все же дерево — это дерево, а не последовательность. Линейный и разветвленные структуры — это все же не одно и то же, принципиально. Так следующим шагом ты и граф в последовательность превратишь Конечно, я говорю о самой структуре, а не о результате ее сериализации.


VD>>Ну, ты уж как-то давай сам решай. Или ты задаешь вопросы и получаешь ответы, или ты уже сам все решил, но тогда не стоит задавать вопросы.


PD>Опять ты на свой тон сбиваешься.


Какой тон? Ты задал вопрос, и вместо того чтобы разобраться в том, что тебе ответили начал снова гнуть свою линию. Хочешь просто поспорить, так не задавай вопросы, а делай утверждения. А уж если задал вопрос, так будь добр не спорить, а осмысливать ответы.

PD> Я не задаю вопросы


О, как? А это
Автор: Pavel Dvorkin
Дата: 22.02.10
что?

PD>и не получаю ответы, я веду дискуссию, и в ней могу высказать свое мнение, тем более, что здесь речь идет не о LinQ, которого я не знаю, а о структурах данных — разделе, где у меня есть некоторые основания высказывать свое мнение


Да дискутируй сколько влезет. Только без меня. Я не вижу в себе сил тебя переубедить. А тратить время впустую не хочу. Ты задал вопрос, я на него ответил. Не нравится ответ — твои проблемы.

VD>>Твое ИМПХО базируется на старых привычках.


PD>Если речь идет о дереве — то оно базируется все же на концепциях структур данных, которые опять же ИМХО ни от чего не зависят, ибо базис.


Ну, ссылку на функциональное дерево я тебе дал. Погляди на досуге его интерфейс. Будешь удивлен но он практически аналогичен линку.

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


PD>Да никакой проблемы нет.


Ну и славно.

PD> Для моих задач LinQ совершенно неуместен,


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

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


Я за других не скажу. Скажу за себя. Для меня критична скорость разработки и простота сопровождения. Разумное использование ФП в целом и линка в частности позволяет добиться этого. Скорость для меня тоже критична, но я как-то научился добиваться приемлемой скорости используя ФП (где возможно) и ИП (где необходимо).

Я не фанат ни ФП, ни ИП ни чего бы то ни было другого. Я фанат комфорта и удобства. По сему в меру использую все новое что смог осознать и что дает реальный толк.

Кстати, в мире ФП есть и другие красивые решения. Например, алгебраические типы и сопоставление с образцом. В некоторых задачах позволяет координально упростить решение задачи.

Ну, а для того чтобы скорость была высокой и при этом решение не страдало от переусложненности я стараюсь применять МП. Ведь сгенерировать оптимальное решение по вполне простому и декларативному описанию намного легче чем выгадывать такты на каждой операции усложняя при этом свой код до безобразия.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[16]: вопрос к специалистам
От: Dufrenite Дания  
Дата: 25.02.10 18:52
Оценка: +2
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>А мне не по душе, когда я вижу код, который мог бы работать быстрее, думая о том парне, которому придется с этой программой работать


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

Я не имею в виду конкретно способы обхода дерева, эти вещи в принципе тривиальны. Плох сам принцип. Преждевременная оптимизация зло — доказано теорией и проверено на практике.
Re[19]: возвращаю задачу специалистам обратно
От: Dufrenite Дания  
Дата: 25.02.10 18:58
Оценка:
Здравствуйте, vdimas, Вы писали:

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


Я не присутствовал на этом обсуждении, поэтому пришлось открывать данный факт самостоятельно.
Re[17]: вопрос к специалистам
От: IT Россия linq2db.com
Дата: 25.02.10 19:31
Оценка: +6
Здравствуйте, Dufrenite, Вы писали:

D>Я не имею в виду конкретно способы обхода дерева, эти вещи в принципе тривиальны. Плох сам принцип. Преждевременная оптимизация зло — доказано теорией и проверено на практике.


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

Я не защищаю Дворкина, у него ковыряние в битах — это игрушка, которую он не отдаст никому. Но приложений, страдающих от недооптимизаций ничуть не меньше, чем пострадавших от излишней оптимизации.
Если нам не помогут, то мы тоже никого не пощадим.
Re[17]: вопрос к специалистам
От: Undying Россия  
Дата: 26.02.10 06:09
Оценка:
Здравствуйте, Dufrenite, Вы писали:

D>Плох сам принцип. Преждевременная оптимизация зло — доказано теорией и проверено на практике.


Преждевременная пессимизация (например, использование для поиска пробега по списку вместо словаря или бинарного поиска) это тоже зло, ничуть не меньшее чем преждевременная оптимизация.
Re[27]: вопрос к специалистам
От: Pavel Dvorkin Россия  
Дата: 26.02.10 07:53
Оценка:
Здравствуйте, samius, Вы писали:

S>        static bool SearchAndInsert<T>(this Node<T> tree, T value)
S>        {
S>            if (tree == null)
S>                throw new ArgumentNullException("tree");

S>            var eq = Comparer<T>.Default.Compare(tree.Value, value);
S>            if (eq == 0)
S>                return true;

S>            if(eq > 0)
S>            {
S>                if(tree.Left != null)
S>                    SearchAndInsert(tree.Left, value);
S>                else
S>                    tree.Left = new Node<T>(value, null, null);
S>            }
S>            else
S>            {
S>                if (tree.Right != null)
S>                    SearchAndInsert(tree.Right, value);
S>                else
S>                    tree.Right = new Node<T>(value, null, null);
S>            }
S>            return false;
S>        }



Боже, зачем же так сложно и длинно ? Да еще ArgumentNullException, которого тут вообще не должно быть!


    class Node<T>
    {
        public Node(T value, Node<T> left, Node<T> right)
        {
            Value = value;
            Left = left;
            Right = right;
        }
        public T Value { get; set; }
        public Node<T> Left { get; set; }
        public Node<T> Right { get; set; }

// мне пришлось заменить свойства на поля, так как свойства нельзя передавать по ref
// public их делать совсем не обязательно, но лень было возиться :-)
// так что в моем коде не используются твои Left и Right, а используются мои left и right

        public Node<T> left;
        public Node<T> right;
    }

    static class Program
    {
        static Node<T> Insert<T>(this Node<T> tree, T value)
        {
            if (tree == null)
                return new Node<T>(value, null, null);
            var eq = Comparer<T>.Default.Compare(tree.Value, value);
            if (eq == 0)
                return tree;
            return eq > 0
               ? new Node<T>(tree.Value, Insert(tree.Left, value), tree.Right)
               : new Node<T>(tree.Value, tree.Left, Insert(tree.Right, value));
        }

        static bool SearchAndInsert<T>(this Node<T> tree, T value)
        {
            if (tree == null)
                throw new ArgumentNullException("tree");

            var eq = Comparer<T>.Default.Compare(tree.Value, value);
            if (eq == 0)
                return true;

            if (eq > 0)
            {
                if (tree.Left != null)
                    SearchAndInsert(tree.Left, value);
                else
                    tree.Left = new Node<T>(value, null, null);
            }
            else
            {
                if (tree.Right != null)
                    SearchAndInsert(tree.Right, value);
                else
                    tree.Right = new Node<T>(value, null, null);
            }
            return false;
        }

// а вот и моя версия - чистая калька с С++
// DPL - это я (Дворкин Павел Лазаревич :-)
// как видишь, она ничуть не сложнее твоей LinQ-овской, скорее проще :-)

        static bool DPLSearchAndInsert<T>(ref Node<T> tree, T value)
        {
            if (tree == null)
            {
                tree = new Node<T>(value, null, null);
                return false;
            }

            var eq = Comparer<T>.Default.Compare(tree.Value, value);
            if (eq == 0)
                return true;

            if (eq > 0)
                    return DPLSearchAndInsert(ref tree.left, value);
            else
                    return DPLSearchAndInsert(ref tree.right, value);
        }


        static Node<T> BuildTree<T>(IEnumerable<T> data)
        {
            return data.Aggregate(default(Node<T>), Insert);
        }

        static Node<T> BuildTreeM<T>(IEnumerable<T> data)
        {
            var iter = data.GetEnumerator();
            if (!iter.MoveNext())
            {
                throw new ArgumentException();
            }
            var result = new Node<T>(iter.Current, null, null);
            while (iter.MoveNext())
                SearchAndInsert(result, iter.Current);
            return result;
        }
// это мои построитель

        static Node<T> DPLBuildTreeM<T>(IEnumerable<T> data)
        {
            var iter = data.GetEnumerator();
            if (!iter.MoveNext())
            {
                throw new ArgumentException();
            }
// пришлось заменить var на Node<T>, так как var нельзя присвоить null
            Node<T> result = null;
            while (iter.MoveNext())
                DPLSearchAndInsert(ref result, iter.Current);
            return result;
        }
        static void Main()
        {
            var buffer = Enumerable.Range(0, 1000000).ToArray();
            var rnd = new Random();
            for (int i = 0; i < buffer.Length; i++)
            {
                int j = rnd.Next(buffer.Length);
                var tmp = buffer[i];
                buffer[i] = buffer[j];
                buffer[j] = tmp;
            }

            Test(() => BuildTree(buffer), "Immutable insert");
            Test(() => BuildTreeM(buffer), "SearchAndReplace");
            Test(() => DPLBuildTreeM(buffer), "DPLSearchAndReplace");

            Console.ReadKey();
        }

        static void Test(Action action, string name)
        {
            Console.WriteLine();
            Console.WriteLine(name);
            var sw = Stopwatch.StartNew();
            action();
            Console.WriteLine(sw.Elapsed);
        }
    }




S>При том что иммутабельное заполнение дерева в 3 и более раз короче, оно во столько же раз проигрывает по производительности императивному на миллионе вставок.



Immutable insert
00:00:09.9648256

SearchAndReplace
00:00:03.2450794

DPLSearchAndReplace
00:00:02.8752006


S>Можно сказать паритет


Нет, 2.5:0.5 в мою пользу. Я сделал эту DPLSearchAndInsert столь же простой, как твоя, и даже проще, а выигрыш по времени в 3 раза и ни одного лишнего new. Так что я выиграл и по памяти, и по времени, а вот по простоте кода — в лучшем случае паритет

P.S. А вот машина у тебя получше раза в 2. Если не секрет, какой процессор ? У меня Athlon Dual 4200+
With best regards
Pavel Dvorkin
Re[17]: вопрос к специалистам
От: Pavel Dvorkin Россия  
Дата: 26.02.10 08:03
Оценка: +2
Здравствуйте, Dufrenite, Вы писали:

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


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

D>Я не имею в виду конкретно способы обхода дерева, эти вещи в принципе тривиальны. Плох сам принцип. Преждевременная оптимизация зло — доказано теорией и проверено на практике.


Смотря что под ней понимать. Преждевременное выжимание тактов в цикле путем трюков — да, согласен. Но предварительный анализ задачи, оценка ее временнОй и ресурсной зависимости , выбор оптимального алгоритма и структур данных — это именно то, что аналитик должен сделать до того, как будет написана хоть одна строчка кода. Если, конечно, задача не тривиальна.
With best regards
Pavel Dvorkin
Re[28]: вопрос к специалистам
От: samius Япония http://sams-tricks.blogspot.com
Дата: 26.02.10 10:12
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

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


PD>Боже, зачем же так сложно и длинно ? Да еще ArgumentNullException, которого тут вообще не должно быть!

Поспешил

PD>// мне пришлось заменить свойства на поля, так как свойства нельзя передавать по ref

PD>// public их делать совсем не обязательно, но лень было возиться
PD>// так что в моем коде не используются твои Left и Right, а используются мои left и right

По поводу ref у меня пунктик, да и у много кого тоже. Framework Design Guidlines его тоже не рекоммендуют. Хотя, как средство оптимизации он хорош.
Действительно, если метод вставки затолкать в Node<T>, то поля делать публичными не обязательно.

PD>// а вот и моя версия — чистая калька с С++

PD>// DPL — это я (Дворкин Павел Лазаревич
PD>// как видишь, она ничуть не сложнее твоей LinQ-овской, скорее проще
Проще — нет, ref-ы ее не делают проще. Но визуально меньше кода — это да.

S>>При том что иммутабельное заполнение дерева в 3 и более раз короче, оно во столько же раз проигрывает по

S>>Можно сказать паритет

PD>Нет, 2.5:0.5 в мою пользу. Я сделал эту DPLSearchAndInsert столь же простой, как твоя, и даже проще, а выигрыш по времени в 3 раза и ни одного лишнего new. Так что я выиграл и по памяти, и по времени, а вот по простоте кода — в лучшем случае паритет

По времени и памяти — соглашусь.
По простоте кода — нет. Считаем кол-во непустых линий методов вставки и построения дерева:
Моих — 9
Ваших — 21 (если выкинуть скобки, то 19)
+ ref. Лично у меня с ним проблем нет, но он не делает код проще — это точно.

PD>P.S. А вот машина у тебя получше раза в 2. Если не секрет, какой процессор ? У меня Athlon Dual 4200+

Intel Core 2 Duo E6600
Re[29]: вопрос к специалистам
От: Pavel Dvorkin Россия  
Дата: 26.02.10 10:47
Оценка:
Здравствуйте, samius, Вы писали:

S>Здравствуйте, Pavel Dvorkin, Вы писали:


S>По поводу ref у меня пунктик, да и у много кого тоже.


А у меня нет пунктика такого. Я к этому (на Паскале еще — помнишь передачу по var ?) привык. По крайней мере я решительно не вижу, что можно возразить против его применеия в данном конкретном случае.


PD>>Нет, 2.5:0.5 в мою пользу. Я сделал эту DPLSearchAndInsert столь же простой, как твоя, и даже проще, а выигрыш по времени в 3 раза и ни одного лишнего new. Так что я выиграл и по памяти, и по времени, а вот по простоте кода — в лучшем случае паритет

S>По времени и памяти — соглашусь.
S>По простоте кода — нет. Считаем кол-во непустых линий методов вставки и построения дерева:
S>Моих — 9
S>Ваших — 21 (если выкинуть скобки, то 19)

Можно на "ты", как это здесь принято

Ну если суммировать с кодом построения, то да. Но он сам по себе. В С++ не было бы у меня никакого Enumerator и Enumerable и тем более ArgumentException (который здесь вообще-то ни при чем. И чего вы все любите так искать возможные exception ? Ну нет их в этом алгоритме вообще никаких, кроме разве что OutOfMemory). А было бы просто


Node result = NULL;
while(GetNext(value))
 SearchAndInsert(result, value);


GetNext — 2 строчки, return buffer[i++] и проверка на окончание.

With best regards
Pavel Dvorkin
Re[30]: вопрос к специалистам
От: samius Япония http://sams-tricks.blogspot.com
Дата: 26.02.10 11:22
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>А у меня нет пунктика такого. Я к этому (на Паскале еще — помнишь передачу по var ?) привык. По крайней мере я решительно не вижу, что можно возразить против его применеия в данном конкретном случае.

Да, помню var, и &. Если честно, ref-ом активно не пользуюсь только потому что мне не хватает const& -а. Здесь, правда, как раз не тот случай, чтобы const совать.

PD>Можно на "ты", как это здесь принято

Я только "за", ждал твоего предложения

PD>Ну если суммировать с кодом построения, то да. Но он сам по себе. В С++ не было бы у меня никакого Enumerator и Enumerable и тем более ArgumentException (который здесь вообще-то ни при чем. И чего вы все любите так искать возможные exception ?

НЕНАВИЖУ ИХ!!! Но это формальная проверка предусловия, которая более детерминированная чем NullReferenceException, который может выстрелить а может и нет. По какому пути пойдет алгоритм. Язык такой, null-ы летают над головой. Вот в F# немного проще с ними, а в Haskell — вообще лофа!

PD>Ну нет их в этом алгоритме вообще никаких, кроме разве что OutOfMemory).

А StackOverflow!!!

PD>А было бы просто

PD>
PD>Node result = NULL;
PD>while(GetNext(value))
PD> SearchAndInsert(result, value);
PD>


PD>GetNext — 2 строчки, return buffer[i++] и проверка на окончание.

А кто будет хранить buffer и i? Ниужели замыкание?
Re[31]: вопрос к специалистам
От: Pavel Dvorkin Россия  
Дата: 26.02.10 11:34
Оценка:
Здравствуйте, samius, Вы писали:

PD>>Можно на "ты", как это здесь принято

S>Я только "за", ждал твоего предложения

Так по умолчанию же.

PD>>Ну нет их в этом алгоритме вообще никаких, кроме разве что OutOfMemory).

S>А StackOverflow!!!

Ну теоретически да. Но реально я с ним бороться буду не с помощью try-catch, а просто установив нужный размер стека. В С++, кстати, stack overflow сделать — пара пустяков


int main()
{
 int a[1000000];
 // и вот он
}
/ccode]

Лечится элементарно


PD>>А было бы просто
PD>>[ccode]
PD>>Node result = NULL;
PD>>while(GetNext(value))
PD>> SearchAndInsert(result, value);
PD>>


PD>>GetNext — 2 строчки, return buffer[i++] и проверка на окончание.

S>А кто будет хранить buffer и i? Ниужели замыкание?

Если С++ — сделаю их членами класса, и GetNext туда же. ctor (или Create) создает этот массив и рандомизирует.

Если начнешь опять про линии кода говорить — имей в виду, я уже начал Enumerator писать. Я тогда весь его код на тебя повешу
With best regards
Pavel Dvorkin
Re[32]: вопрос к специалистам
От: samius Япония http://sams-tricks.blogspot.com
Дата: 26.02.10 11:49
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

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


PD>>>Ну нет их в этом алгоритме вообще никаких, кроме разве что OutOfMemory).

S>>А StackOverflow!!!

PD>Ну теоретически да. Но реально я с ним бороться буду не с помощью try-catch, а просто установив нужный размер стека. В С++, кстати, stack overflow сделать — пара пустяков


На C# тоже можно. Кстати, в Debug режиме или при запуске из под студии, на миллионе элементов стека уже не хватает для рекурсивных методов.

PD> int a[1000000];

PD> // и вот он

В C# тоже можно такое сделать в unsafe режиме (stackalloc)

PD>Лечится элементарно

За C# не отвечу.

PD>>>GetNext — 2 строчки, return buffer[i++] и проверка на окончание.

S>>А кто будет хранить buffer и i? Ниужели замыкание?

PD>Если С++ — сделаю их членами класса, и GetNext туда же. ctor (или Create) создает этот массив и рандомизирует.

Я так и подумал, что добавление из массива — один класс, из списка — другой.

PD>Если начнешь опять про линии кода говорить — имей в виду, я уже начал Enumerator писать. Я тогда весь его код на тебя повешу

Молчу
Re[33]: вопрос к специалистам
От: Pavel Dvorkin Россия  
Дата: 26.02.10 12:04
Оценка:
Здравствуйте, samius, Вы писали:


S>В C# тоже можно такое сделать в unsafe режиме (stackalloc)


Ну хоть это сделать можно

PD>>Лечится элементарно

S>За C# не отвечу.

Я тоже.

PD>>>>GetNext — 2 строчки, return buffer[i++] и проверка на окончание.

S>>>А кто будет хранить buffer и i? Ниужели замыкание?

PD>>Если С++ — сделаю их членами класса, и GetNext туда же. ctor (или Create) создает этот массив и рандомизирует.

S>Я так и подумал, что добавление из массива — один класс, из списка — другой.

Можно создать абстрактный класс, в нем GetNext, от него отнаследовать список и массив. Собственно, реализации IEnumerator GetNext это и делают — ну нельзя же реально ходить по связанному списку аки по массиву.

Понимаешь, с моей точки зрения я всегда вначале думаю — а что там в конечном счете будет ? Хоть какие обертки накрути, но список останется списком, и p=p.next там в том или виде будет в виде LEA, MOV и т.д. Вот это меня в первую очередь интересует, а уж потом — в какие фантики это обернуто.
With best regards
Pavel Dvorkin
Re[34]: вопрос к специалистам
От: samius Япония http://sams-tricks.blogspot.com
Дата: 26.02.10 12:21
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

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


PD>Можно создать абстрактный класс, в нем GetNext, от него отнаследовать список и массив. Собственно, реализации IEnumerator GetNext это и делают — ну нельзя же реально ходить по связанному списку аки по массиву.

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

PD>Понимаешь, с моей точки зрения я всегда вначале думаю — а что там в конечном счете будет ? Хоть какие обертки накрути, но список останется списком, и p=p.next там в том или виде будет в виде LEA, MOV и т.д. Вот это меня в первую очередь интересует, а уж потом — в какие фантики это обернуто.


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

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

Построение дерева из миллиона элементов за 10 сек — меня это устраивает, даже если можно сделать быстрее. Решение какой-то конкретной задачи за 10 сек — тут зависит от задачи. Может и не устроить, тогда я выберу другую реализацию.
Re[35]: вопрос к специалистам
От: Pavel Dvorkin Россия  
Дата: 26.02.10 12:27
Оценка:
Здравствуйте, samius, Вы писали:

S>Построение дерева из миллиона элементов за 10 сек — меня это устраивает, даже если можно сделать быстрее. Решение какой-то конкретной задачи за 10 сек — тут зависит от задачи. Может и не устроить, тогда я выберу другую реализацию.


В общем, как всегда, истина конкретна.

Have a good weekend!
With best regards
Pavel Dvorkin
Re[36]: вопрос к специалистам
От: samius Япония http://sams-tricks.blogspot.com
Дата: 26.02.10 12:48
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

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


PD>Have a good weekend!

Спасибо, и тебе!
Re[18]: вопрос к специалистам
От: VladD2 Российская Империя www.nemerle.org
Дата: 26.02.10 16:18
Оценка:
Здравствуйте, Undying, Вы писали:

U>Преждевременная пессимизация (например, использование для поиска пробега по списку вместо словаря или бинарного поиска) это тоже зло,


И что, без разницы какой размер списка?
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[17]: вопрос к специалистам
От: vdimas Россия  
Дата: 26.02.10 21:46
Оценка: 12 (3)
Здравствуйте, Dufrenite, Вы писали:

D>Здравствуйте, Pavel Dvorkin, Вы писали:


PD>>А мне не по душе, когда я вижу код, который мог бы работать быстрее, думая о том парне, которому придется с этой программой работать


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


О да!
Знаешь, ты скорее говоришь о ситуации, когда люди увлекаются некоторыми подробностями и за деревьями им становится не видно леса. Но это совсем из другой оперы, оптимизация именно быстродействия чего-либо тут вовсе не при чем. Даже если и прозвучало "мы просто хотели сделать оптимальнее" — это обычная отмазка неопытного разработчика, которому хочется быстрее попрограммировать и быстрее увидеть результат. Стоит ли эту отмазку огульно приписывать всем остальным?

Как бы тебе это сказать потактичнее... Когда все делается "как положено", то еще на стадии анализа многие узкие места могут быть увидены и проверена их реальная "узость" в технических экспериментах. Точно так же может стать понятно, насколько гибким должен быть дизайн. За гибкость ВСЕГДА приходится платить, поэтому преждевременная гибкость — это такая же разновидность преждевременной оптимизации. Да, чем хуже формализованы требования, тем большая гибкость требуется относительно реализации каждого такого требования, но это лишь говорит о том, что ни о какой безусловности твоего лозунга не может быть и речи. Например, требуется ли эта "гибкость дизайна" при разработке кодека по устоявшемуся алгоритму или при реализации TCP протокола?

Могу лишь согласиться с тем, что упомянутая тобой разновидность желания "сделать все лучше" не так тяжела в последствиях, как "битовыжимания", ибо наиболее вероятно такой код не придется выкидывать полностью. Но насколько получится его повторно использовать? В 99% не получается, кроме вот этого одного целевого приложения, поэтому вся эта заведомая гибкость лишь добавляет необоснованных трудозатрат.

Вообще о гибкости говорить странно в эпоху продвинутых сред, анализа кода и мощнейшего рефакторинга, где внести лишнюю асбтракцию или перегруппировать имеющиеся — это как два пальца. Единственный универсальный критерий только один — это чтобы на каждом уровне проектирования/программирования было вменяемое кол-во задействованных сущностей. Собственно, это и есть цель любой декомпозиции — сделать каждую задачу легко обозримой для человеческого мышления. Но вот что касается других критериев, например гибкости дизайна, то эти критерии вовсе не универсальны, а должны управляться функциональными и нефункциональными требованиями... вот у нас есть несколько наших библиотек, которые кочуют из проекта в проект, но их гибкость и "мощь архитектуры" наращиваются только в ответ на конкретные требования. Ну посмотри хотя бы на развитие того же BLT (за много лет!), который в первых версиях выглядел не столько ORM, сколько хелпером по генерации эффективных аксесоров.

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


D>Я не имею в виду конкретно способы обхода дерева, эти вещи в принципе тривиальны. Плох сам принцип. Преждевременная оптимизация зло — доказано теорией и проверено на практике.


Вообще-то смешно видеть, когда коллеги сами себе противоречат в непререкаемом тоне. Не так улыбают замеченные противоречия, как пафос при их декларации... Суммируя вышенагенеренный мною спам: оптимизация бывает не только по быстродействию — сей лозунг всего-навсего предостерегает от любых лишних трудозатрат, оправданность которых сугубо умозрительна.
Re[19]: вопрос к специалистам
От: Undying Россия  
Дата: 27.02.10 05:16
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>И что, без разницы какой размер списка?


Если можно гарантировать, что размер списка никогда не будет превышать десяток элементов, тогда да можно обойтись пробегом по списку для поиска. Но в подавляющем большинстве задач это гарантировать нельзя.
Re[20]: вопрос к специалистам
От: VladD2 Российская Империя www.nemerle.org
Дата: 27.02.10 14:33
Оценка: +1
Здравствуйте, Undying, Вы писали:

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


Дык 99% списков именно такие. И больше скажу для списков размером в 20 элементов в 90% случаев тоже не критично искать перебором.

Так что, как всегда, рулит одна простая истина — всегда надо думать головой!
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[18]: вопрос к специалистам
От: Dufrenite Дания  
Дата: 27.02.10 21:12
Оценка:
Здравствуйте, vdimas, Вы писали:

V>О да!

V>Знаешь, ты скорее говоришь о ситуации, когда люди увлекаются некоторыми подробностями и за деревьями им становится не видно леса. Но это совсем из другой оперы, оптимизация именно быстродействия чего-либо тут вовсе не при чем. Даже если и прозвучало "мы просто хотели сделать оптимальнее" — это обычная отмазка неопытного разработчика, которому хочется быстрее попрограммировать и быстрее увидеть результат. Стоит ли эту отмазку огульно приписывать всем остальным?

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

V>Как бы тебе это сказать потактичнее...


Потактичнее не надо. Я на правду-матку не обижаюсь.

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


Я занимаюсь разработкой игр. У нас почти никогда не делается "как положено". Извините, наболело. Под лозунгом повышения быстродействия прокатывают совершенно нереальные по своему убожеству архитектурные решения.

V>Точно так же может стать понятно, насколько гибким должен быть дизайн. За гибкость ВСЕГДА приходится платить, поэтому преждевременная гибкость — это такая же разновидность преждевременной оптимизации. Да, чем хуже формализованы требования, тем большая гибкость требуется относительно реализации каждого такого требования, но это лишь говорит о том, что ни о какой безусловности твоего лозунга не может быть и речи. Например, требуется ли эта "гибкость дизайна" при разработке кодека по устоявшемуся алгоритму или при реализации TCP протокола?


Не поспоришь.

V>Могу лишь согласиться с тем, что упомянутая тобой разновидность желания "сделать все лучше" не так тяжела в последствиях, как "битовыжимания", ибо наиболее вероятно такой код не придется выкидывать полностью. Но насколько получится его повторно использовать? В 99% не получается, кроме вот этого одного целевого приложения, поэтому вся эта заведомая гибкость лишь добавляет необоснованных трудозатрат.


Согласен. Я неоправданно распространил свои задачи на всю индустрию. По себе же скажу — сейчас разрабытаваю игровой движок, фактически технологию или фреймворк, называй как хочешь. Здесь приходится балансировать на острие ножа между требованиями производительности и гибкостью, так как повторное использование предполагается в нескольких проектах.

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


Не совсем. Вопрос в стоимости рефакторинга. Я уже говорил о том, что неумное оптимизирование приводит к масштабному переписыванию кода. Это как раз об этом. Если требуется рефакторинг, затрагивающий, например, 25% кода приложения, как это назвать? Катастрофа.

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


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

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


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

V>Достаточно не забывать о правилах хорошего тона. Например, если серверное приложение долго стартует, то это никого не интересует, но крайне раздражает пользователей в случае клиентских приложений. И не только во время старта — пользователей всегда раздражают случаи демонстрирования "тормознутости" программы. Но опять же, здесь не требуется выжимать разницу в миллисекунды, ибо юзер эту разницу не заметит все-равно... но когда с помощью лишней пары строк кода можно улучшить отклик в десятки раз (как раз обсуждалось), и не заставлять клиента нервничать несколько минут, то это сделать надо непременно. Я не призываю начинать разработку с этого (см. начало моего сообщения), но перед тем, как отдать клиенту — обязательно. И заметь, твоему лозунгу это никак не противоречит.


V>Вообще-то смешно видеть, когда коллеги сами себе противоречат в непререкаемом тоне. Не так улыбают замеченные противоречия, как пафос при их декларации...


Это не пафос. Я просто хотел потаскать за рога священную корову Павла Дворкина. Но он опытен и не поддался

V>Суммируя вышенагенеренный мною спам: оптимизация бывает не только по быстродействию — сей лозунг всего-навсего предостерегает от любых лишних трудозатрат, оправданность которых сугубо умозрительна.


Re[19]: вопрос к специалистам
От: vdimas Россия  
Дата: 27.02.10 23:45
Оценка: +1 -2
Здравствуйте, Dufrenite, Вы писали:

D>Это не пафос. Я просто хотел потаскать за рога священную корову Павла Дворкина. Но он опытен и не поддался


И что за манера поиска козла отпущения? Знаешь, охота на ведьм — это отличительная черта рунета, и этого сайта, в т.ч. В пылу спора походя присваивают оппоненту противоположное мнение и с треском его разбивают. Проблема только найти такого оппонента, что не так просто, ибо все обкатанные уже — где сядешь, там и слезешь... И вот он, Дворкин, ату его, ату!!! Фигли, он же сам же и напросился (хе, смелый, блин), а у нас как раз недостаток кого бы сжечь, прямо пальцы при виде клавы чешутся. И ты думаешь, Дворкина кто-нить вдумчиво читает? Да упрощают и выдергивают из контекста так, что у меня от такой молодецкой удали кофе бывает на клавиатуру разливается. Ситуация смогла зайти так далеко лишь потому, что Дворкина травят люди из админресурса, а он, судя по многолетнему наблюдению, до конца джентельмен. Т.е. там, где любой давно бы одернул увлекшихся коллег, возможно даже в грубой форме, он до конца пытается (вот наивный) вести осмысленный и порядочный диалог. А хрена толку, тебя в подворотне банда цинично насилует, а ты с ними уговорами...

Понимаешь, во всех этих темах про конкретные решения, без контекста говорить не о чем. Я бы усилил — это суть глубокое нубство, обсуждать тонкости решений без контекстов и требований. Дворкин практически всегда дает контекст, ровно как с тем же успехом это полностью игнорируется оппонентами. В стандартном местном шоу загонщики обычно приписывают словам жертвы универсальный характер, что ес-но обычно звучит провокационно... Но ведь именно это и требовалось, правда?
Re[19]: вопрос к специалистам
От: vdimas Россия  
Дата: 28.02.10 00:10
Оценка: 12 (3) +1
Здравствуйте, Dufrenite, Вы писали:

Столько написал только что, и ничего по делу, буду исправлять.

D>Может я и не прав, но у меня есть свое определение оптимизации: "оптимизация, это ухудшение качества кода с целью повышения его быстродействия".


Да ты экстремист.
На практике ровно наоборот, говнокод никогда не работает ни хорошо, ни быстро. Если быстрый код значительно отличается от небыстрого по эффективности, то в 90% случаев это говорит, что использовался другой алгоритм, а не другое "оформление" одного и того же алгоритма.

Про остальные 10% могу более подробно, ибо они гораздо чаще встречаются, хотя в 10 раз реже дают ту самую поразительную разницу в быстродействии, но иногда и 10%-20% прибавки уже неплохо, особенно когда такая ветка кода вызывается многие тысяч раз в секунду (надеюсь понятно, что я не точными цифрами оперирую, а даю оценку грубо? Сам я "числодроблю" последнее время кодеки и серверные миксеры голоса в VoIP, с потоковым real-time видео возился еще лет 10 назад, когда здесь этим никто толком не занимался, до этого однокристалки в самолетных системах выжимал до суха, так что мой субъективный опыт по эффективности примерно из этих областей). В общем да, иногда у недостаточно опытных разработчиков приходилось наблюдать желание отказаться от декомпозиции, превратить код в "лапшу", чтобы сэкономить на коссвености вызовов. Дык, надо просто поручить им провести сравнительное тестирование. Там сразу видно, что даже при большом кол-ве вложенных циклов, не имеет смысл оптимизировать вызовы никакого уровня, кроме 1-2-х самых глубоких. Например, без отказа от декомпозиции можно легко получать такие же точно результаты, если структуры обрабатываемых данных лежат на стеке по значению.
Т.е. сценарий прост:
— скопировали некую структуру из кучи на стек;
— прогнали "числодробильный" алгоритм по ней;
— скопировали результат в кучу обратно.

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


D>Я занимаюсь разработкой игр. У нас почти никогда не делается "как положено". Извините, наболело. Под лозунгом повышения быстродействия прокатывают совершенно нереальные по своему убожеству архитектурные решения.


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


D>Согласен. Я неоправданно распространил свои задачи на всю индустрию. По себе же скажу — сейчас разрабытаваю игровой движок, фактически технологию или фреймворк, называй как хочешь. Здесь приходится балансировать на острие ножа между требованиями производительности и гибкостью, так как повторное использование предполагается в нескольких проектах.


Ага, библиотеку разрабатываешь. Но опять же, даже в случае разработки библиотек, достаточно не закладывать в них "тупиков", т.е. тех решений, отказ от которых приведет в переделке всего клиентского, по отношению к библиотеке, кода. Обычно это означает, что из библиотеки должно как можно меньше торчать наружу внутренних подробностей или требований к "корректному протоколу использования библиотеки". Т.е. простая операция в клиентском коде, типа A=B+C, должна одинаково выглядеть и иметь ту же семантику даже после полной (будь такая надобность) переделки библиотечных кишок. Требуется ли здесь лишняя гибкость дизайна библиотеки? Нет, критерием тут является только низкая связанность "внутреннего" и "внешнего" кода, а необходимый минимальный уровень гибкости должен получаться автоматически, но не закладываться умозрительно. Т.е. стандартная ситуация: на каждой итерации проектирования мы порождаем более детальные функциональные требования к низлежащим уровням и корректируем/собираем нефункциональные требования к вышестоящим, исходя из обновленных более подробных представлениях о принципах работы собственной системы.

Да, разработка АПИ библиотек (не реализации, а именно ее АПИ) с одной стороны — искусство, с другой стороны — основные правила просты. Про низкую связанность уже упомянул. Теперь про оформление: АПИ библиотеки должен быть единообразным, я бы сказал, иметь некий узнаваемый "дух" (чтобы могли потом сказать — это сделано в духе такой-то либы). Единообразность и последовательность, как в именовании методов/параметров, порядка аргументов, так и в основных сценариях работы с либой, сделают ее удобной для использования, ввиду облегчения процесса запоминания связанной с либой информации.

В принципе, это все справедливо и для обычного кода любого проекта (ибо до 80-90% любого большого проекта — это "фреймворк" и прочие хелперы, т.е. суть — внутренняя библиотека), здесь разница лишь в приоритетах. Пусть есть шкала от "легче реализовать, но сложнее использовать" до "сложнее реализовать, легче использовать". Так вот, библиотеки на этой шкале, заведомо и сознательно разрабатываемые для многократного повторного использования или для продажи, лежат в крайне правой позиции, а все остальные внутренние "фрейморки" лежат вдоль всей этой шкалы, выбирая каждый раз такой компромисс, чтобы суммарная трудоемкость была минимальной.

D>Не совсем. Вопрос в стоимости рефакторинга. Я уже говорил о том, что неумное оптимизирование приводит к масштабному переписыванию кода. Это как раз об этом. Если требуется рефакторинг, затрагивающий, например, 25% кода приложения, как это назвать? Катастрофа.


Какой язык? Если С++, то да. Но, в свою очередь, С++ дает мощнейшие ср-ва для кодогенерации, для задания декларативных отношений м/у типами, типами и алгоритмами, алгоритмами и алгоритмами и т.д. Это уменьшает общую связанность, так что и надобность в таком глубоком рефакторинге обычно гораздо ниже ниже, ибо изначально имеющиеся ср-ва декомпозиции таковы, что даже и не снились тем же C#/Java/ObjectPascal.


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


D>Согласен, но. Если код библиотек измеряется миллионами строк, то без хорошо продуманной архитектуры обойтись невозможно.


То она сама должна состоять из нескольких достаточно независимых библиотек. Чем более независимы будут ее составные части, тем более плевать на цифру в мильон. По-другому никак. Да и мильон по нынешним временам цифра частовстречающаяся (если напугать хотел), это всего 10-30 человеколет, т.е. пара лет работы небольшому коллективу.


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


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


Че-то бардак с терминологией. "Оптимизация" — это улучшение чего-то уже существующего. В свою очередь "улучшение" означает сдвиг в положительную сторону одной/нескольких координат вектора оценки решения. Если быстродействие входит в оценку, то увеличение быстродействия всегда есть улучшение. Если не входит — то это "ничего", т.е. потраченное впустую время разработчика. Если качество кода не входит в оценку (как это бывает на небольших задачах или внутренних проектах), то им можно и нужно жертвовать. Если наоборот, то сам понимаешь. А твое определение оптимизации как минимум странное.

Напоследок, скажу страшную вещь, но ты не бойся. При достаточно хорошей декомпозиции все задачи становятся небольшими, угу. А значит... (см. выделенное) Не могу не оговориться, что минимальную культуру кода соблюдать надо по-любому, но это должно быть на уровне мозжечка. А вот что касается "качества" и красоты решения в маленьких задачах-кирпичиках — см. пред. абзац. И тогда вы легко сможете доводить до рабочего состояния даже большие проекты, "оптимизируя" впоследствии лишь, что надо, и в порядке наибольших приоритетов. Просто современный ПО-бизнес очень скотский по-сути, и идеалисты/перфекционисты очень быстро отмирают за невостребованностью...
Re[20]: вопрос к специалистам
От: IT Россия linq2db.com
Дата: 28.02.10 06:28
Оценка:
Здравствуйте, vdimas, Вы писали:

V>он до конца пытается (вот наивный) вести осмысленный и порядочный диалог.


Наивность в его возрасте и в должности преподавателя? Может здесь лучше подобрать другой "синоним"?
Если нам не помогут, то мы тоже никого не пощадим.
Re[21]: вопрос к специалистам
От: vdimas Россия  
Дата: 28.02.10 18:36
Оценка: +1
Здравствуйте, IT, Вы писали:


IT>Наивность в его возрасте и в должности преподавателя? Может здесь лучше подобрать другой "синоним"?


Ну да, не живет человек в нашем мире ПО-бизнеса, не обламывали ему начальники, заказчики и сорванные контракты рогов и не опускали с небес на грешную землю. Счастлив по-своему в своем параллельном мире, однозначно переживет нас всех. Что плохого-то?

И как ты ему прикажешь учить студентов? Преподавать, что реально требуется не качество решения, а сроки и умение "впаривать"? Нет уж, пусть лучше учит писать эффективные алгоритмы. Не использовать имеющиеся знания потом будет гораздо проще, чем использовать отсутствующие. Их и так будет макать в г-но пресловутого треугольника "деньги-время-качество" реальная многолетняя практика, и этому все-равно в теории не научишь. Да простят меня коллеги за выспренность, но преподаватель должен в первую очередь привить интерес к специальности, научить любить свою будущую профессию, лишь тогда будет хоть какая-то вероятность, что студенты чему-нить научатся в ВУЗе. Уверен, писать эффективные алгоритмы куда как интереснее, чем молотить десятки-сотни тысяч примитивнейших строк "бизнес-логики" (повторюсь, еще наедятся этого по самое не хочу), так что пусть пишут "интересненькое", грызут карандаши и ногти. А все эти наши обсуждения про "преждевременную оптимизацию", ИМХО яйца выеденного не стоят относительно процесса получения студентами фундаментальных знаний в области IT.
Re: Linq : неудачный маркетинг?
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 28.02.10 19:07
Оценка:
Здравствуйте, 0x7be, Вы писали:

0>Добрый день.


0>По опыту своих бесед с программистами, не знакомыми с linq, я собрал ряд стереотипных заблуждений и проблем с пониманеим linq, которые у них встречаются. В целом среди них преобладает такое мнение "это убогий SQL в С#, зачем он нужен?". Все попытки объяснить, что linq является воплощением аппарата операций над множествами, который ортогонален языку, и с необходимостью которого никто не спорит, сталкиваются с такой стеной непонимания. Это приводит меня к мысли, что linq подан неудачно. Его SQL-подобный синтаксис вызывает затруднения и у тех кто не знаком с SQL (выглядит больно непривычно) и у тех, кто знаком (не совсем понимают, что SQL делает в языке и сталкиваются с тем, что синтаксис всего лишь похож, а не повторяет SQL). Мое мнение по этому поводу: Linq — хорошая штука, но неудачно подан. Ваши мнения?


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

Постоянно встречаю людей который на yield return смотрят с удивлением, не говоря о большем.
Re[22]: вопрос к специалистам
От: IT Россия linq2db.com
Дата: 01.03.10 04:44
Оценка:
Здравствуйте, vdimas, Вы писали:

V>И как ты ему прикажешь учить студентов? Преподавать, что реально требуется не качество решения, а сроки и умение "впаривать"?


Битовыжимание и качество решения — это слегка разные вещи. Если бы Дворкин агитировал за последнее, то к нему вопросов не было бы совсем.

V>Нет уж, пусть лучше учит писать эффективные алгоритмы.


Битовыжимание и эффективные алгоритмы — это тоже слегка разные вещи.

V>Да простят меня коллеги за выспренность, но преподаватель должен в первую очередь привить интерес к специальности, научить любить свою будущую профессию, лишь тогда будет хоть какая-то вероятность, что студенты чему-нить научатся в ВУЗе.


Битовыжимание и любовь к профессии... ну ты понял.
Если нам не помогут, то мы тоже никого не пощадим.
Re[20]: вопрос к специалистам
От: Dufrenite Дания  
Дата: 01.03.10 05:53
Оценка:
Здравствуйте, vdimas, Вы писали:

V>И что за манера поиска козла отпущения? Знаешь, охота на ведьм — это отличительная черта рунета, и этого сайта, в т.ч. В пылу спора походя присваивают оппоненту противоположное мнение и с треском его разбивают. Проблема только найти такого оппонента, что не так просто, ибо все обкатанные уже — где сядешь, там и слезешь... И вот он, Дворкин, ату его, ату!!! Фигли, он же сам же и напросился (хе, смелый, блин), а у нас как раз недостаток кого бы сжечь, прямо пальцы при виде клавы чешутся. И ты думаешь, Дворкина кто-нить вдумчиво читает? Да упрощают и выдергивают из контекста так, что у меня от такой молодецкой удали кофе бывает на клавиатуру разливается. Ситуация смогла зайти так далеко лишь потому, что Дворкина травят люди из админресурса, а он, судя по многолетнему наблюдению, до конца джентельмен. Т.е. там, где любой давно бы одернул увлекшихся коллег, возможно даже в грубой форме, он до конца пытается (вот наивный) вести осмысленный и порядочный диалог. А хрена толку, тебя в подворотне банда цинично насилует, а ты с ними уговорами...


Я не пытаюсь самоутвердится за счет кого бы то ни было. Павел Дворкин мне показался интересным оппонентом для полемики. Только я переборщил с провокацией и он ушел в "глухую оборону".

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


Да никто вроде контекста и не скрывает. Каждый делится своим опытом.

V>Дворкин практически всегда дает контекст, ровно как с тем же успехом это полностью игнорируется оппонентами. В стандартном местном шоу загонщики обычно приписывают словам жертвы универсальный характер, что ес-но обычно звучит провокационно... Но ведь именно это и требовалось, правда?


Я за творчеством Дворкина, честно говоря, не слежу. По поводу его битв с админами, просматривал один топик: было эпично.
Re[2]: Linq : неудачный маркетинг?
От: Димчанский Литва http://dimchansky.github.io/
Дата: 02.03.10 09:40
Оценка:
Здравствуйте, IB, Вы писали:

IB>Сегодня Эрик Мейер начал лекцию со слов "Do you understand LINQ?". очень в тему.. )


Может в записи есть?
Re[3]: Linq : неудачный маркетинг?
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 02.03.10 10:13
Оценка:
Здравствуйте, Димчанский, Вы писали:

Д>Может в записи есть?


Нет, NDA.
... << RSDN@Home 1.2.0 alpha 4 rev. 1464 on Windows 7 6.1.7600.0>>
AVK Blog
Re[4]: Linq : неудачный маркетинг?
От: Димчанский Литва http://dimchansky.github.io/
Дата: 02.03.10 13:07
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Нет, NDA.


А, так это на MVP summit'е было?
А то у нас коллега один тоже съездил на него, приехал, а толком рассказать ничего не может, говорит NDA в этом году ввели явное.
Re[5]: Linq : неудачный маркетинг?
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 02.03.10 13:12
Оценка:
Здравствуйте, Димчанский, Вы писали:

Д>А, так это на MVP summit'е было?


Да.

Д>А то у нас коллега один тоже съездил на него, приехал, а толком рассказать ничего не может, говорит NDA в этом году ввели явное.


В этом году никаких отличий нет, саммит всегда под NDA был. И ничего сверхсекретного тоже особо не рассказывали. Просто перестраховка на предмет "вы обещали и не сделали".
... << RSDN@Home 1.2.0 alpha 4 rev. 1464 on Windows 7 6.1.7600.0>>
AVK Blog
Re[6]: Linq : неудачный маркетинг?
От: Димчанский Литва http://dimchansky.github.io/
Дата: 02.03.10 13:53
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>В этом году никаких отличий нет, саммит всегда под NDA был. И ничего сверхсекретного тоже особо не рассказывали. Просто перестраховка на предмет "вы обещали и не сделали".


Потому и обидно, что вроде как ничего сверхсекретного, а закрыто за замком. Особенно, когда такие положительные отзывы о докладе.
А может можно в двух словах показать здесь почему мы не знаем/не понимаем LINQ?
Re[7]: Linq : неудачный маркетинг?
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 02.03.10 14:41
Оценка: 7 (2) +1
Здравствуйте, Димчанский, Вы писали:

Д>А может можно в двух словах показать здесь почему мы не знаем/не понимаем LINQ?


Потому что за линком стоит довольно суровая математика, точнее пара разделов из теории категорий. Эрик просто привел это в качестве примера того, как хардкорная математика, при условии грамотного сахара, становится простой и понятной.
... << RSDN@Home 1.2.0 alpha 4 rev. 1464 on Windows 7 6.1.7600.0>>
AVK Blog
Re[20]: вопрос к специалистам
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 03.03.10 15:35
Оценка:
Здравствуйте, vdimas, Вы писали:

V>Ситуация смогла зайти так далеко лишь потому, что Дворкина травят люди из админресурса, а он, судя по многолетнему наблюдению, до конца джентельмен. Т.е. там, где любой давно бы одернул увлекшихся коллег, возможно даже в грубой форме, он до конца пытается (вот наивный) вести осмысленный и порядочный диалог. А хрена толку, тебя в подворотне банда цинично насилует, а ты с ними уговорами...


Чуть не выплеснул кофе на клавиатуру
Люди из адмнресурса вероятно более стойкие в среднем по контингенту сайта, не отчаялись и не прекращают вернуть его на путь истинный.
Re[20]: вопрос к специалистам
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 03.03.10 15:44
Оценка:
Здравствуйте, vdimas, Вы писали:

D>>Не совсем. Вопрос в стоимости рефакторинга. Я уже говорил о том, что неумное оптимизирование приводит к масштабному переписыванию кода. Это как раз об этом. Если требуется рефакторинг, затрагивающий, например, 25% кода приложения, как это назвать? Катастрофа.


V>Какой язык? Если С++, то да. Но, в свою очередь, С++ дает мощнейшие ср-ва для кодогенерации, для задания декларативных отношений м/у типами, типами и алгоритмами, алгоритмами и алгоритмами и т.д. Это уменьшает общую связанность, так что и надобность в таком глубоком рефакторинге обычно гораздо ниже ниже, ибо изначально имеющиеся ср-ва декомпозиции таковы, что даже и не снились тем же C#/Java/ObjectPascal.


Людей, которые понимают С++ на таком уровне раз-два и обчелся. Кроме того, напши ты хучь самый лучший код, через год-два его все равно придется рефакторить.
Re[21]: вопрос к специалистам
От: vdimas Россия  
Дата: 03.03.10 16:24
Оценка: +1 -1
Здравствуйте, Ikemefula, Вы писали:

I>Люди из адмнресурса вероятно более стойкие в среднем по контингенту сайта, не отчаялись и не прекращают вернуть его на путь истинный.


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

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

Поверь человеку, наблюдающему эти безобразия несколько лет — там дальше вымышленных формулировок и додумываний за оппонента еще ни разу дело не дошло. НИ РАЗУ за многие годы. Вот пример из последнего: http://www.rsdn.ru/forum/philosophy/3720169.aspx
Автор: vdimas
Дата: 28.02.10

И это пишет человек, который когда-то начал разработку RFD (бывшее BLT) с задачи оптимизации быстродействия аксессоров и решил ее наиболее "битовыжимным" способом изо всех имеющихся. Что характерно, поступил вполне правильно, что лишь показывает, что задачи-то разные бывают.

В общем, бывает ситуации, когда стыдно за других людей. Здесь та самая ситуация, ибо налицо демонстрация косности мышления и склонности к развешиванию ярлыков.
Re[21]: вопрос к специалистам
От: vdimas Россия  
Дата: 03.03.10 17:06
Оценка:
Здравствуйте, Ikemefula, Вы писали:

I>Людей, которые понимают С++ на таком уровне раз-два и обчелся.


Да ладно, если разработчики пишут пишут typedef чего-то MyContainer, затем MyContainer::iterator и пользуют хотя бы std::char_traits<TCHAR>::length(str), то понимают, а раз понимают — могут использовать в собственных разработках.


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


Мне почти ежедневно рефакторить приходится. Простой рефакторинг делает уже и VisualAssist, а от сложного убегаем через систему декларативных typedef. Опять же, явная или частичная специализация шаблонов — мега инструмент сам по себе. Я пишу довольно много и на С++ и на C#... так вот, в C# настолько не хватает явной специализации шаблонов (т.е. генериков), просто трындец (я уже молчу о частичной специализации). Абсолютно на ровном месте надо использовать тонну лишних, т.е. не относящихся к конечной цели задачи, паттернов, типа фабрик, адаптеров и прочих костылей. И что характерно, вот это все безобразие в дотнете зовется "исскуством дизайна".
Re[22]: вопрос к специалистам
От: IT Россия linq2db.com
Дата: 04.03.10 01:17
Оценка: +1
Здравствуйте, vdimas, Вы писали:

V>Поверь человеку, наблюдающему эти безобразия несколько лет — там дальше вымышленных формулировок и додумываний за оппонента еще ни разу дело не дошло. НИ РАЗУ за многие годы. Вот пример из последнего: http://www.rsdn.ru/forum/philosophy/3720169.aspx
Автор: vdimas
Дата: 28.02.10


Сам по ссылке ходил?

V>И это пишет человек, который когда-то начал разработку RFD (бывшее BLT) с задачи оптимизации быстродействия аксессоров и решил ее наиболее "битовыжимным" способом изо всех имеющихся. Что характерно, поступил вполне правильно, что лишь показывает, что задачи-то разные бывают.


Он ещё буквально вчера закомитил самый быстрый в мире ObjectMapper

V>В общем, бывает ситуации, когда стыдно за других людей. Здесь та самая ситуация, ибо налицо демонстрация косности мышления и склонности к развешиванию ярлыков.


В том то и дело, что Дворкин похоже не понимает, что ситуации бывают разные. У него она одна — сложение матриц на C. Даже когда ему приводят пример чтения последней строчки небольшого файла, реализованного в пол строчки кода в ситуации, когда лишние 10 ms не имеют значения, он всё равно доказывает с пеной у рта, что решать задачу нужно наиболее эффективным способом, пусть даже у нас вместо одной строки кода будет две сотни. Бред.

А насчёт оптимизаций у меня или у Влада, то, конечно же, мы ими занимаемся и занимаемся серьёзно. И не только на уровне битовыжиманий, но и, главное, на уровне архитектуры. Но только приоритеты у нас сильно отличаются от приоритетов Дворкина. У него — оптимизация всего любой ценой. У нас — только там где она необходима.
Если нам не помогут, то мы тоже никого не пощадим.
Re[22]: вопрос к специалистам
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 04.03.10 07:32
Оценка:
Здравствуйте, vdimas, Вы писали:

VI>>Люди из адмнресурса вероятно более стойкие в среднем по контингенту сайта, не отчаялись и не прекращают вернуть его на путь истинный.


V>Какой еще "истинный путь"? Не мели хоть ты ерунды.

V>Не заметил разве, что все выводы относительно Дворкина исключительно умозрительные?

Хороший примр про memory mapped file. Там, ближе к концу дискуссии, очень хорошо заметно.
http://rsdn.ru/forum/philosophy/3591979.flat.10.aspx
Автор: kochetkov.vladimir
Дата: 05.11.09


У меня, например, терпения на подобное не хватает, потому я сижу в КСВ а не здесь.

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

>, объясни мне, непонятливому, оппоненты Дворкина могут знать, насколько нужны или излишни его конкретные "оптимизации" и каков их реальный уровень?

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

V>Поверь человеку, наблюдающему эти безобразия несколько лет — там дальше вымышленных формулировок и додумываний за оппонента еще ни разу дело не дошло. НИ РАЗУ за многие годы. Вот пример из последнего: http://www.rsdn.ru/forum/philosophy/3720169.aspx
Автор: vdimas
Дата: 28.02.10


Это не пример, а ссылка на твое сообщение, в котором ты утверждаешь что люди несправедливы к Дворкину

V>И это пишет человек, который когда-то начал разработку RFD (бывшее BLT) с задачи оптимизации быстродействия аксессоров и решил ее наиболее "битовыжимным" способом изо всех имеющихся. Что характерно, поступил вполне правильно, что лишь показывает, что задачи-то разные бывают.


Вероятно, ты про ИТ ? Я вроде все прочел, но не могу найти конкретно то о чем ты говоришь. Дай более другую ссылку.
Re[23]: вопрос к специалистам
От: vdimas Россия  
Дата: 04.03.10 12:03
Оценка: 3 (1)
Здравствуйте, IT, Вы писали:

IT>Сам по ссылке ходил?


Бывает... А тут ходил: http://www.rsdn.ru/forum/rsdn/3703996.1.aspx
Автор: vdimas
Дата: 14.02.10


IT>Он ещё буквально вчера закомитил самый быстрый в мире ObjectMapper


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

V>>В общем, бывает ситуации, когда стыдно за других людей. Здесь та самая ситуация, ибо налицо демонстрация косности мышления и склонности к развешиванию ярлыков.


IT>В том то и дело, что Дворкин похоже не понимает, что ситуации бывают разные. У него она одна — сложение матриц на C. Даже когда ему приводят пример чтения последней строчки небольшого файла, реализованного в пол строчки кода в ситуации, когда лишние 10 ms не имеют значения, он всё равно доказывает с пеной у рта, что решать задачу нужно наиболее эффективным способом, пусть даже у нас вместо одной строки кода будет две сотни. Бред.


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

Тут все-навсего надо пользоваться здравым смыслом, а он обязательно включает в рассмотрение степень известности параметров задачи, например:
1. Если заведомо известно, что файл будет адекватного размера, то сделать наипростейшим образом и забыть.
2. Если п.1. неизвестен, прикинуть стоимость разработки варианта, которому пофиг размер файла (для данной задачи — это, например, чтение страницами некоторого размера с конца файла). Если стоимость разработки гораздо меньше затрат на выяснение п.1, то однозначно сделать этот "эффективный вариант" и забыть.
3. Если стоимость после прикидки получается дороже, чем затраты на выяснение, то сделать "заглушку" в виде п.1. и добавить еще один вопрос к списку оных, требующих дальнейшего уточнения.

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

Конкретно по этой задаче, если данных по предполагаемому размеру файла у меня нет, то однозначно выходит п.2., ибо там не 200 строк, а 10+/-, и времени — 5-10 минут всего (разработка+тестирование+замер скорости), что несоизмеримо меньше, чем все затраты на уточнение вопроса. А не уточнить и оставить "заглушечный" вариант в надежде на "авось" я тоже не могу, это как бы культура разработки, раскидывать коровьи лепешки по коду, над которым работаю не только я, порядочному человеку не пристало.

Почему 10 мин всего для такого числа операций? Есть наготове "рыбы" для всех задач (именно для того они и есть). Откуда взял, что десяток+/- строк, вот примерный псевдокод:

string ReadLastRow(File file) {
  int pos = file.Size;  

  while(pos != 0) {
    pos -= PAGE_SIZE; // resonable max row size, for ex. 4k
    if(pos<0)
      pos = 0;

    file.Seek(pos);
    string page = file.read(pos, PAGE_SIZE);
    int pagePos = page.findLastOf('\n');
  
    if(pagePos != -1)
      return file.ReadToEnd(pos+pagePos+1);
  }

  return file.Read(0, file.Size);
}


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

IT>А насчёт оптимизаций у меня или у Влада, то, конечно же, мы ими занимаемся и занимаемся серьёзно. И не только на уровне битовыжиманий, но и, главное, на уровне архитектуры. Но только приоритеты у нас сильно отличаются от приоритетов Дворкина. У него — оптимизация всего любой ценой. У нас — только там где она необходима.


Да он вроде всегда открещивается от твоего "оптимизация всего любой ценой" и говорит, что грошовые оптимизации его не интересуют, а лишь те, где выигрыш существеннен. Зачем же так игнорировать позицию оппонента? Если в этой задаче про последнюю строку в файле были бы заранее известны параметры, позволившие утверждать, что выигрыш грошовый, то он с тобой согласиться, и предмет спора как бы исчезнет сам собой.

Тебя не удивило, что я там проговорился насчет Yet Another Logger? Смешно да? Хочешь, еще смешнее сделаю? Мне надо было выиграть десятки-сотни микросекунд на одной операции логгирования, поэтому — очередной самописный. Ну вот попадаются задачи, где требуется выигрывать миллисекунды и меньше, это целые огромные сегменты софта, и там тоже полно разработчиков и есть свой устоявшийся менталитет, немного отличный от "однострочного чтения файла".
Re[23]: вопрос к специалистам
От: vdimas Россия  
Дата: 04.03.10 12:26
Оценка:
Здравствуйте, Ikemefula, Вы писали:


I>Хороший примр про memory mapped file. Там, ближе к концу дискуссии, очень хорошо заметно.

I>http://rsdn.ru/forum/philosophy/3591979.flat.10.aspx
Автор: kochetkov.vladimir
Дата: 05.11.09


Я ее всю не осилил, ибо слишком много уже было подобных дискуссий, можно чуть конкретнее, чтобы было видно, что оппонент "загоняет"?


I>Это не пример, а ссылка на твое сообщение, в котором ты утверждаешь что люди несправедливы к Дворкину


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

Мне, если честно, плохо понятен термин "битовыжимание". Я понимаю, что туда вкладывают много негатива, но хотелось бы достоверных доказательств, что весь этот негатив применим к оппоненту, т.е. что не используется банальное развешивание ярлыков. Мой поинт таков, что если задачи требуют "битовыжимания", значит закатили рукава и битовыжимаем. Например, в кодеках я "битовыжимаю" за счет чтения/записи потока байт в локальные переменные пословно, т.е. по 4 или 8 байт за раз, и затем уже чистая битовая арифметика в регистрах, и аналогичные приемы-приседания во многих местах. Понятное дело, что лишние строки кода и т.д., но это реально улучшает показатели кодека, 10-20% быстродействия на дороге не валяется, особенно на серверной стороне. Комплекс всех этих битовыжиманий позволил, по сравнению с начальным вариантом, каждой отдельной железке обслуживать в 2-3 раза больше клиентов (от используемых кодеков зависит), а это очень хорошее конкурентное преимущество, особенно в сравнении сценариев, когда достаточно одной железки или 2-х. Это для многих клиентов целая пропасть разницы в требовании к развертыванию, т.е. не столько отличается сценарий 2-х и более железок, как одной и более.

Поэтому, ключевое слово здесь не "битовыжимание", а "требуется/не требуется", только вот об этом и можно рассуждать. Полезные были бы рассуждения относительно критериев и практик принятия решений, а так же соотношения синтетических тестов и "боевых". К сожалению, 99% процентов обсуждений на эту тему — это спам о "высоком", который можно сразу в топку.


I>Вероятно, ты про ИТ ? Я вроде все прочел, но не могу найти конкретно то о чем ты говоришь. Дай более другую ссылку.


Ну, если не в курсе, разработка его BLT ORM (тогда еще RFD) началась с того, что IT экспериментировал с "битовыжиманием" относительно реализации аксессоров для полей и св-в в системе .Net. Эксперимент вышел более-менее удачный, и дальше пошло-поехало.
Re[24]: вопрос к специалистам
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 04.03.10 14:25
Оценка:
Здравствуйте, vdimas, Вы писали:

V>Ну, если не в курсе, разработка его BLT ORM (тогда еще RFD) началась с того, что IT экспериментировал с "битовыжиманием" относительно реализации аксессоров для полей и св-в в системе .Net.


Это скорее ты не в курсе.
... << RSDN@Home 1.2.0 alpha 4 rev. 1464 on Windows 7 6.1.7600.0>>
AVK Blog
Re[25]: вопрос к специалистам
От: vdimas Россия  
Дата: 04.03.10 14:55
Оценка:
Здравствуйте, AndrewVK, Вы писали:


V>>Ну, если не в курсе, разработка его BLT ORM (тогда еще RFD) началась с того, что IT экспериментировал с "битовыжиманием" относительно реализации аксессоров для полей и св-в в системе .Net.


AVK>Это скорее ты не в курсе.


Как бы практически с первых версий использовал, c конца 2003-го, и могу сравнивать с тем, что сейчас. Ввиду ндостаточности функционала маппинга на тот момент мы встроенный маппинг не использовали вообще (и не только из-за лишнего боксинга каждого значения), так же как не использовали встроенную систему конфигурации. А вот автогенеренные аксессоры — аж бегом, остальное дописали сами.
Re[26]: вопрос к специалистам
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 04.03.10 16:39
Оценка:
Здравствуйте, vdimas, Вы писали:

V>Как бы практически с первых версий использовал


С первых публичных версий. Это во-первых. А во-вторых это совершенно никак не говорит о твоем знании мотивов, по которым RFD создавался.

V>Ввиду ндостаточности функционала маппинга на тот момент мы встроенный маппинг не использовали вообще


Какой встроенный маппинг? Ты о чем? RFD делался для замены прямой рукопашной выборки из DataReader. Ты переносишь свои личные мотивы его использования на IT.
... << RSDN@Home 1.2.0 alpha 4 rev. 1464 on Windows 7 6.1.7600.0>>
AVK Blog
Re[27]: вопрос к специалистам
От: vdimas Россия  
Дата: 04.03.10 17:04
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Какой встроенный маппинг? Ты о чем? RFD делался для замены прямой рукопашной выборки из DataReader.


Это не есть маппинг?
Re[24]: вопрос к специалистам
От: Silver_s Ниоткуда  
Дата: 04.03.10 17:33
Оценка:
Кстати, по поводу битовыжимания. Жаль что C# компилятор с включенной оптимизацией не достаточно этим занимается.
Полезность LINQ to Objects значительно бы повысилась, если бы глубокая оптимизация была.
Некоторые итераторы с последующим использованием можно было бы вобще раскрывать к обычным циклам — не понятно в чем здесь сложности.
Может разработчики кодогенераторов тоже считают "битовыжимание" ругательным словом?
Слишком уж быстро код генерируется на C# с включенной оптимизацией — компилятор должен 2-10 минут работать над средним проектом, а не 2-5 секунд. (но не засчет Thread.Sleep() конечно)

А что касается студентов, им очень полезно в битовыжиманиях поупражняться.
Re[28]: вопрос к специалистам
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 04.03.10 17:37
Оценка:
Здравствуйте, vdimas, Вы писали:

AVK>>Какой встроенный маппинг? Ты о чем? RFD делался для замены прямой рукопашной выборки из DataReader.


V>Это не есть маппинг?


Встроенный маппинг, который тормознее BLT? Нет, это маппинг рукопашный. И RFD не для улучшения его производительности создавался, а для уменьшения количества ручной работы. И эмит (ты, видимо, его имеешь ввиду) там использовался как единственная альтернатива рефлекшену, для которого заранее было известно, что производительность его неудовлетворительная, а не для битовыжимания в качестве основной цели.
... << RSDN@Home 1.2.0 alpha 4 rev. 1464 on Windows 7 6.1.7600.0>>
AVK Blog
Re[25]: вопрос к специалистам
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 04.03.10 17:44
Оценка:
Здравствуйте, Silver_s, Вы писали:

S_>Кстати, по поводу битовыжимания. Жаль что C# коппилятор с включенной оптимизацией не достаточно этим занимается.

S_>Полезность LINQ to Objects значительно бы повысилась, если бы глубоуая оптимизация была.

Для этого не компилятор надо наворачивать, а CLR дорабатывать. Например, Эрик Мейер считает, что yield должен быть специальной инструкцией IL, а не раскрываться компилятором.

S_>Слишком уж быстро код генерируется на C# с включенной оптимизацией — компилятор должен 2-10 минут работать над средним проектом, а не 2-5 секунд. (но не засчет Thread.Sleep() конечно)



Скорость компилятора такая не из-за отсутствия оптимизаций, а из-за отсутствия замшелых принципов организации исходников. Сейчас все современные компилируемые языки компилируются на порядки быстрее С++.
... << RSDN@Home 1.2.0 alpha 4 rev. 1464 on Windows 7 6.1.7600.0>>
AVK Blog
Re[26]: вопрос к специалистам
От: Silver_s Ниоткуда  
Дата: 04.03.10 18:47
Оценка:
Здравствуйте, AndrewVK, Вы писали:

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


S_>>Кстати, по поводу битовыжимания. Жаль что C# коппилятор с включенной оптимизацией не достаточно этим занимается.

AVK>Для этого не компилятор надо наворачивать, а CLR дорабатывать. Например, Эрик Мейер считает, что yield должен быть специальной инструкцией IL, а не раскрываться компилятором.

Это конечно некоторые возможности откроет. Но все же не все конструкции имеет смысл до IL доводить.
Например кто-то обкурится и напишет :
foreach (var i in Enumerable.Range(2, 200000))
...;
вместо
for (int i = 2; i <= 200000; i++)

Но тем не менее, имеет полное моральное право, ожидать чтобы код работал с такой же скоростью что и for(;)
Сейчас он раз в 10 медленнее. И не видно,вроде, каких-то принципиальных проблем чтобы это компилятором проинлайнилось.
(Не данный частный случай, а вобще подобные конструкции)

S_>>Слишком уж быстро код генерируется на C# с включенной оптимизацией — компилятор должен 2-10 минут работать над средним проектом, а не 2-5 секунд. (но не засчет Thread.Sleep() конечно)


AVK>

AVK>Скорость компилятора такая не из-за отсутствия оптимизаций, а из-за отсутствия замшелых принципов организации исходников. Сейчас все современные компилируемые языки компилируются на порядки быстрее С++.

Ну 10 минут это допустимый предел чтобы пользователи компилятора плеваться не начали. Release не часто собирать приходится.
Re[27]: вопрос к специалистам
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 04.03.10 18:57
Оценка:
Здравствуйте, Silver_s, Вы писали:

S_>Сейчас он раз в 10 медленнее. И не видно,вроде, каких-то принципиальных проблем чтобы это компилятором проинлайнилось.


В случае компилятора как раз таки принципиальная проблема есть — компилятор не имеет права инлайнить код из других сборок. А вот JIT такое вполне может делать.

S_>Ну 10 минут это допустимый предел чтобы пользователи компилятора плеваться не начали.


Сильная оптимизация, оставаясь в рамках IL — не очень разумный подход. Скорее наборот — IL должен быть как можно проще, чтобы меньше проблем создавать оптимизатору JIT.
... << RSDN@Home 1.2.0 alpha 4 rev. 1464 on Windows 7 6.1.7600.0>>
AVK Blog
Re[29]: вопрос к специалистам
От: vdimas Россия  
Дата: 04.03.10 20:18
Оценка:
Здравствуйте, AndrewVK, Вы писали:

Обалдеть, что и требовалось, спасибо.

AVK>Встроенный маппинг, который тормознее BLT? Нет, это маппинг рукопашный. И RFD не для улучшения его производительности создавался, а для уменьшения количества ручной работы. И эмит (ты, видимо, его имеешь ввиду) там использовался как единственная альтернатива рефлекшену, для которого заранее было известно, что производительность его неудовлетворительная, а не для битовыжимания в качестве основной цели.


Насчет заранее спасибо и насчет "основной цели" особенно. Скажи, ты всерьез веришь, что у разработчиков с опытом могут быть битовыжимания в качестве "основной цели", а не средства? Я вот не верю, и среди коллег ни разу таких не встречал за 17 лет работы. Поэтому оправданно, на мой взгляд, пессимистичен, когда подобное настойчиво пытаются кому-то приписать.
Re[28]: вопрос к специалистам
От: vdimas Россия  
Дата: 04.03.10 20:21
Оценка:
Здравствуйте, AndrewVK, Вы писали:


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


А у того потенциально меньше времени, т.к. загрузку стараются ускорить.
Re[28]: вопрос к специалистам
От: Silver_s Ниоткуда  
Дата: 04.03.10 20:46
Оценка:
Здравствуйте, AndrewVK, Вы писали:

S_>>Сейчас он раз в 10 медленнее. И не видно,вроде, каких-то принципиальных проблем чтобы это компилятором проинлайнилось.

AVK>В случае компилятора как раз таки принципиальная проблема есть — компилятор не имеет права инлайнить код из других сборок. А вот JIT такое вполне может делать.
Да, неалгоритмические проблемы есть с этим делом, когда не доступны исходники при компиляции.
При том что пользователь компилятора, в большинстве случаев бы не возражал, если бы созданные бинарники навсегда бы привязались к конкретной версии внешнего бинарника(например System.Core). И на этом основании компилятор выдирал бы оттуда функции, произвольно их переделывал и вставлял их аналоги в создаваемые бинарники. (yield тогда нужен прямо в IL)
Re[30]: вопрос к специалистам
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 05.03.10 06:04
Оценка:
Здравствуйте, vdimas, Вы писали:

V>Насчет заранее спасибо и насчет "основной цели" особенно. Скажи, ты всерьез веришь, что у разработчиков с опытом могут быть битовыжимания в качестве "основной цели", а не средства?


Верю.
... << RSDN@Home 1.2.0 alpha 4 rev. 1464 on Windows 7 6.1.7600.0>>
AVK Blog
Re[29]: вопрос к специалистам
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 05.03.10 06:04
Оценка:
Здравствуйте, vdimas, Вы писали:

V>А у того потенциально меньше времени, т.к. загрузку стараются ускорить.


Есть варианты. Например ngen.
... << RSDN@Home 1.2.0 alpha 4 rev. 1464 on Windows 7 6.1.7600.0>>
AVK Blog
Re[29]: вопрос к специалистам
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 05.03.10 06:04
Оценка:
Здравствуйте, Silver_s, Вы писали:

S_> Да, неалгоритмические проблемы есть с этим делом, когда не доступны исходники при компиляции.


IL практически эквивалентен исходникам в плане полноты информации.
... << RSDN@Home 1.2.0 alpha 4 rev. 1464 on Windows 7 6.1.7600.0>>
AVK Blog
Re[29]: вопрос к специалистам
От: vdimas Россия  
Дата: 05.03.10 08:45
Оценка:
Здравствуйте, AndrewVK, Вы писали:


AVK>Встроенный маппинг, который тормознее BLT? Нет, это маппинг рукопашный. И RFD не для улучшения его производительности создавался, а для уменьшения количества ручной работы. И эмит (ты, видимо, его имеешь ввиду) там использовался как единственная альтернатива рефлекшену, для которого заранее было известно, что производительность его неудовлетворительная, а не для битовыжимания в качестве основной цели.


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

Но суть позиции мне непонятна все-равно. Ты рядом написал "верю", хотя я и сказал о разработчиках с опытом (неопытных надо не ругать а учить, или увольнять в клинических случаях). Почитать вот эти все советы, так начинает казаться, что опыт — это всего лишь приобретенная осторожность, вот мол, не делайте лишней работы и прочие сопли. Дудки, опыт — это прежде всего адекватная оценка собственных знаний и способностей. А это значит, что где знаний достаточно — наоборот нужно быть как можно более решительным и заранее отметать тупиковые варианты, проявляя осторожность лишь там, где информации/наработок недостаточно. Иначе бенефитов от опытности не будет, если каждый раз заново все макетировать, чтобы ни дай бог написать чего лишнего. Понятно, что там не только "черное и белое", "знаю/не знаю", главное — уметь правильно себя на этом градиенте спозиционировать относительно решаемого вопроса.

Так вот, раз уж сказано почти все, могу и открытым текстом: все откровенно выглядит так, будто кое-кто отказывает коллегам в способности принимать решения, не отказывая в то же время самому себе, любимому. И Дворкин здесь выглядит как классический мальчик для битья, если ты понимаешь о чем речь.
Re[25]: вопрос к специалистам
От: vdimas Россия  
Дата: 05.03.10 08:52
Оценка:
Здравствуйте, Silver_s, Вы писали:

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


+1
Мне тоже так кажется, мозги полезно поупражнять в нужном направлении, особенно на тех задачах, которые понимаешь полностью... ИМХО, улучшение производительности через "повышение эффективности архитектурных решений" вряд ли осилит больше, чем 1-2 человека на потоке, и то, если повезет, ибо без реальной практики все эти слова — пустой звук.
Re[30]: вопрос к специалистам
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 05.03.10 14:25
Оценка:
Здравствуйте, vdimas, Вы писали:

V>"По быстрому" там делается за один вечер на коленке через генерацию исходников


Это менее удобно в использовании.

Остальная куча текста к обсуждаемому непонятно как относится.
... << RSDN@Home 1.2.0 alpha 4 rev. 1464 on Windows 7 6.1.7600.0>>
AVK Blog
Re[24]: вопрос к специалистам
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 05.03.10 15:39
Оценка: 8 (1) +2
Здравствуйте, vdimas, Вы писали:

I>>Хороший примр про memory mapped file. Там, ближе к концу дискуссии, очень хорошо заметно.

I>>http://rsdn.ru/forum/philosophy/3591979.flat.10.aspx
Автор: kochetkov.vladimir
Дата: 05.11.09


V>Я ее всю не осилил, ибо слишком много уже было подобных дискуссий, можно чуть конкретнее, чтобы было видно, что оппонент "загоняет"?


Там все не надо, вот, краткое содержание

PD>Если не секрет, объясни, как реализовать обращение к этому Last в процессе обычной энумерации. То есть идем себе и идем по коллекции, потом захотели Last, а потом продолжаем идти с того места, где остановились... Чудо, а не код получится

S>Никаких чудес. На всякий случай напомню, что IEnumerable — это всего лишь способ получения IEnumerator. И у одного IEnumerable можно получить сколько угодно одновременно активных енумераторов.
PD>При открытии файлмэппинга никакой IEnumerable получить нельзя, потому что нечего энумерировать.
S>Рекомендую на досуге ознакомиться с определением IEnumerable и глупостей больше не писать.
PD>Я, конечно, виноват, что перепутал IEnumerable с IEnumerator . В оправдание свое могу сказать, что , честно говоря, мне они оба даром не нужны. Их на С/C++ нет и без них я до сих пор вполне обходился там и буду дальше.
AVK>Аргумент.
PD>Так что, как видишь, аргумент вполне обоснованнный. Если не согласен — поясни, как их к обычному С++ прикрутить.
FR>Да нормально они к C++ прикручиваются, я подобные классы еще когда NET не было использовал:
PD>Речь идет об интерфейсах. Их в языке С++ нет.

Вот теперь сравни начало и конец. И везде гд учавствует Дворкин, такое на каждой странице.

V>Да, промахнулся, там ниже пост IT, который сравнивал "битовыжимание" с другими качествами преподавателя. Хотел показать как пример, где весь пост — суть игра терминов.


Битовыжимание у Дворкина, он готов буквально этим заниматься.

V>Мне, если честно, плохо понятен термин "битовыжимание". Я понимаю, что туда вкладывают много негатива, но хотелось бы достоверных

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

Если

1 задача требует,
2 место, где используется эта самая задача является узким местом
3 на все это установлен соответствующий приоритет
4 есть время для устранения сайдэффектов которыми богато битовыжимание

— то нужно заняться битовыжиманием.

V>Поэтому, ключевое слово здесь не "битовыжимание", а "требуется/не требуется", только вот об этом и можно рассуждать.


Разумеется и вот здесь у Дворкина начинаются сильные проблемы — он отказывается принять точку зрения отличную от его собственной.

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

Я как то не заметил такого у Дворкина. Он праведно возмущается при любом проявлении неэффективного кода.

V>Ну, если не в курсе, разработка его BLT ORM (тогда еще RFD) началась с того, что IT экспериментировал с "битовыжиманием" относительно реализации аксессоров для полей и св-в в системе .Net. Эксперимент вышел более-менее удачный, и дальше пошло-поехало.


Акцессоры для полей-свойств часто становятся самым узким местом в системе. Если взять например persistance то здесь получается выбор решения определяется именно скоростью доступа к свойствам-полям.

Например при высоких требованиях к скорости этого персистанца получается так, есть быстрый доступ — тогда можно взять простой обход графа объектов. Есть только медленный — тогда уже нужна генерация кода например или сложная какая схема. Тут сложности разница примерно на два порядка.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.